Hi,
I'm using tiarmclang v3.2 and have a custom interrupt handler for C functions which is written in assembly. I can't use interrupt function attribute as this does not preserve FPU registers, which I need. I know how to do this but I don't understand how to ensure the stack is 8-byte aligned before executing the C ISR. From the tiarmclang manual interrupt attribute section:
> "The tiarmclang compiler will re-align the stack pointer to an 8-byte boundary on entry into a function marked with the interrupt attribute because the Arm Procedure Call Standard (AAPCS) requires this alignment for all public interfaces."
In that same section they demonstrate an example of the 8-byte stack alignment does:
> tiarmclang -mcpu=cortex-r4 -S interrupt_function_attr.c
> cat interrupt_function_attr.s
...
int2:
.fnstart
@ %bb.0: @ %entry
push {r0, r1, r2, r3, r10, r11, r12, lr}
add r11, sp, #20
bfc sp, #0, #3
bl do_something2
sub sp, r11, #20
pop {r0, r1, r2, r3, r10, r11, r12, lr}
subs pc, lr, #4
...
The problem is, the text explaining what's going on doesn't match the code:
> "When compiled with the -mcpu=cortex-r4 option, the compiler-generated assembly snippet shows general-purpose registers being preserved during the function’s entry and exit code, the re-alignment of the stack pointer via the “sub sp, sp, #8” and “bfc sp, #0, #3” instructions, and the addition of the “subs pc, lr, #4” instruction to effect the exception return."
(emphasis mine)
There is no `sub sp, sp, #8` instruction shown. Could someone clarify:
1. Why `r10` get's pushed to the stack when it's a) not being used, and b) the C Exception handler Calling Convention section only says `R0-R3, R-12, LR` need to be preserved? I'm guessing because the r1 reg is being used and we want to always push an even number of registers to the stack to maintain 8-byte alignment if we already have it?
2. How the add and bfc instructions are keeping the stack 8-byte aligned
3. How my general purpose interrupt handler code below can be modified to ensure the stack is aligned to 8 bytes before calling an ISR. This is inline assembly that I wrap around my ISRs in C instead of using the interrupt attribute. I already have the code to call the function and handle register stacking and exception return so I've omitted that.
push {r0, r1, r2, r3, r10, r11, r12, lr}
vmrs ip, fpexc
stmfd sp!, {ip}
vmrs ip, fpscr
stmfd sp!, {ip}
vpush {d0-d7}
<omitting code to call the function here, I have this already>
<omitting code to handle register unstacking and exception return, I have this>
Thank you!