http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58390

            Bug ID: 58390
           Summary: avr-gcc produces unusable code when label address is
                    placed in register
           Product: gcc
           Version: 4.7.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: semicontinuity at yandex dot ru

Trying to speed up the following code, I've placed 'address' variable to the
r2:r3 (and added -ffixed-r2 -ffixed-r3):

// -------------------------------------------------------------------------
//void* address; // placed in memory (OK)
//register void* address asm("r30"); // placed in r30:r31 (OK)
register void* address asm("r2");  // placed in r2:r3 or any other register
(NOT OK)

void test(void) {
    char flag = 1;

    goto *address; // address is computed properly beforehand

    for(;;) {

    asm volatile("nop\t\n");


    flag = 0;
L1: (void)&&L1;
    if (flag==0) { address = &&L1; return; }

    asm volatile("nop\t\n");

    flag = 0;
L2: (void)&&L2;
    if (flag==0) { address = &&L2; return; }

    }
}


int main(void) {

    for(;;) {
        test();
    }

    return 0;
}
// -------------------------------------------------------------------------

If 'address' variable is placed in memory or in r30:r31, the generated code is
OK:
// -------------------------------------------------------------------------
0000003c <test>:
register void* address asm("r30");

void test(void) {
  3c:    09 94           ijmp

    goto *address; // address is computed properly

    for(;;) {

    asm volatile("nop\t\n");
  3e:    00 00           nop
// -------------------------------------------------------------------------

ijmp is generated for computed goto, address is already in r30:r31 for ijmp.


If 'address' variable is placed in memory or in r2:r3, the generated code is
NOT OK:

// -------------------------------------------------------------------------
0000003c <test>:
register void* address asm("r2");

void test(void) {
  3c:    2f 92           push    r2
  3e:    3f 92           push    r3
  40:    08 95           ret

    goto *address; // address is computed properly

    for(;;) {

    asm volatile("nop\t\n");
  42:    00 00           nop
// -------------------------------------------------------------------------

No ijmp is generated. Instead, push r2, push r3 and ret. No pops are generated.


The expected output should ideally be
// -------------------------------------------------------------------------
0000003c <test>:
register void* address asm("r2");

void test(void) {
  3c:    ? ?           movw    r30, r2
  3e:    09 94           ijmp

    goto *address; // address is computed properly

    for(;;) {

    asm volatile("nop\t\n");
  40:    00 00           nop
// -------------------------------------------------------------------------


=========
avr-gcc -c -mmcu=atmega8535 -I. -gdwarf-2  -I../../bsp -I../../../.. -O3
-save-temps -v -ffixed-r2 -ffixed-r3 -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef
-Wa,-adhlns=.obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c
-o .obj/main.o
Using built-in specs.
COLLECT_GCC=avr-gcc
Target: avr
Configured with: ../../gcc.gnu.org/gcc-4_7-branch/configure --target=avr
--prefix=/local/gnu/install/gcc-4.7-mingw32 --host=i386-mingw32
--build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared
--with-dwarf2 --with-avrlibc=yes
Thread model: single
gcc version 4.7.2 (GCC)

Reply via email to