Reviewers: jochen, ulan,

Message:
PTAL

Description:
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.

[email protected], [email protected]

Please review this at https://codereview.chromium.org/190663009/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+51, -31 lines):
  M src/a64/assembler-a64.h
  M src/a64/code-stubs-a64.cc
  M src/a64/codegen-a64.cc
  M src/a64/deoptimizer-a64.cc
  M src/a64/lithium-codegen-a64.cc


Index: src/a64/assembler-a64.h
diff --git a/src/a64/assembler-a64.h b/src/a64/assembler-a64.h
index 09a8a72014d9c7885266576e35094c6b60926e23..bf115b446648368d1e5398cdb0914719837db381 100644
--- a/src/a64/assembler-a64.h
+++ b/src/a64/assembler-a64.h
@@ -264,36 +264,60 @@ struct FPRegister : public CPURegister {
   static const int kMaxNumRegisters = kNumberOfFPRegisters;

   // Crankshaft can use all the FP registers except:
-  //   - d29 which is used in crankshaft as a double scratch register
-  //   - d30 which is used to keep the 0 double value
+  //   - d15 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
-  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 =
-      kNumberOfFPRegisters - kNumReservedRegisters;
+      (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) +
+      (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1);
static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
-  static const RegList kAllocatableFPRegisters =
-      (1 << kMaxNumAllocatableRegisters) - 1;

-  static FPRegister FromAllocationIndex(int index) {
-    ASSERT((index >= 0) && (index < NumAllocatableRegisters()));
-    return from_code(index);
+  // Return true if the register is one that crankshaft can allocate.
+  bool IsAllocatable() const {
+    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) {
     ASSERT((index >= 0) && (index < NumAllocatableRegisters()));
+    ASSERT((kAllocatableLowRangeBegin == 0) &&
+           (kAllocatableLowRangeEnd == 14) &&
+           (kAllocatableHighRangeBegin == 16) &&
+           (kAllocatableHighRangeEnd == 29));
     const char* const names[] = {
       "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",
-      "d24", "d25", "d26", "d27", "d28",
+      "d24", "d25", "d26", "d27", "d28", "d29"
     };
     return names[index];
   }

   static int ToAllocationIndex(FPRegister reg) {
-    int code = reg.code();
-    ASSERT(code < NumAllocatableRegisters());
-    return code;
+    ASSERT(reg.IsAllocatable());
+    unsigned code = reg.code();
+
+    return (code <= kAllocatableLowRangeEnd)
+        ? code
+        : code - kAllocatableRangeGapSize;
   }

   static FPRegister from_code(int code) {
@@ -375,10 +399,10 @@ ALIAS_REGISTER(Register, lr, x30);
 ALIAS_REGISTER(Register, xzr, x31);
 ALIAS_REGISTER(Register, wzr, w31);

-// Crankshaft double scratch register.
-ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29);
 // 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.
 ALIAS_REGISTER(FPRegister, fp_scratch, d31);

Index: src/a64/code-stubs-a64.cc
diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc
index 2b472da6484d351bc4e01f74ff470e6d72e32169..5b1b688cc9689123b2aadfeaef88e2ec6b31e166 100644
--- a/src/a64/code-stubs-a64.cc
+++ b/src/a64/code-stubs-a64.cc
@@ -1182,7 +1182,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
     if (exponent_type_ == ON_STACK) {
       FPRegister  half_double = d3;
       FPRegister  minus_half_double = d4;
-      FPRegister  zero_double = d5;
// Detect square root case. Crankshaft detects constant +/-0.5 at compile
       // time and uses DoMathPowHalf instead. We then skip this check for
       // non-constant cases of +/-0.5 as these hardly occur.
@@ -1215,26 +1214,24 @@ void MathPowStub::Generate(MacroAssembler* masm) {
       // where base is -INFINITY or -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, zero_double);
+      __ Fadd(base_double, base_double, fp_zero);
       // The operation -0+0 results in +0 in all cases except where the
       // FPCR rounding mode is 'round towards minus infinity' (RM). The
       // A64 simulator does not currently simulate FPCR (where the rounding
       // mode is set), so test the operation with some debug code.
       if (masm->emit_debug_code()) {
         Register temp = masm->Tmp1();
-        //  d5  zero_double   The value +0.0 as a double.
-        __ Fneg(scratch0_double, zero_double);
+        __ Fneg(scratch0_double, fp_zero);
         // Verify that we correctly generated +0.0 and -0.0.
         //  bits(+0.0) = 0x0000000000000000
         //  bits(-0.0) = 0x8000000000000000
-        __ Fmov(temp, zero_double);
+        __ Fmov(temp, fp_zero);
         __ CheckRegisterIsClear(temp, kCouldNotGenerateZero);
         __ Fmov(temp, scratch0_double);
         __ Eor(temp, temp, kDSignMask);
         __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero);
         // 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);
         __ CheckRegisterIsClear(temp, kExpectedPositiveZero);
       }
@@ -1791,6 +1788,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {

   ProfileEntryHookStub::MaybeCallEntryHook(masm);

+  // Set up the reserved register for 0.0.
+  __ Fmov(fp_zero, 0.0);
+
   // Build an entry frame (see layout below).
   Isolate* isolate = masm->isolate();

Index: src/a64/codegen-a64.cc
diff --git a/src/a64/codegen-a64.cc b/src/a64/codegen-a64.cc
index f0084947e049cf6d02346c75edecf0fdf091d767..6a2fa5bd5dcdbe04e203a49a56096069036d2d05 100644
--- a/src/a64/codegen-a64.cc
+++ b/src/a64/codegen-a64.cc
@@ -546,13 +546,11 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
   // Continue the common case first. 'mi' tests N == 1.
   __ 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.
__ 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.
-  __ 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.
   __ Fcsel(result, result, input, vc);
   __ B(&done);
Index: src/a64/deoptimizer-a64.cc
diff --git a/src/a64/deoptimizer-a64.cc b/src/a64/deoptimizer-a64.cc
index 40e3191fe9018f67a3098791cb73f4b71ae8a18c..57c30b2eee6da4076e45a98eef174ab37fb0de20 100644
--- a/src/a64/deoptimizer-a64.cc
+++ b/src/a64/deoptimizer-a64.cc
@@ -149,7 +149,7 @@ void Deoptimizer::EntryGenerator::Generate() {

   // Save all allocatable floating point registers.
   CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSize,
- 0, FPRegister::NumAllocatableRegisters() - 1);
+                                FPRegister::kAllocatableFPRegisters);
   __ PushCPURegList(saved_fp_registers);

   // We save all the registers expcept jssp, sp and lr.
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index 8e443b9fb086bc82bec5593c1ddd79e87fddff5c..5a7abda66275437d57a81c572957373c54682431 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -3917,9 +3917,7 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
   __ B(&done, eq);

   // Add +0.0 to convert -0.0 to +0.0.
-  // TODO(jbramley): A constant zero register would be helpful here.
-  __ Fmov(double_scratch(), 0.0);
-  __ Fadd(double_scratch(), input, double_scratch());
+  __ Fadd(double_scratch(), input, fp_zero);
   __ Fsqrt(result, double_scratch());

   __ Bind(&done);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to