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

Reply via email to