summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 94a3f0d54..8c429caa9 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1086,6 +1086,8 @@ public:
Flow visitAtomicWait(AtomicWait*) { WASM_UNREACHABLE(); }
Flow visitAtomicNotify(AtomicNotify*) { WASM_UNREACHABLE(); }
Flow visitSIMDLoad(SIMDLoad*) { WASM_UNREACHABLE(); }
+ Flow visitSIMDLoadSplat(SIMDLoad*) { WASM_UNREACHABLE(); }
+ Flow visitSIMDLoadExtend(SIMDLoad*) { WASM_UNREACHABLE(); }
Flow visitPush(Push*) { WASM_UNREACHABLE(); }
Flow visitPop(Pop*) { WASM_UNREACHABLE(); }
Flow visitTry(Try*) { WASM_UNREACHABLE(); }
@@ -1702,6 +1704,23 @@ private:
}
Flow visitSIMDLoad(SIMDLoad* curr) {
NOTE_ENTER("SIMDLoad");
+ switch (curr->op) {
+ case LoadSplatVec8x16:
+ case LoadSplatVec16x8:
+ case LoadSplatVec32x4:
+ case LoadSplatVec64x2:
+ return visitSIMDLoadSplat(curr);
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
+ return visitSIMDLoadExtend(curr);
+ }
+ WASM_UNREACHABLE();
+ }
+ Flow visitSIMDLoadSplat(SIMDLoad* curr) {
Load load;
load.type = i32;
load.bytes = curr->getMemBytes();
@@ -1725,6 +1744,8 @@ private:
load.type = i64;
splat = &Literal::splatI64x2;
break;
+ default:
+ WASM_UNREACHABLE();
}
load.finalize();
Flow flow = this->visit(&load);
@@ -1733,6 +1754,61 @@ private:
}
return (flow.value.*splat)();
}
+ Flow visitSIMDLoadExtend(SIMDLoad* curr) {
+ Flow flow = this->visit(curr->ptr);
+ if (flow.breaking()) {
+ return flow;
+ }
+ NOTE_EVAL1(flow);
+ Address src(uint32_t(flow.value.geti32()));
+ auto loadLane = [&](Address addr) {
+ switch (curr->op) {
+ case LoadExtSVec8x8ToVecI16x8:
+ return Literal(int32_t(instance.externalInterface->load8s(addr)));
+ case LoadExtUVec8x8ToVecI16x8:
+ return Literal(int32_t(instance.externalInterface->load8u(addr)));
+ case LoadExtSVec16x4ToVecI32x4:
+ return Literal(int32_t(instance.externalInterface->load16s(addr)));
+ case LoadExtUVec16x4ToVecI32x4:
+ return Literal(int32_t(instance.externalInterface->load16u(addr)));
+ case LoadExtSVec32x2ToVecI64x2:
+ return Literal(int64_t(instance.externalInterface->load32s(addr)));
+ case LoadExtUVec32x2ToVecI64x2:
+ return Literal(int64_t(instance.externalInterface->load32u(addr)));
+ default:
+ WASM_UNREACHABLE();
+ }
+ WASM_UNREACHABLE();
+ };
+ auto fillLanes = [&](auto lanes, size_t laneBytes) {
+ for (auto& lane : lanes) {
+ lane = loadLane(
+ instance.getFinalAddress(Literal(uint32_t(src)), laneBytes));
+ src = Address(uint32_t(src) + laneBytes);
+ }
+ return Literal(lanes);
+ };
+ switch (curr->op) {
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8: {
+ std::array<Literal, 8> lanes;
+ return fillLanes(lanes, 1);
+ }
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4: {
+ std::array<Literal, 4> lanes;
+ return fillLanes(lanes, 2);
+ }
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2: {
+ std::array<Literal, 2> lanes;
+ return fillLanes(lanes, 4);
+ }
+ default:
+ WASM_UNREACHABLE();
+ }
+ WASM_UNREACHABLE();
+ }
Flow visitHost(Host* curr) {
NOTE_ENTER("Host");
switch (curr->op) {