summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-09-23 18:15:14 -0700
committerGitHub <noreply@github.com>2019-09-23 18:15:14 -0700
commit835581f58eb5040656243f7345ebcacf6d7deee5 (patch)
treed5f8878015be2edcdf3d69306c0a8bc20ecd9bf6
parentfb217c80c6d9c4b52d90571c435fc52dc868df47 (diff)
downloadbinaryen-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.
-rw-r--r--CHANGELOG.md1
-rw-r--r--Contributing.md22
-rwxr-xr-xbuild-js.sh12
-rwxr-xr-xscripts/gen-s-parser.py4
-rw-r--r--src/binaryen-c.cpp62
-rw-r--r--src/binaryen-c.h16
-rw-r--r--src/gen-s-parser.inc74
-rw-r--r--src/ir/ExpressionAnalyzer.cpp5
-rw-r--r--src/ir/ExpressionManipulator.cpp4
-rw-r--r--src/ir/ReFinalize.cpp1
-rw-r--r--src/ir/effects.h6
-rw-r--r--src/ir/utils.h2
-rw-r--r--src/js/binaryen.js-post.js51
-rw-r--r--src/passes/DeadCodeElimination.cpp2
-rw-r--r--src/passes/Print.cpp31
-rw-r--r--src/tools/fuzzing.h27
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-builder.h10
-rw-r--r--src/wasm-interpreter.h34
-rw-r--r--src/wasm-s-parser.h1
-rw-r--r--src/wasm-stack.h12
-rw-r--r--src/wasm-traversal.h17
-rw-r--r--src/wasm.h22
-rw-r--r--src/wasm/wasm-binary.cpp61
-rw-r--r--src/wasm/wasm-s-parser.cpp28
-rw-r--r--src/wasm/wasm-stack.cpp20
-rw-r--r--src/wasm/wasm-validator.cpp15
-rw-r--r--src/wasm/wasm.cpp24
-rw-r--r--src/wasm2js.h4
-rw-r--r--test/binaryen.js/exception-handling.js.txt8
-rw-r--r--test/binaryen.js/kitchen-sink.js8
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt506
-rw-r--r--test/binaryen.js/push-pop.js.txt14
-rw-r--r--test/example/c-api-kitchen-sink.c10
-rw-r--r--test/example/c-api-kitchen-sink.txt289
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt20
-rw-r--r--test/spec/simd.wast10
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))