Reading directly from memory
sagacity opened this issue · comments
Context: Just toying around with llvm-mos, nothing urgent.
See https://godbolt.org/z/efK1fYWd4 for details. In the linked code I would expect the generated assembly to simply do a LDA $DC00
or similar to get the joystick state, but instead it's using indirect loads to access the joystick register (via __rc2
and __rc3
) and the code is even reloading __rc2
and __rc3
every loop iteration, even though the joystick address itself obviously doesn't change.
Am I missing something obvious here, that is causing LLVM-MOS to behave this way?
Tricky little distinction here. In the example you posted, JOYSTICK
is a mutable pointer to a const volatile uint8_t
. The compiler knows what it points to at startup, but it has no idea what it points to at the time test
is called. Accordingly, it has to load from the storage location of that pointer and indirect through the result of the load.
Declaring the pointer itself to be const (const volatile uint8_t* const JOYSTICK = (volatile uint8_t*)0xdc00;
) allows the compiler to assume that the value cannot change, allowing it to behave largely as expected: https://godbolt.org/z/q5f9GEW1T
That makes total sense, thanks for the quick reply!