Author: [email protected]
Date: Tue May 12 13:11:01 2009
New Revision: 1922
Modified:
branches/bleeding_edge/src/arm/assembler-arm.h
branches/bleeding_edge/src/arm/macro-assembler-arm.cc
branches/bleeding_edge/src/platform-linux.cc
Log:
Fix fp problems in runtime code on ARM EABI by 8-byte aligning
the stack on exit to C.
Review URL: http://codereview.chromium.org/115256
Modified: branches/bleeding_edge/src/arm/assembler-arm.h
==============================================================================
--- branches/bleeding_edge/src/arm/assembler-arm.h (original)
+++ branches/bleeding_edge/src/arm/assembler-arm.h Tue May 12 13:11:01 2009
@@ -622,8 +622,8 @@
// Pseudo instructions
void nop() { mov(r0, Operand(r0)); }
- void push(Register src) {
- str(src, MemOperand(sp, 4, NegPreIndex), al);
+ void push(Register src, Condition cond = al) {
+ str(src, MemOperand(sp, 4, NegPreIndex), cond);
}
void pop(Register dst) {
Modified: branches/bleeding_edge/src/arm/macro-assembler-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/macro-assembler-arm.cc (original)
+++ branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 12
13:11:01 2009
@@ -291,6 +291,12 @@
void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
+
+ // Compute the argv pointer and keep it in a callee-saved register.
+ // r0 is argc.
+ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
+ sub(r6, r6, Operand(kPointerSize));
+
// Compute parameter pointer before making changes and save it as ip
// register so that it is restored as sp register on exit, thereby
// popping the args.
@@ -298,6 +304,17 @@
// ip = sp + kPointerSize * #args;
add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
+ // Align the stack at this point. After this point we have 5 pushes,
+ // so in fact we have to unalign here! See also the assert on the
+ // alignment immediately below.
+ if (OS::ActivationFrameAlignment() != kPointerSize) {
+ // This code needs to be made more general if this assert doesn't hold.
+ ASSERT(OS::ActivationFrameAlignment() == 2 * kPointerSize);
+ mov(r7, Operand(Smi::FromInt(0)));
+ tst(sp, Operand(OS::ActivationFrameAlignment() - 1));
+ push(r7, eq); // Conditional push instruction.
+ }
+
// Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
mov(fp, Operand(sp)); // setup new frame pointer
@@ -316,9 +333,6 @@
mov(r4, Operand(r0));
mov(r5, Operand(r1));
- // Compute the argv pointer and keep it in a callee-saved register.
- add(r6, fp, Operand(r4, LSL, kPointerSizeLog2));
- add(r6, r6, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize));
#ifdef ENABLE_DEBUGGER_SUPPORT
// Save the state of all registers to the stack from the memory
Modified: branches/bleeding_edge/src/platform-linux.cc
==============================================================================
--- branches/bleeding_edge/src/platform-linux.cc (original)
+++ branches/bleeding_edge/src/platform-linux.cc Tue May 12 13:11:01 2009
@@ -88,6 +88,8 @@
int OS::ActivationFrameAlignment() {
// Floating point code runs faster if the stack is 8-byte aligned.
+ // On EABI ARM targets this is required for fp correctness in the
+ // runtime system.
return 8;
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---