llvm-mos / llvm-mos-sdk

SDK for developing with the llvm-mos compiler
https://www.llvm-mos.org
Other
258 stars 52 forks source link

Reading directly from memory #288

Closed sagacity closed 6 months ago

sagacity commented 6 months ago

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?

mysterymath commented 6 months ago

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

sagacity commented 6 months ago

That makes total sense, thanks for the quick reply!