Skip to content

Commit

Permalink
[maglev] Add MaglevAssembler::TryTruncateDoubleToUint32
Browse files Browse the repository at this point in the history
Bug: v8:7700
Change-Id: I3e60c174a8e429ee9a20c479a5f17d360ac8db50
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4651871
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#88524}
  • Loading branch information
victorgomes authored and V8 LUCI CQ committed Jun 28, 2023
1 parent 51ede0e commit 25db041
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 77 deletions.
36 changes: 36 additions & 0 deletions src/maglev/arm/maglev-assembler-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,42 @@ void MaglevAssembler::TryTruncateDoubleToInt32(Register dst, DoubleRegister src,
bind(&done);
}

void MaglevAssembler::TryTruncateDoubleToUint32(Register dst,
DoubleRegister src,
Label* fail) {
UseScratchRegisterScope temps(this);
LowDwVfpRegister low_double = temps.AcquireLowD();
SwVfpRegister temp_vfps = low_double.low();
DoubleRegister converted_back = low_double;
Label done;

// Convert the input float64 value to uint32.
vcvt_u32_f64(temp_vfps, src);
vmov(dst, temp_vfps);

// Convert that uint32 value back to float64.
vcvt_f64_u32(converted_back, temp_vfps);

// Check that the result of the float64->uint32->float64 is equal to the input
// (i.e. that the conversion didn't truncate.
VFPCompareAndSetFlags(src, converted_back);
JumpIf(kNotEqual, fail);

// Check if {input} is -0.
tst(dst, dst);
JumpIf(kNotEqual, &done);

// In case of 0, we need to check the high bits for the IEEE -0 pattern.
{
Register high_word32_of_input = temps.Acquire();
VmovHigh(high_word32_of_input, src);
cmp(high_word32_of_input, Operand(0));
JumpIf(kLessThan, fail);
}

bind(&done);
}

void MaglevAssembler::TryChangeFloat64ToIndex(Register result,
DoubleRegister value,
Label* success, Label* fail) {
Expand Down
9 changes: 0 additions & 9 deletions src/maglev/arm/maglev-ir-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,6 @@ void FoldedAllocation::GenerateCode(MaglevAssembler* masm,
__ add(ToRegister(result()), ToRegister(raw_allocation()), Operand(offset()));
}

void CheckedTruncateFloat64ToUint32::SetValueLocationConstraints() {
UseRegister(input());
DefineAsRegister(this);
}
void CheckedTruncateFloat64ToUint32::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
MAGLEV_NODE_NOT_IMPLEMENTED(CheckedTruncateFloat64ToUint32);
}

void CheckNumber::SetValueLocationConstraints() {
UseRegister(receiver_input());
}
Expand Down
27 changes: 27 additions & 0 deletions src/maglev/arm64/maglev-assembler-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,33 @@ void MaglevAssembler::TryTruncateDoubleToInt32(Register dst, DoubleRegister src,
Bind(&check_done);
}

void MaglevAssembler::TryTruncateDoubleToUint32(Register dst,
DoubleRegister src,
Label* fail) {
ScratchRegisterScope temps(this);
DoubleRegister converted_back = temps.AcquireDouble();

// Convert the input float64 value to uint32.
Fcvtzu(dst, src);
// Convert that uint32 value back to float64.
Ucvtf(converted_back, dst);
// Check that the result of the float64->uint32->float64 is equal to the input
// (i.e. that the conversion didn't truncate.
Fcmp(src, converted_back);
JumpIf(ne, fail);

// Check if {input} is -0.
Label check_done;
Cbnz(dst, &check_done);

// In case of 0, we need to check for the IEEE 0 pattern (which is all zeros).
Register input_bits = temps.Acquire();
Fmov(input_bits, src);
Cbnz(input_bits, fail);

Bind(&check_done);
}

void MaglevAssembler::TryChangeFloat64ToIndex(Register result,
DoubleRegister value,
Label* success, Label* fail) {
Expand Down
33 changes: 0 additions & 33 deletions src/maglev/arm64/maglev-ir-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,39 +151,6 @@ void FoldedAllocation::GenerateCode(MaglevAssembler* masm,
__ Add(ToRegister(result()), ToRegister(raw_allocation()), offset());
}

void CheckedTruncateFloat64ToUint32::SetValueLocationConstraints() {
UseRegister(input());
DefineAsRegister(this);
}
void CheckedTruncateFloat64ToUint32::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
DoubleRegister input_reg = ToDoubleRegister(input());
Register result_reg = ToRegister(result()).W();

MaglevAssembler::ScratchRegisterScope temps(masm);
DoubleRegister converted_back = temps.AcquireDouble();

// Convert the input float64 value to uint32.
__ Fcvtzu(result_reg, input_reg);
// Convert that uint32 value back to float64.
__ Ucvtf(converted_back, result_reg);
// Check that the result of the float64->uint32->float64 is equal to the input
// (i.e. that the conversion didn't truncate.
__ Fcmp(input_reg, converted_back);
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotUint32, this);

// Check if {input} is -0.
Label check_done;
__ Cbnz(result_reg, &check_done);

