There is some problem w/ inline assembler I could not understand.
I have a function with inline assembler. Inside the ASM block I need to use some scratch register to modify some system value.
void setHW(uint32_t val) {
asm volatile (
mrc 15, 0, r0, ...
orr r0, r0, %0
mcr 15, 0, r0, ...
: :"r"(val) :"r0"
);
}
Actually function is inlined by compiler and it's alright, code still works well.
The problem appears when I try to replace hardcoded r0 with some stub variable so compiler could choose the best possible register to use. It looks like this
void setHW(uint32_t val) {
uint32_t reg;
asm volatile (
mrc 15, 0, %[reg], ...
orr %[reg], %[reg], %0
mcr 15, 0, %[reg], ...
:[reg]"=r"(reg) :"r"(val) :
);
}
Now compiler choose register by itself but actually corrupt the value of setHW caller function.
In disassembler it looks like
add r2, r4, r5 ; caller part, r2 contain some intermedia result
mrc 15, 0, r2, ... ; inlined setHW(), r2 is choosen as scratch reg
orr r2, r2, r0
mcr 15, 0, r2, ...
; caller continue
As you could see r2 is corrupted and everything just fall apart.
How should I define scratch register to avoid this?