[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] Missing compiler optimizations?
From: |
Nigel Winterbottom |
Subject: |
RE: [avr-gcc-list] Missing compiler optimizations? |
Date: |
Mon, 23 Jan 2006 14:53:42 +0100 (CET) |
Hi Erik,
> Right off the bat the compiler is making use of mostly low registers,
> as well as Y (r29:r28), all of which have to be saved.
> Why isn't it using the high registers that are caller-saved
> (r18-r27, r30-r31) instead, and saving more than a third of
> the code size and half the cycle count just in the push/pops?
Watch out. Registers (r18-r27, r30-r31) ARE trashable by any function.
Because you call "bootloader_eeprom_read_byte", that too is allowed to
trash these registers. You cannot use (r18-r27, r30-r31) for variables
which "live" across a function call, unless of course you "push/pop" around
that function call.
avr-gcc seems to prefer using the non-clobbered (lower) registers which is
what you have seen in your example.
> Because the compiler stores things in low registers, it has to use
> subi+subc of 0xffff just to increment the pointer by one.
> adiw works if you use the top 4 pairs of registers, 3 of which are
> conveniently caller-saved.
Incorrect. Only Y (r28/r29) is saved.
> In other cases I've seen all kinds of relatively common idioms get
> translated very poorly. A classic one is constructing a word
> from two bytes, which in my case happens as TWI interrupts feed them
> to me one at a time:
>
> w = b | (c<<8);
> 68: 99 27 eor r25, r25
> 6a: 33 27 eor r19, r19
> 6c: 32 2f mov r19, r18
> 6e: 22 27 eor r18, r18
> 70: 82 2b or r24, r18
> 72: 93 2b or r25, r19
Try this macro:
#define HILOTO16(hi, lo) ({ \
unsigned int __result; \
__asm__ ( " mov %B0,%1 \n" : "=r" (__result) : "r" (hi), "0" (lo) ); \
__result; })
e.g. w = HILOTO16(c, b);
This gives optimal code and should cause a different compiler to complain,
thereby highlighting the non portability.
Regards
Nigel Winterbottom