Code: Select all
dest_channel = xcore_getep_wait( control_channel, desc.xcore_endpoint);
ldw (ru6) r2, sp[0x10] <--- r2 is the value of control_channel
ldc (ru6) r1, 0x20 <--- r1 is 0x20
stw (ru6) r0, sp[0xa] Saving R0 for whatever reason
add (2rus) r0, r2, 0x0 <-- Parameter 1 is now correct... set to control_channel
stw (ru6) r1, sp[0x9] Saving R1 for whatever reason
add (2rus) r1, r3, 0x0 <---- R3 is '5' so at this point, which is wrong ***
bl (lu10) 0x13c
stw (ru6) r0, sp[0x12]
My initial thought was that r3 was being clobbered by one of the functions, and isn't loaded here because it's a register variable/optimization. The compiler keeps it around to use. however according to the ABI docs r3 is "caller save".
I'm at a loss here. Why is the compiler adding in 'r3' when it is never set up? Is r3 really callee save and the docs are incorrect?
R3 is set many lines above this code and used below this code. It seems like it's trying to cache into this variable, which doesn't seem right.
So my question:
Will the compiler use r0-r4 caller save registers if it thinks it can? Am I supposed to somehow list these in "side effects" in the assembler function declarations? According to everything I am reading on the ABI, r3 should be OK to clobber in asm functions. So I'm not sure why the compiler thinks it doesn't have to initialize it here.
Interesting to note that changing the code slightly fixes it, which really proves nothing:
Code: Select all
unsigned int dbg = desc.xcore_endpoint;
ld8u (3r) r2, r0[r1]
stw (ru6) r2, sp[0xd]
dest_channel = xcore_getep_wait( control_channel, dbg);
ldw (ru6) r3, sp[0x11]
bl (u10) 0x354
add (2rus) r0, r3, 0x0
stw (ru6) r1, sp[0x9]
add (2rus) r1, r2, 0x0
bl (lu10) 0x13c
stw (ru6) r0, sp[0x13]
I'm going to try to preserve r0-r3 in all my asm calls and see if that helps. But this still seems odd.