PPC: Clean up register save/restore logic.
authormbrandy <mbrandy@us.ibm.com>
Mon, 3 Aug 2015 14:36:43 +0000 (07:36 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 3 Aug 2015 14:36:56 +0000 (14:36 +0000)
NOPRESUBMIT=true
R=titzer@chromium.org, michael_dawson@ca.ibm.com, jyan@ca.ibm.com, joransiu@ca.ibm.com
BUG=

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

Cr-Commit-Position: refs/heads/master@{#29978}

src/compiler/c-linkage.cc
src/compiler/ppc/code-generator-ppc.cc
src/ppc/code-stubs-ppc.cc
src/ppc/code-stubs-ppc.h
src/ppc/frames-ppc.h
src/ppc/macro-assembler-ppc.cc
src/ppc/macro-assembler-ppc.h
src/ppc/regexp-macro-assembler-ppc.cc

index d261d78..61b3ee3 100644 (file)
@@ -138,7 +138,11 @@ LinkageLocation stackloc(int i) {
 #define CALLEE_SAVE_REGISTERS                                                 \
   r14.bit() | r15.bit() | r16.bit() | r17.bit() | r18.bit() | r19.bit() |     \
       r20.bit() | r21.bit() | r22.bit() | r23.bit() | r24.bit() | r25.bit() | \
-      r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit() | fp.bit()
+      r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit()
+#define CALLEE_SAVE_FP_REGISTERS                                              \
+  d14.bit() | d15.bit() | d16.bit() | d17.bit() | d18.bit() | d19.bit() |     \
+      d20.bit() | d21.bit() | d22.bit() | d23.bit() | d24.bit() | d25.bit() | \
+      d26.bit() | d27.bit() | d28.bit() | d29.bit() | d30.bit() | d31.bit()
 
 #else
 // ===========================================================================
index 3d91e68..4e9f99f 100644 (file)
@@ -1296,27 +1296,34 @@ void CodeGenerator::AssemblePrologue() {
   int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ function_descriptor();
-    int register_save_area_size = 0;
-    RegList frame_saves = fp.bit();
+    RegList frame_saves = 0;
     __ mflr(r0);
     if (FLAG_enable_embedded_constant_pool) {
       __ Push(r0, fp, kConstantPoolRegister);
       // Adjust FP to point to saved FP.
       __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
-      register_save_area_size += kPointerSize;
       frame_saves |= kConstantPoolRegister.bit();
     } else {
       __ Push(r0, fp);
       __ mr(fp, sp);
     }
+
     // Save callee-saved registers.
     const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves;
-    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-      if (!((1 << i) & saves)) continue;
-      register_save_area_size += kPointerSize;
-    }
-    frame()->SetRegisterSaveAreaSize(register_save_area_size);
     __ MultiPush(saves);
+    // register save area does not include the fp.
+    DCHECK(kNumCalleeSaved - 1 ==
+           base::bits::CountPopulation32(saves | frame_saves));
+    int register_save_area_size = (kNumCalleeSaved - 1) * kPointerSize;
+
+    // Save callee-saved Double registers.
+    const RegList double_saves = descriptor->CalleeSavedFPRegisters();
+    __ MultiPushDoubles(double_saves);
+    DCHECK(kNumCalleeSavedDoubles ==
+           base::bits::CountPopulation32(double_saves));
+    register_save_area_size += kNumCalleeSavedDoubles * kDoubleSize;
+
+    frame()->SetRegisterSaveAreaSize(register_save_area_size);
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
@@ -1359,15 +1366,17 @@ void CodeGenerator::AssembleReturn() {
       if (stack_slots > 0) {
         __ Add(sp, sp, stack_slots * kPointerSize, r0);
       }
+      // Restore double registers.
+      const RegList double_saves = descriptor->CalleeSavedFPRegisters();
+      __ MultiPopDoubles(double_saves);
+
       // Restore registers.
-      RegList frame_saves = fp.bit();
+      RegList frame_saves = 0;
       if (FLAG_enable_embedded_constant_pool) {
         frame_saves |= kConstantPoolRegister.bit();
       }
       const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves;
-      if (saves != 0) {
-        __ MultiPop(saves);
-      }
+      __ MultiPop(saves);
     }
     __ LeaveFrame(StackFrame::MANUAL);
     __ Ret();
index 35e9f29..13e0948 100644 (file)
@@ -749,7 +749,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
   __ mflr(r0);
   __ MultiPush(kJSCallerSaved | r0.bit());
   if (save_doubles()) {
-    __ SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+    __ MultiPushDoubles(kCallerSavedDoubles);
   }
   const int argument_count = 1;
   const int fp_argument_count = 0;
@@ -761,7 +761,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
   __ CallCFunction(ExternalReference::store_buffer_overflow_function(isolate()),
                    argument_count);
   if (save_doubles()) {
-    __ RestoreFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+    __ MultiPopDoubles(kCallerSavedDoubles);
   }
   __ MultiPop(kJSCallerSaved | r0.bit());
   __ mtlr(r0);
@@ -1234,11 +1234,10 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
   // Save callee saved registers on the stack.
   __ MultiPush(kCalleeSaved);
 
-  // Floating point regs FPR0 - FRP13 are volatile
-  // FPR14-FPR31 are non-volatile, but sub-calls will save them for us
-
-  //  int offset_to_argv = kPointerSize * 22; // matches (22*4) above
-  //  __ lwz(r7, MemOperand(sp, offset_to_argv));
+  // Save callee-saved double registers.
+  __ MultiPushDoubles(kCalleeSavedDoubles);
+  // Set up the reserved register for 0.0.
+  __ LoadDoubleLiteral(kDoubleRegZero, 0.0, r0);
 
   // Push a frame with special values setup to mark it as an entry frame.
   // r3: code entry
@@ -1360,20 +1359,16 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
   // Reset the stack to the callee saved registers.
   __ addi(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
 
-// Restore callee-saved registers and return.
-#ifdef DEBUG
-  if (FLAG_debug_code) {
-    Label here;
-    __ b(&here, SetLK);
-    __ bind(&here);
-  }
-#endif
+  // Restore callee-saved double registers.
+  __ MultiPopDoubles(kCalleeSavedDoubles);
 
+  // Restore callee-saved registers.
   __ MultiPop(kCalleeSaved);
 
+  // Return
   __ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
-  __ mtctr(r0);
-  __ bctr();
+  __ mtlr(r0);
+  __ blr();
 }
 
 
index 3c71a23..238c9f7 100644 (file)
@@ -181,7 +181,7 @@ class RecordWriteStub : public PlatformCodeStub {
       masm->MultiPush(kJSCallerSaved & ~scratch1_.bit());
       if (mode == kSaveFPRegs) {
         // Save all volatile FP registers except d0.
-        masm->SaveFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
+        masm->MultiPushDoubles(kCallerSavedDoubles & ~d0.bit());
       }
     }
 
@@ -189,7 +189,7 @@ class RecordWriteStub : public PlatformCodeStub {
                                            SaveFPRegsMode mode) {
       if (mode == kSaveFPRegs) {
         // Restore all volatile FP registers except d0.
-        masm->RestoreFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
+        masm->MultiPopDoubles(kCallerSavedDoubles & ~d0.bit());
       }
       masm->MultiPop(kJSCallerSaved & ~scratch1_.bit());
       masm->pop(r0);
index 16e86db..d5b6d3c 100644 (file)
@@ -55,6 +55,43 @@ const RegList kCalleeSaved = 1 << 14 |  // r14
 
 const int kNumCalleeSaved = 18;
 
+const RegList kCallerSavedDoubles = 1 << 0 |   // d0
+                                    1 << 1 |   // d1
+                                    1 << 2 |   // d2
+                                    1 << 3 |   // d3
+                                    1 << 4 |   // d4
+                                    1 << 5 |   // d5
+                                    1 << 6 |   // d6
+                                    1 << 7 |   // d7
+                                    1 << 8 |   // d8
+                                    1 << 9 |   // d9
+                                    1 << 10 |  // d10
+                                    1 << 11 |  // d11
+                                    1 << 12 |  // d12
+                                    1 << 13;   // d13
+
+const RegList kCalleeSavedDoubles = 1 << 14 |  // d14
+                                    1 << 15 |  // d15
+                                    1 << 16 |  // d16
+                                    1 << 17 |  // d17
+                                    1 << 18 |  // d18
+                                    1 << 19 |  // d19
+                                    1 << 20 |  // d20
+                                    1 << 21 |  // d21
+                                    1 << 22 |  // d22
+                                    1 << 23 |  // d23
+                                    1 << 24 |  // d24
+                                    1 << 25 |  // d25
+                                    1 << 26 |  // d26
+                                    1 << 27 |  // d27
+                                    1 << 28 |  // d28
+                                    1 << 29 |  // d29
+                                    1 << 30 |  // d30
+                                    1 << 31;   // d31
+
+const int kNumCalleeSavedDoubles = 18;
+
+
 // Number of registers for which space is reserved in safepoints. Must be a
 // multiple of 8.
 const int kNumSafepointRegisters = 32;
index 1598f8f..4ee6323 100644 (file)
@@ -224,30 +224,59 @@ void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
 }
 
 
-void MacroAssembler::MultiPush(RegList regs) {
+void MacroAssembler::MultiPush(RegList regs, Register location) {
   int16_t num_to_push = NumberOfBitsSet(regs);
   int16_t stack_offset = num_to_push * kPointerSize;
 
-  subi(sp, sp, Operand(stack_offset));
-  for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
+  subi(location, location, Operand(stack_offset));
+  for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) {
     if ((regs & (1 << i)) != 0) {
       stack_offset -= kPointerSize;
-      StoreP(ToRegister(i), MemOperand(sp, stack_offset));
+      StoreP(ToRegister(i), MemOperand(location, stack_offset));
     }
   }
 }
 
 
-void MacroAssembler::MultiPop(RegList regs) {
+void MacroAssembler::MultiPop(RegList regs, Register location) {
   int16_t stack_offset = 0;
 
-  for (int16_t i = 0; i < kNumRegisters; i++) {
+  for (int16_t i = 0; i < Register::kNumRegisters; i++) {
     if ((regs & (1 << i)) != 0) {
-      LoadP(ToRegister(i), MemOperand(sp, stack_offset));
+      LoadP(ToRegister(i), MemOperand(location, stack_offset));
       stack_offset += kPointerSize;
     }
   }
-  addi(sp, sp, Operand(stack_offset));
+  addi(location, location, Operand(stack_offset));
+}
+
+
+void MacroAssembler::MultiPushDoubles(RegList dregs, Register location) {
+  int16_t num_to_push = NumberOfBitsSet(dregs);
+  int16_t stack_offset = num_to_push * kDoubleSize;
+
+  subi(location, location, Operand(stack_offset));
+  for (int16_t i = DoubleRegister::kNumRegisters - 1; i >= 0; i--) {
+    if ((dregs & (1 << i)) != 0) {
+      DoubleRegister dreg = DoubleRegister::from_code(i);
+      stack_offset -= kDoubleSize;
+      stfd(dreg, MemOperand(location, stack_offset));
+    }
+  }
+}
+
+
+void MacroAssembler::MultiPopDoubles(RegList dregs, Register location) {
+  int16_t stack_offset = 0;
+
+  for (int16_t i = 0; i < DoubleRegister::kNumRegisters; i++) {
+    if ((dregs & (1 << i)) != 0) {
+      DoubleRegister dreg = DoubleRegister::from_code(i);
+      lfd(dreg, MemOperand(location, stack_offset));
+      stack_offset += kDoubleSize;
+    }
+  }
+  addi(location, location, Operand(stack_offset));
 }
 
 
@@ -825,7 +854,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
 
   // Optionally save all volatile double registers.
   if (save_doubles) {
-    SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+    MultiPushDoubles(kCallerSavedDoubles);
     // Note that d0 will be accessible at
     //   fp - ExitFrameConstants::kFrameSize -
     //   kNumVolatileRegisters * kDoubleSize,
@@ -891,7 +920,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
     const int offset =
         (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize);
     addi(r6, fp, Operand(-offset));
-    RestoreFPRegs(r6, 0, kNumRegs);
+    MultiPopDoubles(kCallerSavedDoubles, r6);
   }
 
   // Clear top frame.
@@ -2955,28 +2984,6 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
 }
 
 
-void MacroAssembler::SaveFPRegs(Register location, int first, int count) {
-  DCHECK(count > 0);
-  int cur = first;
-  subi(location, location, Operand(count * kDoubleSize));
-  for (int i = 0; i < count; i++) {
-    DoubleRegister reg = DoubleRegister::from_code(cur++);
-    stfd(reg, MemOperand(location, i * kDoubleSize));
-  }
-}
-
-
-void MacroAssembler::RestoreFPRegs(Register location, int first, int count) {
-  DCHECK(count > 0);
-  int cur = first + count - 1;
-  for (int i = count - 1; i >= 0; i--) {
-    DoubleRegister reg = DoubleRegister::from_code(cur--);
-    lfd(reg, MemOperand(location, i * kDoubleSize));
-  }
-  addi(location, location, Operand(count * kDoubleSize));
-}
-
-
 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
     Register first, Register second, Register scratch1, Register scratch2,
     Label* failure) {
index 95e98e4..77621e7 100644 (file)
@@ -152,8 +152,11 @@ class MacroAssembler : public Assembler {
   void Move(Register dst, Register src, Condition cond = al);
   void Move(DoubleRegister dst, DoubleRegister src);
 
-  void MultiPush(RegList regs);
-  void MultiPop(RegList regs);
+  void MultiPush(RegList regs, Register location = sp);
+  void MultiPop(RegList regs, Register location = sp);
+
+  void MultiPushDoubles(RegList dregs, Register location = sp);
+  void MultiPopDoubles(RegList dregs, Register location = sp);
 
   // Load an object from the root table.
   void LoadRoot(Register destination, Heap::RootListIndex index,
@@ -888,12 +891,6 @@ class MacroAssembler : public Assembler {
     bind(&label);
   }
 
-  // Pushes <count> double values to <location>, starting from d<first>.
-  void SaveFPRegs(Register location, int first, int count);
-
-  // Pops <count> double values from <location>, starting from d<first>.
-  void RestoreFPRegs(Register location, int first, int count);
-
   // ---------------------------------------------------------------------------
   // Runtime calls
 
index 05e84e4..9e4e9e5 100644 (file)
@@ -171,8 +171,7 @@ void RegExpMacroAssemblerPPC::Backtrack() {
   // Pop Code* offset from backtrack stack, add Code* and jump to location.
   Pop(r3);
   __ add(r3, r3, code_pointer());
-  __ mtctr(r3);
-  __ bctr();
+  __ Jump(r3);
 }
 
 
@@ -834,8 +833,8 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
     // Restore registers r25..r31 and return (restoring lr to pc).
     __ MultiPop(registers_to_retain);
     __ pop(r0);
-    __ mtctr(r0);
-    __ bctr();
+    __ mtlr(r0);
+    __ blr();
 
     // Backtrack code (branch target for conditional backtracks).
     if (backtrack_label_.is_linked()) {