Commit 5b662703 authored by baptiste.afsa@arm.com's avatar baptiste.afsa@arm.com

A64: Add and use a double register which holds the 0.0 value.

This patch also modify the crankshaft allocatable double registers because
we need this register to be callee saved to be efficient.

R=jochen@chromium.org

Review URL: https://codereview.chromium.org/190663009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 59616147
...@@ -264,36 +264,60 @@ struct FPRegister : public CPURegister { ...@@ -264,36 +264,60 @@ struct FPRegister : public CPURegister {
static const int kMaxNumRegisters = kNumberOfFPRegisters; static const int kMaxNumRegisters = kNumberOfFPRegisters;
// Crankshaft can use all the FP registers except: // Crankshaft can use all the FP registers except:
// - d29 which is used in crankshaft as a double scratch register // - d15 which is used to keep the 0 double value
// - d30 which is used to keep the 0 double value // - d30 which is used in crankshaft as a double scratch register
// - d31 which is used in the MacroAssembler as a double scratch register // - d31 which is used in the MacroAssembler as a double scratch register
static const int kNumReservedRegisters = 3; static const unsigned kAllocatableLowRangeBegin = 0;
static const unsigned kAllocatableLowRangeEnd = 14;
static const unsigned kAllocatableHighRangeBegin = 16;
static const unsigned kAllocatableHighRangeEnd = 29;
static const RegList kAllocatableFPRegisters = 0x3fff7fff;
// Gap between low and high ranges.
static const int kAllocatableRangeGapSize =
(kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1;
static const int kMaxNumAllocatableRegisters = static const int kMaxNumAllocatableRegisters =
kNumberOfFPRegisters - kNumReservedRegisters; (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) +
(kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1);
static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
static const RegList kAllocatableFPRegisters =
(1 << kMaxNumAllocatableRegisters) - 1;
static FPRegister FromAllocationIndex(int index) { // Return true if the register is one that crankshaft can allocate.
ASSERT((index >= 0) && (index < NumAllocatableRegisters())); bool IsAllocatable() const {
return from_code(index); return (Bit() & kAllocatableFPRegisters) != 0;
}
static FPRegister FromAllocationIndex(unsigned int index) {
ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters()));
return (index <= kAllocatableLowRangeEnd)
? from_code(index)
: from_code(index + kAllocatableRangeGapSize);
} }
static const char* AllocationIndexToString(int index) { static const char* AllocationIndexToString(int index) {
ASSERT((index >= 0) && (index < NumAllocatableRegisters())); ASSERT((index >= 0) && (index < NumAllocatableRegisters()));
ASSERT((kAllocatableLowRangeBegin == 0) &&
(kAllocatableLowRangeEnd == 14) &&
(kAllocatableHighRangeBegin == 16) &&
(kAllocatableHighRangeEnd == 29));
const char* const names[] = { const char* const names[] = {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", "d8", "d9", "d10", "d11", "d12", "d13", "d14",
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
"d24", "d25", "d26", "d27", "d28", "d24", "d25", "d26", "d27", "d28", "d29"
}; };
return names[index]; return names[index];
} }
static int ToAllocationIndex(FPRegister reg) { static int ToAllocationIndex(FPRegister reg) {
int code = reg.code(); ASSERT(reg.IsAllocatable());
ASSERT(code < NumAllocatableRegisters()); unsigned code = reg.code();
return code;
return (code <= kAllocatableLowRangeEnd)
? code
: code - kAllocatableRangeGapSize;
} }
static FPRegister from_code(int code) { static FPRegister from_code(int code) {
...@@ -375,10 +399,10 @@ ALIAS_REGISTER(Register, lr, x30); ...@@ -375,10 +399,10 @@ ALIAS_REGISTER(Register, lr, x30);
ALIAS_REGISTER(Register, xzr, x31); ALIAS_REGISTER(Register, xzr, x31);
ALIAS_REGISTER(Register, wzr, w31); ALIAS_REGISTER(Register, wzr, w31);
// Crankshaft double scratch register.
ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29);
// Keeps the 0 double value. // Keeps the 0 double value.
ALIAS_REGISTER(FPRegister, fp_zero, d30); ALIAS_REGISTER(FPRegister, fp_zero, d15);
// Crankshaft double scratch register.
ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d30);
// MacroAssembler double scratch register. // MacroAssembler double scratch register.
ALIAS_REGISTER(FPRegister, fp_scratch, d31); ALIAS_REGISTER(FPRegister, fp_scratch, d31);
......
...@@ -1182,7 +1182,6 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -1182,7 +1182,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
if (exponent_type_ == ON_STACK) { if (exponent_type_ == ON_STACK) {
FPRegister half_double = d3; FPRegister half_double = d3;
FPRegister minus_half_double = d4; FPRegister minus_half_double = d4;
FPRegister zero_double = d5;
// Detect square root case. Crankshaft detects constant +/-0.5 at compile // Detect square root case. Crankshaft detects constant +/-0.5 at compile
// time and uses DoMathPowHalf instead. We then skip this check for // time and uses DoMathPowHalf instead. We then skip this check for
// non-constant cases of +/-0.5 as these hardly occur. // non-constant cases of +/-0.5 as these hardly occur.
...@@ -1215,8 +1214,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -1215,8 +1214,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// where base is -INFINITY or -0. // where base is -INFINITY or -0.
// Add +0 to base. This has no effect other than turning -0 into +0. // Add +0 to base. This has no effect other than turning -0 into +0.
__ Fmov(zero_double, 0.0); __ Fadd(base_double, base_double, fp_zero);
__ Fadd(base_double, base_double, zero_double);
// The operation -0+0 results in +0 in all cases except where the // The operation -0+0 results in +0 in all cases except where the
// FPCR rounding mode is 'round towards minus infinity' (RM). The // FPCR rounding mode is 'round towards minus infinity' (RM). The
// A64 simulator does not currently simulate FPCR (where the rounding // A64 simulator does not currently simulate FPCR (where the rounding
...@@ -1224,18 +1222,17 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -1224,18 +1222,17 @@ void MathPowStub::Generate(MacroAssembler* masm) {
if (masm->emit_debug_code()) { if (masm->emit_debug_code()) {
UseScratchRegisterScope temps(masm); UseScratchRegisterScope temps(masm);
Register temp = temps.AcquireX(); Register temp = temps.AcquireX();
// d5 zero_double The value +0.0 as a double. __ Fneg(scratch0_double, fp_zero);
__ Fneg(scratch0_double, zero_double);
// Verify that we correctly generated +0.0 and -0.0. // Verify that we correctly generated +0.0 and -0.0.
// bits(+0.0) = 0x0000000000000000 // bits(+0.0) = 0x0000000000000000
// bits(-0.0) = 0x8000000000000000 // bits(-0.0) = 0x8000000000000000
__ Fmov(temp, zero_double); __ Fmov(temp, fp_zero);
__ CheckRegisterIsClear(temp, kCouldNotGenerateZero); __ CheckRegisterIsClear(temp, kCouldNotGenerateZero);
__ Fmov(temp, scratch0_double); __ Fmov(temp, scratch0_double);
__ Eor(temp, temp, kDSignMask); __ Eor(temp, temp, kDSignMask);
__ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero); __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero);
// Check that -0.0 + 0.0 == +0.0. // Check that -0.0 + 0.0 == +0.0.
__ Fadd(scratch0_double, scratch0_double, zero_double); __ Fadd(scratch0_double, scratch0_double, fp_zero);
__ Fmov(temp, scratch0_double); __ Fmov(temp, scratch0_double);
__ CheckRegisterIsClear(temp, kExpectedPositiveZero); __ CheckRegisterIsClear(temp, kExpectedPositiveZero);
} }
...@@ -1793,6 +1790,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { ...@@ -1793,6 +1790,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
ProfileEntryHookStub::MaybeCallEntryHook(masm); ProfileEntryHookStub::MaybeCallEntryHook(masm);
// Set up the reserved register for 0.0.
__ Fmov(fp_zero, 0.0);
// Build an entry frame (see layout below). // Build an entry frame (see layout below).
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
......
...@@ -546,13 +546,11 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, ...@@ -546,13 +546,11 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
// Continue the common case first. 'mi' tests N == 1. // Continue the common case first. 'mi' tests N == 1.
__ B(&result_is_finite_non_zero, mi); __ B(&result_is_finite_non_zero, mi);
// TODO(jbramley): Add (and use) a zero D register for A64.
// TODO(jbramley): Consider adding a +infinity register for A64. // TODO(jbramley): Consider adding a +infinity register for A64.
__ Ldr(double_temp2, ExpConstant(constants, 2)); // Synthesize +infinity. __ Ldr(double_temp2, ExpConstant(constants, 2)); // Synthesize +infinity.
__ Fsub(double_temp1, double_temp1, double_temp1); // Synthesize +0.0.
// Select between +0.0 and +infinity. 'lo' tests C == 0. // Select between +0.0 and +infinity. 'lo' tests C == 0.
__ Fcsel(result, double_temp1, double_temp2, lo); __ Fcsel(result, fp_zero, double_temp2, lo);
// Select between {+0.0 or +infinity} and input. 'vc' tests V == 0. // Select between {+0.0 or +infinity} and input. 'vc' tests V == 0.
__ Fcsel(result, result, input, vc); __ Fcsel(result, result, input, vc);
__ B(&done); __ B(&done);
......
...@@ -149,7 +149,7 @@ void Deoptimizer::EntryGenerator::Generate() { ...@@ -149,7 +149,7 @@ void Deoptimizer::EntryGenerator::Generate() {
// Save all allocatable floating point registers. // Save all allocatable floating point registers.
CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSize, CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSize,
0, FPRegister::NumAllocatableRegisters() - 1); FPRegister::kAllocatableFPRegisters);
__ PushCPURegList(saved_fp_registers); __ PushCPURegList(saved_fp_registers);
// We save all the registers expcept jssp, sp and lr. // We save all the registers expcept jssp, sp and lr.
......
...@@ -3979,9 +3979,7 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { ...@@ -3979,9 +3979,7 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
__ B(&done, eq); __ B(&done, eq);
// Add +0.0 to convert -0.0 to +0.0. // Add +0.0 to convert -0.0 to +0.0.
// TODO(jbramley): A constant zero register would be helpful here. __ Fadd(double_scratch(), input, fp_zero);
__ Fmov(double_scratch(), 0.0);
__ Fadd(double_scratch(), input, double_scratch());
__ Fsqrt(result, double_scratch()); __ Fsqrt(result, double_scratch());
__ Bind(&done); __ Bind(&done);
......
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