avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AW: [avr-gcc-list] miscompilation: save/restore of clobbered registers


From: Haase Bjoern (PT-BEU/EMT) *
Subject: AW: [avr-gcc-list] miscompilation: save/restore of clobbered registers
Date: Tue, 12 Jul 2005 09:31:51 +0200

Hi,

This is not a bug! It is done by purpose. Avr-gcc has a calling convention that 
says that any function may freely change the content of all so call "call used" 
registers. Only the remaining registers will prerve their values after a 
function call.

Excerpt of avr.h:

#define CALL_USED_REGISTERS {                   \
  1,1,/* r0 r1 */                               \
    0,0,/* r2 r3 */                             \
    0,0,/* r4 r5 */                             \
    0,0,/* r6 r7 */                             \
    0,0,/* r8 r9 */                             \
    0,0,/* r10 r11 */                           \
    0,0,/* r12 r13 */                           \
    0,0,/* r14 r15 */                           \
    0,0,/* r16 r17 */                           \
    1,1,/* r18 r19 */                           \
    1,1,/* r20 r21 */                           \
    1,1,/* r22 r23 */                           \
    1,1,/* r24 r25 */                           \
    1,1,/* r26 r27 */                           \
    0,0,/* r28 r29 */                           \
    1,1,/* r30 r31 */                           \
    1,1,/*  STACK */                            \
    1,1 /* arg pointer */  }
 
In case that you need by accident that your function saves *all* registers, you 
could add __attribute__ ((signal)) to your function's declaration. I.e.

u4 sram_read_u4( u1 *ptr ) __attribute__ ((signal));

u4 sram_read_u4( u1 *ptr )
{
    return (((u4) *ptr) << 24)
         | (((u4) *(ptr + 1)) << 16)
         | (((u4) *(ptr + 2)) << 8)
         | (((u4) *(ptr + 3)));
}

HTH,

Björn

-----Ursprüngliche Nachricht-----
Von: address@hidden [mailto:address@hidden Im Auftrag von Jeyasankar Kottalam
Gesendet: Montag, 11. Juli 2005 23:44
An: address@hidden
Betreff: [avr-gcc-list] miscompilation: save/restore of clobbered registers

Hello,

With GCC 3.4.4 and 4.0.0 the following code is miscompiled; registers that the
function modifies are not saved and restored when entering/leaving the
function. We worked around the issue by adding explicit pushes and pops of
registers r16 through r19 in our code.

typedef unsigned char u1;
typedef unsigned long u4;

u4 sram_read_u4( u1 *ptr )
{
    return (((u4) *ptr) << 24)
         | (((u4) *(ptr + 1)) << 16)
         | (((u4) *(ptr + 2)) << 8)
         | (((u4) *(ptr + 3)));
}

I've attached the output of GCC 4.0.0 with "-mmcu=atmega128", but the problem is
 present in 3.4.4 as well, and also present with or without optimization.

I briefly looked into the problem and it looks like the problem lies in
avr_regs_to_save() determining which registers should be saved and restored by
the prologue/epilogue.

Thanks,
-Jey Kottalam



_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list







reply via email to

[Prev in Thread] Current Thread [Next in Thread]