There is an issue with the -Os optimization parameter in mspgcc 4.7.0 20120911 when using 20-bit pointers.
The following code writes a byte to 0x18000 (in flash > 64 KB) on an MSP430F5342:
#include <msp430f5342.h>
#include <stdint.h>
#include <string.h>
int main(){
uint8_t* addr=(uint8_t*)0x18000;
WDTCTL = WDTPW+WDTHOLD;
FCTL3 = FWKEY + LOCKA; // Clear LOCK and LOCKA
FCTL1 = FWKEY + ERASE; // Enable segment erase
*addr = 0; // Dummy write, erase the selected segment
while(FCTL3 & BUSY); // Wait for erase to finish
FCTL1 = FWKEY + WRT; // Enable write
*addr = 0x88; // WRITE
while(FCTL3 & BUSY); // Wait for write to finish
FCTL1 = FWKEY; // Disable writes / erases
FCTL3 = FWKEY + LOCK + LOCKA; // Set LOCK and LOCKA
return 0;
}
It works fine when compiling without -Os:
msp430-gcc -mmcu=msp430f5342 -mmemory-model=large test.c
But with -Os it returns:
/tmp/ccANT1um.s: Assembler messages:
/tmp/ccANT1um.s:18: Error: value 98304 out of range for 16-bit immediate
/tmp/ccANT1um.s:23: Error: value 98304 out of range for 16-bit immediate
A workaround is to replace
uint8_t* addr=(uint8_t*)0x18000;
by
uint8_t* volatile addr=(uint8_t*)0x18000;
which will prevent gcc from doing any optimizations on this pointer.