In the architecture spec, the following registers are listed as callee-saved, i.e. preserved across function calls:
R1 (SP), R2 (FP), R9 (LR), R10, and all odd registers R13-R31
The compiler, however, is defined such that the following registers are callee-saved:
R1 (SP), R2 (FP), R9 (LR), and all even registers R10-R30
In other words, the spec and the compiler don’t match for registers R12-R31.
(The relevant portion of gcc/gcc/config/or32.h is reproduced below)
I suppose that the compiler could be changed to match the spec, but that would render all existing library binaries as incorrect and hence unlinkable against newer code that uses spec-conformant register allocation. Probably the simpler thing to do is revamp the spec to match the implementation.
On a related note, I noticed that R2, the frame pointer, is listed in the FIXED_REGISTERS array, preventing it from being used by the register allocator as a GPR. For the case in which no frame pointer is needed for a function, there’s no reason that R2 couldn’t be used as a conventional callee-saved register, hence I would recommend removing it from the FIXED_REGISTERS array. This change would allow backward-compatible linking with existing binaries.
/* 1 for registers that have pervasive standard uses and are not available for the register allocator. On the or1k, these are r1 as stack pointer and r2 as frame/arg pointer. */ #define FIXED_REGISTERS {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */ #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1 \ , 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}
|