Index: src/wasm/function-body-decoder.cc |
diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc |
index 7a2006f32baf30588a6a34b3a1e5d6a9b76c36d3..12fe67c2e674e1c8b6a6d75671691b2124a52941 100644 |
--- a/src/wasm/function-body-decoder.cc |
+++ b/src/wasm/function-body-decoder.cc |
@@ -495,14 +495,17 @@ class WasmDecoder : public Decoder { |
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
#undef DECLARE_OPCODE_CASE |
- { |
- return 2; |
- } |
+ return 2; |
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
+#undef DECLARE_OPCODE_CASE |
+ return 3; |
+#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
+ FOREACH_SIMD_MEM_OPCODE(DECLARE_OPCODE_CASE) |
#undef DECLARE_OPCODE_CASE |
{ |
- return 3; |
+ MemoryAccessOperand<true> operand(decoder, pc + 1, UINT32_MAX); |
+ return 2 + operand.length; |
} |
// Shuffles require a byte per lane, or 16 immediate bytes. |
case kExprS8x16Shuffle: |
@@ -523,14 +526,19 @@ class WasmDecoder : public Decoder { |
FunctionSig* sig = WasmOpcodes::Signature(opcode); |
if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode); |
if (sig) return {sig->parameter_count(), sig->return_count()}; |
+ if (WasmOpcodes::IsPrefixOpcode(opcode)) { |
+ opcode = static_cast<WasmOpcode>(opcode << 8 | *(pc + 1)); |
+ } |
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
// clang-format off |
switch (opcode) { |
case kExprSelect: |
return {3, 1}; |
+ case kExprS128StoreMem: |
FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) |
return {2, 0}; |
+ case kExprS128LoadMem: |
FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) |
case kExprTeeLocal: |
case kExprGrowMemory: |
@@ -1229,10 +1237,6 @@ class WasmFullDecoder : public WasmDecoder { |
case kExprF64LoadMem: |
len = DecodeLoadMem(kWasmF64, MachineType::Float64()); |
break; |
- case kExprS128LoadMem: |
- CHECK_PROTOTYPE_OPCODE(simd); |
- len = DecodeLoadMem(kWasmS128, MachineType::Simd128()); |
- break; |
case kExprI32StoreMem8: |
len = DecodeStoreMem(kWasmI32, MachineType::Int8()); |
break; |
@@ -1260,10 +1264,6 @@ class WasmFullDecoder : public WasmDecoder { |
case kExprF64StoreMem: |
len = DecodeStoreMem(kWasmF64, MachineType::Float64()); |
break; |
- case kExprS128StoreMem: |
- CHECK_PROTOTYPE_OPCODE(simd); |
- len = DecodeStoreMem(kWasmS128, MachineType::Simd128()); |
- break; |
case kExprGrowMemory: { |
if (!CheckHasMemory()) break; |
MemoryIndexOperand<true> operand(this, pc_); |
@@ -1506,6 +1506,29 @@ class WasmFullDecoder : public WasmDecoder { |
return 1 + operand.length; |
} |
+ int DecodePrefixedLoadMem(ValueType type, MachineType mem_type) { |
+ if (!CheckHasMemory()) return 0; |
+ MemoryAccessOperand<true> operand( |
+ this, pc_ + 1, ElementSizeLog2Of(mem_type.representation())); |
+ |
+ Value index = Pop(0, kWasmI32); |
+ TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, |
+ operand.alignment, position()); |
+ Push(type, node); |
+ return operand.length; |
+ } |
+ |
+ int DecodePrefixedStoreMem(ValueType type, MachineType mem_type) { |
+ if (!CheckHasMemory()) return 0; |
+ MemoryAccessOperand<true> operand( |
+ this, pc_ + 1, ElementSizeLog2Of(mem_type.representation())); |
+ Value val = Pop(1, type); |
+ Value index = Pop(0, kWasmI32); |
+ BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, |
+ val.node, position()); |
+ return operand.length; |
+ } |
+ |
unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) { |
SimdLaneOperand<true> operand(this, pc_); |
if (Validate(pc_, opcode, operand)) { |
@@ -1591,6 +1614,14 @@ class WasmFullDecoder : public WasmDecoder { |
len = Simd8x16ShuffleOp(); |
break; |
} |
+ case kExprS128LoadMem: |
+ CHECK_PROTOTYPE_OPCODE(simd); |
+ len = DecodePrefixedLoadMem(kWasmS128, MachineType::Simd128()); |
+ break; |
+ case kExprS128StoreMem: |
+ CHECK_PROTOTYPE_OPCODE(simd); |
+ len = DecodePrefixedStoreMem(kWasmS128, MachineType::Simd128()); |
+ break; |
default: { |
FunctionSig* sig = WasmOpcodes::Signature(opcode); |
if (sig != nullptr) { |