GCC gives three mechansims,
asm clobber
- Local register variable
- Global register variables
It is important to note that compiler register allocation is fundamental to modern optimization and reserving a register can generate worse compiled code. With the ARM mode and 16 registers (only 13 usable) you should be able to reserve one register like this for a function without too much harm. However, you should not use these facilities lightly and it would not be surprising to find some performance issues.
It sounds like the global register variable is the most applicable to you. Just have register int *foo asm ("r4"); at the start of each 'C' module that needs it.
If you have a small cluster/tree of functions, you could use a macro to reserve and contain this to one 'C' unit.
#define RESERVE_REG(reg) register int RR_##reg asm (#reg) \
__attribute__((unused))
int bar(int a) {
RESERVE_REG(R4);
int b;
b += CRAZY_ASM(a);
return b;
}
void foo(void) {
RESERVE_REG(R4);
CRAZY_ASM_SET_R4(82);
printf("value is %d\n", bar(1));
}
Knowing the use of the variable is important as there are more efficient ways (like asm clobber) to get the same effect for some variable life-times and uses. In most cases, people would just declare a parameter. Ie, it is much better to let the compiler know what you are using this for as it can make informed decision on when to spill or not.
It is difficult to think of a case where reserving a register is not misguided. An example where this might be useful is interacting with a cross language/interpreter. The above macro should work as a quick way to pass information between routines by reserving a register.
You should not use R0-R3 as you will restrict the parameters that can be passed among routines. The ARM ABI passes parameters in R0-R3. Given you have flexibility to choose a register, pick R4-R9 (possibly even R9 is off limits) as these are 'callee' saved registers without any special use. As well, if you choose R0-R3 you may NOT call standard 'C' library routines or the reserved register will be saved on the stack.
Reference: GCC local register variables
ARM register calling conventions