Reland "[wasm-gc] Liftoff support part 5: i31"
This is a reland of a3ce2f6da2
(No changes; was reverted because a dependency was reverted.)
Original change's description:
> [wasm-gc] Liftoff support part 5: i31
>
> This implements support for i31.get_s and i31.get_u.
>
> Bug: v8:7748
> Change-Id: Icbfddbc2ff46b4eb6bf3edf7b3a794f9797361d4
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2595309
> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Clemens Backes <clemensb@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#71808}
Bug: v8:7748
Change-Id: Id8e66cab285d2a36fcd712b92a522e83dea93193
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2617089
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71984}
This commit is contained in:
parent
2651820e68
commit
432c0a78e9
@ -703,11 +703,13 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
|
||||
LiftoffRegister src,
|
||||
LiftoffRegList pinned) {
|
||||
STATIC_ASSERT(kTaggedSize == kInt32Size);
|
||||
{
|
||||
// Store the value.
|
||||
UseScratchRegisterScope temps(this);
|
||||
MemOperand dst_op =
|
||||
liftoff::GetMemOp(this, &temps, dst_addr, offset_reg, offset_imm);
|
||||
str(src.gp(), dst_op);
|
||||
}
|
||||
// The write barrier.
|
||||
Label write_barrier;
|
||||
Label exit;
|
||||
|
@ -71,6 +71,7 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Register base,
|
||||
case ValueType::kI32:
|
||||
case ValueType::kOptRef:
|
||||
case ValueType::kRef:
|
||||
case ValueType::kRtt:
|
||||
assm->mov(dst.gp(), src);
|
||||
break;
|
||||
case ValueType::kI64:
|
||||
|
@ -4136,6 +4136,9 @@ class LiftoffCompiler {
|
||||
__ PushRegister(kWasmI32, len);
|
||||
}
|
||||
|
||||
// 1 bit Smi tag, 31 bits Smi shift, 1 bit i31ref high-bit truncation.
|
||||
constexpr static int kI31To32BitSmiShift = 33;
|
||||
|
||||
void I31New(FullDecoder* decoder, const Value& input, Value* result) {
|
||||
LiftoffRegister src = __ PopToRegister();
|
||||
LiftoffRegister dst = __ GetUnusedRegister(kGpReg, {src}, {});
|
||||
@ -4144,20 +4147,33 @@ class LiftoffCompiler {
|
||||
__ emit_i32_shli(dst.gp(), src.gp(), kSmiTagSize);
|
||||
} else {
|
||||
DCHECK(SmiValuesAre32Bits());
|
||||
// 1 bit Smi tag, 31 bits Smi shift, 1 bit i31ref high-bit truncation.
|
||||
constexpr int kI31To32BitSmiShift = 33;
|
||||
__ emit_i64_shli(dst, src, kI31To32BitSmiShift);
|
||||
}
|
||||
__ PushRegister(kWasmI31Ref, dst);
|
||||
}
|
||||
|
||||
void I31GetS(FullDecoder* decoder, const Value& input, Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "i31.get_s");
|
||||
LiftoffRegister src = __ PopToRegister();
|
||||
LiftoffRegister dst = __ GetUnusedRegister(kGpReg, {src}, {});
|
||||
if (SmiValuesAre31Bits()) {
|
||||
__ emit_i32_sari(dst.gp(), src.gp(), kSmiTagSize);
|
||||
} else {
|
||||
DCHECK(SmiValuesAre32Bits());
|
||||
__ emit_i64_sari(dst, src, kI31To32BitSmiShift);
|
||||
}
|
||||
__ PushRegister(kWasmI32, dst);
|
||||
}
|
||||
|
||||
void I31GetU(FullDecoder* decoder, const Value& input, Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "i31.get_u");
|
||||
LiftoffRegister src = __ PopToRegister();
|
||||
LiftoffRegister dst = __ GetUnusedRegister(kGpReg, {src}, {});
|
||||
if (SmiValuesAre31Bits()) {
|
||||
__ emit_i32_shri(dst.gp(), src.gp(), kSmiTagSize);
|
||||
} else {
|
||||
DCHECK(SmiValuesAre32Bits());
|
||||
__ emit_i64_shri(dst, src, kI31To32BitSmiShift);
|
||||
}
|
||||
__ PushRegister(kWasmI32, dst);
|
||||
}
|
||||
|
||||
void RttCanon(FullDecoder* decoder, const HeapTypeImmediate<validate>& imm,
|
||||
|
@ -91,6 +91,7 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
|
||||
case ValueType::kI64:
|
||||
case ValueType::kOptRef:
|
||||
case ValueType::kRef:
|
||||
case ValueType::kRtt:
|
||||
assm->movq(dst.gp(), src);
|
||||
break;
|
||||
case ValueType::kF32:
|
||||
|
@ -42,6 +42,7 @@ class WasmGCTester {
|
||||
flag_liftoff_only(
|
||||
&v8::internal::FLAG_liftoff_only,
|
||||
execution_tier == TestExecutionTier::kLiftoff ? true : false),
|
||||
flag_tierup(&v8::internal::FLAG_wasm_tier_up, false),
|
||||
zone(&allocator, ZONE_NAME),
|
||||
builder_(&zone),
|
||||
isolate_(CcTest::InitIsolateOnce()),
|
||||
@ -182,6 +183,7 @@ class WasmGCTester {
|
||||
const FlagScope<bool> flag_typedfuns;
|
||||
const FlagScope<bool> flag_liftoff;
|
||||
const FlagScope<bool> flag_liftoff_only;
|
||||
const FlagScope<bool> flag_tierup;
|
||||
|
||||
v8::internal::AccountingAllocator allocator;
|
||||
Zone zone;
|
||||
@ -1091,8 +1093,9 @@ WASM_COMPILED_EXEC_TEST(RefTestCastNull) {
|
||||
tester.CheckHasThrown(kRefCastNull, 0);
|
||||
}
|
||||
|
||||
TEST(BasicI31) {
|
||||
WasmGCTester tester;
|
||||
WASM_COMPILED_EXEC_TEST(BasicI31) {
|
||||
WasmGCTester tester(execution_tier);
|
||||
FLAG_experimental_liftoff_extern_ref = true;
|
||||
const byte kSigned = tester.DefineFunction(
|
||||
tester.sigs.i_i(), {},
|
||||
{WASM_I31_GET_S(WASM_I31_NEW(WASM_LOCAL_GET(0))), kExprEnd});
|
||||
@ -1112,8 +1115,9 @@ TEST(BasicI31) {
|
||||
tester.CheckResult(kUnsigned, 0x7FFFFFFF, 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
TEST(I31Casts) {
|
||||
WasmGCTester tester;
|
||||
WASM_COMPILED_EXEC_TEST(I31Casts) {
|
||||
WasmGCTester tester(execution_tier);
|
||||
FLAG_experimental_liftoff_extern_ref = true;
|
||||
const byte struct_type = tester.DefineStruct({F(wasm::kWasmI32, true)});
|
||||
const byte i31_rtt =
|
||||
tester.AddGlobal(ValueType::Rtt(HeapType::kI31, 1), false,
|
||||
@ -1173,8 +1177,9 @@ TEST(I31Casts) {
|
||||
|
||||
// This flushed out a few bugs, so it serves as a regression test. It can also
|
||||
// be modified (made to run longer) to measure performance of casts.
|
||||
TEST(CastsBenchmark) {
|
||||
WasmGCTester tester;
|
||||
WASM_COMPILED_EXEC_TEST(CastsBenchmark) {
|
||||
WasmGCTester tester(execution_tier);
|
||||
FLAG_experimental_liftoff_extern_ref = true;
|
||||
const byte SuperType = tester.DefineStruct({F(wasm::kWasmI32, true)});
|
||||
const byte SubType =
|
||||
tester.DefineStruct({F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)});
|
||||
|
Loading…
Reference in New Issue
Block a user