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

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

RE: [avr-gcc-list] Inconsisten behaviour of switch statement


From: Eric Weddington
Subject: RE: [avr-gcc-list] Inconsisten behaviour of switch statement
Date: Mon, 26 Mar 2007 06:45:39 -0600

 

> -----Original Message-----
> From: 
> address@hidden 
> [mailto:address@hidden
> org] On Behalf Of Schwichtenberg, Knut
> Sent: Monday, March 26, 2007 12:39 AM
> To: address@hidden
> 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





reply via email to

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