summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/gen-s-parser.py2
-rw-r--r--src/gen-s-parser.inc11
-rw-r--r--src/ir/ReFinalize.cpp1
-rw-r--r--src/ir/cost.h1
-rw-r--r--src/ir/effects.h1
-rw-r--r--src/passes/Print.cpp20
-rw-r--r--src/wasm-binary.h4
-rw-r--r--src/wasm-delegations-fields.h8
-rw-r--r--src/wasm-delegations.h1
-rw-r--r--src/wasm-interpreter.h1
-rw-r--r--src/wasm-s-parser.h1
-rw-r--r--src/wasm.h20
-rw-r--r--src/wasm/wasm-binary.cpp24
-rw-r--r--src/wasm/wasm-s-parser.cpp9
-rw-r--r--src/wasm/wasm-stack.cpp13
-rw-r--r--src/wasm/wasm.cpp5
-rw-r--r--src/wasm2js.h4
-rw-r--r--test/binaryen.js/exception-handling.js.txt6
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt58
-rw-r--r--test/simd.wast10
-rw-r--r--test/simd.wast.from-wast10
-rw-r--r--test/simd.wast.fromBinary10
-rw-r--r--test/simd.wast.fromBinary.noDebugInfo10
23 files changed, 197 insertions, 33 deletions
diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py
index af29f4020..c65e5ddc4 100755
--- a/scripts/gen-s-parser.py
+++ b/scripts/gen-s-parser.py
@@ -522,6 +522,8 @@ instructions = [
("i32x4.trunc_sat_f64x2_zero_u", "makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4)"),
("f32x4.demote_f64x2_zero", "makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4)"),
("f64x2.promote_low_f32x4", "makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2)"),
+ ("i32x4.widen_i8x16_s", "makeSIMDWiden(s, SIMDWidenOp::WidenSVecI8x16ToVecI32x4)"),
+ ("i32x4.widen_i8x16_u", "makeSIMDWiden(s, SIMDWidenOp::WidenUVecI8x16ToVecI32x4)"),
# prefetch instructions
("prefetch.t", "makePrefetch(s, PrefetchOp::PrefetchTemporal)"),
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 281a2cfca..4e5a61d92 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -1832,6 +1832,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'i': {
+ switch (op[18]) {
+ case 's':
+ if (strcmp(op, "i32x4.widen_i8x16_s") == 0) { return makeSIMDWiden(s, SIMDWidenOp::WidenSVecI8x16ToVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.widen_i8x16_u") == 0) { return makeSIMDWiden(s, SIMDWidenOp::WidenUVecI8x16ToVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 'l': {
switch (op[22]) {
case 's':
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 808b9d41b..de4184596 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -112,6 +112,7 @@ void ReFinalize::visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); }
void ReFinalize::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
curr->finalize();
}
+void ReFinalize::visitSIMDWiden(SIMDWiden* curr) { curr->finalize(); }
void ReFinalize::visitPrefetch(Prefetch* curr) { curr->finalize(); }
void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); }
void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); }
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 212933ffb..50941bdd3 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -540,6 +540,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
Index visitSIMDShift(SIMDShift* curr) {
return 1 + visit(curr->vec) + visit(curr->shift);
}
+ Index visitSIMDWiden(SIMDWiden* curr) { return 1 + visit(curr->vec); }
Index visitSIMDShuffle(SIMDShuffle* curr) {
return 1 + visit(curr->left) + visit(curr->right);
}
diff --git a/src/ir/effects.h b/src/ir/effects.h
index c7142dc34..d52fcfb15 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -430,6 +430,7 @@ private:
}
parent.implicitTrap = true;
}
+ void visitSIMDWiden(SIMDWiden* curr) {}
void visitPrefetch(Prefetch* curr) {
// Do not reorder with respect to other memory ops
parent.writesMemory = true;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 39c66cc57..74bd5598f 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -671,6 +671,19 @@ struct PrintExpressionContents
}
o << " " << int(curr->index);
}
+ void visitSIMDWiden(SIMDWiden* curr) {
+ prepareColor(o);
+ switch (curr->op) {
+ case WidenSVecI8x16ToVecI32x4:
+ o << "i32x4.widen_i8x16_s ";
+ break;
+ case WidenUVecI8x16ToVecI32x4:
+ o << "i32x4.widen_i8x16_u ";
+ break;
+ }
+ restoreNormalColor(o);
+ o << int(curr->index);
+ }
void visitPrefetch(Prefetch* curr) {
prepareColor(o);
switch (curr->op) {
@@ -2303,6 +2316,13 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
printFullLine(curr->vec);
decIndent();
}
+ void visitSIMDWiden(SIMDWiden* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ incIndent();
+ printFullLine(curr->vec);
+ decIndent();
+ }
void visitPrefetch(Prefetch* curr) {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 0213baffe..6a409f7db 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -979,6 +979,9 @@ enum ASTNodes {
F32x4DemoteZeroF64x2 = 0x57,
F64x2PromoteLowF32x4 = 0x69,
+ I32x4WidenSI8x16 = 0x67,
+ I32x4WidenUI8x16 = 0x68,
+
// prefetch opcodes
PrefetchT = 0xc5,
@@ -1521,6 +1524,7 @@ public:
bool maybeVisitSIMDShift(Expression*& out, uint32_t code);
bool maybeVisitSIMDLoad(Expression*& out, uint32_t code);
bool maybeVisitSIMDLoadStoreLane(Expression*& out, uint32_t code);
+ bool maybeVisitSIMDWiden(Expression*& out, uint32_t code);
bool maybeVisitPrefetch(Expression*& out, uint32_t code);
bool maybeVisitMemoryInit(Expression*& out, uint32_t code);
bool maybeVisitDataDrop(Expression*& out, uint32_t code);
diff --git a/src/wasm-delegations-fields.h b/src/wasm-delegations-fields.h
index d4ea25b3d..b99ebef40 100644
--- a/src/wasm-delegations-fields.h
+++ b/src/wasm-delegations-fields.h
@@ -386,6 +386,14 @@ switch (DELEGATE_ID) {
DELEGATE_END(SIMDLoadStoreLane);
break;
}
+ case Expression::Id::SIMDWidenId: {
+ DELEGATE_START(SIMDWiden);
+ DELEGATE_FIELD_CHILD(SIMDWiden, vec);
+ DELEGATE_FIELD_INT(SIMDWiden, op);
+ DELEGATE_FIELD_INT(SIMDWiden, index);
+ DELEGATE_END(SIMDWiden);
+ break;
+ }
case Expression::Id::PrefetchId: {
DELEGATE_START(Prefetch);
DELEGATE_FIELD_CHILD(Prefetch, ptr);
diff --git a/src/wasm-delegations.h b/src/wasm-delegations.h
index fd419f508..5a05a731f 100644
--- a/src/wasm-delegations.h
+++ b/src/wasm-delegations.h
@@ -40,6 +40,7 @@ DELEGATE(SIMDTernary);
DELEGATE(SIMDShift);
DELEGATE(SIMDLoad);
DELEGATE(SIMDLoadStoreLane);
+DELEGATE(SIMDWiden);
DELEGATE(Prefetch);
DELEGATE(MemoryInit);
DELEGATE(DataDrop);
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index c01b56ec7..26764c304 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1132,6 +1132,7 @@ public:
}
WASM_UNREACHABLE("invalid op");
}
+ Flow visitSIMDWiden(SIMDWiden* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitSelect(Select* curr) {
NOTE_ENTER("Select");
Flow ifTrue = visit(curr->ifTrue);
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 921ef6b4a..031589894 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -220,6 +220,7 @@ private:
Expression* makeSIMDShift(Element& s, SIMDShiftOp op);
Expression* makeSIMDLoad(Element& s, SIMDLoadOp op);
Expression* makeSIMDLoadStoreLane(Element& s, SIMDLoadStoreLaneOp op);
+ Expression* makeSIMDWiden(Element& s, SIMDWidenOp op);
Expression* makePrefetch(Element& s, PrefetchOp op);
Expression* makeMemoryInit(Element& s);
Expression* makeDataDrop(Element& s);
diff --git a/src/wasm.h b/src/wasm.h
index bd2e31814..0050fcc28 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -481,7 +481,7 @@ enum SIMDReplaceOp {
ReplaceLaneVecI32x4,
ReplaceLaneVecI64x2,
ReplaceLaneVecF32x4,
- ReplaceLaneVecF64x2
+ ReplaceLaneVecF64x2,
};
enum SIMDShiftOp {
@@ -537,6 +537,11 @@ enum SIMDTernaryOp {
SignSelectVec64x2
};
+enum SIMDWidenOp {
+ WidenSVecI8x16ToVecI32x4,
+ WidenUVecI8x16ToVecI32x4,
+};
+
enum PrefetchOp {
PrefetchTemporal,
PrefetchNontemporal,
@@ -625,6 +630,7 @@ public:
SIMDShiftId,
SIMDLoadId,
SIMDLoadStoreLaneId,
+ SIMDWidenId,
MemoryInitId,
DataDropId,
MemoryCopyId,
@@ -1072,6 +1078,18 @@ public:
void finalize();
};
+class SIMDWiden : public SpecificExpression<Expression::SIMDWidenId> {
+public:
+ SIMDWiden() = default;
+ SIMDWiden(MixedArena& allocator) {}
+
+ SIMDWidenOp op;
+ uint8_t index;
+ Expression* vec;
+
+ void finalize();
+};
+
class Prefetch : public SpecificExpression<Expression::PrefetchId> {
public:
Prefetch() = default;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b7ffcd8d7..2c473a254 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3005,6 +3005,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitSIMDLoadStoreLane(curr, opcode)) {
break;
}
+ if (maybeVisitSIMDWiden(curr, opcode)) {
+ break;
+ }
if (maybeVisitPrefetch(curr, opcode)) {
break;
}
@@ -5466,6 +5469,27 @@ bool WasmBinaryBuilder::maybeVisitSIMDLoadStoreLane(Expression*& out,
return true;
}
+bool WasmBinaryBuilder::maybeVisitSIMDWiden(Expression*& out, uint32_t code) {
+ SIMDWidenOp op;
+ switch (code) {
+ case BinaryConsts::I32x4WidenSI8x16:
+ op = WidenSVecI8x16ToVecI32x4;
+ break;
+ case BinaryConsts::I32x4WidenUI8x16:
+ op = WidenUVecI8x16ToVecI32x4;
+ break;
+ default:
+ return false;
+ }
+ auto* curr = allocator.alloc<SIMDWiden>();
+ curr->op = op;
+ curr->index = getLaneIndex(4);
+ curr->vec = popNonVoidExpression();
+ curr->finalize();
+ out = curr;
+ return true;
+}
+
bool WasmBinaryBuilder::maybeVisitPrefetch(Expression*& out, uint32_t code) {
PrefetchOp op;
switch (code) {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 3075f70d7..0dc121f2c 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1666,6 +1666,15 @@ SExpressionWasmBuilder::makeSIMDLoadStoreLane(Element& s,
return ret;
}
+Expression* SExpressionWasmBuilder::makeSIMDWiden(Element& s, SIMDWidenOp op) {
+ auto* ret = allocator.alloc<SIMDWiden>();
+ ret->op = op;
+ ret->index = parseLaneIndex(s[1], 4);
+ ret->vec = parseExpression(s[2]);
+ ret->finalize();
+ return ret;
+}
+
Expression* SExpressionWasmBuilder::makePrefetch(Element& s, PrefetchOp op) {
Address offset, align;
size_t i = parseMemAttributes(s, offset, align, /*defaultAlign*/ 1);
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index d42080bac..cb8702d0c 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -691,6 +691,19 @@ void BinaryInstWriter::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
o << curr->index;
}
+void BinaryInstWriter::visitSIMDWiden(SIMDWiden* curr) {
+ o << int8_t(BinaryConsts::SIMDPrefix);
+ switch (curr->op) {
+ case WidenSVecI8x16ToVecI32x4:
+ o << U32LEB(BinaryConsts::I32x4WidenSI8x16);
+ break;
+ case WidenUVecI8x16ToVecI32x4:
+ o << U32LEB(BinaryConsts::I32x4WidenUI8x16);
+ break;
+ }
+ o << uint8_t(curr->index);
+}
+
void BinaryInstWriter::visitPrefetch(Prefetch* curr) {
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index f8d8890ec..e9d2bf116 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -496,6 +496,11 @@ void SIMDLoadStoreLane::finalize() {
}
}
+void SIMDWiden::finalize() {
+ assert(vec);
+ type = vec->type == Type::unreachable ? Type::unreachable : Type::v128;
+}
+
Index SIMDLoadStoreLane::getMemBytes() {
switch (op) {
case LoadLaneVec8x16:
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 43c5f4cbd..db25fd472 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -2119,6 +2119,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
unimplemented(curr);
WASM_UNREACHABLE("unimp");
}
+ Ref visitSIMDWiden(SIMDWiden* curr) {
+ unimplemented(curr);
+ WASM_UNREACHABLE("unimp");
+ }
Ref visitMemoryInit(MemoryInit* curr) {
ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_INIT);
return ValueBuilder::makeCall(ABI::wasm2js::MEMORY_INIT,
diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt
index e7c72e6a7..69b619564 100644
--- a/test/binaryen.js/exception-handling.js.txt
+++ b/test/binaryen.js/exception-handling.js.txt
@@ -19,6 +19,6 @@
)
)
-getExpressionInfo(throw) = {"id":47,"type":1,"event":"e"}
-getExpressionInfo(rethrow) = {"id":48,"type":1,"depth":0}
-getExpressionInfo(try) = {"id":46,"type":1,"hasCatchAll":0}
+getExpressionInfo(throw) = {"id":48,"type":1,"event":"e"}
+getExpressionInfo(rethrow) = {"id":49,"type":1,"depth":0}
+getExpressionInfo(try) = {"id":47,"type":1,"hasCatchAll":0}
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 5ad60b286..9b45d9a01 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -76,35 +76,35 @@ SIMDShuffleId: 32
SIMDTernaryId: 33
SIMDShiftId: 34
SIMDLoadId: 35
-MemoryInitId: 37
-DataDropId: 38
-MemoryCopyId: 39
-MemoryFillId: 40
-PopId: 41
-RefNullId: 42
-RefIsId: 43
-RefFuncId: 44
-RefEqId: 45
-TryId: 46
-ThrowId: 47
-RethrowId: 48
-TupleMakeId: 49
-TupleExtractId: 50
-I31NewId: 51
-I31GetId: 52
-CallRefId: 53
-RefTestId: 54
-RefCastId: 55
-BrOnId: 56
-RttCanonId: 57
-RttSubId: 58
-StructNewId: 59
-StructGetId: 60
-StructSetId: 61
-ArrayNewId: 62
-ArrayGetId: 63
-ArraySetId: 64
-ArrayLenId: 65
+MemoryInitId: 38
+DataDropId: 39
+MemoryCopyId: 40
+MemoryFillId: 41
+PopId: 42
+RefNullId: 43
+RefIsId: 44
+RefFuncId: 45
+RefEqId: 46
+TryId: 47
+ThrowId: 48
+RethrowId: 49
+TupleMakeId: 50
+TupleExtractId: 51
+I31NewId: 52
+I31GetId: 53
+CallRefId: 54
+RefTestId: 55
+RefCastId: 56
+BrOnId: 57
+RttCanonId: 58
+RttSubId: 59
+StructNewId: 60
+StructGetId: 61
+StructSetId: 62
+ArrayNewId: 63
+ArrayGetId: 64
+ArraySetId: 65
+ArrayLenId: 66
getExpressionInfo={"id":15,"type":4,"op":6}
(f32.neg
(f32.const -33.61199951171875)
diff --git a/test/simd.wast b/test/simd.wast
index a171c5398..8d12ea0ac 100644
--- a/test/simd.wast
+++ b/test/simd.wast
@@ -1436,4 +1436,14 @@
(local.get $0)
)
)
+ (func $i32x4.widen_i8x16_s (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_s 0
+ (local.get $0)
+ )
+ )
+ (func $i32x4.widen_i8x16_u (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_u 0
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.from-wast b/test/simd.wast.from-wast
index 223191c18..6fbacea11 100644
--- a/test/simd.wast.from-wast
+++ b/test/simd.wast.from-wast
@@ -1454,4 +1454,14 @@
(local.get $0)
)
)
+ (func $i32x4.widen_i8x16_s (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_s 0
+ (local.get $0)
+ )
+ )
+ (func $i32x4.widen_i8x16_u (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_u 0
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.fromBinary b/test/simd.wast.fromBinary
index 1c0b12493..4c84b5b25 100644
--- a/test/simd.wast.fromBinary
+++ b/test/simd.wast.fromBinary
@@ -1454,5 +1454,15 @@
(local.get $0)
)
)
+ (func $i32x4.widen_i8x16_s (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_s 0
+ (local.get $0)
+ )
+ )
+ (func $i32x4.widen_i8x16_u (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_u 0
+ (local.get $0)
+ )
+ )
)
diff --git a/test/simd.wast.fromBinary.noDebugInfo b/test/simd.wast.fromBinary.noDebugInfo
index 3feb5a7b4..bb5cdd5e0 100644
--- a/test/simd.wast.fromBinary.noDebugInfo
+++ b/test/simd.wast.fromBinary.noDebugInfo
@@ -1454,5 +1454,15 @@
(local.get $0)
)
)
+ (func $256 (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_s 0
+ (local.get $0)
+ )
+ )
+ (func $257 (param $0 v128) (result v128)
+ (i32x4.widen_i8x16_u 0
+ (local.get $0)
+ )
+ )
)