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
-~----------~----~----~----~------~----~------~--~---

Reply via email to