Revision: 18836
Author:   [email protected]
Date:     Fri Jan 24 16:02:19 2014 UTC
Log: A64: Preserve/restore the FP registers in the exit frame when required.

BUG=none
[email protected]

Review URL: https://codereview.chromium.org/146883002
http://code.google.com/p/v8/source/detail?r=18836

Modified:
 /branches/experimental/a64/src/a64/frames-a64.h
 /branches/experimental/a64/src/a64/macro-assembler-a64.cc
 /branches/experimental/a64/src/a64/macro-assembler-a64.h

=======================================
--- /branches/experimental/a64/src/a64/frames-a64.h Wed Jan 22 12:46:44 2014 UTC +++ /branches/experimental/a64/src/a64/frames-a64.h Fri Jan 24 16:02:19 2014 UTC
@@ -61,12 +61,12 @@

 class ExitFrameConstants : public AllStatic {
  public:
-  static const int kCallerSPDisplacement  =  2 * kPointerSize;
-  static const int kCallerPCOffset        =  1 * kPointerSize;
-  static const int kCallerFPOffset        =  0 * kPointerSize;   // <- fp
-  static const int kSPOffset              = -1 * kPointerSize;
-  static const int kCodeOffset            = -2 * kPointerSize;
-  static const int kCallerSavedRegsOffset = -3 * kPointerSize;
+  static const int kCallerSPDisplacement =  2 * kPointerSize;
+  static const int kCallerPCOffset       =  1 * kPointerSize;
+  static const int kCallerFPOffset       =  0 * kPointerSize;   // <- fp
+  static const int kSPOffset             = -1 * kPointerSize;
+  static const int kCodeOffset           = -2 * kPointerSize;
+  static const int kLastExitFrameField   = kCodeOffset;
 };


=======================================
--- /branches/experimental/a64/src/a64/macro-assembler-a64.cc Fri Jan 24 14:09:40 2014 UTC +++ /branches/experimental/a64/src/a64/macro-assembler-a64.cc Fri Jan 24 16:02:19 2014 UTC
@@ -1275,9 +1275,7 @@
   Mov(x0, function->nargs);
   Mov(x1, Operand(ExternalReference(function, isolate())));

- // TODO(all): Here we should ask CEntryStub to save floating point registers
-  // but this is not supported at the moment.
-  CEntryStub stub(1);
+  CEntryStub stub(1, kSaveFPRegs);
   CallStub(&stub);
 }

@@ -2627,6 +2625,27 @@
   AssertStackConsistency();
   Pop(fp, lr);
 }
+
+
+void MacroAssembler::ExitFramePreserveFPRegs() {
+  PushCPURegList(kCallerSavedFP);
+}
+
+
+void MacroAssembler::ExitFrameRestoreFPRegs() {
+ // Read the registers from the stack without popping them. The stack pointer
+  // will be reset as part of the unwinding process.
+  CPURegList saved_fp_regs = kCallerSavedFP;
+  ASSERT(saved_fp_regs.Count() % 2 == 0);
+
+  int offset = ExitFrameConstants::kLastExitFrameField;
+  while (!saved_fp_regs.IsEmpty()) {
+    const CPURegister& dst0 = saved_fp_regs.PopHighestIndex();
+    const CPURegister& dst1 = saved_fp_regs.PopHighestIndex();
+    offset -= 2 * kDRegSizeInBytes;
+    Ldp(dst1, dst0, MemOperand(fp, offset));
+  }
+}


 // TODO(jbramley): Check that we're handling FP correctly [GOOGJSE-33].
@@ -2659,9 +2678,10 @@
                                          isolate())));
   Str(cp, MemOperand(scratch));

+  STATIC_ASSERT((-2 * kPointerSize) ==
+                ExitFrameConstants::kLastExitFrameField);
   if (save_doubles) {
-    // TODO(jbramley): Implement kSaveFPRegs. It is only used by Lithium.
-    TODO_UNIMPLEMENTED("EnterExitFrame: save_doubles");
+    ExitFramePreserveFPRegs();
   }

   // Reserve space for the return address and for user requested memory.
@@ -2672,11 +2692,9 @@
   //   fp -> fp[0]: CallerFP (old fp)
   //         fp[-8]: Space reserved for SPOffset.
   //         fp[-16]: CodeObject()
- // jssp[8 + extra_space * 8]: Saved doubles (if save_doubles is true).
+  //         jssp[-16 - fp_size]: Saved doubles (if save_doubles is true).
// jssp[8]: Extra space reserved for caller (if extra_space != 0).
   // jssp -> jssp[0]: Space reserved for the return address.
-  STATIC_ASSERT((-3 * kPointerSize) ==
-                ExitFrameConstants::kCallerSavedRegsOffset);

   // Align and synchronize the system stack pointer with jssp.
   AlignAndSetCSPForFrame();
@@ -2706,8 +2724,7 @@
   ASSERT(csp.Is(StackPointer()));

   if (restore_doubles) {
-    // TODO(jbramley): Implement kSaveFPRegs. It is only used by Lithium.
-    TODO_UNIMPLEMENTED("LeaveExitFrame: restore_doubles");
+    ExitFrameRestoreFPRegs();
   }

   // Restore the context pointer from the top frame.
=======================================
--- /branches/experimental/a64/src/a64/macro-assembler-a64.h Fri Jan 24 14:09:40 2014 UTC +++ /branches/experimental/a64/src/a64/macro-assembler-a64.h Fri Jan 24 16:02:19 2014 UTC
@@ -1493,6 +1493,12 @@
                                         Register scratch1,
                                         Register scratch2);

+ // The stack pointer has to switch between csp and jssp when setting up and
+  // destroying the exit frame. Hence preserving/restoring the registers is
+  // slightly more complicated than simple push/pop operations.
+  void ExitFramePreserveFPRegs();
+  void ExitFrameRestoreFPRegs();
+
// Enter exit frame. Exit frames are used when calling C code from generated
   // (JavaScript) code.
   //
@@ -1510,7 +1516,7 @@
   //   fp -> fp[0]: CallerFP (old fp)
   //         fp[-8]: SPOffset (new csp)
   //         fp[-16]: CodeObject()
-  //         csp[...]: Saved doubles, if saved_doubles is true.
+  //         fp[-16 - fp-size]: Saved doubles, if saved_doubles is true.
   //         csp[8]: Memory reserved for the caller if extra_space != 0.
   //                 Alignment padding, if necessary.
   //  csp -> csp[0]: Space reserved for the return address.

--
--
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/groups/opt_out.

Reply via email to