http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56439
Bug #: 56439
Summary: global and local register variables don't work in a
useful way -- AVR
Classification: Unclassified
Product: gcc
Version: 4.7.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rfmerr...@berkeley.edu
I am writing some interrupt code for an Atmel AVR microcontroller and I'm
trying to shave cycles off, specifically at the beginning of the interrupt. I
want to achieve this by minimizing the registers that need to be saved, so I
decided to declare a few variables as global register variables.
What I found is that GCC will "optimize away" the register assignment and
instead produce code that is almost what I want, except it copies the value in
and out of another register (allocated the usual way) instead of operating on
the assigned one.
For example the following C:
register unsigned char foo asm ("r4");
void baz();
void quux();
void bar() {
foo = foo * 2;
if (foo > 10)
baz();
else
quux();
}
generates the following assembly:
mov r24,r4
lsl r24
mov r4,r24
cpi r24,lo8(11)
brsh .L4
rjmp quux
.L4:
rjmp baz
It does the same thing (copy to r24, manipulate, copy back) on every
optimization level.
Surely this can't be desired behavior? If you use local register variables it's
often even worse, as gcc won't touch the assigned register at all but instead
produce identical code that uses a different register.
I'm fairly certain this shouldn't work this way...