Reviewers: m.m.capewell, jbramley,

Description:
A64: Preserve/restore the FP registers in the exit frame when required.

BUG=none

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

SVN Base: https://v8.googlecode.com/svn/branches/experimental/a64

Affected files (+40, -17 lines):
  M src/a64/frames-a64.h
  M src/a64/macro-assembler-a64.h
  M src/a64/macro-assembler-a64.cc


Index: src/a64/frames-a64.h
diff --git a/src/a64/frames-a64.h b/src/a64/frames-a64.h
index d47f93bc273c1e3bf384aaa1e136f121910d2300..9a0dc4a8a6484e72183a3a831e691edab54351fe 100644
--- a/src/a64/frames-a64.h
+++ b/src/a64/frames-a64.h
@@ -61,12 +61,12 @@ class EntryFrameConstants : public AllStatic {

 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;
 };


Index: src/a64/macro-assembler-a64.cc
diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc
index aec18e72dc9b950ca876ac28a049ffac4c5cd79b..3e715f2b97c188f03044e964ab7e503ab0389951 100644
--- a/src/a64/macro-assembler-a64.cc
+++ b/src/a64/macro-assembler-a64.cc
@@ -1275,9 +1275,7 @@ void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
   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);
 }

@@ -2629,6 +2627,27 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
 }


+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].
 void MacroAssembler::EnterExitFrame(bool save_doubles,
                                     const Register& scratch,
@@ -2659,9 +2678,10 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
                                          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 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
   //   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 @@ void MacroAssembler::LeaveExitFrame(bool restore_doubles,
   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.
Index: src/a64/macro-assembler-a64.h
diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h
index 38d2804991247d297b0edd1146145887ba76f880..8b8783c284e1dae95736b2bc88918a1f6986fa04 100644
--- a/src/a64/macro-assembler-a64.h
+++ b/src/a64/macro-assembler-a64.h
@@ -1493,6 +1493,12 @@ class MacroAssembler : public Assembler {
                                         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 @@ class MacroAssembler : public Assembler {
   //   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