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.