I'm using the following code to generate supervisor calls:
#define SVC(code) __asm__ volatile ("svc %0" : : "I" (code))
void svc_rgb(uint8_t red, uint8_t green, uint8_t blue) {
SVC(7);
}
int main() {
svc_rgb(0, 255, 0);
wait();
svc_rgb(0, 255, 255);
}
for which I then have an SVC handler that takes care of implementing the functionality taking into account the passed arguments. However, that code produces the following disassembly:
0000a108 <main>:
a108: b510 push {r4, lr}
a10a: df07 svc 7
a10c: f7ff ffec bl a0e8 <wait>
a110: df07 svc 7
a112: e7fe b.n a112 <main+0xa>
which ignores the rgb arguments passed to the svc_rgb function. Initially I thought that GCC was optimizing out the apparently unused parameters, so I added a __attribute__((optimize("-O0"))) to the svc_rgb function. That yields the following dissassembly:
0000a0e8 <svc_rgb>:
a0e8: b590 push {r4, r7, lr}
a0ea: b083 sub sp, #12
a0ec: af00 add r7, sp, #0
a0ee: 0004 movs r4, r0
a0f0: 0008 movs r0, r1
a0f2: 0011 movs r1, r2
a0f4: 1dfb adds r3, r7, #7
a0f6: 1c22 adds r2, r4, #0
a0f8: 701a strb r2, [r3, #0]
a0fa: 1dbb adds r3, r7, #6
a0fc: 1c02 adds r2, r0, #0
a0fe: 701a strb r2, [r3, #0]
a100: 1d7b adds r3, r7, #5
a102: 1c0a adds r2, r1, #0
a104: 701a strb r2, [r3, #0]
a106: df07 svc 7
a108: 46c0 nop ; (mov r8, r8)
a10a: 46bd mov sp, r7
a10c: b003 add sp, #12
a10e: bd90 pop {r4, r7, pc}
which is not what I expect, since it makes it so that the first call to svc_rgb is such that the registers r0, r1 and r2 contain the values 255, 0, 0, respectively, just before the svc instruction, passing the wrong values to the SVC handler.
How can I let GCC know that I'm going to use the parameters of svc_rgb as the arguments to my supervisor call?