Saving one part of a register pair in the callee-saved list.

Hello,

I would like to know if there’s a way of setting the callee-saved register list inside getCalleeSavedRegs() to make the PEI pass save/restore only one half of a register pair if the other half is not being used, instead of saving the whole pair. Here is an example of what I try to explain to make things more clear:

Suppose this situation where we have a register file of 8bit regs, and that you can form regpairs by joining two adjacent regs. Pairs are pseudo regs that are formed by two 8 bit subregisters, with their lo and hi parts defined in the register.td file. Both 8 and 16bit types are legal.
In the following function: char foo(char a, char b, char c, int d)
Arguments are passed this way: a=R10, b=R8, c=R6, d=R5:R4, so first three come in a single reg while the last argument comes in a pair. Since all registers are callee clobbered they have to be saved/restored in the function. The current situation is that I’ve listed in the the callee-saved register list the whole pairs of registers instead of their parts, so I’m getting saved and restored R11:R10, R9:R8, R7:R6 and R5:R4 which is expected. However, what I would like is to not save the first 3 pairs, but only their low register parts, since the high register part is not being used (push R10+push R8+push R6+push R5:R4).

I’ve tried listing both the pairs and their parts, but if a pair and one of it’s parts are used separately then I get both the pair and the part saved (ie: push R1:R0+push R1+push R0) duplicating code. Also, only listing the 8bit regs works BUT I’m getting machine verifier errors because registers are appearing twice in the live-ins list so I’m getting an error like this:
*** Bad machine code: Using an undefined physical register ***

I would like to know if it’s possible to handle this situation.

Thanks!

Hi Borja,

Hello Jim,

I’ve rechecked my register description file to see if I had made any mistakes defining the subregisters but they look exactly the same to what x86 or ARM do. The only difference I noticed is that i didn’t set the CoveredBySubRegs bit, but the generated file by tablegen was exactly the same as before.

Using my previous example but using x86 regs it may become more clear:

If 8bit arguments are passed in AL, BL, CL, instead of doing:
push AX
push BX
push CX
(saving the whole pair)

I would like to only push AL, BL and CL, since the hi part of the pair is not written then there’s no need to save the whole register pair. Of course if a 16bit argument is passed then it will have to use the whole pair (both subregs), so in this case indeed we would have to do push AX.

What should I do to get this behaviour or how would the callee saved register list look like?

Thanks for the help.

2012/7/11 Jim Grosbach <grosbach@apple.com>