// In case of 0, we need to check for the IEEE 0 pattern (which is all zeros).
Register input_bits = temps.Acquire();
__ Fmov(input_bits, input_reg);
__ Cbnz(input_bits, __ GetDeoptLabel(this, DeoptimizeReason::kNotUint32));

__ Bind(&check_done);
}

void CheckNumber::SetValueLocationConstraints() {
UseRegister(receiver_input());
}
Expand Down
1 change: 1 addition & 0 deletions src/maglev/maglev-assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ class MaglevAssembler : public MacroAssembler {

void TruncateDoubleToInt32(Register dst, DoubleRegister src);
void TryTruncateDoubleToInt32(Register dst, DoubleRegister src, Label* fail);
void TryTruncateDoubleToUint32(Register dst, DoubleRegister src, Label* fail);

void TryChangeFloat64ToIndex(Register result, DoubleRegister value,
Label* success, Label* fail);
Expand Down
11 changes: 11 additions & 0 deletions src/maglev/maglev-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4040,6 +4040,17 @@ void CheckedTruncateFloat64ToInt32::GenerateCode(MaglevAssembler* masm,
__ GetDeoptLabel(this, DeoptimizeReason::kNotInt32));
}

void CheckedTruncateFloat64ToUint32::SetValueLocationConstraints() {
UseRegister(input());
DefineAsRegister(this);
}
void CheckedTruncateFloat64ToUint32::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
__ TryTruncateDoubleToUint32(
ToRegister(result()), ToDoubleRegister(input()),
__ GetDeoptLabel(this, DeoptimizeReason::kNotUint32));
}

void UnsafeTruncateFloat64ToInt32::SetValueLocationConstraints() {
UseRegister(input());
DefineAsRegister(this);
Expand Down
29 changes: 29 additions & 0 deletions src/maglev/x64/maglev-assembler-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,35 @@ void MaglevAssembler::TryTruncateDoubleToInt32(Register dst, DoubleRegister src,
bind(&check_done);
}

void MaglevAssembler::TryTruncateDoubleToUint32(Register dst,
DoubleRegister src,
Label* fail) {
DoubleRegister converted_back = kScratchDoubleReg;

// Convert the input float64 value to uint32.
Cvttsd2ui(dst, src, fail);
// Convert that uint32 value back to float64.
Cvtlui2sd(converted_back, dst);
// Check that the result of the float64->uint32->float64 is equal to the input
// (i.e. that the conversion didn't truncate.
Ucomisd(src, converted_back);
JumpIf(parity_even, fail);
JumpIf(not_equal, fail);

// Check if {input} is -0.
Label check_done;
cmpl(dst, Immediate(0));
j(not_equal, &check_done);

// In case of 0, we need to check the high bits for the IEEE -0 pattern.
Register high_word32_of_input = kScratchRegister;
Pextrd(high_word32_of_input, src, 1);
cmpl(high_word32_of_input, Immediate(0));
JumpIf(less, fail);

bind(&check_done);
}

void MaglevAssembler::TryChangeFloat64ToIndex(Register result,
DoubleRegister value,
Label* success, Label* fail) {
Expand Down
35 changes: 0 additions & 35 deletions src/maglev/x64/maglev-ir-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1031,41 +1031,6 @@ void HoleyFloat64ToMaybeNanFloat64::GenerateCode(MaglevAssembler* masm,
__ Subsd(value, kScratchDoubleReg);
}

void CheckedTruncateFloat64ToUint32::SetValueLocationConstraints() {
UseRegister(input());
DefineAsRegister(this);
}
void CheckedTruncateFloat64ToUint32::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
DoubleRegister input_reg = ToDoubleRegister(input());
Register result_reg = ToRegister(result());
DoubleRegister converted_back = kScratchDoubleReg;

// Convert the input float64 value to uint32.
Label* deopt = __ GetDeoptLabel(this, DeoptimizeReason::kNotUint32);
__ Cvttsd2ui(result_reg, input_reg, deopt);
// Convert that uint32 value back to float64.
__ Cvtlui2sd(converted_back, result_reg);
// Check that the result of the float64->uint32->float64 is equal to the input
// (i.e. that the conversion didn't truncate.
__ Ucomisd(input_reg, converted_back);
__ EmitEagerDeoptIf(parity_even, DeoptimizeReason::kNotUint32, this);
__ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kNotUint32, this);

// Check if {input} is -0.
Label check_done;
__ cmpl(result_reg, Immediate(0));
__ j(not_equal, &check_done);

// In case of 0, we need to check the high bits for the IEEE -0 pattern.
Register high_word32_of_input = kScratchRegister;
__ Pextrd(high_word32_of_input, input_reg, 1);
__ cmpl(high_word32_of_input, Immediate(0));
__ EmitEagerDeoptIf(less, DeoptimizeReason::kNotUint32, this);

__ bind(&check_done);
}

namespace {

enum class ReduceInterruptBudgetType { kLoop, kReturn };
Expand Down

0 comments on commit 25db041

Please sign in to comment.