Pseudo instructions and register allocation

Howdy

My backend needs a scratch location for copying a value between two specialized registers (it’s rather non-homogeneous and lacks “MOV XDest, XSrc”, instead needing the pair “MOV GenReg, XSrc; MOV XDest, GenReg” where GenReg is a register from a general class).

I anticipate using a pseudo instruction for “MOV XDest XSrc” but this means that in
expandPostRAPseudo() a suitable GenReg needs to already have been assigned, e.g. I guess it would look like another “ins” for the instruction selection, except that it isn’t an explicit operand with a source, just an available register from a certain class. So something like:

let isPseudo = 1 in {

def MOVXX : ToyInst<bit_pattern,
(outs xRegs:$dst), (ins xRegs:$src, genRegs:$SCRATCH),
“movxx {$dst, $src}”,
[(set xRegs:$dst, (xRegs:$src, genRegs:$SCRATCH))]>;

}

and then in expandPostRAPseudo():

auto scratchReg = MI->getOperand(2).getReg();

I haven’t yet seen (or perhaps not understood…) such a case in the documentation or existing target codebases - would welcome any guidance.

–Tyro

There’s no really clean way to do this. Your proposal is basically what other targets do. See the Int_eh_sjlj_longjmp definition in the ARM backend, for example.

-Jim