Commit 365492f1 authored by bbudge's avatar bbudge Committed by Commit bot

[WASM] Implement Simd128 Load/Store on ARM.

- Adds new load/store opcodes (0xc0, 0xc1) for S128 type.
- Implements these for ARM.
- Enables more WASM SIMD tests, and adds new LoadStoreLoad test.

LOG=N
BUG=v8:6020

Review-Url: https://codereview.chromium.org/2745853002
Cr-Commit-Position: refs/heads/master@{#43841}
parent 79e01fd9
......@@ -1965,6 +1965,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.OutputSimd128Register());
break;
}
case kArmSimd128Load: {
MemOperand src = i.InputOffset();
__ vld1(Neon8, NeonListOperand(i.OutputSimd128Register()),
NeonMemOperand(src.rn(), src.rm()));
break;
}
case kArmSimd128Store: {
MemOperand src = i.InputOffset(1);
__ vst1(Neon8, NeonListOperand(i.InputSimd128Register(0)),
NeonMemOperand(src.rn(), src.rm()));
break;
}
case kArmSimd128And: {
__ vand(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
......
......@@ -211,6 +211,8 @@ namespace compiler {
V(ArmUint8x16LessThan) \
V(ArmUint8x16LessThanOrEqual) \
V(ArmSimd128Zero) \
V(ArmSimd128Load) \
V(ArmSimd128Store) \
V(ArmSimd128And) \
V(ArmSimd128Or) \
V(ArmSimd128Xor) \
......
......@@ -199,6 +199,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmUint8x16LessThan:
case kArmUint8x16LessThanOrEqual:
case kArmSimd128Zero:
case kArmSimd128Load:
case kArmSimd128Store:
case kArmSimd128And:
case kArmSimd128Or:
case kArmSimd128Xor:
......
......@@ -426,8 +426,10 @@ void InstructionSelector::VisitLoad(Node* node) {
case MachineRepresentation::kWord32:
opcode = kArmLdr;
break;
case MachineRepresentation::kSimd128:
opcode = kArmSimd128Load;
break;
case MachineRepresentation::kWord64: // Fall through.
case MachineRepresentation::kSimd128: // Fall through.
case MachineRepresentation::kSimd1x4: // Fall through.
case MachineRepresentation::kSimd1x8: // Fall through.
case MachineRepresentation::kSimd1x16: // Fall through.
......@@ -514,8 +516,10 @@ void InstructionSelector::VisitStore(Node* node) {
case MachineRepresentation::kWord32:
opcode = kArmStr;
break;
case MachineRepresentation::kSimd128:
opcode = kArmSimd128Store;
break;
case MachineRepresentation::kWord64: // Fall through.
case MachineRepresentation::kSimd128: // Fall through.
case MachineRepresentation::kSimd1x4: // Fall through.
case MachineRepresentation::kSimd1x8: // Fall through.
case MachineRepresentation::kSimd1x16: // Fall through.
......
......@@ -1160,6 +1160,9 @@ class WasmFullDecoder : public WasmDecoder {
case kExprF64LoadMem:
len = DecodeLoadMem(kWasmF64, MachineType::Float64());
break;
case kExprS128LoadMem:
len = DecodeLoadMem(kWasmS128, MachineType::Simd128());
break;
case kExprI32StoreMem8:
len = DecodeStoreMem(kWasmI32, MachineType::Int8());
break;
......@@ -1187,6 +1190,9 @@ class WasmFullDecoder : public WasmDecoder {
case kExprF64StoreMem:
len = DecodeStoreMem(kWasmF64, MachineType::Float64());
break;
case kExprS128StoreMem:
len = DecodeStoreMem(kWasmS128, MachineType::Simd128());
break;
case kExprGrowMemory: {
if (!CheckHasMemory()) break;
MemoryIndexOperand operand(this, pc_);
......
......@@ -129,10 +129,12 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_SIGN_OP(INT, LoadMem8, "load8")
CASE_SIGN_OP(INT, LoadMem16, "load16")
CASE_SIGN_OP(I64, LoadMem32, "load32")
CASE_S128_OP(LoadMem, "load128")
CASE_ALL_OP(StoreMem, "store")
CASE_INT_OP(StoreMem8, "store8")
CASE_INT_OP(StoreMem16, "store16")
CASE_I64_OP(StoreMem32, "store32")
CASE_S128_OP(StoreMem, "store128")
// Non-standard opcodes.
CASE_OP(Try, "try")
......
......@@ -100,7 +100,8 @@ constexpr WasmCodePosition kNoCodePosition = -1;
V(I64LoadMem16S, 0x32, l_i) \
V(I64LoadMem16U, 0x33, l_i) \
V(I64LoadMem32S, 0x34, l_i) \
V(I64LoadMem32U, 0x35, l_i)
V(I64LoadMem32U, 0x35, l_i) \
V(S128LoadMem, 0xc0, s_i)
// Store memory expressions.
#define FOREACH_STORE_MEM_OPCODE(V) \
......@@ -112,7 +113,8 @@ constexpr WasmCodePosition kNoCodePosition = -1;
V(I32StoreMem16, 0x3b, i_ii) \
V(I64StoreMem8, 0x3c, l_il) \
V(I64StoreMem16, 0x3d, l_il) \
V(I64StoreMem32, 0x3e, l_il)
V(I64StoreMem32, 0x3e, l_il) \
V(S128StoreMem, 0xc1, s_is)
// Miscellaneous memory expressions
#define FOREACH_MISC_MEM_OPCODE(V) \
......@@ -247,17 +249,17 @@ constexpr WasmCodePosition kNoCodePosition = -1;
// For compatibility with Asm.js.
#define FOREACH_ASMJS_COMPAT_OPCODE(V) \
V(F64Acos, 0xc0, d_d) \
V(F64Asin, 0xc1, d_d) \
V(F64Atan, 0xc2, d_d) \
V(F64Cos, 0xc3, d_d) \
V(F64Sin, 0xc4, d_d) \
V(F64Tan, 0xc5, d_d) \
V(F64Exp, 0xc6, d_d) \
V(F64Log, 0xc7, d_d) \
V(F64Atan2, 0xc8, d_dd) \
V(F64Pow, 0xc9, d_dd) \
V(F64Mod, 0xca, d_dd) \
V(F64Acos, 0xc2, d_d) \
V(F64Asin, 0xc3, d_d) \
V(F64Atan, 0xc4, d_d) \
V(F64Cos, 0xc5, d_d) \
V(F64Sin, 0xc6, d_d) \
V(F64Tan, 0xc7, d_d) \
V(F64Exp, 0xc8, d_d) \
V(F64Log, 0xc9, d_d) \
V(F64Atan2, 0xca, d_dd) \
V(F64Pow, 0xcb, d_dd) \
V(F64Mod, 0xcc, d_dd) \
V(I32AsmjsDivS, 0xd0, i_ii) \
V(I32AsmjsDivU, 0xd1, i_ii) \
V(I32AsmjsRemS, 0xd2, i_ii) \
......@@ -684,6 +686,8 @@ class V8_EXPORT_PRIVATE WasmOpcodes {
return store ? kExprF32StoreMem : kExprF32LoadMem;
} else if (type == MachineType::Float64()) {
return store ? kExprF64StoreMem : kExprF64LoadMem;
} else if (type == MachineType::Simd128()) {
return store ? kExprS128StoreMem : kExprS128LoadMem;
} else {
UNREACHABLE();
return kExprNop;
......
......@@ -1612,9 +1612,6 @@ WASM_EXEC_COMPILED_TEST(S1x16Or) { RunS1x16BinOpTest(kExprS1x16Or, Or); }
WASM_EXEC_COMPILED_TEST(S1x16Xor) { RunS1x16BinOpTest(kExprS1x16Xor, Xor); }
#endif // V8_TARGET_ARCH_ARM
#if SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdI32x4ExtractWithF32x4) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
......@@ -1668,9 +1665,7 @@ WASM_EXEC_COMPILED_TEST(SimdI32x4AddWithF32x4) {
WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
#endif // SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdI32x4Local) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t> r(kExecuteCompiled);
......@@ -1752,9 +1747,7 @@ WASM_EXEC_COMPILED_TEST(SimdF32x4For) {
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdI32x4GetGlobal) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
......@@ -1846,4 +1839,22 @@ WASM_EXEC_COMPILED_TEST(SimdF32x4SetGlobal) {
CHECK_EQ(*(global + 2), 32.25);
CHECK_EQ(*(global + 3), 65.0);
}
#endif // SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(SimdLoadStoreLoad) {
FLAG_wasm_simd_prototype = true;
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)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i;
r.module().WriteMemory(&memory[0], expected);
CHECK_EQ(expected, r.Call());
}
}
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
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