Commit 631c429f authored by gdeepti's avatar gdeepti Committed by Commit Bot

[wasm] SIMD/Atomics ops update to use the right prefix opcodes

 - Use correct prefixes for SIMD/Atomics ops
 - S128 LoadMem/StoreMem should not use 0xc0/0xc1 opcodes, these are now
 being used for sign extension
 - S128 LoadMem/StoreMem should use prefixed opcodes

BUG=v8:6020

Review-Url: https://codereview.chromium.org/2943773002
Cr-Commit-Position: refs/heads/master@{#46016}
parent ea241630
......@@ -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:
......@@ -1225,10 +1233,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;
......@@ -1256,10 +1260,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) {
......
......@@ -43,6 +43,7 @@ namespace wasm {
CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str)
#define CASE_SIGN_OP(TYPE, name, str) \
CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u")
#define CASE_UNSIGNED_OP(TYPE, name, str) CASE_##TYPE##_OP(name##U, str "_u")
#define CASE_ALL_SIGN_OP(name, str) \
CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str)
#define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \
......@@ -52,6 +53,10 @@ namespace wasm {
CASE_SIGN_OP(I32, name##8, str "8") \
CASE_SIGN_OP(I32, name##16, str "16") \
CASE_I32_OP(name, str "32")
#define CASE_U32_OP(name, str) \
CASE_I32_OP(name, str "32") \
CASE_UNSIGNED_OP(I32, name##8, str "8") \
CASE_UNSIGNED_OP(I32, name##16, str "16")
const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
switch (opcode) {
......@@ -228,13 +233,13 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_S1x16_OP(AllTrue, "all_true")
// Atomic operations.
CASE_L32_OP(AtomicAdd, "atomic_add")
CASE_L32_OP(AtomicAnd, "atomic_and")
CASE_L32_OP(AtomicCompareExchange, "atomic_cmpxchng")
CASE_L32_OP(AtomicExchange, "atomic_xchng")
CASE_L32_OP(AtomicOr, "atomic_or")
CASE_L32_OP(AtomicSub, "atomic_sub")
CASE_L32_OP(AtomicXor, "atomic_xor")
CASE_U32_OP(AtomicAdd, "atomic_add")
CASE_U32_OP(AtomicSub, "atomic_sub")
CASE_U32_OP(AtomicAnd, "atomic_and")
CASE_U32_OP(AtomicOr, "atomic_or")
CASE_U32_OP(AtomicXor, "atomic_xor")
CASE_U32_OP(AtomicExchange, "atomic_xchng")
CASE_U32_OP(AtomicCompareExchange, "atomic_cmpxchng")
default : return "unknown";
// clang-format on
......
This diff is collapsed.
......@@ -195,6 +195,7 @@ void wasm::PrintWasmText(const WasmModule *module,
FOREACH_SIMD_0_OPERAND_OPCODE(CASE_OPCODE)
FOREACH_SIMD_1_OPERAND_OPCODE(CASE_OPCODE)
FOREACH_SIMD_MASK_OPERAND_OPCODE(CASE_OPCODE)
FOREACH_SIMD_MEM_OPCODE(CASE_OPCODE)
FOREACH_ATOMIC_OPCODE(CASE_OPCODE)
os << WasmOpcodes::OpcodeName(opcode);
break;
......
......@@ -406,6 +406,11 @@ T RecipSqrt(T a) {
TO_BYTE(m[11]), TO_BYTE(m[12]), TO_BYTE(m[13]), TO_BYTE(m[14]), \
TO_BYTE(m[15])
#define WASM_SIMD_LOAD_MEM(index) \
index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, ZERO_OFFSET
#define WASM_SIMD_STORE_MEM(index, val) \
index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, ZERO_OFFSET
// Skip FP tests involving extremely large or extremely small values, which
// may fail due to non-IEEE-754 SIMD arithmetic on some platforms.
bool SkipFPValue(float x) {
......@@ -2191,11 +2196,8 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) {
WasmRunner<int32_t> r(kExecuteCompiled);
int32_t* memory = r.module().AddMemoryElems<int32_t>(4);
BUILD(r,
WASM_STORE_MEM(MachineType::Simd128(), WASM_ZERO,
WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO)),
WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_LOAD_MEM(MachineType::Simd128(), WASM_ZERO)));
BUILD(r, WASM_SIMD_STORE_MEM(WASM_ZERO, WASM_SIMD_LOAD_MEM(WASM_ZERO)),
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment