> -----Original Message----- > From: > [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] > org] On Behalf Of Schwichtenberg, Knut > Sent: Monday, March 26, 2007 12:39 AM > To: avr-gcc-list@nongnu.org > Subject: [avr-gcc-list] Inconsisten behaviour of switch statement > > Hi, > > while the size of my programm shrunk after adding some cases > I looked to the list file. I saw that a switch was converted > from a structured if-then-else to a table jump (compiled with > -Os). That's okay. A detailed analyses points to a gcc > problem: I use a volatile variable. If a samll number cases > are used, the value is reloaded for every compare. If the > switch is implemented by a table jump, the value is loaded > once and moved into 2 register pairs. One the first glance > both implementations are correct, but under special > conditions based on the number of case the dynamic behaviour > can change! > > I don't know which behaviour is correct, but it should not > change by the number of cases. Attached you will find an > example showing both behaviours. It is reduced and therefore > became stupid.
The compiler has heuristics that decide when to compile a switch statement into an if-else-if structure, or as a table jump. If you do not like the output that it produces, it would be better if you coded your algorithm as a dispatch table (array of pointers to functions). This gives you more control as to how the compiler will transform the C into assembly. > BTW: Is there any reason why the compares within the switch > are at least 16 bit and not type dependent for 8 bit types? > If you program this as a normal if, 8 bit compares are generated. According to the C language standard, integer constants (like what you are using in the cases) are of type int by default, which on the AVRs, makes them 16 bits. Therefore, they do a 16 bit compare. I agree that the AVR GCC compiler could have much better optimization in this area. The compiler should be able to figure out the smallest possible integral type to use and generate assembly for that. Have you tried typecasting all of the case integer constants to uint8_t? Perhaps that will have the desired effect. HTH Eric Weddington _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list