diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2019-09-23 18:15:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-23 18:15:14 -0700 |
commit | 835581f58eb5040656243f7345ebcacf6d7deee5 (patch) | |
tree | d5f8878015be2edcdf3d69306c0a8bc20ecd9bf6 | |
parent | fb217c80c6d9c4b52d90571c435fc52dc868df47 (diff) | |
download | binaryen-835581f58eb5040656243f7345ebcacf6d7deee5.tar.gz binaryen-835581f58eb5040656243f7345ebcacf6d7deee5.tar.bz2 binaryen-835581f58eb5040656243f7345ebcacf6d7deee5.zip |
vNxM.load_splat instructions (#2350)
Introduces a new instruction class, `SIMDLoad`. Implements encoding,
decoding, parsing, printing, and interpretation of the load and splat
instructions, including in the C and JS APIs. `v128.load` remains in
the `Load` instruction class for now because the interpreter code
expects a `Load` to be able to load any memory value type.
37 files changed, 1041 insertions, 398 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 370576ce5..0775ab552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ full changeset diff at the end of each section. Current Trunk ------------- +- Added load_splat SIMD instructions - Binaryen.js instruction API changes: - `notify` -> `atomic.notify` - `i32.wait` / `i64.wait` -> `i32.atomic.wait` / `i64.atomic.wait` diff --git a/Contributing.md b/Contributing.md index 1cc607fa4..3fafe57f7 100644 --- a/Contributing.md +++ b/Contributing.md @@ -6,3 +6,25 @@ Interested in participating? Please follow [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md Also, please be sure to read [the README.md](README.md) for this repository. + +## Adding support for new instructions + +Use this handy checklist to make sure your new instructions are fully supported: + + - [ ] Instruction class or opcode added to src/wasm.h + - [ ] Instruction class added to src/wasm-builder.h + - [ ] Instruction class added to src/wasm-traversal.h + - [ ] Validation added to src/wasm/wasm-validator.cpp + - [ ] Interpretation added to src/wasm-interpreter.h + - [ ] Effects handled in src/ir/effects.h + - [ ] Hashing and comparing in src/ir/ExpressionAnalyzer.cpp + - [ ] Parsing added in scripts/gen-s-parser.py and src/wasm/wasm-s-parser.cpp + - [ ] Printing added in src/passes/Print.cpp + - [ ] Decoding added in src/wasm/wasm-binary.cpp + - [ ] Binary writing added in src/wasm-stack.h and src/wasm/wasm-stack.cpp + - [ ] Support added to src/tools/fuzzing.h + - [ ] C API support added in src/binaryen-c.h and src/binaryen-c.cpp + - [ ] JS API support added in build-js.sh and src/js/binaryen.js-post.js + - [ ] C API tested in test/example/c-api-kitchen-sink.c + - [ ] JS API tested in test/binaryen.js/kitchen-sink.js + - [ ] Tests added in test/spec diff --git a/build-js.sh b/build-js.sh index 92ab38ed9..9f6137b08 100755 --- a/build-js.sh +++ b/build-js.sh @@ -225,6 +225,7 @@ export_function "_BinaryenSIMDReplaceId" export_function "_BinaryenSIMDShuffleId" export_function "_BinaryenSIMDTernaryId" export_function "_BinaryenSIMDShiftId" +export_function "_BinaryenSIMDLoadId" export_function "_BinaryenMemoryInitId" export_function "_BinaryenDataDropId" export_function "_BinaryenMemoryCopyId" @@ -550,6 +551,10 @@ export_function "_BinaryenConvertSVecI32x4ToVecF32x4" export_function "_BinaryenConvertUVecI32x4ToVecF32x4" export_function "_BinaryenConvertSVecI64x2ToVecF64x2" export_function "_BinaryenConvertUVecI64x2ToVecF64x2" +export_function "_BinaryenLoadSplatVec8x16" +export_function "_BinaryenLoadSplatVec16x8" +export_function "_BinaryenLoadSplatVec32x4" +export_function "_BinaryenLoadSplatVec64x2" export_function "_BinaryenNarrowSVecI16x8ToVecI8x16" export_function "_BinaryenNarrowUVecI16x8ToVecI8x16" export_function "_BinaryenNarrowSVecI32x4ToVecI16x8" @@ -601,6 +606,7 @@ export_function "_BinaryenSIMDReplace" export_function "_BinaryenSIMDShuffle" export_function "_BinaryenSIMDTernary" export_function "_BinaryenSIMDShift" +export_function "_BinaryenSIMDLoad" export_function "_BinaryenMemoryInit" export_function "_BinaryenDataDrop" export_function "_BinaryenMemoryCopy" @@ -772,6 +778,12 @@ export_function "_BinaryenSIMDShiftGetOp" export_function "_BinaryenSIMDShiftGetVec" export_function "_BinaryenSIMDShiftGetShift" +# 'SIMDLoad' expression operations +export_function "_BinaryenSIMDLoadGetOp" +export_function "_BinaryenSIMDLoadGetOffset" +export_function "_BinaryenSIMDLoadGetAlign" +export_function "_BinaryenSIMDLoadGetPtr" + # 'MemoryInit' expression operations export_function "_BinaryenMemoryInitGetSegment" export_function "_BinaryenMemoryInitGetDest" diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index ece3ee086..f00a18db9 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -429,6 +429,10 @@ instructions = [ ("f32x4.convert_i32x4_u", "makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4)"), ("f64x2.convert_i64x2_s", "makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2)"), ("f64x2.convert_i64x2_u", "makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2)"), + ("v8x16.load_splat", "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec8x16)"), + ("v16x8.load_splat", "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8)"), + ("v32x4.load_splat", "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4)"), + ("v64x2.load_splat", "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2)"), ("i8x16.narrow_i16x8_s", "makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16)"), ("i8x16.narrow_i16x8_u", "makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16)"), ("i16x8.narrow_i32x4_s", "makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 0b2ff3b78..5a32737e4 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -349,6 +349,9 @@ BinaryenExpressionId BinaryenSIMDTernaryId(void) { BinaryenExpressionId BinaryenSIMDShiftId(void) { return Expression::Id::SIMDShiftId; } +BinaryenExpressionId BinaryenSIMDLoadId(void) { + return Expression::Id::SIMDLoadId; +} BinaryenExpressionId BinaryenMemoryInitId(void) { return Expression::Id::MemoryInitId; } @@ -880,6 +883,10 @@ BinaryenOp BinaryenConvertSVecI64x2ToVecF64x2(void) { BinaryenOp BinaryenConvertUVecI64x2ToVecF64x2(void) { return ConvertUVecI64x2ToVecF64x2; } +BinaryenOp BinaryenLoadSplatVec8x16(void) { return LoadSplatVec8x16; } +BinaryenOp BinaryenLoadSplatVec16x8(void) { return LoadSplatVec16x8; } +BinaryenOp BinaryenLoadSplatVec32x4(void) { return LoadSplatVec32x4; } +BinaryenOp BinaryenLoadSplatVec64x2(void) { return LoadSplatVec64x2; } BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void) { return NarrowSVecI16x8ToVecI8x16; } @@ -1599,6 +1606,20 @@ BinaryenExpressionRef BinaryenSIMDShift(BinaryenModuleRef module, } return static_cast<Expression*>(ret); } +BinaryenExpressionRef BinaryenSIMDLoad(BinaryenModuleRef module, + BinaryenOp op, + uint32_t offset, + uint32_t align, + BinaryenExpressionRef ptr) { + auto* ret = + Builder(*(Module*)module) + .makeSIMDLoad( + SIMDLoadOp(op), Address(offset), Address(align), (Expression*)ptr); + if (tracing) { + traceExpression(ret, "BinaryenSIMDLoad", op, offset, align, ptr); + } + return static_cast<Expression*>(ret); +} BinaryenExpressionRef BinaryenMemoryInit(BinaryenModuleRef module, uint32_t segment, BinaryenExpressionRef dest, @@ -2767,6 +2788,47 @@ BinaryenExpressionRef BinaryenSIMDShiftGetShift(BinaryenExpressionRef expr) { assert(expression->is<SIMDShift>()); return static_cast<SIMDShift*>(expression)->shift; } +// SIMDLoad +BinaryenOp BinaryenSIMDLoadGetOp(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenSIMDLoadGetOp(expressions[" << expressions[expr] + << "])\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<SIMDLoad>()); + return static_cast<SIMDLoad*>(expression)->op; +} +uint32_t BinaryenSIMDLoadGetOffset(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenSIMDLoadGetOffset(expressions[" << expressions[expr] + << "])\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<SIMDLoad>()); + return static_cast<SIMDLoad*>(expression)->offset; +} +uint32_t BinaryenSIMDLoadGetAlign(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenSIMDLoadGetAlign(expressions[" << expressions[expr] + << "])\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<SIMDLoad>()); + return static_cast<SIMDLoad*>(expression)->align; +} +BinaryenExpressionRef BinaryenSIMDLoadGetPtr(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenSIMDLoadGetPtr(expressions[" << expressions[expr] + << "])\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<SIMDLoad>()); + return static_cast<SIMDLoad*>(expression)->ptr; +} // MemoryInit uint32_t BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr) { if (tracing) { diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 8667f7a6d..c4fbb9748 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -131,6 +131,7 @@ BINARYEN_API BinaryenExpressionId BinaryenSIMDReplaceId(void); BINARYEN_API BinaryenExpressionId BinaryenSIMDShuffleId(void); BINARYEN_API BinaryenExpressionId BinaryenSIMDTernaryId(void); BINARYEN_API BinaryenExpressionId BinaryenSIMDShiftId(void); +BINARYEN_API BinaryenExpressionId BinaryenSIMDLoadId(void); BINARYEN_API BinaryenExpressionId BinaryenMemoryInitId(void); BINARYEN_API BinaryenExpressionId BinaryenDataDropId(void); BINARYEN_API BinaryenExpressionId BinaryenMemoryCopyId(void); @@ -522,6 +523,10 @@ BINARYEN_API BinaryenOp BinaryenConvertSVecI32x4ToVecF32x4(void); BINARYEN_API BinaryenOp BinaryenConvertUVecI32x4ToVecF32x4(void); BINARYEN_API BinaryenOp BinaryenConvertSVecI64x2ToVecF64x2(void); BINARYEN_API BinaryenOp BinaryenConvertUVecI64x2ToVecF64x2(void); +BINARYEN_API BinaryenOp BinaryenLoadSplatVec8x16(void); +BINARYEN_API BinaryenOp BinaryenLoadSplatVec16x8(void); +BINARYEN_API BinaryenOp BinaryenLoadSplatVec32x4(void); +BINARYEN_API BinaryenOp BinaryenLoadSplatVec64x2(void); BINARYEN_API BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void); BINARYEN_API BinaryenOp BinaryenNarrowUVecI16x8ToVecI8x16(void); BINARYEN_API BinaryenOp BinaryenNarrowSVecI32x4ToVecI16x8(void); @@ -736,6 +741,11 @@ BinaryenSIMDShift(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef vec, BinaryenExpressionRef shift); +BINARYEN_API BinaryenExpressionRef BinaryenSIMDLoad(BinaryenModuleRef module, + BinaryenOp op, + uint32_t offset, + uint32_t align, + BinaryenExpressionRef ptr); BINARYEN_API BinaryenExpressionRef BinaryenMemoryInit(BinaryenModuleRef module, uint32_t segment, @@ -962,6 +972,12 @@ BinaryenSIMDShiftGetVec(BinaryenExpressionRef expr); BINARYEN_API BinaryenExpressionRef BinaryenSIMDShiftGetShift(BinaryenExpressionRef expr); +BINARYEN_API BinaryenOp BinaryenSIMDLoadGetOp(BinaryenExpressionRef expr); +BINARYEN_API uint32_t BinaryenSIMDLoadGetOffset(BinaryenExpressionRef expr); +BINARYEN_API uint32_t BinaryenSIMDLoadGetAlign(BinaryenExpressionRef expr); +BINARYEN_API BinaryenExpressionRef +BinaryenSIMDLoadGetPtr(BinaryenExpressionRef expr); + BINARYEN_API uint32_t BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr); BINARYEN_API BinaryenExpressionRef BinaryenMemoryInitGetDest(BinaryenExpressionRef expr); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index adfeb061d..b1bd5c016 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -2418,40 +2418,62 @@ switch (op[0]) { case 'v': { switch (op[1]) { case '1': { - switch (op[5]) { - case 'a': - if (strcmp(op, "v128.and") == 0) { return makeBinary(s, BinaryOp::AndVec128); } - goto parse_error; - case 'b': - if (strcmp(op, "v128.bitselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::Bitselect); } - goto parse_error; - case 'c': - if (strcmp(op, "v128.const") == 0) { return makeConst(s, v128); } + switch (op[2]) { + case '2': { + switch (op[5]) { + case 'a': + if (strcmp(op, "v128.and") == 0) { return makeBinary(s, BinaryOp::AndVec128); } + goto parse_error; + case 'b': + if (strcmp(op, "v128.bitselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::Bitselect); } + goto parse_error; + case 'c': + if (strcmp(op, "v128.const") == 0) { return makeConst(s, v128); } + goto parse_error; + case 'l': + if (strcmp(op, "v128.load") == 0) { return makeLoad(s, v128, /*isAtomic=*/false); } + goto parse_error; + case 'n': + if (strcmp(op, "v128.not") == 0) { return makeUnary(s, UnaryOp::NotVec128); } + goto parse_error; + case 'o': + if (strcmp(op, "v128.or") == 0) { return makeBinary(s, BinaryOp::OrVec128); } + goto parse_error; + case 'p': + if (strcmp(op, "v128.pop") == 0) { return makePop(v128); } + goto parse_error; + case 's': + if (strcmp(op, "v128.store") == 0) { return makeStore(s, v128, /*isAtomic=*/false); } + goto parse_error; + case 'x': + if (strcmp(op, "v128.xor") == 0) { return makeBinary(s, BinaryOp::XorVec128); } + goto parse_error; + default: goto parse_error; + } + } + case '6': + if (strcmp(op, "v16x8.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8); } goto parse_error; + default: goto parse_error; + } + } + case '3': + if (strcmp(op, "v32x4.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4); } + goto parse_error; + case '6': + if (strcmp(op, "v64x2.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2); } + goto parse_error; + case '8': { + switch (op[6]) { case 'l': - if (strcmp(op, "v128.load") == 0) { return makeLoad(s, v128, /*isAtomic=*/false); } - goto parse_error; - case 'n': - if (strcmp(op, "v128.not") == 0) { return makeUnary(s, UnaryOp::NotVec128); } - goto parse_error; - case 'o': - if (strcmp(op, "v128.or") == 0) { return makeBinary(s, BinaryOp::OrVec128); } - goto parse_error; - case 'p': - if (strcmp(op, "v128.pop") == 0) { return makePop(v128); } + if (strcmp(op, "v8x16.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec8x16); } goto parse_error; case 's': - if (strcmp(op, "v128.store") == 0) { return makeStore(s, v128, /*isAtomic=*/false); } - goto parse_error; - case 'x': - if (strcmp(op, "v128.xor") == 0) { return makeBinary(s, BinaryOp::XorVec128); } + if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); } goto parse_error; default: goto parse_error; } } - case '8': - if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); } - goto parse_error; default: goto parse_error; } } diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index ee3cb0123..f7b7b636e 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -196,6 +196,11 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) { } void visitSIMDTernary(SIMDTernary* curr) { visitor.visitInt(curr->op); } void visitSIMDShift(SIMDShift* curr) { visitor.visitInt(curr->op); } + void visitSIMDLoad(SIMDLoad* curr) { + visitor.visitInt(curr->op); + visitor.visitAddress(curr->offset); + visitor.visitAddress(curr->align); + } void visitMemoryInit(MemoryInit* curr) { visitor.visitIndex(curr->segment); } diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp index 7c4de4ceb..fdefbb2e0 100644 --- a/src/ir/ExpressionManipulator.cpp +++ b/src/ir/ExpressionManipulator.cpp @@ -179,6 +179,10 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { return builder.makeSIMDShift( curr->op, copy(curr->vec), copy(curr->shift)); } + Expression* visitSIMDLoad(SIMDLoad* curr) { + return builder.makeSIMDLoad( + curr->op, curr->offset, curr->align, copy(curr->ptr)); + } Expression* visitConst(Const* curr) { return builder.makeConst(curr->value); } diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 6c4e7a447..b27b49bd4 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -147,6 +147,7 @@ void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); } void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } void ReFinalize::visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); } void ReFinalize::visitSIMDShift(SIMDShift* curr) { curr->finalize(); } +void ReFinalize::visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); } void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); } void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); } void ReFinalize::visitMemoryCopy(MemoryCopy* curr) { curr->finalize(); } diff --git a/src/ir/effects.h b/src/ir/effects.h index dcee4404b..e93c63017 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -307,6 +307,12 @@ struct EffectAnalyzer void visitSIMDShuffle(SIMDShuffle* curr) {} void visitSIMDTernary(SIMDTernary* curr) {} void visitSIMDShift(SIMDShift* curr) {} + void visitSIMDLoad(SIMDLoad* curr) { + readsMemory = true; + if (!ignoreImplicitTraps) { + implicitTrap = true; + } + } void visitMemoryInit(MemoryInit* curr) { writesMemory = true; if (!ignoreImplicitTraps) { diff --git a/src/ir/utils.h b/src/ir/utils.h index 4ca80caa3..ca8803741 100644 --- a/src/ir/utils.h +++ b/src/ir/utils.h @@ -134,6 +134,7 @@ struct ReFinalize void visitSIMDShuffle(SIMDShuffle* curr); void visitSIMDTernary(SIMDTernary* curr); void visitSIMDShift(SIMDShift* curr); + void visitSIMDLoad(SIMDLoad* curr); void visitMemoryInit(MemoryInit* curr); void visitDataDrop(DataDrop* curr); void visitMemoryCopy(MemoryCopy* curr); @@ -198,6 +199,7 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> { void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } void visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); } void visitSIMDShift(SIMDShift* curr) { curr->finalize(); } + void visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); } void visitMemoryInit(MemoryInit* curr) { curr->finalize(); } void visitDataDrop(DataDrop* curr) { curr->finalize(); } void visitMemoryCopy(MemoryCopy* curr) { curr->finalize(); } diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 3cf3e1197..c82aaaf6d 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -76,6 +76,7 @@ Module['SIMDReplaceId'] = Module['_BinaryenSIMDReplaceId'](); Module['SIMDShuffleId'] = Module['_BinaryenSIMDShuffleId'](); Module['SIMDTernaryId'] = Module['_BinaryenSIMDTernaryId'](); Module['SIMDShiftId'] = Module['_BinaryenSIMDShiftId'](); +Module['SIMDLoadId'] = Module['_BinaryenSIMDLoadId'](); Module['MemoryInitId'] = Module['_BinaryenMemoryInitId'](); Module['DataDropId'] = Module['_BinaryenDataDropId'](); Module['MemoryCopyId'] = Module['_BinaryenMemoryCopyId'](); @@ -394,6 +395,10 @@ Module['ConvertSVecI32x4ToVecF32x4'] = Module['_BinaryenConvertSVecI32x4ToVecF32 Module['ConvertUVecI32x4ToVecF32x4'] = Module['_BinaryenConvertUVecI32x4ToVecF32x4'](); Module['ConvertSVecI64x2ToVecF64x2'] = Module['_BinaryenConvertSVecI64x2ToVecF64x2'](); Module['ConvertUVecI64x2ToVecF64x2'] = Module['_BinaryenConvertUVecI64x2ToVecF64x2'](); +Module['LoadSplatVec8x16'] = Module['_BinaryenLoadSplatVec8x16'](); +Module['LoadSplatVec16x8'] = Module['_BinaryenLoadSplatVec16x8'](); +Module['LoadSplatVec32x4'] = Module['_BinaryenLoadSplatVec32x4'](); +Module['LoadSplatVec64x2'] = Module['_BinaryenLoadSplatVec64x2'](); Module['NarrowSVecI16x8ToVecI8x16'] = Module['_BinaryenNarrowSVecI16x8ToVecI8x16'](); Module['NarrowUVecI16x8ToVecI8x16'] = Module['_BinaryenNarrowUVecI16x8ToVecI8x16'](); Module['NarrowSVecI32x4ToVecI16x8'] = Module['_BinaryenNarrowSVecI32x4ToVecI16x8'](); @@ -1347,14 +1352,6 @@ function wrapModule(module, self) { } }; - self['v8x16'] = { - 'shuffle': function(left, right, mask) { - return preserveStack(function() { - return Module['_BinaryenSIMDShuffle'](module, left, right, i8sToStack(mask)); - }); - }, - }; - self['i8x16'] = { 'splat': function(value) { return Module['_BinaryenUnary'](module, Module['SplatVecI8x16'], value); @@ -1814,6 +1811,35 @@ function wrapModule(module, self) { }, }; + self['v8x16'] = { + 'shuffle': function(left, right, mask) { + return preserveStack(function() { + return Module['_BinaryenSIMDShuffle'](module, left, right, i8sToStack(mask)); + }); + }, + 'load_splat': function(offset, align, ptr) { + return Module['_BinaryenSIMDLoad'](module, Module['LoadSplatVec8x16'], offset, align, ptr); + }, + }; + + self['v16x8'] = { + 'load_splat': function(offset, align, ptr) { + return Module['_BinaryenSIMDLoad'](module, Module['LoadSplatVec16x8'], offset, align, ptr); + }, + }; + + self['v32x4'] = { + 'load_splat': function(offset, align, ptr) { + return Module['_BinaryenSIMDLoad'](module, Module['LoadSplatVec32x4'], offset, align, ptr); + }, + }; + + self['v64x2'] = { + 'load_splat': function(offset, align, ptr) { + return Module['_BinaryenSIMDLoad'](module, Module['LoadSplatVec64x2'], offset, align, ptr); + }, + }; + self['exnref'] = { 'pop': function() { return Module['_BinaryenPop'](module, Module['exnref']); @@ -2452,6 +2478,15 @@ Module['getExpressionInfo'] = function(expr) { 'vec': Module['_BinaryenSIMDShiftGetVec'](expr), 'shift': Module['_BinaryenSIMDShiftGetShift'](expr) }; + case Module['SIMDLoadId']: + return { + 'id': id, + 'type': type, + 'op': Module['_BinaryenSIMDLoadGetOp'](expr), + 'offset': Module['_BinaryenSIMDLoadGetOffset'](expr), + 'align': Module['_BinaryenSIMDLoadGetAlign'](expr), + 'ptr': Module['_BinaryenSIMDLoadGetPtr'](expr) + }; case Module['MemoryInitId']: return { 'id': id, diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index 1d13ed67c..5f562f7ba 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -310,6 +310,8 @@ struct DeadCodeElimination DELEGATE(SIMDTernary); case Expression::Id::SIMDShiftId: DELEGATE(SIMDShift); + case Expression::Id::SIMDLoadId: + DELEGATE(SIMDLoad); case Expression::Id::MemoryInitId: DELEGATE(MemoryInit); case Expression::Id::DataDropId: diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index f8f5c1a56..afdb12444 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -391,6 +391,30 @@ struct PrintExpressionContents break; } } + void visitSIMDLoad(SIMDLoad* curr) { + prepareColor(o); + switch (curr->op) { + case LoadSplatVec8x16: + o << "v8x16.load_splat"; + break; + case LoadSplatVec16x8: + o << "v16x8.load_splat"; + break; + case LoadSplatVec32x4: + o << "v32x4.load_splat"; + break; + case LoadSplatVec64x2: + o << "v64x2.load_splat"; + break; + } + restoreNormalColor(o); + if (curr->offset) { + o << " offset=" << curr->offset; + } + if (curr->align != curr->getMemBytes()) { + o << " align=" << curr->align; + } + } void visitMemoryInit(MemoryInit* curr) { prepareColor(o); o << "memory.init " << curr->segment; @@ -1604,6 +1628,13 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { printFullLine(curr->shift); decIndent(); } + void visitSIMDLoad(SIMDLoad* curr) { + o << '('; + PrintExpressionContents(currFunction, o).visit(curr); + incIndent(); + printFullLine(curr->ptr); + decIndent(); + } void visitMemoryInit(MemoryInit* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr); diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index bc2f54ecd..2f0c5d315 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -2338,7 +2338,7 @@ private: if (type != v128) { return makeSIMDExtract(type); } - switch (upTo(6)) { + switch (upTo(7)) { case 0: return makeUnary(v128); case 1: @@ -2351,6 +2351,8 @@ private: return makeSIMDTernary(); case 5: return makeSIMDShift(); + case 6: + return makeSIMDLoad(); } WASM_UNREACHABLE(); } @@ -2488,6 +2490,29 @@ private: return builder.makeSIMDShift(op, vec, shift); } + Expression* makeSIMDLoad() { + SIMDLoadOp op = pick( + LoadSplatVec8x16, LoadSplatVec16x8, LoadSplatVec32x4, LoadSplatVec64x2); + Address offset = logify(get()); + Address align; + switch (op) { + case LoadSplatVec8x16: + align = 1; + break; + case LoadSplatVec16x8: + align = pick(1, 2); + break; + case LoadSplatVec32x4: + align = pick(1, 2, 4); + break; + case LoadSplatVec64x2: + align = pick(1, 2, 4, 8); + break; + } + Expression* ptr = makePointer(); + return builder.makeSIMDLoad(op, offset, align, ptr); + } + Expression* makeBulkMemory(Type type) { if (!allowMemory) { return makeTrivial(type); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 02f21455e..3cbc1cc6b 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -856,6 +856,10 @@ enum ASTNodes { F32x4ConvertUI32x4 = 0xb0, F64x2ConvertSI64x2 = 0xb1, F64x2ConvertUI64x2 = 0xb2, + V8x16LoadSplat = 0xc2, + V16x8LoadSplat = 0xc3, + V32x4LoadSplat = 0xc4, + V64x2LoadSplat = 0xc5, I8x16NarrowSI16x8 = 0xc6, I8x16NarrowUI16x8 = 0xc7, I16x8NarrowSI32x4 = 0xc8, @@ -1257,13 +1261,13 @@ public: bool maybeVisitSIMDBinary(Expression*& out, uint32_t code); bool maybeVisitSIMDUnary(Expression*& out, uint32_t code); bool maybeVisitSIMDConst(Expression*& out, uint32_t code); - bool maybeVisitSIMDLoad(Expression*& out, uint32_t code); bool maybeVisitSIMDStore(Expression*& out, uint32_t code); bool maybeVisitSIMDExtract(Expression*& out, uint32_t code); bool maybeVisitSIMDReplace(Expression*& out, uint32_t code); bool maybeVisitSIMDShuffle(Expression*& out, uint32_t code); bool maybeVisitSIMDTernary(Expression*& out, uint32_t code); bool maybeVisitSIMDShift(Expression*& out, uint32_t code); + bool maybeVisitSIMDLoad(Expression*& out, uint32_t code); bool maybeVisitMemoryInit(Expression*& out, uint32_t code); bool maybeVisitDataDrop(Expression*& out, uint32_t code); bool maybeVisitMemoryCopy(Expression*& out, uint32_t code); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index c2f1e41b6..d47ec413f 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -420,6 +420,16 @@ public: ret->finalize(); return ret; } + SIMDLoad* + makeSIMDLoad(SIMDLoadOp op, Address offset, Address align, Expression* ptr) { + auto* ret = allocator.alloc<SIMDLoad>(); + ret->op = op; + ret->offset = offset; + ret->align = align; + ret->ptr = ptr; + ret->finalize(); + return ret; + } MemoryInit* makeMemoryInit(uint32_t segment, Expression* dest, Expression* offset, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 95503fb09..a128cf6e5 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1083,6 +1083,7 @@ public: Flow visitAtomicCmpxchg(AtomicCmpxchg*) { WASM_UNREACHABLE(); } Flow visitAtomicWait(AtomicWait*) { WASM_UNREACHABLE(); } Flow visitAtomicNotify(AtomicNotify*) { WASM_UNREACHABLE(); } + Flow visitSIMDLoad(SIMDLoad*) { WASM_UNREACHABLE(); } Flow visitPush(Push*) { WASM_UNREACHABLE(); } Flow visitPop(Pop*) { WASM_UNREACHABLE(); } Flow visitTry(Try*) { WASM_UNREACHABLE(); } @@ -1697,6 +1698,39 @@ private: // TODO: add threads support! return Literal(int32_t(0)); // none woken up } + Flow visitSIMDLoad(SIMDLoad* curr) { + NOTE_ENTER("SIMDLoad"); + Load load; + load.type = i32; + load.bytes = curr->getMemBytes(); + load.signed_ = false; + load.offset = curr->offset; + load.align = curr->align; + load.isAtomic = false; + load.ptr = curr->ptr; + Literal (Literal::*splat)() const = nullptr; + switch (curr->op) { + case LoadSplatVec8x16: + splat = &Literal::splatI8x16; + break; + case LoadSplatVec16x8: + splat = &Literal::splatI16x8; + break; + case LoadSplatVec32x4: + splat = &Literal::splatI32x4; + break; + case LoadSplatVec64x2: + load.type = i64; + splat = &Literal::splatI64x2; + break; + } + load.finalize(); + Flow flow = this->visit(&load); + if (flow.breaking()) { + return flow; + } + return (flow.value.*splat)(); + } Flow visitHost(Host* curr) { NOTE_ENTER("Host"); switch (curr->op) { diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 67035f0ff..c7d43b581 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -200,6 +200,7 @@ private: Expression* makeSIMDShuffle(Element& s); Expression* makeSIMDTernary(Element& s, SIMDTernaryOp op); Expression* makeSIMDShift(Element& s, SIMDShiftOp op); + Expression* makeSIMDLoad(Element& s, SIMDLoadOp op); Expression* makeMemoryInit(Element& s); Expression* makeDataDrop(Element& s); Expression* makeMemoryCopy(Element& s); diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 4b0ffde40..26105ccdc 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -109,6 +109,7 @@ public: void visitSIMDShuffle(SIMDShuffle* curr); void visitSIMDTernary(SIMDTernary* curr); void visitSIMDShift(SIMDShift* curr); + void visitSIMDLoad(SIMDLoad* curr); void visitMemoryInit(MemoryInit* curr); void visitDataDrop(DataDrop* curr); void visitMemoryCopy(MemoryCopy* curr); @@ -185,6 +186,7 @@ public: void visitSIMDShuffle(SIMDShuffle* curr); void visitSIMDTernary(SIMDTernary* curr); void visitSIMDShift(SIMDShift* curr); + void visitSIMDLoad(SIMDLoad* curr); void visitMemoryInit(MemoryInit* curr); void visitDataDrop(DataDrop* curr); void visitMemoryCopy(MemoryCopy* curr); @@ -588,6 +590,16 @@ void BinaryenIRWriter<SubType>::visitSIMDShift(SIMDShift* curr) { } template<typename SubType> +void BinaryenIRWriter<SubType>::visitSIMDLoad(SIMDLoad* curr) { + visit(curr->ptr); + if (curr->type == unreachable) { + emitUnreachable(); + return; + } + emit(curr); +} + +template<typename SubType> void BinaryenIRWriter<SubType>::visitMemoryInit(MemoryInit* curr) { visit(curr->dest); visit(curr->offset); diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 06ab69615..8f4fb5922 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -60,6 +60,7 @@ template<typename SubType, typename ReturnType = void> struct Visitor { ReturnType visitSIMDShuffle(SIMDShuffle* curr) { return ReturnType(); } ReturnType visitSIMDTernary(SIMDTernary* curr) { return ReturnType(); } ReturnType visitSIMDShift(SIMDShift* curr) { return ReturnType(); } + ReturnType visitSIMDLoad(SIMDLoad* curr) { return ReturnType(); } ReturnType visitMemoryInit(MemoryInit* curr) { return ReturnType(); } ReturnType visitDataDrop(DataDrop* curr) { return ReturnType(); } ReturnType visitMemoryCopy(MemoryCopy* curr) { return ReturnType(); } @@ -143,6 +144,8 @@ template<typename SubType, typename ReturnType = void> struct Visitor { DELEGATE(SIMDTernary); case Expression::Id::SIMDShiftId: DELEGATE(SIMDShift); + case Expression::Id::SIMDLoadId: + DELEGATE(SIMDLoad); case Expression::Id::MemoryInitId: DELEGATE(MemoryInit); case Expression::Id::DataDropId: @@ -227,6 +230,7 @@ struct OverriddenVisitor { UNIMPLEMENTED(SIMDShuffle); UNIMPLEMENTED(SIMDTernary); UNIMPLEMENTED(SIMDShift); + UNIMPLEMENTED(SIMDLoad); UNIMPLEMENTED(MemoryInit); UNIMPLEMENTED(DataDrop); UNIMPLEMENTED(MemoryCopy); @@ -311,6 +315,8 @@ struct OverriddenVisitor { DELEGATE(SIMDTernary); case Expression::Id::SIMDShiftId: DELEGATE(SIMDShift); + case Expression::Id::SIMDLoadId: + DELEGATE(SIMDLoad); case Expression::Id::MemoryInitId: DELEGATE(MemoryInit); case Expression::Id::DataDropId: @@ -436,6 +442,9 @@ struct UnifiedExpressionVisitor : public Visitor<SubType, ReturnType> { ReturnType visitSIMDShift(SIMDShift* curr) { return static_cast<SubType*>(this)->visitExpression(curr); } + ReturnType visitSIMDLoad(SIMDLoad* curr) { + return static_cast<SubType*>(this)->visitExpression(curr); + } ReturnType visitMemoryInit(MemoryInit* curr) { return static_cast<SubType*>(this)->visitExpression(curr); } @@ -738,6 +747,9 @@ struct Walker : public VisitorType { static void doVisitSIMDShift(SubType* self, Expression** currp) { self->visitSIMDShift((*currp)->cast<SIMDShift>()); } + static void doVisitSIMDLoad(SubType* self, Expression** currp) { + self->visitSIMDLoad((*currp)->cast<SIMDLoad>()); + } static void doVisitMemoryInit(SubType* self, Expression** currp) { self->visitMemoryInit((*currp)->cast<MemoryInit>()); } @@ -959,6 +971,11 @@ struct PostWalker : public Walker<SubType, VisitorType> { self->pushTask(SubType::scan, &curr->cast<SIMDShift>()->vec); break; } + case Expression::Id::SIMDLoadId: { + self->pushTask(SubType::doVisitSIMDLoad, currp); + self->pushTask(SubType::scan, &curr->cast<SIMDLoad>()->ptr); + break; + } case Expression::Id::MemoryInitId: { self->pushTask(SubType::doVisitMemoryInit, currp); self->pushTask(SubType::scan, &curr->cast<MemoryInit>()->size); diff --git a/src/wasm.h b/src/wasm.h index 2c057b7a4..735b24163 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -433,6 +433,13 @@ enum SIMDShiftOp { ShrUVecI64x2 }; +enum SIMDLoadOp { + LoadSplatVec8x16, + LoadSplatVec16x8, + LoadSplatVec32x4, + LoadSplatVec64x2 +}; + enum SIMDTernaryOp { Bitselect, QFMAF32x4, QFMSF32x4, QFMAF64x2, QFMSF64x2 }; // @@ -492,6 +499,7 @@ public: SIMDShuffleId, SIMDTernaryId, SIMDShiftId, + SIMDLoadId, MemoryInitId, DataDropId, MemoryCopyId, @@ -877,6 +885,20 @@ public: void finalize(); }; +class SIMDLoad : public SpecificExpression<Expression::SIMDLoadId> { +public: + SIMDLoad() = default; + SIMDLoad(MixedArena& allocator) {} + + SIMDLoadOp op; + Address offset; + Address align; + Expression* ptr; + + Index getMemBytes(); + void finalize(); +}; + class MemoryInit : public SpecificExpression<Expression::MemoryInitId> { public: MemoryInit() = default; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7b9d9c624..136301500 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2340,9 +2340,6 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitSIMDConst(curr, opcode)) { break; } - if (maybeVisitSIMDLoad(curr, opcode)) { - break; - } if (maybeVisitSIMDStore(curr, opcode)) { break; } @@ -2361,6 +2358,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitSIMDShift(curr, opcode)) { break; } + if (maybeVisitSIMDLoad(curr, opcode)) { + break; + } throwError("invalid code after SIMD prefix: " + std::to_string(opcode)); break; } @@ -4158,21 +4158,6 @@ bool WasmBinaryBuilder::maybeVisitSIMDConst(Expression*& out, uint32_t code) { return true; } -bool WasmBinaryBuilder::maybeVisitSIMDLoad(Expression*& out, uint32_t code) { - if (code != BinaryConsts::V128Load) { - return false; - } - auto* curr = allocator.alloc<Load>(); - curr->type = v128; - curr->bytes = 16; - readMemoryAccess(curr->align, curr->offset); - curr->isAtomic = false; - curr->ptr = popNonVoidExpression(); - curr->finalize(); - out = curr; - return true; -} - bool WasmBinaryBuilder::maybeVisitSIMDStore(Expression*& out, uint32_t code) { if (code != BinaryConsts::V128Store) { return false; @@ -4394,6 +4379,46 @@ bool WasmBinaryBuilder::maybeVisitSIMDShift(Expression*& out, uint32_t code) { return true; } +bool WasmBinaryBuilder::maybeVisitSIMDLoad(Expression*& out, uint32_t code) { + if (code == BinaryConsts::V128Load) { + auto* curr = allocator.alloc<Load>(); + curr->type = v128; + curr->bytes = 16; + readMemoryAccess(curr->align, curr->offset); + curr->isAtomic = false; + curr->ptr = popNonVoidExpression(); + curr->finalize(); + out = curr; + return true; + } + SIMDLoad* curr; + switch (code) { + case BinaryConsts::V8x16LoadSplat: + curr = allocator.alloc<SIMDLoad>(); + curr->op = LoadSplatVec8x16; + break; + case BinaryConsts::V16x8LoadSplat: + curr = allocator.alloc<SIMDLoad>(); + curr->op = LoadSplatVec16x8; + break; + case BinaryConsts::V32x4LoadSplat: + curr = allocator.alloc<SIMDLoad>(); + curr->op = LoadSplatVec32x4; + break; + case BinaryConsts::V64x2LoadSplat: + curr = allocator.alloc<SIMDLoad>(); + curr->op = LoadSplatVec64x2; + break; + default: + return false; + } + readMemoryAccess(curr->align, curr->offset); + curr->ptr = popNonVoidExpression(); + curr->finalize(); + out = curr; + return true; +} + void WasmBinaryBuilder::visitSelect(Select* curr) { if (debug) { std::cerr << "zz node: Select" << std::endl; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 322c36c45..9f1fe0044 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1251,10 +1251,10 @@ static uint8_t parseMemBytes(const char*& s, uint8_t fallback) { static size_t parseMemAttributes(Element& s, Address* offset, Address* align, - Address fallback) { + Address fallbackAlign) { size_t i = 1; *offset = 0; - *align = fallback; + *align = fallbackAlign; while (!s[i]->isList()) { const char* str = s[i]->c_str(); const char* eq = strchr(str, '='); @@ -1493,6 +1493,30 @@ Expression* SExpressionWasmBuilder::makeSIMDShift(Element& s, SIMDShiftOp op) { return ret; } +Expression* SExpressionWasmBuilder::makeSIMDLoad(Element& s, SIMDLoadOp op) { + auto ret = allocator.alloc<SIMDLoad>(); + ret->op = op; + Address defaultAlign; + switch (op) { + case LoadSplatVec8x16: + defaultAlign = 1; + break; + case LoadSplatVec16x8: + defaultAlign = 2; + break; + case LoadSplatVec32x4: + defaultAlign = 4; + break; + case LoadSplatVec64x2: + defaultAlign = 8; + break; + } + size_t i = parseMemAttributes(s, &ret->offset, &ret->align, defaultAlign); + ret->ptr = parseExpression(s[i]); + ret->finalize(); + return ret; +} + Expression* SExpressionWasmBuilder::makeMemoryInit(Element& s) { auto ret = allocator.alloc<MemoryInit>(); ret->segment = atoi(s[1]->str().c_str()); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 1da6e9015..c673a3fb0 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -554,6 +554,26 @@ void BinaryInstWriter::visitSIMDShift(SIMDShift* curr) { } } +void BinaryInstWriter::visitSIMDLoad(SIMDLoad* curr) { + o << int8_t(BinaryConsts::SIMDPrefix); + switch (curr->op) { + case LoadSplatVec8x16: + o << U32LEB(BinaryConsts::V8x16LoadSplat); + break; + case LoadSplatVec16x8: + o << U32LEB(BinaryConsts::V16x8LoadSplat); + break; + case LoadSplatVec32x4: + o << U32LEB(BinaryConsts::V32x4LoadSplat); + break; + case LoadSplatVec64x2: + o << U32LEB(BinaryConsts::V64x2LoadSplat); + break; + } + assert(curr->align); + emitMemoryAccess(curr->align, /*(unused) bytes=*/0, curr->offset); +} + void BinaryInstWriter::visitMemoryInit(MemoryInit* curr) { o << int8_t(BinaryConsts::MiscPrefix); o << U32LEB(BinaryConsts::MemoryInit); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e64e2ef73..68002e4d2 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -276,6 +276,7 @@ public: void visitSIMDShuffle(SIMDShuffle* curr); void visitSIMDTernary(SIMDTernary* curr); void visitSIMDShift(SIMDShift* curr); + void visitSIMDLoad(SIMDLoad* curr); void visitMemoryInit(MemoryInit* curr); void visitDataDrop(DataDrop* curr); void visitMemoryCopy(MemoryCopy* curr); @@ -1054,6 +1055,20 @@ void FunctionValidator::visitSIMDShift(SIMDShift* curr) { curr->shift->type, i32, curr, "expected shift amount to have type i32"); } +void FunctionValidator::visitSIMDLoad(SIMDLoad* curr) { + shouldBeTrue( + getModule()->memory.exists, curr, "Memory operations require a memory"); + shouldBeTrue( + getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)"); + shouldBeEqualOrFirstIsUnreachable( + curr->type, v128, curr, "load_splat must have type v128"); + shouldBeEqualOrFirstIsUnreachable( + curr->ptr->type, i32, curr, "load_splat address must have type i32"); + Type lane_t = curr->op == LoadSplatVec64x2 ? i64 : i32; + Index bytes = curr->getMemBytes(); + validateAlignment(curr->align, lane_t, bytes, /*isAtomic=*/false, curr); +} + void FunctionValidator::visitMemoryInit(MemoryInit* curr) { shouldBeTrue(getModule()->features.hasBulkMemory(), curr, diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index f8439ea96..58510cc8f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -159,6 +159,8 @@ const char* getExpressionName(Expression* curr) { return "simd_ternary"; case Expression::Id::SIMDShiftId: return "simd_shift"; + case Expression::Id::SIMDLoadId: + return "simd_load"; case Expression::Id::MemoryInitId: return "memory_init"; case Expression::Id::DataDropId: @@ -626,6 +628,28 @@ void SIMDShift::finalize() { } } +void SIMDLoad::finalize() { + assert(ptr); + type = v128; + if (ptr->type == unreachable) { + type = unreachable; + } +} + +Index SIMDLoad::getMemBytes() { + switch (op) { + case LoadSplatVec8x16: + return 1; + case LoadSplatVec16x8: + return 2; + case LoadSplatVec32x4: + return 4; + case LoadSplatVec64x2: + return 8; + } + WASM_UNREACHABLE(); +} + Const* Const::set(Literal value_) { value = value_; type = value.type; diff --git a/src/wasm2js.h b/src/wasm2js.h index 86af511fb..337ea3806 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1841,6 +1841,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, unimplemented(curr); WASM_UNREACHABLE(); } + Ref visitSIMDLoad(SIMDLoad* curr) { + unimplemented(curr); + WASM_UNREACHABLE(); + } Ref visitMemoryInit(MemoryInit* curr) { unimplemented(curr); WASM_UNREACHABLE(); diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt index 463743ff6..dd395a25a 100644 --- a/test/binaryen.js/exception-handling.js.txt +++ b/test/binaryen.js/exception-handling.js.txt @@ -26,7 +26,7 @@ ) ) -getExpressionInfo(throw) = {"id":40,"type":8,"event":"e"} -getExpressionInfo(br_on_exn) = {"id":42,"type":7,"name":"l","event":"e"} -getExpressionInfo(rethrow) = {"id":41,"type":8} -getExpressionInfo(try) = {"id":39,"type":0} +getExpressionInfo(throw) = {"id":41,"type":8,"event":"e"} +getExpressionInfo(br_on_exn) = {"id":43,"type":7,"name":"l","event":"e"} +getExpressionInfo(rethrow) = {"id":42,"type":8} +getExpressionInfo(try) = {"id":40,"type":0} diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index 4ec06b415..037d92b99 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -110,6 +110,7 @@ function test_ids() { console.log("BinaryenSIMDShuffleId: " + Binaryen.SIMDShuffleId); console.log("BinaryenSIMDTernaryId: " + Binaryen.SIMDTernaryId); console.log("BinaryenSIMDShiftId: " + Binaryen.SIMDShiftId); + console.log("BinaryenSIMDLoadId: " + Binaryen.SIMDLoadId); console.log("MemoryInitId: " + Binaryen.MemoryInitId); console.log("DataDropId: " + Binaryen.DataDropId); console.log("MemoryCopyId: " + Binaryen.MemoryCopyId); @@ -366,7 +367,7 @@ function test_core() { module.i64x2.replace_lane(module.v128.const(v128_bytes), 1, module.i64.const(42, 43)), module.f32x4.replace_lane(module.v128.const(v128_bytes), 1, module.f32.const(42)), module.f64x2.replace_lane(module.v128.const(v128_bytes), 1, module.f64.const(42)), - // // SIMD shift + // SIMD shift module.i8x16.shl(module.v128.const(v128_bytes), module.i32.const(1)), module.i8x16.shr_s(module.v128.const(v128_bytes), module.i32.const(1)), module.i8x16.shr_u(module.v128.const(v128_bytes), module.i32.const(1)), @@ -379,6 +380,11 @@ function test_core() { module.i64x2.shl(module.v128.const(v128_bytes), module.i32.const(1)), module.i64x2.shr_s(module.v128.const(v128_bytes), module.i32.const(1)), module.i64x2.shr_u(module.v128.const(v128_bytes), module.i32.const(1)), + // SIMD load + module.v8x16.load_splat(0, 1, module.i32.const(128)), + module.v16x8.load_splat(16, 1, module.i32.const(128)), + module.v32x4.load_splat(16, 4, module.i32.const(128)), + module.v64x2.load_splat(0, 4, module.i32.const(128)), // Other SIMD module.v8x16.shuffle(module.v128.const(v128_bytes), module.v128.const(v128_bytes), v128_bytes), module.v128.bitselect(module.v128.const(v128_bytes), module.v128.const(v128_bytes), module.v128.const(v128_bytes)), diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 450ab252b..25202788b 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -51,16 +51,17 @@ BinaryenSIMDReplaceId: 29 BinaryenSIMDShuffleId: 30 BinaryenSIMDTernaryId: 31 BinaryenSIMDShiftId: 32 -MemoryInitId: 33 -DataDropId: 34 -MemoryCopyId: 35 -MemoryFillId: 36 -TryId: 39 -ThrowId: 40 -RethrowId: 41 -BrOnExnId: 42 -PushId: 37 -PopId: 38 +BinaryenSIMDLoadId: 33 +MemoryInitId: 34 +DataDropId: 35 +MemoryCopyId: 36 +MemoryFillId: 37 +TryId: 40 +ThrowId: 41 +RethrowId: 42 +BrOnExnId: 43 +PushId: 38 +PopId: 39 getExpressionInfo={"id":15,"type":3,"op":6} (f32.neg (f32.const -33.61199951171875) @@ -1336,6 +1337,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) @@ -2868,6 +2889,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) @@ -4932,233 +4973,241 @@ int main() { } expressions[597] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); expressions[598] = BinaryenSIMDShift(the_module, 11, expressions[596], expressions[597]); + expressions[599] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[600] = BinaryenSIMDLoad(the_module, 0, 0, 1, expressions[599]); + expressions[601] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[602] = BinaryenSIMDLoad(the_module, 1, 16, 1, expressions[601]); + expressions[603] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[604] = BinaryenSIMDLoad(the_module, 2, 16, 4, expressions[603]); + expressions[605] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[606] = BinaryenSIMDLoad(the_module, 3, 0, 4, expressions[605]); { uint8_t t221[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[599] = BinaryenConst(the_module, BinaryenLiteralVec128(t221)); + expressions[607] = BinaryenConst(the_module, BinaryenLiteralVec128(t221)); } { uint8_t t222[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[600] = BinaryenConst(the_module, BinaryenLiteralVec128(t222)); + expressions[608] = BinaryenConst(the_module, BinaryenLiteralVec128(t222)); } { uint8_t mask[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[601] = BinaryenSIMDShuffle(the_module, expressions[599], expressions[600], mask); + expressions[609] = BinaryenSIMDShuffle(the_module, expressions[607], expressions[608], mask); } { uint8_t t223[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[602] = BinaryenConst(the_module, BinaryenLiteralVec128(t223)); + expressions[610] = BinaryenConst(the_module, BinaryenLiteralVec128(t223)); } { uint8_t t224[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[603] = BinaryenConst(the_module, BinaryenLiteralVec128(t224)); + expressions[611] = BinaryenConst(the_module, BinaryenLiteralVec128(t224)); } { uint8_t t225[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[604] = BinaryenConst(the_module, BinaryenLiteralVec128(t225)); + expressions[612] = BinaryenConst(the_module, BinaryenLiteralVec128(t225)); } - expressions[605] = BinaryenSIMDTernary(the_module, 0, expressions[602], expressions[603], expressions[604]); + expressions[613] = BinaryenSIMDTernary(the_module, 0, expressions[610], expressions[611], expressions[612]); { uint8_t t226[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[606] = BinaryenConst(the_module, BinaryenLiteralVec128(t226)); + expressions[614] = BinaryenConst(the_module, BinaryenLiteralVec128(t226)); } { uint8_t t227[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[607] = BinaryenConst(the_module, BinaryenLiteralVec128(t227)); + expressions[615] = BinaryenConst(the_module, BinaryenLiteralVec128(t227)); } { uint8_t t228[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[608] = BinaryenConst(the_module, BinaryenLiteralVec128(t228)); + expressions[616] = BinaryenConst(the_module, BinaryenLiteralVec128(t228)); } - expressions[609] = BinaryenSIMDTernary(the_module, 1, expressions[606], expressions[607], expressions[608]); + expressions[617] = BinaryenSIMDTernary(the_module, 1, expressions[614], expressions[615], expressions[616]); { uint8_t t229[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[610] = BinaryenConst(the_module, BinaryenLiteralVec128(t229)); + expressions[618] = BinaryenConst(the_module, BinaryenLiteralVec128(t229)); } { uint8_t t230[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[611] = BinaryenConst(the_module, BinaryenLiteralVec128(t230)); + expressions[619] = BinaryenConst(the_module, BinaryenLiteralVec128(t230)); } { uint8_t t231[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[612] = BinaryenConst(the_module, BinaryenLiteralVec128(t231)); + expressions[620] = BinaryenConst(the_module, BinaryenLiteralVec128(t231)); } - expressions[613] = BinaryenSIMDTernary(the_module, 2, expressions[610], expressions[611], expressions[612]); + expressions[621] = BinaryenSIMDTernary(the_module, 2, expressions[618], expressions[619], expressions[620]); { uint8_t t232[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[614] = BinaryenConst(the_module, BinaryenLiteralVec128(t232)); + expressions[622] = BinaryenConst(the_module, BinaryenLiteralVec128(t232)); } { uint8_t t233[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[615] = BinaryenConst(the_module, BinaryenLiteralVec128(t233)); + expressions[623] = BinaryenConst(the_module, BinaryenLiteralVec128(t233)); } { uint8_t t234[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[616] = BinaryenConst(the_module, BinaryenLiteralVec128(t234)); + expressions[624] = BinaryenConst(the_module, BinaryenLiteralVec128(t234)); } - expressions[617] = BinaryenSIMDTernary(the_module, 3, expressions[614], expressions[615], expressions[616]); + expressions[625] = BinaryenSIMDTernary(the_module, 3, expressions[622], expressions[623], expressions[624]); { uint8_t t235[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[618] = BinaryenConst(the_module, BinaryenLiteralVec128(t235)); + expressions[626] = BinaryenConst(the_module, BinaryenLiteralVec128(t235)); } { uint8_t t236[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[619] = BinaryenConst(the_module, BinaryenLiteralVec128(t236)); + expressions[627] = BinaryenConst(the_module, BinaryenLiteralVec128(t236)); } { uint8_t t237[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[620] = BinaryenConst(the_module, BinaryenLiteralVec128(t237)); - } - expressions[621] = BinaryenSIMDTernary(the_module, 4, expressions[618], expressions[619], expressions[620]); - expressions[622] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[623] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[624] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); - expressions[625] = BinaryenMemoryInit(the_module, 0, expressions[622], expressions[623], expressions[624]); - expressions[626] = BinaryenDataDrop(the_module, 0); - expressions[627] = BinaryenConst(the_module, BinaryenLiteralInt32(2048)); - expressions[628] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[629] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); - expressions[630] = BinaryenMemoryCopy(the_module, expressions[627], expressions[628], expressions[629]); + expressions[628] = BinaryenConst(the_module, BinaryenLiteralVec128(t237)); + } + expressions[629] = BinaryenSIMDTernary(the_module, 4, expressions[626], expressions[627], expressions[628]); + expressions[630] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); expressions[631] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[632] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); - expressions[633] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[634] = BinaryenMemoryFill(the_module, expressions[631], expressions[632], expressions[633]); + expressions[632] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); + expressions[633] = BinaryenMemoryInit(the_module, 0, expressions[630], expressions[631], expressions[632]); + expressions[634] = BinaryenDataDrop(the_module, 0); + expressions[635] = BinaryenConst(the_module, BinaryenLiteralInt32(2048)); + expressions[636] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); + expressions[637] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); + expressions[638] = BinaryenMemoryCopy(the_module, expressions[635], expressions[636], expressions[637]); + expressions[639] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[640] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[641] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); + expressions[642] = BinaryenMemoryFill(the_module, expressions[639], expressions[640], expressions[641]); { BinaryenExpressionRef children[] = { 0 }; - expressions[635] = BinaryenBlock(the_module, NULL, children, 0, 0); - } - expressions[636] = BinaryenIf(the_module, expressions[7], expressions[8], expressions[9]); - expressions[637] = BinaryenIf(the_module, expressions[10], expressions[11], expressions[0]); - expressions[638] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[639] = BinaryenLoop(the_module, "in", expressions[638]); - expressions[640] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[641] = BinaryenLoop(the_module, NULL, expressions[640]); - expressions[642] = BinaryenBreak(the_module, "the-value", expressions[12], expressions[13]); - expressions[643] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); - expressions[644] = BinaryenBreak(the_module, "the-nothing", expressions[643], expressions[0]); - expressions[645] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); - expressions[646] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[645]); - expressions[647] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]); + expressions[643] = BinaryenBlock(the_module, NULL, children, 0, 0); + } + expressions[644] = BinaryenIf(the_module, expressions[7], expressions[8], expressions[9]); + expressions[645] = BinaryenIf(the_module, expressions[10], expressions[11], expressions[0]); + expressions[646] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[647] = BinaryenLoop(the_module, "in", expressions[646]); + expressions[648] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[649] = BinaryenLoop(the_module, NULL, expressions[648]); + expressions[650] = BinaryenBreak(the_module, "the-value", expressions[12], expressions[13]); + expressions[651] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[652] = BinaryenBreak(the_module, "the-nothing", expressions[651], expressions[0]); + expressions[653] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); + expressions[654] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[653]); + expressions[655] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]); { const char* names[] = { "the-value" }; - expressions[648] = BinaryenSwitch(the_module, names, 1, "the-value", expressions[14], expressions[15]); + expressions[656] = BinaryenSwitch(the_module, names, 1, "the-value", expressions[14], expressions[15]); } - expressions[649] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[657] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); { const char* names[] = { "the-nothing" }; - expressions[650] = BinaryenSwitch(the_module, names, 1, "the-nothing", expressions[649], expressions[0]); + expressions[658] = BinaryenSwitch(the_module, names, 1, "the-nothing", expressions[657], expressions[0]); } - expressions[651] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); - expressions[652] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); - expressions[653] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); - expressions[654] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + expressions[659] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[660] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); + expressions[661] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[662] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); { - BinaryenExpressionRef operands[] = { expressions[651], expressions[652], expressions[653], expressions[654] }; - expressions[655] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1); + BinaryenExpressionRef operands[] = { expressions[659], expressions[660], expressions[661], expressions[662] }; + expressions[663] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1); } - expressions[656] = BinaryenUnary(the_module, 20, expressions[655]); - expressions[657] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); - expressions[658] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); - { - BinaryenExpressionRef operands[] = { expressions[657], expressions[658] }; - expressions[659] = BinaryenCall(the_module, "an-imported", operands, 2, 3); - } - expressions[660] = BinaryenUnary(the_module, 25, expressions[659]); - expressions[661] = BinaryenUnary(the_module, 20, expressions[660]); - expressions[662] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); - expressions[663] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); - expressions[664] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); - expressions[665] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[664] = BinaryenUnary(the_module, 20, expressions[663]); + expressions[665] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); expressions[666] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); { - BinaryenExpressionRef operands[] = { expressions[663], expressions[664], expressions[665], expressions[666] }; - expressions[667] = BinaryenCallIndirect(the_module, expressions[662], operands, 4, "iiIfF"); - } - expressions[668] = BinaryenUnary(the_module, 20, expressions[667]); - expressions[669] = BinaryenLocalGet(the_module, 0, 1); - expressions[670] = BinaryenDrop(the_module, expressions[669]); - expressions[671] = BinaryenConst(the_module, BinaryenLiteralInt32(101)); - expressions[672] = BinaryenLocalSet(the_module, 0, expressions[671]); - expressions[673] = BinaryenConst(the_module, BinaryenLiteralInt32(102)); - expressions[674] = BinaryenLocalTee(the_module, 0, expressions[673]); - expressions[675] = BinaryenDrop(the_module, expressions[674]); - expressions[676] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); - expressions[677] = BinaryenLoad(the_module, 4, 1, 0, 0, 1, expressions[676]); - expressions[678] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); - expressions[679] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[678]); - expressions[680] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); - expressions[681] = BinaryenLoad(the_module, 4, 1, 0, 0, 3, expressions[680]); - expressions[682] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); - expressions[683] = BinaryenLoad(the_module, 8, 1, 2, 8, 4, expressions[682]); - expressions[684] = BinaryenStore(the_module, 4, 0, 0, expressions[19], expressions[20], 1); - expressions[685] = BinaryenStore(the_module, 8, 2, 4, expressions[21], expressions[22], 2); - expressions[686] = BinaryenSelect(the_module, expressions[16], expressions[17], expressions[18]); - expressions[687] = BinaryenConst(the_module, BinaryenLiteralInt32(1337)); - expressions[688] = BinaryenReturn(the_module, expressions[687]); - expressions[689] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); - expressions[690] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); - expressions[691] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); - expressions[692] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); - { - BinaryenExpressionRef operands[] = { expressions[689], expressions[690], expressions[691], expressions[692] }; - expressions[693] = BinaryenReturnCall(the_module, "kitchen()sinker", operands, 4, 1); - } - expressions[694] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); - expressions[695] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); - expressions[696] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); - expressions[697] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); - expressions[698] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); - { - BinaryenExpressionRef operands[] = { expressions[695], expressions[696], expressions[697], expressions[698] }; - expressions[699] = BinaryenReturnCallIndirect(the_module, expressions[694], operands, 4, "iiIfF"); - } - expressions[700] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - { - BinaryenExpressionRef operands[] = { expressions[700] }; - expressions[701] = BinaryenThrow(the_module, "a-event", operands, 1); - } - expressions[702] = BinaryenPop(the_module, 7); - expressions[703] = BinaryenLocalSet(the_module, 5, expressions[702]); - expressions[704] = BinaryenLocalGet(the_module, 5, 7); - expressions[705] = BinaryenBrOnExn(the_module, "try-block", "a-event", expressions[704]); - expressions[706] = BinaryenRethrow(the_module, expressions[705]); - { - BinaryenExpressionRef children[] = { expressions[706] }; - expressions[707] = BinaryenBlock(the_module, "try-block", children, 1, 1); - } - expressions[708] = BinaryenDrop(the_module, expressions[707]); - { - BinaryenExpressionRef children[] = { expressions[703], expressions[708] }; - expressions[709] = BinaryenBlock(the_module, NULL, children, 2, 0); - } - expressions[710] = BinaryenTry(the_module, expressions[701], expressions[709]); - expressions[711] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[712] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[713] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[712]); - expressions[714] = BinaryenAtomicStore(the_module, 4, 0, expressions[711], expressions[713], 1); - expressions[715] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[716] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[717] = BinaryenConst(the_module, BinaryenLiteralInt64(0)); - expressions[718] = BinaryenAtomicWait(the_module, expressions[715], expressions[716], expressions[717], 1); - expressions[719] = BinaryenDrop(the_module, expressions[718]); + BinaryenExpressionRef operands[] = { expressions[665], expressions[666] }; + expressions[667] = BinaryenCall(the_module, "an-imported", operands, 2, 3); + } + expressions[668] = BinaryenUnary(the_module, 25, expressions[667]); + expressions[669] = BinaryenUnary(the_module, 20, expressions[668]); + expressions[670] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); + expressions[671] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); + expressions[673] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[674] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + { + BinaryenExpressionRef operands[] = { expressions[671], expressions[672], expressions[673], expressions[674] }; + expressions[675] = BinaryenCallIndirect(the_module, expressions[670], operands, 4, "iiIfF"); + } + expressions[676] = BinaryenUnary(the_module, 20, expressions[675]); + expressions[677] = BinaryenLocalGet(the_module, 0, 1); + expressions[678] = BinaryenDrop(the_module, expressions[677]); + expressions[679] = BinaryenConst(the_module, BinaryenLiteralInt32(101)); + expressions[680] = BinaryenLocalSet(the_module, 0, expressions[679]); + expressions[681] = BinaryenConst(the_module, BinaryenLiteralInt32(102)); + expressions[682] = BinaryenLocalTee(the_module, 0, expressions[681]); + expressions[683] = BinaryenDrop(the_module, expressions[682]); + expressions[684] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[685] = BinaryenLoad(the_module, 4, 1, 0, 0, 1, expressions[684]); + expressions[686] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); + expressions[687] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[686]); + expressions[688] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[689] = BinaryenLoad(the_module, 4, 1, 0, 0, 3, expressions[688]); + expressions[690] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); + expressions[691] = BinaryenLoad(the_module, 8, 1, 2, 8, 4, expressions[690]); + expressions[692] = BinaryenStore(the_module, 4, 0, 0, expressions[19], expressions[20], 1); + expressions[693] = BinaryenStore(the_module, 8, 2, 4, expressions[21], expressions[22], 2); + expressions[694] = BinaryenSelect(the_module, expressions[16], expressions[17], expressions[18]); + expressions[695] = BinaryenConst(the_module, BinaryenLiteralInt32(1337)); + expressions[696] = BinaryenReturn(the_module, expressions[695]); + expressions[697] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[698] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); + expressions[699] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[700] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + { + BinaryenExpressionRef operands[] = { expressions[697], expressions[698], expressions[699], expressions[700] }; + expressions[701] = BinaryenReturnCall(the_module, "kitchen()sinker", operands, 4, 1); + } + expressions[702] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); + expressions[703] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[704] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); + expressions[705] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[706] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + { + BinaryenExpressionRef operands[] = { expressions[703], expressions[704], expressions[705], expressions[706] }; + expressions[707] = BinaryenReturnCallIndirect(the_module, expressions[702], operands, 4, "iiIfF"); + } + expressions[708] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + { + BinaryenExpressionRef operands[] = { expressions[708] }; + expressions[709] = BinaryenThrow(the_module, "a-event", operands, 1); + } + expressions[710] = BinaryenPop(the_module, 7); + expressions[711] = BinaryenLocalSet(the_module, 5, expressions[710]); + expressions[712] = BinaryenLocalGet(the_module, 5, 7); + expressions[713] = BinaryenBrOnExn(the_module, "try-block", "a-event", expressions[712]); + expressions[714] = BinaryenRethrow(the_module, expressions[713]); + { + BinaryenExpressionRef children[] = { expressions[714] }; + expressions[715] = BinaryenBlock(the_module, "try-block", children, 1, 1); + } + expressions[716] = BinaryenDrop(the_module, expressions[715]); + { + BinaryenExpressionRef children[] = { expressions[711], expressions[716] }; + expressions[717] = BinaryenBlock(the_module, NULL, children, 2, 0); + } + expressions[718] = BinaryenTry(the_module, expressions[709], expressions[717]); + expressions[719] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); expressions[720] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[721] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[722] = BinaryenAtomicNotify(the_module, expressions[720], expressions[721]); - expressions[723] = BinaryenDrop(the_module, expressions[722]); - expressions[724] = BinaryenAtomicFence(the_module); - expressions[725] = BinaryenPop(the_module, 1); - expressions[726] = BinaryenPush(the_module, expressions[725]); - expressions[727] = BinaryenPop(the_module, 2); - expressions[728] = BinaryenPush(the_module, expressions[727]); - expressions[729] = BinaryenPop(the_module, 3); - expressions[730] = BinaryenPush(the_module, expressions[729]); - expressions[731] = BinaryenPop(the_module, 4); - expressions[732] = BinaryenPush(the_module, expressions[731]); - expressions[733] = BinaryenPop(the_module, 5); + expressions[721] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[720]); + expressions[722] = BinaryenAtomicStore(the_module, 4, 0, expressions[719], expressions[721], 1); + expressions[723] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[724] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[725] = BinaryenConst(the_module, BinaryenLiteralInt64(0)); + expressions[726] = BinaryenAtomicWait(the_module, expressions[723], expressions[724], expressions[725], 1); + expressions[727] = BinaryenDrop(the_module, expressions[726]); + expressions[728] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[729] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[730] = BinaryenAtomicNotify(the_module, expressions[728], expressions[729]); + expressions[731] = BinaryenDrop(the_module, expressions[730]); + expressions[732] = BinaryenAtomicFence(the_module); + expressions[733] = BinaryenPop(the_module, 1); expressions[734] = BinaryenPush(the_module, expressions[733]); - expressions[735] = BinaryenPop(the_module, 7); + expressions[735] = BinaryenPop(the_module, 2); expressions[736] = BinaryenPush(the_module, expressions[735]); - expressions[737] = BinaryenNop(the_module); - expressions[738] = BinaryenUnreachable(the_module); + expressions[737] = BinaryenPop(the_module, 3); + expressions[738] = BinaryenPush(the_module, expressions[737]); + expressions[739] = BinaryenPop(the_module, 4); + expressions[740] = BinaryenPush(the_module, expressions[739]); + expressions[741] = BinaryenPop(the_module, 5); + expressions[742] = BinaryenPush(the_module, expressions[741]); + expressions[743] = BinaryenPop(the_module, 7); + expressions[744] = BinaryenPush(the_module, expressions[743]); + expressions[745] = BinaryenNop(the_module); + expressions[746] = BinaryenUnreachable(the_module); BinaryenExpressionGetId(expressions[30]); BinaryenExpressionGetType(expressions[30]); BinaryenUnaryGetOp(expressions[30]); @@ -5169,26 +5218,26 @@ getExpressionInfo={"id":15,"type":3,"op":6} (f32.const -33.61199951171875) ) - expressions[739] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); - BinaryenExpressionGetId(expressions[739]); - BinaryenExpressionGetType(expressions[739]); - BinaryenConstGetValueI32(expressions[739]); + expressions[747] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); + BinaryenExpressionGetId(expressions[747]); + BinaryenExpressionGetType(expressions[747]); + BinaryenConstGetValueI32(expressions[747]); getExpressionInfo(i32.const)={"id":14,"type":1,"value":5} - expressions[740] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078)); - BinaryenExpressionGetId(expressions[740]); - BinaryenExpressionGetType(expressions[740]); - BinaryenConstGetValueI64Low(expressions[740]); - BinaryenConstGetValueI64High(expressions[740]); + expressions[748] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078)); + BinaryenExpressionGetId(expressions[748]); + BinaryenExpressionGetType(expressions[748]); + BinaryenConstGetValueI64Low(expressions[748]); + BinaryenConstGetValueI64High(expressions[748]); getExpressionInfo(i64.const)={"id":14,"type":2,"value":{"low":6,"high":7}} - expressions[741] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5)); - BinaryenExpressionGetId(expressions[741]); - BinaryenExpressionGetType(expressions[741]); - BinaryenConstGetValueF32(expressions[741]); + expressions[749] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5)); + BinaryenExpressionGetId(expressions[749]); + BinaryenExpressionGetType(expressions[749]); + BinaryenConstGetValueF32(expressions[749]); getExpressionInfo(f32.const)={"id":14,"type":3,"value":8.5} - expressions[742] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5)); - BinaryenExpressionGetId(expressions[742]); - BinaryenExpressionGetType(expressions[742]); - BinaryenConstGetValueF64(expressions[742]); + expressions[750] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5)); + BinaryenExpressionGetId(expressions[750]); + BinaryenExpressionGetType(expressions[750]); + BinaryenConstGetValueF64(expressions[750]); getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} { BinaryenExpressionRef children[] = { expressions[24], expressions[26], expressions[28], expressions[30], expressions[32], @@ -5228,33 +5277,34 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} expressions[542], expressions[544], expressions[547], expressions[550], expressions[553], expressions[556], expressions[559], expressions[562], expressions[565], expressions[568], expressions[571], expressions[574], expressions[577], expressions[580], expressions[583], expressions[586], expressions[589], expressions[592], - expressions[595], expressions[598], expressions[601], expressions[605], expressions[609], expressions[613], - expressions[617], expressions[621], expressions[625], expressions[626], expressions[630], expressions[634], - expressions[635], expressions[636], expressions[637], expressions[639], expressions[641], expressions[642], - expressions[644], expressions[646], expressions[647], expressions[648], expressions[650], expressions[656], - expressions[661], expressions[668], expressions[670], expressions[672], expressions[675], expressions[677], - expressions[679], expressions[681], expressions[683], expressions[684], expressions[685], expressions[686], - expressions[688], expressions[693], expressions[699], expressions[710], expressions[714], expressions[719], - expressions[723], expressions[724], expressions[726], expressions[728], expressions[730], expressions[732], - expressions[734], expressions[736], expressions[737], expressions[738] }; - expressions[743] = BinaryenBlock(the_module, "the-value", children, 273, 0); + expressions[595], expressions[598], expressions[600], expressions[602], expressions[604], expressions[606], + expressions[609], expressions[613], expressions[617], expressions[621], expressions[625], expressions[629], + expressions[633], expressions[634], expressions[638], expressions[642], expressions[643], expressions[644], + expressions[645], expressions[647], expressions[649], expressions[650], expressions[652], expressions[654], + expressions[655], expressions[656], expressions[658], expressions[664], expressions[669], expressions[676], + expressions[678], expressions[680], expressions[683], expressions[685], expressions[687], expressions[689], + expressions[691], expressions[692], expressions[693], expressions[694], expressions[696], expressions[701], + expressions[707], expressions[718], expressions[722], expressions[727], expressions[731], expressions[732], + expressions[734], expressions[736], expressions[738], expressions[740], expressions[742], expressions[744], + expressions[745], expressions[746] }; + expressions[751] = BinaryenBlock(the_module, "the-value", children, 277, 0); } - expressions[744] = BinaryenDrop(the_module, expressions[743]); + expressions[752] = BinaryenDrop(the_module, expressions[751]); { - BinaryenExpressionRef children[] = { expressions[744] }; - expressions[745] = BinaryenBlock(the_module, "the-nothing", children, 1, 0); + BinaryenExpressionRef children[] = { expressions[752] }; + expressions[753] = BinaryenBlock(the_module, "the-nothing", children, 1, 0); } - expressions[746] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[754] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); { - BinaryenExpressionRef children[] = { expressions[745], expressions[746] }; - expressions[747] = BinaryenBlock(the_module, "the-body", children, 2, 0); + BinaryenExpressionRef children[] = { expressions[753], expressions[754] }; + expressions[755] = BinaryenBlock(the_module, "the-body", children, 2, 0); } { BinaryenType varTypes[] = { 1, 7 }; - functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[747]); + functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[755]); } - expressions[748] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); - globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[748]); + expressions[756] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[756]); { BinaryenType paramTypes[] = { 1, 4 }; functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2); @@ -5284,13 +5334,13 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} const char* funcNames[] = { "kitchen()sinker" }; BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1); } - expressions[749] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[757] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[749], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[757], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } @@ -5298,10 +5348,10 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[750] = BinaryenNop(the_module); + expressions[758] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[750]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[758]); } BinaryenSetStart(the_module, functions[1]); { @@ -6578,6 +6628,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) @@ -8112,6 +8182,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) diff --git a/test/binaryen.js/push-pop.js.txt b/test/binaryen.js/push-pop.js.txt index 80166906a..2b895ed4f 100644 --- a/test/binaryen.js/push-pop.js.txt +++ b/test/binaryen.js/push-pop.js.txt @@ -22,10 +22,10 @@ ) ) -getExpressionInfo(i32.pop) = {"id":38,"type":1} -getExpressionInfo(i64.pop) = {"id":38,"type":2} -getExpressionInfo(f32.pop) = {"id":38,"type":3} -getExpressionInfo(f64.pop) = {"id":38,"type":4} -getExpressionInfo(v128.pop) = {"id":38,"type":5} -getExpressionInfo(exnref.pop) = {"id":38,"type":7} -getExpressionInfo(push) = {"id":37} +getExpressionInfo(i32.pop) = {"id":39,"type":1} +getExpressionInfo(i64.pop) = {"id":39,"type":2} +getExpressionInfo(f32.pop) = {"id":39,"type":3} +getExpressionInfo(f64.pop) = {"id":39,"type":4} +getExpressionInfo(v128.pop) = {"id":39,"type":5} +getExpressionInfo(exnref.pop) = {"id":39,"type":7} +getExpressionInfo(push) = {"id":38} diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 1c45b90b5..ae037a14d 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -1,4 +1,3 @@ - // We always need asserts here #ifdef NDEBUG #undef NDEBUG @@ -482,6 +481,15 @@ void test_core() { makeSIMDShift(module, BinaryenShlVecI64x2()), makeSIMDShift(module, BinaryenShrSVecI64x2()), makeSIMDShift(module, BinaryenShrUVecI64x2()), + // SIMD load + BinaryenSIMDLoad( + module, BinaryenLoadSplatVec8x16(), 0, 1, makeInt32(module, 128)), + BinaryenSIMDLoad( + module, BinaryenLoadSplatVec16x8(), 16, 1, makeInt32(module, 128)), + BinaryenSIMDLoad( + module, BinaryenLoadSplatVec32x4(), 16, 4, makeInt32(module, 128)), + BinaryenSIMDLoad( + module, BinaryenLoadSplatVec64x2(), 0, 4, makeInt32(module, 128)), // Other SIMD makeSIMDShuffle(module), makeSIMDTernary(module, BinaryenBitselectVec128()), diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 040eb2b45..12e8887ae 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1293,6 +1293,26 @@ BinaryenFeatureAll: 511 ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) @@ -3390,177 +3410,185 @@ int main() { } expressions[618] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); expressions[619] = BinaryenSIMDShift(the_module, 11, expressions[617], expressions[618]); + expressions[620] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[621] = BinaryenSIMDLoad(the_module, 0, 0, 1, expressions[620]); + expressions[622] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[623] = BinaryenSIMDLoad(the_module, 1, 16, 1, expressions[622]); + expressions[624] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[625] = BinaryenSIMDLoad(the_module, 2, 16, 4, expressions[624]); + expressions[626] = BinaryenConst(the_module, BinaryenLiteralInt32(128)); + expressions[627] = BinaryenSIMDLoad(the_module, 3, 0, 4, expressions[626]); { uint8_t t222[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[620] = BinaryenConst(the_module, BinaryenLiteralVec128(t222)); + expressions[628] = BinaryenConst(the_module, BinaryenLiteralVec128(t222)); } { uint8_t t223[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[621] = BinaryenConst(the_module, BinaryenLiteralVec128(t223)); + expressions[629] = BinaryenConst(the_module, BinaryenLiteralVec128(t223)); } { uint8_t mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - expressions[622] = BinaryenSIMDShuffle(the_module, expressions[620], expressions[621], mask); + expressions[630] = BinaryenSIMDShuffle(the_module, expressions[628], expressions[629], mask); } { uint8_t t224[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[623] = BinaryenConst(the_module, BinaryenLiteralVec128(t224)); + expressions[631] = BinaryenConst(the_module, BinaryenLiteralVec128(t224)); } { uint8_t t225[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[624] = BinaryenConst(the_module, BinaryenLiteralVec128(t225)); + expressions[632] = BinaryenConst(the_module, BinaryenLiteralVec128(t225)); } { uint8_t t226[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[625] = BinaryenConst(the_module, BinaryenLiteralVec128(t226)); + expressions[633] = BinaryenConst(the_module, BinaryenLiteralVec128(t226)); } - expressions[626] = BinaryenSIMDTernary(the_module, 0, expressions[623], expressions[624], expressions[625]); + expressions[634] = BinaryenSIMDTernary(the_module, 0, expressions[631], expressions[632], expressions[633]); { uint8_t t227[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[627] = BinaryenConst(the_module, BinaryenLiteralVec128(t227)); + expressions[635] = BinaryenConst(the_module, BinaryenLiteralVec128(t227)); } { uint8_t t228[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[628] = BinaryenConst(the_module, BinaryenLiteralVec128(t228)); + expressions[636] = BinaryenConst(the_module, BinaryenLiteralVec128(t228)); } { uint8_t t229[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[629] = BinaryenConst(the_module, BinaryenLiteralVec128(t229)); + expressions[637] = BinaryenConst(the_module, BinaryenLiteralVec128(t229)); } - expressions[630] = BinaryenSIMDTernary(the_module, 1, expressions[627], expressions[628], expressions[629]); + expressions[638] = BinaryenSIMDTernary(the_module, 1, expressions[635], expressions[636], expressions[637]); { uint8_t t230[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[631] = BinaryenConst(the_module, BinaryenLiteralVec128(t230)); + expressions[639] = BinaryenConst(the_module, BinaryenLiteralVec128(t230)); } { uint8_t t231[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[632] = BinaryenConst(the_module, BinaryenLiteralVec128(t231)); + expressions[640] = BinaryenConst(the_module, BinaryenLiteralVec128(t231)); } { uint8_t t232[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[633] = BinaryenConst(the_module, BinaryenLiteralVec128(t232)); + expressions[641] = BinaryenConst(the_module, BinaryenLiteralVec128(t232)); } - expressions[634] = BinaryenSIMDTernary(the_module, 2, expressions[631], expressions[632], expressions[633]); + expressions[642] = BinaryenSIMDTernary(the_module, 2, expressions[639], expressions[640], expressions[641]); { uint8_t t233[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[635] = BinaryenConst(the_module, BinaryenLiteralVec128(t233)); + expressions[643] = BinaryenConst(the_module, BinaryenLiteralVec128(t233)); } { uint8_t t234[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[636] = BinaryenConst(the_module, BinaryenLiteralVec128(t234)); + expressions[644] = BinaryenConst(the_module, BinaryenLiteralVec128(t234)); } { uint8_t t235[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[637] = BinaryenConst(the_module, BinaryenLiteralVec128(t235)); + expressions[645] = BinaryenConst(the_module, BinaryenLiteralVec128(t235)); } - expressions[638] = BinaryenSIMDTernary(the_module, 3, expressions[635], expressions[636], expressions[637]); + expressions[646] = BinaryenSIMDTernary(the_module, 3, expressions[643], expressions[644], expressions[645]); { uint8_t t236[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[639] = BinaryenConst(the_module, BinaryenLiteralVec128(t236)); + expressions[647] = BinaryenConst(the_module, BinaryenLiteralVec128(t236)); } { uint8_t t237[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[640] = BinaryenConst(the_module, BinaryenLiteralVec128(t237)); + expressions[648] = BinaryenConst(the_module, BinaryenLiteralVec128(t237)); } { uint8_t t238[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - expressions[641] = BinaryenConst(the_module, BinaryenLiteralVec128(t238)); - } - expressions[642] = BinaryenSIMDTernary(the_module, 4, expressions[639], expressions[640], expressions[641]); - expressions[643] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[644] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[645] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); - expressions[646] = BinaryenMemoryInit(the_module, 0, expressions[643], expressions[644], expressions[645]); - expressions[647] = BinaryenDataDrop(the_module, 0); - expressions[648] = BinaryenConst(the_module, BinaryenLiteralInt32(2048)); - expressions[649] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[650] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); - expressions[651] = BinaryenMemoryCopy(the_module, expressions[648], expressions[649], expressions[650]); + expressions[649] = BinaryenConst(the_module, BinaryenLiteralVec128(t238)); + } + expressions[650] = BinaryenSIMDTernary(the_module, 4, expressions[647], expressions[648], expressions[649]); + expressions[651] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); expressions[652] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[653] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); - expressions[654] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); - expressions[655] = BinaryenMemoryFill(the_module, expressions[652], expressions[653], expressions[654]); + expressions[653] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); + expressions[654] = BinaryenMemoryInit(the_module, 0, expressions[651], expressions[652], expressions[653]); + expressions[655] = BinaryenDataDrop(the_module, 0); + expressions[656] = BinaryenConst(the_module, BinaryenLiteralInt32(2048)); + expressions[657] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); + expressions[658] = BinaryenConst(the_module, BinaryenLiteralInt32(12)); + expressions[659] = BinaryenMemoryCopy(the_module, expressions[656], expressions[657], expressions[658]); + expressions[660] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[661] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[662] = BinaryenConst(the_module, BinaryenLiteralInt32(1024)); + expressions[663] = BinaryenMemoryFill(the_module, expressions[660], expressions[661], expressions[662]); { BinaryenExpressionRef children[] = { 0 }; - expressions[656] = BinaryenBlock(the_module, NULL, children, 0, BinaryenTypeAuto()); - } - expressions[657] = BinaryenIf(the_module, expressions[18], expressions[19], expressions[20]); - expressions[658] = BinaryenIf(the_module, expressions[21], expressions[22], expressions[0]); - expressions[659] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[660] = BinaryenLoop(the_module, "in", expressions[659]); - expressions[661] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); - expressions[662] = BinaryenLoop(the_module, NULL, expressions[661]); - expressions[663] = BinaryenBreak(the_module, "the-value", expressions[23], expressions[24]); - expressions[664] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); - expressions[665] = BinaryenBreak(the_module, "the-nothing", expressions[664], expressions[0]); - expressions[666] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); - expressions[667] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[666]); - expressions[668] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]); + expressions[664] = BinaryenBlock(the_module, NULL, children, 0, BinaryenTypeAuto()); + } + expressions[665] = BinaryenIf(the_module, expressions[18], expressions[19], expressions[20]); + expressions[666] = BinaryenIf(the_module, expressions[21], expressions[22], expressions[0]); + expressions[667] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[668] = BinaryenLoop(the_module, "in", expressions[667]); + expressions[669] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[670] = BinaryenLoop(the_module, NULL, expressions[669]); + expressions[671] = BinaryenBreak(the_module, "the-value", expressions[23], expressions[24]); + expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[673] = BinaryenBreak(the_module, "the-nothing", expressions[672], expressions[0]); + expressions[674] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); + expressions[675] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[674]); + expressions[676] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]); { const char* names[] = { "the-value" }; - expressions[669] = BinaryenSwitch(the_module, names, 1, "the-value", expressions[25], expressions[26]); + expressions[677] = BinaryenSwitch(the_module, names, 1, "the-value", expressions[25], expressions[26]); } - expressions[670] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[678] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); { const char* names[] = { "the-nothing" }; - expressions[671] = BinaryenSwitch(the_module, names, 1, "the-nothing", expressions[670], expressions[0]); + expressions[679] = BinaryenSwitch(the_module, names, 1, "the-nothing", expressions[678], expressions[0]); } { BinaryenExpressionRef operands[] = { expressions[10], expressions[11], expressions[12], expressions[13] }; - expressions[672] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1); + expressions[680] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1); } - expressions[673] = BinaryenUnary(the_module, 20, expressions[672]); + expressions[681] = BinaryenUnary(the_module, 20, expressions[680]); { BinaryenExpressionRef operands[] = { expressions[8], expressions[9] }; - expressions[674] = BinaryenCall(the_module, "an-imported", operands, 2, 3); + expressions[682] = BinaryenCall(the_module, "an-imported", operands, 2, 3); } - expressions[675] = BinaryenUnary(the_module, 25, expressions[674]); - expressions[676] = BinaryenUnary(the_module, 20, expressions[675]); - expressions[677] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); + expressions[683] = BinaryenUnary(the_module, 25, expressions[682]); + expressions[684] = BinaryenUnary(the_module, 20, expressions[683]); + expressions[685] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); { BinaryenExpressionRef operands[] = { expressions[14], expressions[15], expressions[16], expressions[17] }; - expressions[678] = BinaryenCallIndirect(the_module, expressions[677], operands, 4, "iiIfF"); - } - expressions[679] = BinaryenUnary(the_module, 20, expressions[678]); - expressions[680] = BinaryenLocalGet(the_module, 0, 1); - expressions[681] = BinaryenDrop(the_module, expressions[680]); - expressions[682] = BinaryenConst(the_module, BinaryenLiteralInt32(101)); - expressions[683] = BinaryenLocalSet(the_module, 0, expressions[682]); - expressions[684] = BinaryenConst(the_module, BinaryenLiteralInt32(102)); - expressions[685] = BinaryenLocalTee(the_module, 0, expressions[684]); - expressions[686] = BinaryenDrop(the_module, expressions[685]); - expressions[687] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); - expressions[688] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[687]); - expressions[689] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); - expressions[690] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[689]); - expressions[691] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); - expressions[692] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[691]); - expressions[693] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); - expressions[694] = BinaryenLoad(the_module, 8, 0, 2, 8, 4, expressions[693]); - expressions[695] = BinaryenStore(the_module, 4, 0, 0, expressions[30], expressions[31], 1); - expressions[696] = BinaryenStore(the_module, 8, 2, 4, expressions[32], expressions[33], 2); - expressions[697] = BinaryenSelect(the_module, expressions[27], expressions[28], expressions[29]); - expressions[698] = BinaryenConst(the_module, BinaryenLiteralInt32(1337)); - expressions[699] = BinaryenReturn(the_module, expressions[698]); + expressions[686] = BinaryenCallIndirect(the_module, expressions[685], operands, 4, "iiIfF"); + } + expressions[687] = BinaryenUnary(the_module, 20, expressions[686]); + expressions[688] = BinaryenLocalGet(the_module, 0, 1); + expressions[689] = BinaryenDrop(the_module, expressions[688]); + expressions[690] = BinaryenConst(the_module, BinaryenLiteralInt32(101)); + expressions[691] = BinaryenLocalSet(the_module, 0, expressions[690]); + expressions[692] = BinaryenConst(the_module, BinaryenLiteralInt32(102)); + expressions[693] = BinaryenLocalTee(the_module, 0, expressions[692]); + expressions[694] = BinaryenDrop(the_module, expressions[693]); + expressions[695] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[696] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[695]); + expressions[697] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); + expressions[698] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[697]); + expressions[699] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[700] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[699]); + expressions[701] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); + expressions[702] = BinaryenLoad(the_module, 8, 0, 2, 8, 4, expressions[701]); + expressions[703] = BinaryenStore(the_module, 4, 0, 0, expressions[30], expressions[31], 1); + expressions[704] = BinaryenStore(the_module, 8, 2, 4, expressions[32], expressions[33], 2); + expressions[705] = BinaryenSelect(the_module, expressions[27], expressions[28], expressions[29]); + expressions[706] = BinaryenConst(the_module, BinaryenLiteralInt32(1337)); + expressions[707] = BinaryenReturn(the_module, expressions[706]); { BinaryenExpressionRef operands[] = { expressions[10], expressions[11], expressions[12], expressions[13] }; - expressions[700] = BinaryenReturnCall(the_module, "kitchen()sinker", operands, 4, 1); + expressions[708] = BinaryenReturnCall(the_module, "kitchen()sinker", operands, 4, 1); } - expressions[701] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); + expressions[709] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); { BinaryenExpressionRef operands[] = { expressions[14], expressions[15], expressions[16], expressions[17] }; - expressions[702] = BinaryenReturnCallIndirect(the_module, expressions[701], operands, 4, "iiIfF"); - } - expressions[703] = BinaryenTry(the_module, expressions[35], expressions[43]); - expressions[704] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[23]); - expressions[705] = BinaryenAtomicStore(the_module, 4, 0, expressions[23], expressions[704], 1); - expressions[706] = BinaryenAtomicWait(the_module, expressions[23], expressions[23], expressions[33], 1); - expressions[707] = BinaryenDrop(the_module, expressions[706]); - expressions[708] = BinaryenAtomicNotify(the_module, expressions[23], expressions[23]); - expressions[709] = BinaryenDrop(the_module, expressions[708]); - expressions[710] = BinaryenAtomicFence(the_module); - expressions[711] = BinaryenNop(the_module); - expressions[712] = BinaryenUnreachable(the_module); + expressions[710] = BinaryenReturnCallIndirect(the_module, expressions[709], operands, 4, "iiIfF"); + } + expressions[711] = BinaryenTry(the_module, expressions[35], expressions[43]); + expressions[712] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[23]); + expressions[713] = BinaryenAtomicStore(the_module, 4, 0, expressions[23], expressions[712], 1); + expressions[714] = BinaryenAtomicWait(the_module, expressions[23], expressions[23], expressions[33], 1); + expressions[715] = BinaryenDrop(the_module, expressions[714]); + expressions[716] = BinaryenAtomicNotify(the_module, expressions[23], expressions[23]); + expressions[717] = BinaryenDrop(the_module, expressions[716]); + expressions[718] = BinaryenAtomicFence(the_module); + expressions[719] = BinaryenNop(the_module); + expressions[720] = BinaryenUnreachable(the_module); BinaryenExpressionPrint(expressions[51]); (f32.neg (f32.const -33.61199951171875) @@ -3603,34 +3631,35 @@ int main() { expressions[563], expressions[565], expressions[568], expressions[571], expressions[574], expressions[577], expressions[580], expressions[583], expressions[586], expressions[589], expressions[592], expressions[595], expressions[598], expressions[601], expressions[604], expressions[607], expressions[610], expressions[613], - expressions[616], expressions[619], expressions[622], expressions[626], expressions[630], expressions[634], - expressions[638], expressions[642], expressions[646], expressions[647], expressions[651], expressions[655], - expressions[656], expressions[657], expressions[658], expressions[660], expressions[662], expressions[663], - expressions[665], expressions[667], expressions[668], expressions[669], expressions[671], expressions[673], - expressions[676], expressions[679], expressions[681], expressions[683], expressions[686], expressions[688], - expressions[690], expressions[692], expressions[694], expressions[695], expressions[696], expressions[697], - expressions[699], expressions[700], expressions[702], expressions[703], expressions[705], expressions[707], - expressions[709], expressions[710], expressions[711], expressions[712] }; - expressions[713] = BinaryenBlock(the_module, "the-value", children, 267, BinaryenTypeAuto()); + expressions[616], expressions[619], expressions[621], expressions[623], expressions[625], expressions[627], + expressions[630], expressions[634], expressions[638], expressions[642], expressions[646], expressions[650], + expressions[654], expressions[655], expressions[659], expressions[663], expressions[664], expressions[665], + expressions[666], expressions[668], expressions[670], expressions[671], expressions[673], expressions[675], + expressions[676], expressions[677], expressions[679], expressions[681], expressions[684], expressions[687], + expressions[689], expressions[691], expressions[694], expressions[696], expressions[698], expressions[700], + expressions[702], expressions[703], expressions[704], expressions[705], expressions[707], expressions[708], + expressions[710], expressions[711], expressions[713], expressions[715], expressions[717], expressions[718], + expressions[719], expressions[720] }; + expressions[721] = BinaryenBlock(the_module, "the-value", children, 271, BinaryenTypeAuto()); } - expressions[714] = BinaryenDrop(the_module, expressions[713]); + expressions[722] = BinaryenDrop(the_module, expressions[721]); { - BinaryenExpressionRef children[] = { expressions[714] }; - expressions[715] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto()); + BinaryenExpressionRef children[] = { expressions[722] }; + expressions[723] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto()); } - expressions[716] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[724] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); { - BinaryenExpressionRef children[] = { expressions[715], expressions[716] }; - expressions[717] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto()); + BinaryenExpressionRef children[] = { expressions[723], expressions[724] }; + expressions[725] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto()); } { BinaryenType varTypes[] = { 1, 7 }; - functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[717]); + functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[725]); } - expressions[718] = BinaryenConst(the_module, BinaryenLiteralInt32(7)); - globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[718]); - expressions[719] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5)); - globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[719]); + expressions[726] = BinaryenConst(the_module, BinaryenLiteralInt32(7)); + globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[726]); + expressions[727] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5)); + globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[727]); { BinaryenType paramTypes[] = { 1, 4 }; functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2); @@ -3642,13 +3671,13 @@ int main() { const char* funcNames[] = { "kitchen()sinker" }; BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1); } - expressions[720] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[728] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[720], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[728], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } @@ -3656,10 +3685,10 @@ int main() { BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[721] = BinaryenNop(the_module); + expressions[729] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[721]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[729]); } BinaryenSetStart(the_module, functions[1]); { @@ -4942,6 +4971,26 @@ int main() { ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index 568134304..4e259802f 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -1272,6 +1272,26 @@ ) ) (drop + (v8x16.load_splat + (i32.const 128) + ) + ) + (drop + (v16x8.load_splat offset=16 align=1 + (i32.const 128) + ) + ) + (drop + (v32x4.load_splat offset=16 + (i32.const 128) + ) + ) + (drop + (v64x2.load_splat align=4 + (i32.const 128) + ) + ) + (drop (v8x16.shuffle 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) diff --git a/test/spec/simd.wast b/test/spec/simd.wast index 760b6a778..ec5a3b012 100644 --- a/test/spec/simd.wast +++ b/test/spec/simd.wast @@ -1,7 +1,7 @@ (module (memory 1) (data (i32.const 128) "WASMSIMDGOESFAST") - (func (export "v128.load") (param $0 i32) (result v128)(v128.load (local.get $0))) + (func (export "v128.load") (param $0 i32) (result v128) (v128.load (local.get $0))) (func (export "v128.store") (param $0 i32) (param $1 v128) (result v128) (v128.store offset=0 align=16 (local.get $0) (local.get $1)) (v128.load (local.get $0)) @@ -174,6 +174,10 @@ (func (export "f32x4.convert_i32x4_u") (param $0 v128) (result v128) (f32x4.convert_i32x4_u (local.get $0))) (func (export "f64x2.convert_i64x2_s") (param $0 v128) (result v128) (f64x2.convert_i64x2_s (local.get $0))) (func (export "f64x2.convert_i64x2_u") (param $0 v128) (result v128) (f64x2.convert_i64x2_u (local.get $0))) + (func (export "v8x16.load_splat") (param $0 i32) (result v128) (v8x16.load_splat (local.get $0))) + (func (export "v16x8.load_splat") (param $0 i32) (result v128) (v16x8.load_splat (local.get $0))) + (func (export "v32x4.load_splat") (param $0 i32) (result v128) (v32x4.load_splat (local.get $0))) + (func (export "v64x2.load_splat") (param $0 i32) (result v128) (v64x2.load_splat (local.get $0))) (func (export "i8x16.narrow_i16x8_s") (param $0 v128) (param $1 v128) (result v128) (i8x16.narrow_i16x8_s (local.get $0) (local.get $1))) (func (export "i8x16.narrow_i16x8_u") (param $0 v128) (param $1 v128) (result v128) (i8x16.narrow_i16x8_u (local.get $0) (local.get $1))) (func (export "i16x8.narrow_i32x4_s") (param $0 v128) (param $1 v128) (result v128) (i16x8.narrow_i32x4_s (local.get $0) (local.get $1))) @@ -191,6 +195,10 @@ ;; Basic v128 manipulation (assert_return (invoke "v128.load" (i32.const 128)) (v128.const i8x16 87 65 83 77 83 73 77 68 71 79 69 83 70 65 83 84)) (assert_return (invoke "v128.store" (i32.const 16) (v128.const i32x4 1 2 3 4)) (v128.const i32x4 1 2 3 4)) +(assert_return (invoke "v8x16.load_splat" (i32.const 128)) (v128.const i8x16 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87)) +(assert_return (invoke "v16x8.load_splat" (i32.const 128)) (v128.const i8x16 87 65 87 65 87 65 87 65 87 65 87 65 87 65 87 65)) +(assert_return (invoke "v32x4.load_splat" (i32.const 128)) (v128.const i8x16 87 65 83 77 87 65 83 77 87 65 83 77 87 65 83 77)) +(assert_return (invoke "v64x2.load_splat" (i32.const 128)) (v128.const i8x16 87 65 83 77 83 73 77 68 87 65 83 77 83 73 77 68)) (assert_return (invoke "v128.const.i8x16") (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)) (assert_return (invoke "v128.const.i16x8") (v128.const i8x16 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00)) (assert_return (invoke "v128.const.i32x4") (v128.const i8x16 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00)) |