Description
When activating the "Optimize code, inline standard funtions" (-Os
) or the "Optimize code, inline more code" (-Oi
) option, if a C source code has (in sequence) a direct write statement and a direct read statement on the same RAM memory location, the reading step is omitted.
The problem arises if the memory is accessed using the address directly. It does not occur if the address to read and write from is stored in a (temporary) pointer variable, or if the optimization is disabled.
Currently, the only workaround to avoid allocating an additional variable is to assign a value of 0 to the (destination) memory location: this prevents the optimizer from exploiting the value just written.
However, I believe there should be a way to indicate that (specific?) memory locations can be "volatile" so that the optimizer cannot make any assumptions about the reusability of their value.
Example:
unsigned char port;
[...]
(*(unsigned char*)0xff08) = 0x04;
port = (*(unsigned char*)0xff08); `
This is the correct assembly output (without -Osir
optimizations):
00042Cr 1 ;
00042Cr 1 ; (*(unsigned char*)0xff08) = 0x04;
00042Cr 1 ;
00042Cr 1 A2 00 ldx #$00
00042Er 1 A9 04 lda #$04
000430r 1 8D 08 FF sta $FF08
000433r 1 ;
000433r 1 ; port = (*(unsigned char*)0xff08);
000433r 1 ;
000433r 1 A2 00 ldx #$00
000435r 1 AD 08 FF lda $FF08 ; <--- this is the step missed!
000438r 1 8D rr rr sta L0117
00043Br 1 ;
This is the (wrong) assembly output:
000281r 1 ; (*(unsigned char*)0xff08) = 0x04;
000281r 1 ;
000281r 1 A9 04 lda #$04
000283r 1 8D 08 FF L0158: sta $FF08
000286r 1 ;
000286r 1 ; port = (*(unsigned char*)0xff08);
000286r 1 ;
000286r 1 8D rr rr sta L0118
000289r 1 ;
This is the workaround:
000289r 1 ; (*(unsigned char*)0xff08) = 0x04;
000289r 1 ;
000289r 1 8D 08 FF sta $FF08
00028Cr 1 ;
00028Cr 1 ; port = 0;
00028Cr 1 ;
00028Cr 1 8C rr rr sty L0118
00028Fr 1 ;
00028Fr 1 ; port = (*(unsigned char*)0xff08);
00028Fr 1 ;
00028Fr 1 AD 08 FF lda $FF08 ; <--- this is the step needed
000292r 1 8D rr rr sta L0118
Command line used to compile:
cl65 -T -l obj/plus4/midres_plus4.asm -t plus4 -c -W -const-comparison -Osir -Cl -D__CBM__ -o obj/plus4/midres_plus4.o obj/plus4/midres_plus4.c