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