https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677

--- Comment #5 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
Maybe -fno-caller-saves is what you are looking for?

Here is a C test case guessed from your first code snipped:

typedef struct
{
    unsigned char x, y;
} point;

extern void printSpeed (long, unsigned char);
extern long cnvGroundSpeed (void);

void panVel (point p)
{
    printSpeed (cnvGroundSpeed(), p.y & 0x40);
}

compiled with avr-gcc 5.x

$ avr-gcc -S -Os

we'll get

panVel:
        push   r28
        push   r29
        push   __zero_reg__
        in r28,__SP_L__
        in r29,__SP_H__

        mov   r20,r25
        andi  r20,lo8(64)
        std   Y+1,r20
        rcall cnvGroundSpeed
        ldd   r20,Y+1

        pop   __tmp_reg__
        pop   r29
        pop   r28
        rjmp  printSpeed


Adding -fno-caller-saves:

panVel:
        push  r28

        mov   r28,r25
        andi  r28,lo8(64)
        rcall cnvGroundSpeed
        mov   r20,r28

        pop   r28
        rjmp  printSpeed


I actually don't know whether this is a flaw in the avr backend (like a cost
issue) or wrong assumptions in the middle-end.  Saving / Restoring in the frame
is actually not more costly than saving in a call-saved register;  what makes
it expensive is the frame setup in prologue and epilogue...

Reply via email to