Commit 436f0180 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][liftoff] Implement global get and set for S128

Most of the implementation work has been done as part of previous
patches, this finishes it by adding a new case for LoadType, and also
adding a test. The arm and arm64 implementation is new, and wasn't
required, since the Liftoff tests (in nooptimization variants) are
skipped on arm and arm64, and hence did not fail.

Bug: v8:9909
Change-Id: I01bd86d2e46de852bc067f44c802f66ac9e9b029
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2001561Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65798}
parent 61cc328b
...@@ -372,20 +372,26 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, ...@@ -372,20 +372,26 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
} }
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
if (type.value() == LoadType::kF64Load || if (type.value() == LoadType::kF64Load ||
type.value() == LoadType::kF32Load) { type.value() == LoadType::kF32Load ||
type.value() == LoadType::kS128Load) {
Register actual_src_addr = liftoff::CalculateActualAddress( Register actual_src_addr = liftoff::CalculateActualAddress(
this, &temps, src_addr, offset_reg, offset_imm); this, &temps, src_addr, offset_reg, offset_imm);
if (type.value() == LoadType::kF64Load) { if (type.value() == LoadType::kF64Load) {
// Armv6 is not supported so Neon can be used to avoid alignment issues. // Armv6 is not supported so Neon can be used to avoid alignment issues.
CpuFeatureScope scope(this, NEON); CpuFeatureScope scope(this, NEON);
vld1(Neon64, NeonListOperand(dst.fp()), NeonMemOperand(actual_src_addr)); vld1(Neon64, NeonListOperand(dst.fp()), NeonMemOperand(actual_src_addr));
} else { } else if (type.value() == LoadType::kF32Load) {
// TODO(arm): Use vld1 for f32 when implemented in simulator as used for // TODO(arm): Use vld1 for f32 when implemented in simulator as used for
// f64. It supports unaligned access. // f64. It supports unaligned access.
Register scratch = Register scratch =
(actual_src_addr == src_addr) ? temps.Acquire() : actual_src_addr; (actual_src_addr == src_addr) ? temps.Acquire() : actual_src_addr;
ldr(scratch, MemOperand(actual_src_addr)); ldr(scratch, MemOperand(actual_src_addr));
vmov(liftoff::GetFloatRegister(dst.fp()), scratch); vmov(liftoff::GetFloatRegister(dst.fp()), scratch);
} else {
// Armv6 is not supported so Neon can be used to avoid alignment issues.
CpuFeatureScope scope(this, NEON);
vld1(Neon8, NeonListOperand(dst.low_fp(), 2),
NeonMemOperand(actual_src_addr));
} }
} else { } else {
MemOperand src_op = MemOperand src_op =
......
...@@ -296,6 +296,9 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, ...@@ -296,6 +296,9 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
case LoadType::kF64Load: case LoadType::kF64Load:
Ldr(dst.fp().D(), src_op); Ldr(dst.fp().D(), src_op);
break; break;
case LoadType::kS128Load:
Ldr(dst.fp().Q(), src_op);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -99,6 +99,8 @@ class LoadType { ...@@ -99,6 +99,8 @@ class LoadType {
return kF32Load; return kF32Load;
case kWasmF64: case kWasmF64:
return kF64Load; return kF64Load;
case kWasmS128:
return kS128Load;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -34,6 +34,24 @@ WASM_SIMD_LIFTOFF_TEST(S128Local) { ...@@ -34,6 +34,24 @@ WASM_SIMD_LIFTOFF_TEST(S128Local) {
r.CheckUsedExecutionTier(ExecutionTier::kLiftoff); r.CheckUsedExecutionTier(ExecutionTier::kLiftoff);
} }
WASM_SIMD_LIFTOFF_TEST(S128Global) {
WasmRunner<int32_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);
int32_t* g0 = r.builder().AddGlobal<int32_t>(kWasmS128);
int32_t* g1 = r.builder().AddGlobal<int32_t>(kWasmS128);
BUILD(r, WASM_SET_GLOBAL(1, WASM_GET_GLOBAL(0)), WASM_ONE);
int32_t expected = 0x1234;
for (int i = 0; i < 4; i++) {
WriteLittleEndianValue<int32_t>(&g0[i], expected);
}
r.Call();
for (int i = 0; i < 4; i++) {
int32_t actual = ReadLittleEndianValue<int32_t>(&g1[i]);
CHECK_EQ(actual, expected);
}
}
#undef WASM_SIMD_LIFTOFF_TEST #undef WASM_SIMD_LIFTOFF_TEST
} // namespace test_run_wasm_simd_liftoff } // namespace test_run_wasm_simd_liftoff
......
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