[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[openrisc] Compiler register alloc doesn't match spec



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}