[maglev][arm64] Implement first Float64 operations
Bug: v8:7700 Change-Id: Ib2d9d0cab90042e2b425f56da8022b25b94c4805 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4082208 Commit-Queue: Darius Mercadier <dmercadier@chromium.org> Reviewed-by: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/main@{#84735}
This commit is contained in:
parent
73801dac2f
commit
ada6f41e91
@ -1106,16 +1106,18 @@ void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) {
|
||||
|
||||
void TurboAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); }
|
||||
|
||||
void TurboAssembler::SmiToInt32(Register smi) {
|
||||
DCHECK(smi.Is64Bits());
|
||||
void TurboAssembler::SmiToInt32(Register smi) { SmiToInt32(smi, smi); }
|
||||
|
||||
void TurboAssembler::SmiToInt32(Register dst, Register smi) {
|
||||
DCHECK(dst.Is64Bits());
|
||||
if (v8_flags.enable_slow_asserts) {
|
||||
AssertSmi(smi);
|
||||
}
|
||||
DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
|
||||
if (COMPRESS_POINTERS_BOOL) {
|
||||
Asr(smi.W(), smi.W(), kSmiShift);
|
||||
Asr(dst.W(), smi.W(), kSmiShift);
|
||||
} else {
|
||||
Lsr(smi, smi, kSmiShift);
|
||||
Lsr(dst, smi, kSmiShift);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,6 +561,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
inline void SmiTag(Register smi);
|
||||
|
||||
inline void SmiToInt32(Register smi);
|
||||
inline void SmiToInt32(Register dst, Register smi);
|
||||
|
||||
// Calls Abort(msg) if the condition cond is not satisfied.
|
||||
// Use --debug_code to enable.
|
||||
@ -1821,7 +1822,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
|
||||
DCHECK(!registers.has(fp_zero));
|
||||
registers.set(fp_zero);
|
||||
}
|
||||
PushQRegList(registers);
|
||||
PushDRegList(registers);
|
||||
}
|
||||
inline void PopAll(DoubleRegList registers,
|
||||
int stack_slot_size = kDoubleSize) {
|
||||
@ -1829,7 +1830,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
|
||||
DCHECK(!registers.has(fp_zero));
|
||||
registers.set(fp_zero);
|
||||
}
|
||||
PopQRegList(registers);
|
||||
PopDRegList(registers);
|
||||
}
|
||||
|
||||
// Push the specified register 'count' times.
|
||||
|
@ -100,19 +100,16 @@ inline void MaglevAssembler::Move(MemOperand dst, Register src) {
|
||||
Str(src, dst);
|
||||
}
|
||||
inline void MaglevAssembler::Move(MemOperand dst, DoubleRegister src) {
|
||||
// TODO(v8:7700): Implement!
|
||||
UNREACHABLE();
|
||||
Str(src, dst);
|
||||
}
|
||||
inline void MaglevAssembler::Move(Register dst, MemOperand src) {
|
||||
Ldr(dst, src);
|
||||
}
|
||||
inline void MaglevAssembler::Move(DoubleRegister dst, MemOperand src) {
|
||||
// TODO(v8:7700): Implement!
|
||||
UNREACHABLE();
|
||||
Ldr(dst, src);
|
||||
}
|
||||
inline void MaglevAssembler::Move(DoubleRegister dst, DoubleRegister src) {
|
||||
// TODO(v8:7700): Implement!
|
||||
UNREACHABLE();
|
||||
fmov(dst, src);
|
||||
}
|
||||
inline void MaglevAssembler::Move(Register dst, Smi src) {
|
||||
MacroAssembler::Move(dst, src);
|
||||
@ -127,8 +124,7 @@ inline void MaglevAssembler::Move(Register dst, int32_t i) {
|
||||
Mov(dst, Immediate(i));
|
||||
}
|
||||
inline void MaglevAssembler::Move(DoubleRegister dst, double n) {
|
||||
// TODO(v8:7700): Implement!
|
||||
UNREACHABLE();
|
||||
Fmov(dst, n);
|
||||
}
|
||||
inline void MaglevAssembler::Move(Register dst, Handle<HeapObject> obj) {
|
||||
Mov(dst, Operand(obj));
|
||||
|
@ -79,6 +79,23 @@ void MaglevAssembler::Allocate(RegisterSnapshot& register_snapshot,
|
||||
bind(*done);
|
||||
}
|
||||
|
||||
void MaglevAssembler::AllocateHeapNumber(RegisterSnapshot register_snapshot,
|
||||
Register result,
|
||||
DoubleRegister value) {
|
||||
// In the case we need to call the runtime, we should spill the value
|
||||
// register. Even if it is not live in the next node, otherwise the
|
||||
// allocation call might trash it.
|
||||
register_snapshot.live_double_registers.set(value);
|
||||
Allocate(register_snapshot, result, HeapNumber::kSize);
|
||||
// `Allocate` needs 2 scratch registers, so it's important to `AcquireX` after
|
||||
// `Allocate` is done and not before.
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register scratch = temps.AcquireX();
|
||||
LoadRoot(scratch, RootIndex::kHeapNumberMap);
|
||||
StoreTaggedField(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
|
||||
Str(value, FieldMemOperand(result, HeapNumber::kValueOffset));
|
||||
}
|
||||
|
||||
void MaglevAssembler::Prologue(Graph* graph) {
|
||||
if (v8_flags.maglev_ool_prologue) {
|
||||
// TODO(v8:7700): Implement!
|
||||
|
@ -115,13 +115,6 @@ void Int32DecrementWithOverflow::GenerateCode(MaglevAssembler* masm,
|
||||
__ EmitEagerDeoptIf(vs, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_NODE(Float64Add)
|
||||
UNIMPLEMENTED_NODE(Float64Subtract)
|
||||
UNIMPLEMENTED_NODE(Float64Multiply)
|
||||
UNIMPLEMENTED_NODE(Float64Divide)
|
||||
UNIMPLEMENTED_NODE_WITH_CALL(Float64Exponentiate)
|
||||
UNIMPLEMENTED_NODE(Float64Modulus)
|
||||
UNIMPLEMENTED_NODE(Float64Negate)
|
||||
UNIMPLEMENTED_NODE(Float64Equal)
|
||||
UNIMPLEMENTED_NODE(Float64StrictEqual)
|
||||
UNIMPLEMENTED_NODE(Float64LessThan)
|
||||
@ -170,9 +163,7 @@ UNIMPLEMENTED_NODE(TruncateUint32ToInt32)
|
||||
UNIMPLEMENTED_NODE(TruncateFloat64ToInt32)
|
||||
UNIMPLEMENTED_NODE(Int32ToNumber)
|
||||
UNIMPLEMENTED_NODE(Uint32ToNumber)
|
||||
UNIMPLEMENTED_NODE(Float64Box)
|
||||
UNIMPLEMENTED_NODE(HoleyFloat64Box)
|
||||
UNIMPLEMENTED_NODE(CheckedFloat64Unbox)
|
||||
UNIMPLEMENTED_NODE(LogicalNot)
|
||||
UNIMPLEMENTED_NODE(SetPendingMessage)
|
||||
UNIMPLEMENTED_NODE_WITH_CALL(StringAt)
|
||||
@ -372,6 +363,97 @@ DEF_OPERATION(Int32GreaterThan)
|
||||
DEF_OPERATION(Int32GreaterThanOrEqual)
|
||||
#undef DEF_OPERATION
|
||||
|
||||
void Float64Add::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
|
||||
void Float64Add::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister left = ToDoubleRegister(left_input());
|
||||
DoubleRegister right = ToDoubleRegister(right_input());
|
||||
DoubleRegister out = ToDoubleRegister(result());
|
||||
__ Fadd(out, left, right);
|
||||
}
|
||||
|
||||
void Float64Subtract::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
|
||||
void Float64Subtract::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister left = ToDoubleRegister(left_input());
|
||||
DoubleRegister right = ToDoubleRegister(right_input());
|
||||
DoubleRegister out = ToDoubleRegister(result());
|
||||
__ Fsub(out, left, right);
|
||||
}
|
||||
|
||||
void Float64Multiply::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
|
||||
void Float64Multiply::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister left = ToDoubleRegister(left_input());
|
||||
DoubleRegister right = ToDoubleRegister(right_input());
|
||||
DoubleRegister out = ToDoubleRegister(result());
|
||||
__ Fmul(out, left, right);
|
||||
}
|
||||
|
||||
void Float64Divide::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
|
||||
void Float64Divide::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister left = ToDoubleRegister(left_input());
|
||||
DoubleRegister right = ToDoubleRegister(right_input());
|
||||
DoubleRegister out = ToDoubleRegister(result());
|
||||
__ Fdiv(out, left, right);
|
||||
}
|
||||
|
||||
int Float64Modulus::MaxCallStackArgs() const { return 0; }
|
||||
void Float64Modulus::SetValueLocationConstraints() {
|
||||
UseFixed(left_input(), v0);
|
||||
UseFixed(right_input(), v1);
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void Float64Modulus::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
AllowExternalCallThatCantCauseGC scope(masm);
|
||||
__ CallCFunction(ExternalReference::mod_two_doubles_operation(), 0, 2);
|
||||
}
|
||||
|
||||
void Float64Negate::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void Float64Negate::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister value = ToDoubleRegister(input());
|
||||
DoubleRegister out = ToDoubleRegister(result());
|
||||
__ Fneg(out, value);
|
||||
}
|
||||
|
||||
int Float64Exponentiate::MaxCallStackArgs() const { return 0; }
|
||||
void Float64Exponentiate::SetValueLocationConstraints() {
|
||||
UseFixed(left_input(), v0);
|
||||
UseFixed(right_input(), v1);
|
||||
DefineSameAsFirst(this);
|
||||
}
|
||||
void Float64Exponentiate::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
AllowExternalCallThatCantCauseGC scope(masm);
|
||||
__ CallCFunction(ExternalReference::ieee754_pow_function(), 2);
|
||||
}
|
||||
|
||||
void CheckInt32IsSmi::SetValueLocationConstraints() { UseRegister(input()); }
|
||||
void CheckInt32IsSmi::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
@ -421,6 +503,44 @@ void UnsafeSmiTag::GenerateCode(MaglevAssembler* masm,
|
||||
}
|
||||
}
|
||||
|
||||
void Float64Box::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void Float64Box::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
DoubleRegister value = ToDoubleRegister(input());
|
||||
Register object = ToRegister(result());
|
||||
__ AllocateHeapNumber(register_snapshot(), object, value);
|
||||
}
|
||||
|
||||
void CheckedFloat64Unbox::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineAsRegister(this);
|
||||
}
|
||||
void CheckedFloat64Unbox::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(input());
|
||||
Label is_not_smi, done;
|
||||
// Check if Smi.
|
||||
__ JumpIfNotSmi(value, &is_not_smi);
|
||||
// If Smi, convert to Float64.
|
||||
UseScratchRegisterScope temps(masm);
|
||||
Register temp = temps.AcquireX();
|
||||
__ SmiToInt32(temp, value);
|
||||
__ sxtw(temp, temp.W());
|
||||
__ scvtf(ToDoubleRegister(result()), temp);
|
||||
__ Jump(&done);
|
||||
__ bind(&is_not_smi);
|
||||
// Check if HeapNumber, deopt otherwise.
|
||||
__ Move(temp, FieldMemOperand(value, HeapObject::kMapOffset));
|
||||
__ CompareRoot(temp, RootIndex::kHeapNumberMap);
|
||||
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotANumber, this);
|
||||
__ Move(temp, FieldMemOperand(value, HeapNumber::kValueOffset));
|
||||
__ fmov(ToDoubleRegister(result()), temp);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void IncreaseInterruptBudget::SetValueLocationConstraints() {}
|
||||
void IncreaseInterruptBudget::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
|
@ -1900,21 +1900,23 @@ class Float64BinaryNode : public FixedInputValueNodeT<2, Derived> {
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
||||
};
|
||||
|
||||
#define DEF_FLOAT64_BINARY_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Float64##Name, Float64BinaryNode, Name)
|
||||
DEF_FLOAT64_BINARY_NODE(Add)
|
||||
DEF_FLOAT64_BINARY_NODE(Subtract)
|
||||
DEF_FLOAT64_BINARY_NODE(Multiply)
|
||||
DEF_FLOAT64_BINARY_NODE(Divide)
|
||||
DEF_FLOAT64_BINARY_NODE(Modulus)
|
||||
#undef DEF_FLOAT64_BINARY_NODE
|
||||
#define DEF_OPERATION_NODE_WITH_CALL(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
public: \
|
||||
explicit Name(uint64_t bitfield) : Base(bitfield) {} \
|
||||
int MaxCallStackArgs() const; \
|
||||
void SetValueLocationConstraints(); \
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||
};
|
||||
|
||||
class Float64Exponentiate
|
||||
: public FixedInputValueNodeT<2, Float64Exponentiate> {
|
||||
using Base = FixedInputValueNodeT<2, Float64Exponentiate>;
|
||||
template <class Derived, Operation kOperation>
|
||||
class Float64BinaryNodeWithCall : public FixedInputValueNodeT<2, Derived> {
|
||||
using Base = FixedInputValueNodeT<2, Derived>;
|
||||
|
||||
public:
|
||||
explicit Float64Exponentiate(uint64_t bitfield) : Base(bitfield) {}
|
||||
static constexpr OpProperties kProperties =
|
||||
OpProperties::Float64() | OpProperties::Call();
|
||||
static constexpr typename Base::InputTypes kInputTypes{
|
||||
@ -1925,12 +1927,31 @@ class Float64Exponentiate
|
||||
Input& left_input() { return Node::input(kLeftIndex); }
|
||||
Input& right_input() { return Node::input(kRightIndex); }
|
||||
|
||||
int MaxCallStackArgs() const;
|
||||
void SetValueLocationConstraints();
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&);
|
||||
protected:
|
||||
explicit Float64BinaryNodeWithCall(uint64_t bitfield) : Base(bitfield) {}
|
||||
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
||||
};
|
||||
|
||||
#define DEF_FLOAT64_BINARY_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Float64##Name, Float64BinaryNode, Name)
|
||||
#define DEF_FLOAT64_BINARY_NODE_WITH_CALL(Name) \
|
||||
DEF_OPERATION_NODE_WITH_CALL(Float64##Name, Float64BinaryNodeWithCall, Name)
|
||||
DEF_FLOAT64_BINARY_NODE(Add)
|
||||
DEF_FLOAT64_BINARY_NODE(Subtract)
|
||||
DEF_FLOAT64_BINARY_NODE(Multiply)
|
||||
DEF_FLOAT64_BINARY_NODE(Divide)
|
||||
#ifdef V8_TARGET_ARCH_ARM64
|
||||
// On Arm64, floating point modulus is implemented with a call to a C++
|
||||
// function, while on x64, it's implemented natively without call.
|
||||
DEF_FLOAT64_BINARY_NODE_WITH_CALL(Modulus)
|
||||
#else
|
||||
DEF_FLOAT64_BINARY_NODE(Modulus)
|
||||
#endif
|
||||
DEF_FLOAT64_BINARY_NODE_WITH_CALL(Exponentiate)
|
||||
#undef DEF_FLOAT64_BINARY_NODE
|
||||
#undef DEF_FLOAT64_BINARY_NODE_WITH_CALL
|
||||
|
||||
template <class Derived, Operation kOperation>
|
||||
class Float64CompareNode : public FixedInputValueNodeT<2, Derived> {
|
||||
using Base = FixedInputValueNodeT<2, Derived>;
|
||||
@ -1963,6 +1984,7 @@ DEF_FLOAT64_COMPARE_NODE(GreaterThanOrEqual)
|
||||
#undef DEF_FLOAT64_COMPARE_NODE
|
||||
|
||||
#undef DEF_OPERATION_NODE
|
||||
#undef DEF_OPERATION_NODE_WITH_CALL
|
||||
|
||||
class Float64Negate : public FixedInputValueNodeT<1, Float64Negate> {
|
||||
using Base = FixedInputValueNodeT<1, Float64Negate>;
|
||||
|
Loading…
Reference in New Issue
Block a user