I've gone to a lot of effort with my latest project to ensure that it compiles under GCC and IAR. I was interested in the code size that each compiler generated. I had GCC set to -Os and IAR -z3 which I increased to -z6 (IAR size optimization). That's when the IAR code stopped working. I had the following code:
while(true) { DISABLE_INTERRUPTS(); if (Event To Process) { Process The Event; } ENABLE_INTERRUPTS(); }
The IAR compiler optimised it to:
sei
cli
if statement test
rjump to sei
Seems that if you have an sei and then a cli just after it, interrupts are never enabled. The working GCC code was:
cli
if statement test
sei
rjmp to cli
The rjmp between the sei and cli was enough to allow interrupts to be enabled.
A very subtle bug to be aware of when cranking up the optimisation on a compiler!