I'm using arm-elf-gcc compiler, build for cygwin environment (gnuarm.org). Here is example, which shows wrong results: //--------------------------------------------------------------------------- #include <string.h>
#define FPGA_BASE 0x81000000 static inline void fpga_write( unsigned short address, unsigned short data ) { *((volatile unsigned short*)(FPGA_BASE+address)) = data; asm volatile( "nop" ); /* Slow down IO */ } int f() { unsigned int counter; unsigned short* buf = (unsigned short*)((void*)&counter); memcpy( buf, "test", 4 ); counter++; fpga_write( 0x6A, buf[0] ); fpga_write( 0x6A, buf[1] ); return 0; } //--------------------------------------------------------------------------- I run gcc with following options: arm-elf-gcc -Wa,-adhls=test.lst -fomit-frame-pointer -Os -Wall -g -c -march=armv4t -mtune=arm7tdmi -msoft-float -pipe test.c Gcc produces following listing for my code: str lr,[sp,#-4]! sub sp,sp,#4 mov r0,sp ldr r1,.L3 mov r2,#4 bl memcpy ldr r3,[sp,#0] ldrh r1,[sp,#0] ; source of problem. This word is extracted from memory add r3,r3,#1 ; before actual increment. This is wrong. mov r2,#-2130706432 str r3,[sp,#0] ; Saving incremented value. But least significant word strh r1,[r2,#106] ; will not be incremented. :( nop ldrh r3,[sp,#2] ; All is right here. strh r3,[r2,#106] nop mov r0,#0 add sp,sp,#4 ldmfd sp!,{pc} Disabling optimisations solves this problem. But in this case binary code will be noticeably bigger. -- Summary: Wrong compilation results with -Os option specified Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dednev at pisem dot net GCC host triplet: i686-cygwin GCC target triplet: arm-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31421