I was trying to write a register context saving/restoring when I came across a weird behaviour.
My code (sorry, tried to format tens of times, but the editor WANTS to make asm a table):
When the exception is returned from, the calling function:
msg = "returned from SVC\r\n";
serial_io.put_string(msg, util_str_len(msg)+1);
asm volatile (
);
msg = "cpsr = ";
util_word_to_hex(scratchpad, tmp1);
serial_io.put_string(scratchpad, 9);
serial_io.put_string("\r\n", 3);
outputs "returned from SVC" and "cpsr = 60000013".
Why the "00000002"? the barriers don't seem to have any effect.
And another weirdness - this time the gcc:
The source:
// rpi2_svc_handler2() // - No C in naked function
The disassembly:
1f000cf8: e1a0000d mov r0, sp
1f000cfc: e2001007 and r1, r0, #7
1f000d00: e0400001 sub r0, r0, r1
1f000d04: e1a0d000 mov sp, r0
1f000d08: e92d0003 push {r0, r1}
1f000d0c: e1a0000d mov r0, sp
1f000d10: e1a0100e mov r1, lr
1f000d14: e92d000f push {r0, r1, r2, r3}
1f000d18: ebffff51 bl 1f000a64 <rpi2_svc_handler2>
1f000d1c: e8bd000f pop {r0, r1, r2, r3}
Where's the "pop {r0, r1}?
1f000d20: e0800001 add r0, r0, r1
1f000d24: e1a0d000 mov sp, r0
The stack fix pop in "restore"-part ("pop {r0, r1}\n\t") is missing from the disassembly!
OK, the push and pop around call to rpi2_svc_handler2 are needless, but still - the stack effect...
The compiler shouldn't "optimize" such that the stack gets unbalanced, and the data got is wrong.
Aarghh - found it: the pervious line "comments" it off!
This: "@ restore stack correction" doesn't end with "\n\t", so the next physical line
is logically a continuation...
becomes:
"@ restore stack correction pop {r0, r1}\n\t"
And because the logical line is a comment, there is no error messages or anything...