Does armclang saves all needed register on stack with attribute("IRQ")?

125 views Asked by At

I'm working with Keil ARMCompiler 6.15 (armclang.exe) and I'm in doubt of the correctness of the generated assembler code. It seems to me that the attribute 'interrupt("IRQ")' is ignored. For me r1 and r2 should be saved on the stack, too. When I remove the attribute 'used' my complete function is removed (optimization).

Can anyone see the mistake I made or what I've forgotten?

Originally the code was created for gcc.

Attributes used for interrupt routines:

#define INTERRUPT_PROCEDURE __attribute__((interrupt("IRQ"),used,section(".IsrSection")))
#define ISR_VARIABLE __attribute__((section(".IsrSection")))
#define FAST_SHARED_DATA __attribute__((section(".FastSharedDataSection")))

C++ Code:

uint64_t volatile FAST_SHARED_DATA systick_value = uint64_t(0);
extern "C" {
    void INTERRUPT_PROCEDURE SysTick_Handler()
    {
        systick_value++;
    }
}

Assembler Code:

0x08001280  push {r4, r6, r7, lr} 
0x08001282  add r7, sp, #8 
0x08001284  mov r4, sp 
0x08001286  bfc r4, #0, #3 
0x0800128a  mov sp, r4 
0x0800128c  movw r0, #8192  ; 0x2000 
0x08001290  movt r0, #8192  ; 0x2000 
0x08001294  ldrd r1, r2, [r0] 
0x08001298  adds r1, #1 
0x0800129a  adc.w r2, r2, #0 
0x0800129e  strd r1, r2, [r0] 
0x080012a2  sub.w r4, r7, #8 
0x080012a6  mov sp, r4 
0x080012a8  pop {r4, r6, r7, pc} 
0x080012aa  movs r0, r0 
0x080012ac  movs r0, r0 
0x080012ae  movs r0, r0 
1

There are 1 answers

1
0___________ On

You do not need this attribute. It is needed in very rare circumstances when the stack is not aligned to 8 bytes (STKALGN bit is not set) by the hardware and you are going to use functions with 64 bits parameters (like uint64_t). ARM automatically saves R0-R3 + some others registers on the stack when entering the ISR handler. If you use FPU you may want to enable FPU registers stackup as well.