Does anyone have any tips on when and which registers to allocate in a routine?
In my 68HC11 compiler it was really easy: there are so few registers that I had to load and store variables like crazy! (Though an optimisation pass got rid of some of the more stupid sequences of instructions, e.g. loading a certain variable into the accumulator when it must already be there.)
It's more complicated on ARM since
a) Routines are allowed to stomp on R0 to R3, and
b) Routines are NOT allowed to stomp on R4-R11.
Every time I think up suitable code I find that instruction A depends on instruction B, which depends on instruction C, which... and I soon lose track of what order decisions have to be made in.
E.G. Suppose I want to code this C in assembler: void A(int B, int C) { D(B); E(C); }
I might produce:
STMFD SP!, {R4, LR}
MOV R4, R1
BL D
MOV R0, R4
BL E
LDMFD SP!, {R4, PC}
The 1st instruction is there because we need to save R4 because it's used later (instruction 2) and we need to save LR because we use a BL (instruction 3 (and 5)).
The 2nd instruction is there because the BL is allowed to stomp on R0-R3 but C, which is in R1, is used later (instruction 4). (R4 could be any of R4 to R11.)
The 4th instruction is there to put E's parameter in the right place (C currently being in R4).
The 6th instruction complements the 1st.
It's all doing my head in!