This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with ARM_DOUBLEWORD_ALIGN on ARM


On Nov 21, 2007, at 16:34, Daniel Jacobowitz wrote:
>Did you mean to send this to the list?  If so, feel free to reply
>there.
Indeed, I did. I now Cc-ed the list as well.
>>Here's the first few lines of a-textio.adb disassembly:
>>Dump of assembler code for function ada__text_io__put_line:
>>0x800150ac <ada__text_io__put_line+0>:  mov     r12, sp
>>0x800150b0 <ada__text_io__put_line+4>:  stmdb   sp!, {r4, r5, r6, r7, r8, r9, 
>>r10, r11, r12, lr, pc}
>>0x800150b4 <ada__text_io__put_line+8>:  sub     r11, r12, #4    ; 0x4
>>0x800150b8 <ada__text_io__put_line+12>: sub     sp, sp, #20     ; 0x14
>>
>>So, stack pointer is not properly aligned.

>Sure it's aligned.  The stmdb decrements it by 11 * 4, the sub
>decrements it by 5 * 4, that adds up to a nice 16 * 4 frame size.

Ah, I missed that. Turns out the (or: at least one) problem was 
with nested functions indeed. See below for a rough patch against
GCC 4.1 that seems to fix the issue we're seeing (thanks
Richard, for the help). However,  we're not quite sure if this is
right.  If you or other ARM-knowledgeable people have any feedback,
that would be most welcome. I'll then make an updated patch against
head and submit for review after testing etc.

>>I guess, the biggest question is how things are supposed
>>to work and what the invariants are that should be kept to ensure
>>proper stack aligment.

>I can't answer this for you, except that our extensive arm-eabi and
>arm-linux-gnueabi testing has not turned up problems with this
>alignment in quite a while, so it mostly does work.

Nested functions aren't used that much in C indeed... :)

  -Geert

--- arm.c.orig  2007-11-20 16:27:04.000000000 -0500
+++ arm.c       2007-11-21 18:15:18.000000000 -0500
@@ -10448,6 +10448,14 @@ arm_get_frame_offsets (void)
   /* Saved registers include the stack frame.  */
   offsets->saved_regs = offsets->saved_args + saved;
   offsets->soft_frame = offsets->saved_regs + CALLER_INTERWORKING_SLOT_SIZE;
+
+  /* Allow for storage of static chain when it needs its own space in the
+     frame. */
+  if (IS_NESTED (arm_current_func_type ())
+      && regs_ever_live[3]
+      && offsets->saved_args == 0)
+    offsets->soft_frame += 4;
+
   /* A leaf function does not need any stack alignment if it has nothing
      on the stack.  */
   if (leaf && frame_size == 0)
@@ -10569,6 +10577,7 @@ arm_expand_prologue (void)
   unsigned long live_regs_mask;
   unsigned long func_type;
   int fp_offset = 0;
+  int static_chain_size = 0;
   int saved_pretend_args = 0;
   int saved_regs = 0;
   unsigned HOST_WIDE_INT args_to_push;
@@ -10643,6 +10652,7 @@ arm_expand_prologue (void)
              insn = emit_insn (insn);
 
              fp_offset = 4;
+             static_chain_size = 4;
 
              /* Just tell the dwarf backend that we adjusted SP.  */
              dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
@@ -10836,14 +10846,15 @@ arm_expand_prologue (void)
     }
 
   offsets = arm_get_frame_offsets ();
-  if (offsets->outgoing_args != offsets->saved_args + saved_regs)
+  if (offsets->outgoing_args != offsets->saved_args + saved_regs
+      + static_chain_size)
     {
       /* This add can produce multiple insns for a large constant, so we
         need to get tricky.  */
       rtx last = get_last_insn ();
 
       amount = GEN_INT (offsets->saved_args + saved_regs
-                       - offsets->outgoing_args);
+                        + static_chain_size - offsets->outgoing_args);
 
       insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
                                    amount));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]