Commit 1a1138f5 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Implement I64x2 splat extract_lane replace_lane for arm64

Bug: v8:8460
Change-Id: Ic92efbcb7c64184c237d0fb00c3c7aa75323a3e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1717662
Auto-Submit: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62928}
parent 11e27b5e
......@@ -1828,6 +1828,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputSimd128Register(0).V4S());
break;
}
case kArm64I64x2Splat: {
__ Dup(i.OutputSimd128Register().V2D(), i.InputRegister64(0));
break;
}
case kArm64I64x2ExtractLane: {
__ Mov(i.OutputRegister64(), i.InputSimd128Register(0).V2D(),
i.InputInt8(1));
break;
}
case kArm64I64x2ReplaceLane: {
VRegister dst = i.OutputSimd128Register().V2D(),
src1 = i.InputSimd128Register(0).V2D();
if (!dst.is(src1)) {
__ Mov(dst, src1);
}
__ Mov(dst, i.InputInt8(1), i.InputRegister64(2));
break;
}
case kArm64I32x4Splat: {
__ Dup(i.OutputSimd128Register().V4S(), i.InputRegister32(0));
break;
......
......@@ -192,6 +192,9 @@ namespace compiler {
V(Arm64F32x4Ne) \
V(Arm64F32x4Lt) \
V(Arm64F32x4Le) \
V(Arm64I64x2Splat) \
V(Arm64I64x2ExtractLane) \
V(Arm64I64x2ReplaceLane) \
V(Arm64I32x4Splat) \
V(Arm64I32x4ExtractLane) \
V(Arm64I32x4ReplaceLane) \
......
......@@ -156,6 +156,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64F32x4Ne:
case kArm64F32x4Lt:
case kArm64F32x4Le:
case kArm64I64x2Splat:
case kArm64I64x2ExtractLane:
case kArm64I64x2ReplaceLane:
case kArm64I32x4Splat:
case kArm64I32x4ExtractLane:
case kArm64I32x4ReplaceLane:
......
......@@ -3046,6 +3046,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
#define SIMD_TYPE_LIST(V) \
V(F32x4) \
V(I64x2) \
V(I32x4) \
V(I16x8) \
V(I8x16)
......
......@@ -2579,9 +2579,11 @@ void InstructionSelector::VisitF64x2Eq(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Ne(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Lt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Le(Node* node) { UNIMPLEMENTED(); }
#if !V8_TARGET_ARCH_ARM64
void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_ARM64
void InstructionSelector::VisitI64x2Neg(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS1x2AnyTrue(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS1x2AllTrue(Node* node) { UNIMPLEMENTED(); }
......
......@@ -716,6 +716,58 @@ WASM_SIMD_TEST(F32x4Le) {
RunF32x4CompareOpTest(execution_tier, lower_simd, kExprF32x4Le, LessEqual);
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(I64x2Splat) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
// Set up a global to hold output vector.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
byte param1 = 0;
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(param1))),
WASM_ONE);
FOR_INT64_INPUTS(x) {
r.Call(x);
int64_t expected = x;
for (int i = 0; i < 2; i++) {
int64_t actual = ReadLittleEndianValue<int64_t>(&g[i]);
CHECK_EQ(actual, expected);
}
}
}
WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractLane) {
WasmRunner<int64_t> r(execution_tier, lower_simd);
r.AllocateLocal(kWasmI64);
r.AllocateLocal(kWasmS128);
BUILD(
r,
WASM_SET_LOCAL(0, WASM_SIMD_I64x2_EXTRACT_LANE(
0, WASM_SIMD_I64x2_SPLAT(WASM_I64V(0xFFFFFFFFFF)))),
WASM_SET_LOCAL(1, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(0))),
WASM_SIMD_I64x2_EXTRACT_LANE(1, WASM_GET_LOCAL(1)));
CHECK_EQ(0xFFFFFFFFFF, r.Call());
}
WASM_SIMD_TEST_NO_LOWERING(I64x2ReplaceLane) {
WasmRunner<int32_t> r(execution_tier, lower_simd);
// Set up a global to hold input/output vector.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
// Build function to replace each lane with its index.
byte temp1 = r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(temp1, WASM_SIMD_I64x2_SPLAT(WASM_I64V(-1))),
WASM_SET_LOCAL(temp1, WASM_SIMD_I64x2_REPLACE_LANE(
0, WASM_GET_LOCAL(temp1), WASM_I64V(0))),
WASM_SET_GLOBAL(0, WASM_SIMD_I64x2_REPLACE_LANE(
1, WASM_GET_LOCAL(temp1), WASM_I64V(1))),
WASM_ONE);
r.Call();
for (int64_t i = 0; i < 2; i++) {
CHECK_EQ(i, ReadLittleEndianValue<int64_t>(&g[i]));
}
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
#if V8_TARGET_ARCH_X64
WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) {
WasmRunner<int32_t, double> r(execution_tier, lower_simd);
......@@ -1017,24 +1069,6 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Mul) {
#undef FOR_FLOAT64_NAN_INPUTS
WASM_SIMD_TEST_NO_LOWERING(I64x2Splat) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
// Set up a global to hold output vector.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
byte param1 = 0;
BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(param1))),
WASM_ONE);
FOR_INT64_INPUTS(x) {
r.Call(x);
int64_t expected = x;
for (int i = 0; i < 2; i++) {
int64_t actual = ReadLittleEndianValue<int64_t>(&g[i]);
CHECK_EQ(actual, expected);
}
}
}
WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) {
WasmRunner<int64_t> r(execution_tier, lower_simd);
BUILD(r, WASM_IF_ELSE_L(
......@@ -1045,25 +1079,6 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) {
CHECK_EQ(1, r.Call());
}
WASM_SIMD_TEST_NO_LOWERING(I64x2ReplaceLane) {
WasmRunner<int32_t> r(execution_tier, lower_simd);
// Set up a global to hold input/output vector.
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
// Build function to replace each lane with its index.
byte temp1 = r.AllocateLocal(kWasmS128);
BUILD(r, WASM_SET_LOCAL(temp1, WASM_SIMD_I64x2_SPLAT(WASM_I64V(-1))),
WASM_SET_LOCAL(temp1, WASM_SIMD_I64x2_REPLACE_LANE(
0, WASM_GET_LOCAL(temp1), WASM_I64V(0))),
WASM_SET_GLOBAL(0, WASM_SIMD_I64x2_REPLACE_LANE(
1, WASM_GET_LOCAL(temp1), WASM_I64V(1))),
WASM_ONE);
r.Call();
for (int64_t i = 0; i < 2; i++) {
CHECK_EQ(i, ReadLittleEndianValue<int64_t>(&g[i]));
}
}
void RunI64x2UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64UnOp expected_op) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
......
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