summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-10-22 21:47:17 -0700
committerGitHub <noreply@github.com>2020-10-22 21:47:17 -0700
commitdaf0782b7754e225c9063f9fbf5195b4b4a3c7e3 (patch)
treed0004ebe92a2559e8bfcd86c4bdfdf972dc81432 /src/wasm-interpreter.h
parenta2fa37eb94fdd6896f4d90f22e34fbd5f028d742 (diff)
downloadbinaryen-daf0782b7754e225c9063f9fbf5195b4b4a3c7e3.tar.gz
binaryen-daf0782b7754e225c9063f9fbf5195b4b4a3c7e3.tar.bz2
binaryen-daf0782b7754e225c9063f9fbf5195b4b4a3c7e3.zip
Implement v128.{load,store}{8,16,32,64}_lane instructions (#3278)
These instructions are proposed in https://github.com/WebAssembly/simd/pull/350. This PR implements them throughout Binaryen except in the C/JS APIs and in the fuzzer, where it leaves TODOs instead. Right now these instructions are just being implemented for prototyping so adding them to the APIs isn't critical and they aren't generally available to be fuzzed in Wasm engines.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h79
1 files changed, 78 insertions, 1 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 203786e72..5ca590208 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1240,6 +1240,9 @@ public:
Flow visitSIMDLoadSplat(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitSIMDLoadExtend(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitSIMDLoadZero(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
+ WASM_UNREACHABLE("unimp");
+ }
Flow visitPop(Pop* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitRefNull(RefNull* curr) {
NOTE_ENTER("RefNull");
@@ -1627,6 +1630,10 @@ public:
NOTE_ENTER("SIMDLoadExtend");
return Flow(NONCONSTANT_FLOW);
}
+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
+ NOTE_ENTER("SIMDLoadStoreLane");
+ return Flow(NONCONSTANT_FLOW);
+ }
Flow visitPop(Pop* curr) {
NOTE_ENTER("Pop");
return Flow(NONCONSTANT_FLOW);
@@ -2369,7 +2376,7 @@ private:
}
NOTE_EVAL1(flow);
Address src = instance.getFinalAddress(
- curr, flow.getSingleValue(), curr->op == Load32Zero ? 32 : 64);
+ curr, flow.getSingleValue(), curr->getMemBytes());
auto zero =
Literal::makeZero(curr->op == Load32Zero ? Type::i32 : Type::i64);
if (curr->op == Load32Zero) {
@@ -2380,6 +2387,76 @@ private:
return Literal(std::array<Literal, 2>{{val, zero}});
}
}
+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
+ NOTE_ENTER("SIMDLoadStoreLane");
+ Flow flow = this->visit(curr->ptr);
+ if (flow.breaking()) {
+ return flow;
+ }
+ NOTE_EVAL1(flow);
+ Address addr = instance.getFinalAddress(
+ curr, flow.getSingleValue(), curr->getMemBytes());
+ flow = this->visit(curr->vec);
+ if (flow.breaking()) {
+ return flow;
+ }
+ Literal vec = flow.getSingleValue();
+ switch (curr->op) {
+ case LoadLaneVec8x16:
+ case StoreLaneVec8x16: {
+ std::array<Literal, 16> lanes = vec.getLanesUI8x16();
+ if (curr->isLoad()) {
+ lanes[curr->index] =
+ Literal(instance.externalInterface->load8u(addr));
+ return Literal(lanes);
+ } else {
+ instance.externalInterface->store8(addr,
+ lanes[curr->index].geti32());
+ return {};
+ }
+ }
+ case LoadLaneVec16x8:
+ case StoreLaneVec16x8: {
+ std::array<Literal, 8> lanes = vec.getLanesUI16x8();
+ if (curr->isLoad()) {
+ lanes[curr->index] =
+ Literal(instance.externalInterface->load16u(addr));
+ return Literal(lanes);
+ } else {
+ instance.externalInterface->store16(addr,
+ lanes[curr->index].geti32());
+ return {};
+ }
+ }
+ case LoadLaneVec32x4:
+ case StoreLaneVec32x4: {
+ std::array<Literal, 4> lanes = vec.getLanesI32x4();
+ if (curr->isLoad()) {
+ lanes[curr->index] =
+ Literal(instance.externalInterface->load32u(addr));
+ return Literal(lanes);
+ } else {
+ instance.externalInterface->store32(addr,
+ lanes[curr->index].geti32());
+ return {};
+ }
+ }
+ case StoreLaneVec64x2:
+ case LoadLaneVec64x2: {
+ std::array<Literal, 2> lanes = vec.getLanesI64x2();
+ if (curr->isLoad()) {
+ lanes[curr->index] =
+ Literal(instance.externalInterface->load64u(addr));
+ return Literal(lanes);
+ } else {
+ instance.externalInterface->store64(addr,
+ lanes[curr->index].geti64());
+ return {};
+ }
+ }
+ }
+ WASM_UNREACHABLE("unexpected op");
+ }
Flow visitMemorySize(MemorySize* curr) {
NOTE_ENTER("MemorySize");
return Literal::makeFromInt64(instance.memorySize,