[maglev][arm64] Add Checked/Truncate/Int32/Float64 IRs
Bug: v8:7700 Change-Id: I3a94cc3d4902b7296a9be93b9998d4cfa9b3153b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4111162 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Patrick Thier <pthier@chromium.org> Cr-Commit-Position: refs/heads/main@{#84929}
This commit is contained in:
parent
de5df9aebc
commit
5a486deea3
@ -122,15 +122,6 @@ UNIMPLEMENTED_NODE(LoadDoubleDataViewElement)
|
||||
UNIMPLEMENTED_NODE(LoadSignedIntTypedArrayElement, elements_kind_)
|
||||
UNIMPLEMENTED_NODE(LoadUnsignedIntTypedArrayElement, elements_kind_)
|
||||
UNIMPLEMENTED_NODE(LoadDoubleTypedArrayElement, elements_kind_)
|
||||
UNIMPLEMENTED_NODE(CheckedSmiTagUint32)
|
||||
UNIMPLEMENTED_NODE(CheckedInt32ToUint32)
|
||||
UNIMPLEMENTED_NODE(CheckedUint32ToInt32)
|
||||
UNIMPLEMENTED_NODE(ChangeInt32ToFloat64)
|
||||
UNIMPLEMENTED_NODE(ChangeUint32ToFloat64)
|
||||
UNIMPLEMENTED_NODE(CheckedTruncateFloat64ToInt32)
|
||||
UNIMPLEMENTED_NODE(CheckedTruncateFloat64ToUint32)
|
||||
UNIMPLEMENTED_NODE(TruncateUint32ToInt32)
|
||||
UNIMPLEMENTED_NODE(TruncateFloat64ToInt32)
|
||||
UNIMPLEMENTED_NODE(HoleyFloat64Box)
|
||||
UNIMPLEMENTED_NODE(LogicalNot)
|
||||
UNIMPLEMENTED_NODE(SetPendingMessage)
|
||||
@ -242,6 +233,120 @@ void CreateEmptyObjectLiteral::GenerateCode(MaglevAssembler* masm,
|
||||
}
|
||||
}
|
||||
|
||||
void CheckedInt32ToUint32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void CheckedInt32ToUint32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register input_reg = ToRegister(input()).W();
|
||||
__ Tst(input_reg, input_reg);
|
||||
__ EmitEagerDeoptIf(mi, DeoptimizeReason::kNotUint32, this);
|
||||
}
|
||||
|
||||
void CheckedUint32ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void CheckedUint32ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register input_reg = ToRegister(input()).W();
|
||||
// Check if the top bit is set -- if it is, then this is not a valid int32,
|
||||
// otherwise it is.
|
||||
// TODO(victorgomes): I am manually creating an eager deopt here, if this is a
|
||||
// common pattern, maybe abstract to a helper function.
|
||||
static_assert(CheckedUint32ToInt32::kProperties.can_eager_deopt());
|
||||
__ RegisterEagerDeopt(eager_deopt_info(), DeoptimizeReason::kNotInt32);
|
||||
__ RecordComment("-- Jump to eager deopt");
|
||||
__ Tbnz(input_reg, 31, eager_deopt_info()->deopt_entry_label());
|
||||
}
|
||||
|
||||
void ChangeInt32ToFloat64::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void ChangeInt32ToFloat64::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
__ Scvtf(ToDoubleRegister(result()), ToRegister(input()).W());
|
||||
}
|
||||
|
||||
void ChangeUint32ToFloat64::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void ChangeUint32ToFloat64::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
__ Ucvtf(ToDoubleRegister(result()), ToRegister(input()).W());
|
||||
}
|
||||
|
||||
void CheckedTruncateFloat64ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void CheckedTruncateFloat64ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister input_reg = ToDoubleRegister(input());
|
||||
Register result_reg = ToRegister(result()).W();
|
||||
DoubleRegister converted_back = kScratchDoubleReg;
|
||||
|
||||
// Convert the input float64 value to int32.
|
||||
__ Fcvtzs(result_reg, input_reg);
|
||||
// Convert that int32 value back to float64.
|
||||
__ Scvtf(converted_back, result_reg);
|
||||
// Check that the result of the float64->int32->float64 is equal to the input
|
||||
// (i.e. that the conversion didn't truncate.
|
||||
__ Fcmp(input_reg, converted_back);
|
||||
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotInt32, this);
|
||||
|
||||
// Check if {input} is -0.
|
||||
Label check_done;
|
||||
__ Cmp(result_reg, wzr);
|
||||
__ B(&check_done, ne);
|
||||
|
||||
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register high_word32_of_input = temps.AcquireW();
|
||||
__ Umov(high_word32_of_input, input_reg.V2S(), 1);
|
||||
__ Cmp(high_word32_of_input, wzr);
|
||||
__ EmitEagerDeoptIf(lt, DeoptimizeReason::kNotInt32, this);
|
||||
|
||||
__ bind(&check_done);
|
||||
}
|
||||
|
||||
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();
|
||||
DoubleRegister converted_back = kScratchDoubleReg;
|
||||
|
||||
// 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;
|
||||
__ Cmp(result_reg, wzr);
|
||||
__ B(&check_done, ne);
|
||||
|
||||
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register high_word32_of_input = temps.AcquireW();
|
||||
__ Umov(high_word32_of_input, input_reg.V2S(), 1);
|
||||
__ Cmp(high_word32_of_input, wzr);
|
||||
__ EmitEagerDeoptIf(lt, DeoptimizeReason::kNotUint32, this);
|
||||
|
||||
__ bind(&check_done);
|
||||
}
|
||||
|
||||
void CheckedTruncateNumberToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
@ -959,6 +1064,21 @@ void CheckedSmiTagInt32::GenerateCode(MaglevAssembler* masm,
|
||||
__ EmitEagerDeoptIf(vs, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
void CheckedSmiTagUint32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void CheckedSmiTagUint32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register reg = ToRegister(input()).W();
|
||||
Register result_reg = ToRegister(result()).W();
|
||||
// Perform an unsigned comparison against Smi::kMaxValue.
|
||||
__ Cmp(reg, Immediate(Smi::kMaxValue));
|
||||
__ EmitEagerDeoptIf(hi, DeoptimizeReason::kOverflow, this);
|
||||
__ Adds(result_reg, reg, reg);
|
||||
__ Assert(vc, AbortReason::kInputDoesNotFitSmi);
|
||||
}
|
||||
|
||||
void CheckedInternalizedString::SetValueLocationConstraints() {
|
||||
UseRegister(object_input());
|
||||
DefineSameAsFirst(this);
|
||||
|
@ -1583,6 +1583,25 @@ void ToNumberOrNumeric::GenerateCode(MaglevAssembler* masm,
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
}
|
||||
|
||||
void TruncateUint32ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void TruncateUint32ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
// No code emitted -- as far as the machine is concerned, int32 is uint32.
|
||||
DCHECK_EQ(ToRegister(input()), ToRegister(result()));
|
||||
}
|
||||
|
||||
void TruncateFloat64ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void TruncateFloat64ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
__ TruncateDoubleToInt32(ToRegister(result()), ToDoubleRegister(input()));
|
||||
}
|
||||
|
||||
// ---
|
||||
// Arch agnostic call nodes
|
||||
// ---
|
||||
|
@ -2553,25 +2553,6 @@ void CheckedTruncateFloat64ToUint32::GenerateCode(
|
||||
__ bind(&check_done);
|
||||
}
|
||||
|
||||
void TruncateUint32ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void TruncateUint32ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
// No code emitted -- as far as the machine is concerned, int32 is uint32.
|
||||
DCHECK_EQ(ToRegister(input()), ToRegister(result()));
|
||||
}
|
||||
|
||||
void TruncateFloat64ToInt32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void TruncateFloat64ToInt32::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
__ TruncateDoubleToInt32(ToRegister(result()), ToDoubleRegister(input()));
|
||||
}
|
||||
|
||||
int Construct::MaxCallStackArgs() const {
|
||||
using D = Construct_WithFeedbackDescriptor;
|
||||
return num_args() + D::GetStackParameterCount();
|
||||
|
Loading…
Reference in New Issue
Block a user