avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Weird optimization issue with avr-gcc 4.5.3, re "naked."


From: William \"Chops\" Westfield
Subject: [avr-gcc-list] Weird optimization issue with avr-gcc 4.5.3, re "naked."
Date: Thu, 26 Jan 2012 11:10:54 -0800

A week or so ago I mentioned that avr-gcc 4.5.3 caused the optiboot bootloader 
(used by Arduino and etc) to grow 22 bytes (from 500 bytes to 522 bytes, 
pushing it over the size that it needs to be.)

This took a while to track down, because it's weird.  Apparently gcc is 
optimizing code differently depending on whether the function is defined as 
"naked" or not.  Optiboot sets up main() as naked to save space, and the lost 
optimization is hurting it.

I have a small test case (even smaller than optiboot :-)
(files also attached.  foo.c, foo-naked.S, foo-clothed.S)

Consider:

int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
int main()
{
  uint8_t ch;

  for (;;) {
    ch = getch();

    if(ch == STK_GET_PARAMETER) {
      register uint8_t which = getch();
      verifySpace();
      if (which == 0x82) {
        putch(OPTIBOOT_MINVER);
      } else if (which == 0x81) {
          putch(OPTIBOOT_MAJVER);
      } else {
        putch(0x03);
      }
    }

Without the extra attributes for main, the is optimized to fact out the call to 
putch():

        /*
         * Send optiboot version as "minor SW version"
         */
        putch(OPTIBOOT_MINVER);
  1c:   85 e0           ldi     r24, 0x05       ; 5
  1e:   00 c0           rjmp    .+0             ; 0x20 <main+0x20>
      } else if (which == 0x81) {
  20:   81 38           cpi     r24, 0x81       ; 129
  22:   01 f4           brne    .+0             ; 0x24 <main+0x24>
          putch(OPTIBOOT_MAJVER);
  24:   84 e0           ldi     r24, 0x04       ; 4
  26:   00 c0           rjmp    .+0             ; 0x28 <main+0x28>
      } else {
        /*
         * GET PARAMETER returns a generic 0x03 reply for
         * other parameters - enough to keep Avrdude happy
         */
        putch(0x03);
  28:   83 e0           ldi     r24, 0x03       ; 3
  2a:   00 d0           rcall   .+0             ; 0x2c <main+0x2c>
  2c:   00 c0           rjmp    .+0             ; 0x2e <main+0x2e>
      }
    }

WITH the extra attributes, I get three separate rcall instructions:

        putch(OPTIBOOT_MINVER);
  12:   85 e0           ldi     r24, 0x05       ; 5
  14:   00 d0           rcall   .+0             ; 0x16 <main+0x16>
  16:   00 c0           rjmp    .+0             ; 0x18 <main+0x18>
      } else if (which == 0x81) {
  18:   81 38           cpi     r24, 0x81       ; 129
  1a:   01 f4           brne    .+0             ; 0x1c <main+0x1c>
          putch(OPTIBOOT_MAJVER);
  1c:   84 e0           ldi     r24, 0x04       ; 4
  1e:   00 d0           rcall   .+0             ; 0x20 <main+0x20>
  20:   00 c0           rjmp    .+0             ; 0x22 <main+0x22>
      } else {
        /*
         * GET PARAMETER returns a generic 0x03 reply for
         * other parameters - enough to keep Avrdude happy
         */
        putch(0x03);
  22:   83 e0           ldi     r24, 0x03       ; 3
  24:   00 d0           rcall   .+0             ; 0x26 <main+0x26>
  26:   00 c0           rjmp    .+0             ; 0x28 <main+0x28>
      }
    }

Any thoughts as to what might be going on here?

Thanks
WestfW

Attachment: foo.c
Description: Binary data


Attachment: foo-naked.S
Description: Binary data


Attachment: foo-clothed.S
Description: Binary data



reply via email to

[Prev in Thread] Current Thread [Next in Thread]