Why arm-linux-gcc saves r0-r4 only when entering IRQ mode

I am using S5PV210 which is based on ARM cortex-A8

When I declare an interrupt procedure as follows:

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

And compile it like

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

I know gcc will switch the context for me by pressing some registers. Before I know this, I did it manually. So I am wondering how to do gcc. After disassembling, I found the codes as shown below

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

This contradicts my concept of context switching. The official Arm cortex-A8 whitepaper clearly states that r0-r12 is separated by user mode and IRQ mode. However, lr in user mode is independent of IRQ mode. So I used a context like this to switch

 PUSH {r0-r12} 

Everything is good? Why is gcc push lr registered and why does gcc push r5-r10 not work?

+5
source share
2 answers

r4-r11 are stored in all function calls as part of ARI ARI, so the interrupt procedure does not need to be saved if the function itself is not going to knock them down. If another function called by the interrupt routine wants to change these registers, it is already required to save and restore them as part of the regular ABI. Among this set, it seems that the compiler just wanted to use r4 and r11 (r5-r10 are not used).

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

+7
source

r5-r10 are the caller's save registers in ARM, so gcc will push them if they are used in isr_routine. If they are not used (and he will try not to use them if possible), he will not take care of saving / restoring their value, because this is not necessary. I assume your isr_routine is simple enough that they are not needed (everything fits into r0-r4 or r11-r12)

+3
source

Source: https://habr.com/ru/post/1204569/


All Articles