diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 11 | ||||
-rw-r--r-- | src/ir/ReFinalize.cpp | 1 | ||||
-rw-r--r-- | src/ir/cost.h | 1 | ||||
-rw-r--r-- | src/ir/effects.h | 1 | ||||
-rw-r--r-- | src/passes/Print.cpp | 20 | ||||
-rw-r--r-- | src/wasm-binary.h | 4 | ||||
-rw-r--r-- | src/wasm-delegations-fields.h | 8 | ||||
-rw-r--r-- | src/wasm-delegations.h | 1 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 1 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 1 | ||||
-rw-r--r-- | src/wasm.h | 20 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 13 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 5 | ||||
-rw-r--r-- | src/wasm2js.h | 4 |
16 files changed, 123 insertions, 1 deletions
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, |