posted September 18, 2006 14:07
When using avr-gcc optimization levels -O2 or -Os, I have seen a couple of cases, when calling variable length functions (variables always passed on stack), where r28, r29 were initialized to point to stack frame for the first call to fn(x,...) and, when calling fn(x,...) again from a different location, it is assumed that r28, r29 have not changed. This would also happen when calling a function with more parameters than will fit in registers, forcing usage of the stack to pass the remaining parameters.
Here's an example of why this is a problem:
With O2, or -Os optimization, the following code breaks:
/* Display the line1 */
/* -------- Prior to call, r28,r29 are set as frame pointer -------- */
twi_lcd_printf(&twi_lcd_msg, 1, 1, "%-16s", "Set Offset");
OS_WaitBinSem(TWI_LCD_BINSEM_P, OSNO_TIMEOUT, LBL_SAO_5);
/* -------- r28, r29 no longer valid! OSDispatch() version of r28,r29 is restored in call to OSCtxSw() -------- */
twi_lcd_goto_xy(&twi_lcd_msg, 0, 1);
OS_WaitBinSem(TWI_LCD_BINSEM_P, OSNO_TIMEOUT, LBL_SAO_6);
/* Display Line 2
*/
/* -------- Error, assumes r28,r29 has not been modified since the last call to twi_lcd_printf() -------- */
twi_lcd_printf(&twi_lcd_msg, 1, 1, "%-16d", offset);
OS_WaitBinSem(TWI_LCD_BINSEM_P, OSNO_TIMEOUT, LBL_SAO_7);
Adding the avr-gcc option -fno-gcse will fix this. The -fgcse option is included with the -O2 optimization level and is also included in the -Os optimization level. So, -O2 and -Os optimization levels require the -fno-gcse option when compiling a source module with Salvo tasks.
-Tom
[This message has been edited by zoomcityzoom (edited September 18, 2006).]