diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2018-12-13 17:40:27 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-13 17:40:27 -0800 |
commit | 3325a9cc203932e58b6e85dfefe5feb6e72839a4 (patch) | |
tree | 1d969ab30854fd773fdc615d799c9a9ed7e9c0be /src/ir | |
parent | 0fd96e6b07f0a0907737c0f44e55060e057c2bb9 (diff) | |
download | binaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.tar.gz binaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.tar.bz2 binaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.zip |
SIMD (#1820)
Implement and test the following functionality for SIMD.
- Parsing and printing
- Assembling and disassembling
- Interpretation
- C API
- JS API
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/ExpressionAnalyzer.cpp | 71 | ||||
-rw-r--r-- | src/ir/ReFinalize.cpp | 6 | ||||
-rw-r--r-- | src/ir/cost.h | 109 | ||||
-rw-r--r-- | src/ir/literal-utils.h | 19 | ||||
-rw-r--r-- | src/ir/utils.h | 10 |
5 files changed, 190 insertions, 25 deletions
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index 7788f7cde..7248691a9 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -248,6 +248,37 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left, Expression* right, Expr PUSH(AtomicWake, wakeCount); break; } + case Expression::Id::SIMDExtractId: { + CHECK(SIMDExtract, op); + CHECK(SIMDExtract, idx); + PUSH(SIMDExtract, vec); + break; + } + case Expression::Id::SIMDReplaceId: { + CHECK(SIMDReplace, op); + CHECK(SIMDReplace, idx); + PUSH(SIMDReplace, vec); + PUSH(SIMDReplace, value); + break; + } + case Expression::Id::SIMDShuffleId: { + CHECK(SIMDShuffle, mask); + PUSH(SIMDShuffle, left); + PUSH(SIMDShuffle, right); + break; + } + case Expression::Id::SIMDBitselectId: { + PUSH(SIMDBitselect, left); + PUSH(SIMDBitselect, right); + PUSH(SIMDBitselect, cond); + break; + } + case Expression::Id::SIMDShiftId: { + CHECK(SIMDShift, op); + PUSH(SIMDShift, vec); + PUSH(SIMDShift, shift); + break; + } case Expression::Id::ConstId: { if (left->cast<Const>()->value != right->cast<Const>()->value) { return false; @@ -496,15 +527,43 @@ HashType ExpressionAnalyzer::hash(Expression* curr) { PUSH(AtomicWake, wakeCount); break; } + case Expression::Id::SIMDExtractId: { + HASH(SIMDExtract, op); + HASH(SIMDExtract, idx); + PUSH(SIMDExtract, vec); + break; + } + case Expression::Id::SIMDReplaceId: { + HASH(SIMDReplace, op); + HASH(SIMDReplace, idx); + PUSH(SIMDReplace, vec); + PUSH(SIMDReplace, value); + break; + } + case Expression::Id::SIMDShuffleId: { + for (size_t i = 0; i < 16; ++i) { + HASH(SIMDShuffle, mask[i]); + } + PUSH(SIMDShuffle, left); + PUSH(SIMDShuffle, right); + break; + } + case Expression::Id::SIMDBitselectId: { + PUSH(SIMDBitselect, left); + PUSH(SIMDBitselect, right); + PUSH(SIMDBitselect, cond); + break; + } + case Expression::Id::SIMDShiftId: { + HASH(SIMDShift, op); + PUSH(SIMDShift, vec); + PUSH(SIMDShift, shift); + break; + } case Expression::Id::ConstId: { auto* c = curr->cast<Const>(); hash(c->type); - auto bits = c->value.getBits(); - if (getTypeSize(c->type) == 4) { - hash(HashType(bits)); - } else { - hash64(bits); - } + hash(std::hash<Literal>()(c->value)); break; } case Expression::Id::UnaryId: { diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 31140837f..68526678a 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -137,6 +137,11 @@ void ReFinalize::visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); } void ReFinalize::visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void ReFinalize::visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void ReFinalize::visitAtomicWake(AtomicWake* curr) { curr->finalize(); } +void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); } +void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); } +void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } +void ReFinalize::visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); } +void ReFinalize::visitSIMDShift(SIMDShift* curr) { curr->finalize(); } void ReFinalize::visitConst(Const* curr) { curr->finalize(); } void ReFinalize::visitUnary(Unary* curr) { curr->finalize(); } void ReFinalize::visitBinary(Binary* curr) { curr->finalize(); } @@ -195,4 +200,3 @@ void ReFinalize::replaceUntaken(Expression* value, Expression* condition) { } } // namespace wasm - diff --git a/src/ir/cost.h b/src/ir/cost.h index e28f535e7..354f663e1 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -152,6 +152,39 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { case TruncSatUFloat64ToInt64: ret = 1; break; case SqrtFloat32: case SqrtFloat64: ret = 2; break; + case SplatVecI8x16: + case SplatVecI16x8: + case SplatVecI32x4: + case SplatVecI64x2: + case SplatVecF32x4: + case SplatVecF64x2: + case NotVec128: + case NegVecI8x16: + case AnyTrueVecI8x16: + case AllTrueVecI8x16: + case NegVecI16x8: + case AnyTrueVecI16x8: + case AllTrueVecI16x8: + case NegVecI32x4: + case AnyTrueVecI32x4: + case AllTrueVecI32x4: + case NegVecI64x2: + case AnyTrueVecI64x2: + case AllTrueVecI64x2: + case AbsVecF32x4: + case NegVecF32x4: + case SqrtVecF32x4: + case AbsVecF64x2: + case NegVecF64x2: + case SqrtVecF64x2: + case TruncSatSVecF32x4ToVecI32x4: + case TruncSatUVecF32x4ToVecI32x4: + case TruncSatSVecF64x2ToVecI64x2: + case TruncSatUVecF64x2ToVecI64x2: + case ConvertSVecI32x4ToVecF32x4: + case ConvertUVecI32x4ToVecF32x4: + case ConvertSVecI64x2ToVecF64x2: + case ConvertUVecI64x2ToVecF64x2: assert(false && "v128 not implemented yet"); case InvalidUnary: WASM_UNREACHABLE(); } return ret + visit(curr->value); @@ -235,6 +268,82 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> { case NeFloat32: ret = 1; break; case EqFloat64: ret = 1; break; case NeFloat64: ret = 1; break; + case EqVecI8x16: + case NeVecI8x16: + case LtSVecI8x16: + case LtUVecI8x16: + case LeSVecI8x16: + case LeUVecI8x16: + case GtSVecI8x16: + case GtUVecI8x16: + case GeSVecI8x16: + case GeUVecI8x16: + case EqVecI16x8: + case NeVecI16x8: + case LtSVecI16x8: + case LtUVecI16x8: + case LeSVecI16x8: + case LeUVecI16x8: + case GtSVecI16x8: + case GtUVecI16x8: + case GeSVecI16x8: + case GeUVecI16x8: + case EqVecI32x4: + case NeVecI32x4: + case LtSVecI32x4: + case LtUVecI32x4: + case LeSVecI32x4: + case LeUVecI32x4: + case GtSVecI32x4: + case GtUVecI32x4: + case GeSVecI32x4: + case GeUVecI32x4: + case EqVecF32x4: + case NeVecF32x4: + case LtVecF32x4: + case LeVecF32x4: + case GtVecF32x4: + case GeVecF32x4: + case EqVecF64x2: + case NeVecF64x2: + case LtVecF64x2: + case LeVecF64x2: + case GtVecF64x2: + case GeVecF64x2: + case AndVec128: + case OrVec128: + case XorVec128: + case AddVecI8x16: + case AddSatSVecI8x16: + case AddSatUVecI8x16: + case SubVecI8x16: + case SubSatSVecI8x16: + case SubSatUVecI8x16: + case MulVecI8x16: + case AddVecI16x8: + case AddSatSVecI16x8: + case AddSatUVecI16x8: + case SubVecI16x8: + case SubSatSVecI16x8: + case SubSatUVecI16x8: + case MulVecI16x8: + case AddVecI32x4: + case SubVecI32x4: + case MulVecI32x4: + case AddVecI64x2: + case SubVecI64x2: + case AddVecF32x4: + case SubVecF32x4: + case MulVecF32x4: + case DivVecF32x4: + case MinVecF32x4: + case MaxVecF32x4: + case AddVecF64x2: + case SubVecF64x2: + case MulVecF64x2: + case DivVecF64x2: + case MinVecF64x2: + case MaxVecF64x2: assert(false && "v128 not implemented yet"); case InvalidBinary: WASM_UNREACHABLE(); } return ret + visit(curr->left) + visit(curr->right); diff --git a/src/ir/literal-utils.h b/src/ir/literal-utils.h index e00f05c52..543c34e9f 100644 --- a/src/ir/literal-utils.h +++ b/src/ir/literal-utils.h @@ -23,26 +23,9 @@ namespace wasm { namespace LiteralUtils { -inline Literal makeLiteralFromInt32(int32_t x, Type type) { - switch (type) { - case i32: return Literal(int32_t(x)); break; - case i64: return Literal(int64_t(x)); break; - case f32: return Literal(float(x)); break; - case f64: return Literal(double(x)); break; - case v128: assert(false && "v128 not implemented yet"); - case none: - case unreachable: WASM_UNREACHABLE(); - } - WASM_UNREACHABLE(); -} - -inline Literal makeLiteralZero(Type type) { - return makeLiteralFromInt32(0, type); -} - inline Expression* makeFromInt32(int32_t x, Type type, Module& wasm) { auto* ret = wasm.allocator.alloc<Const>(); - ret->value = makeLiteralFromInt32(x, type); + ret->value = Literal::makeFromInt32(x, type); ret->type = type; return ret; } diff --git a/src/ir/utils.h b/src/ir/utils.h index a4082b6bc..afb63b01c 100644 --- a/src/ir/utils.h +++ b/src/ir/utils.h @@ -129,6 +129,11 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R void visitAtomicCmpxchg(AtomicCmpxchg* curr); void visitAtomicWait(AtomicWait* curr); void visitAtomicWake(AtomicWake* curr); + void visitSIMDExtract(SIMDExtract* curr); + void visitSIMDReplace(SIMDReplace* curr); + void visitSIMDShuffle(SIMDShuffle* curr); + void visitSIMDBitselect(SIMDBitselect* curr); + void visitSIMDShift(SIMDShift* curr); void visitConst(Const* curr); void visitUnary(Unary* curr); void visitBinary(Binary* curr); @@ -176,6 +181,11 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> { void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void visitAtomicWake(AtomicWake* curr) { curr->finalize(); } + void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); } + void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); } + void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } + void visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); } + void visitSIMDShift(SIMDShift* curr) { curr->finalize(); } void visitConst(Const* curr) { curr->finalize(); } void visitUnary(Unary* curr) { curr->finalize(); } void visitBinary(Binary* curr) { curr->finalize(); } |