summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-validator.cpp
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/wasm-validator.cpp
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/wasm-validator.cpp')
-rw-r--r--src/wasm/wasm-validator.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index ef6a29373..31b68a80c 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -317,6 +317,7 @@ public:
void visitSIMDTernary(SIMDTernary* curr);
void visitSIMDShift(SIMDShift* curr);
void visitSIMDLoad(SIMDLoad* curr);
+ void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr);
void visitMemoryInit(MemoryInit* curr);
void visitDataDrop(DataDrop* curr);
void visitMemoryCopy(MemoryCopy* curr);
@@ -1264,6 +1265,59 @@ void FunctionValidator::visitSIMDLoad(SIMDLoad* curr) {
validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);
}
+void FunctionValidator::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
+ shouldBeTrue(
+ getModule()->memory.exists, curr, "Memory operations require a memory");
+ shouldBeTrue(
+ getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)");
+ if (curr->isLoad()) {
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->type, Type(Type::v128), curr, "loadX_lane must have type v128");
+ } else {
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->type, Type(Type::none), curr, "storeX_lane must have type none");
+ }
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->ptr->type,
+ indexType(),
+ curr,
+ "loadX_lane or storeX_lane address must match memory index type");
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->vec->type,
+ Type(Type::v128),
+ curr,
+ "loadX_lane or storeX_lane vector argument must have type v128");
+ size_t lanes;
+ Type memAlignType = Type::none;
+ switch (curr->op) {
+ case LoadLaneVec8x16:
+ case StoreLaneVec8x16:
+ lanes = 16;
+ memAlignType = Type::i32;
+ break;
+ case LoadLaneVec16x8:
+ case StoreLaneVec16x8:
+ lanes = 8;
+ memAlignType = Type::i32;
+ break;
+ case LoadLaneVec32x4:
+ case StoreLaneVec32x4:
+ lanes = 4;
+ memAlignType = Type::i32;
+ break;
+ case LoadLaneVec64x2:
+ case StoreLaneVec64x2:
+ lanes = 2;
+ memAlignType = Type::i64;
+ break;
+ default:
+ WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op");
+ }
+ Index bytes = curr->getMemBytes();
+ validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);
+ shouldBeTrue(curr->index < lanes, curr, "invalid lane index");
+}
+
void FunctionValidator::visitMemoryInit(MemoryInit* curr) {
shouldBeTrue(getModule()->features.hasBulkMemory(),
curr,