Why does arm-linux-gcc only reserve r0-r4 when entering IRQ mode
Asked Answered
S

2

5

I'm using S5PV210 which is based on ARM cortex-A8

When i declare a interrupt routine like this:

void isr_routine(void)  __attribute__ ((interrupt ("IRQ")));

And compile like this

arm-linux-gcc -c -march=armv7-a -fpie -fno-builtin $< -o $@

I know that gcc will switch context for me by push some registers.Before i know this, i did it manually.So i'm curious about how gcc do it. After disassembling, I found codes like below

PUSH     {r0-r4,r11,r12,lr}

It goes against my conception about how to switch context. In Arm cortex-A8 official document, it's explicit that r0-r12 is shared by user mode and IRQ mode.However lr in user mode is independent from IRQ mode.So, I used to switch context like this

PUSH     {r0-r12}

Is it OK? Why does gcc push lr register and why doesn't gcc push r5-r10 rigsters?

Saucer answered 13/10, 2014 at 14:54 Comment(0)
F
7

r4-r11 are preserved across function calls as part of the ARM ABI, so the interrupt routine does not need to save them unless the function itself is going to clobber them. If another function the interrupt routine calls wants to modify these registers, it's already obligated to save and restore them as part of the normal ABI. It seems that among this set, the compiler only wanted to use r4 and r11 (r5-r10 are not used).

While non-authoritative, the Wikipedia article is easy to read and may be helpful: http://en.wikipedia.org/wiki/Calling_convention#ARM

Fallal answered 13/10, 2014 at 16:9 Comment(0)
H
3

r5-r10 are callee save registers in ARM, so gcc will push them if they are used in isr_routine. If they are not used (and it will try not to use them if possible), it won't bother to save/restore their value, because it is unnecessary. I'm guessing that your isr_routine is simple enough that they are not needed (everything fits in r0-r4 or r11-r12)

Hypochondriasis answered 13/10, 2014 at 16:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.