CFI directives for callee saved registers

Hello,

I’ve made changes to the prologue to not spill callee saved gprs to the stack but rather spill them to unused vector registers. I’m not sure how to handle this in the cfi directives. Originally, we would use cfi_offset to give an offset of where it is saved on the stack. I tried to instead use the cfi_restore directive. As the docs say “.cfi_restore says that the rule for Register is now the same as it was at the beginning of the function, after all initial instructions added by .cfi_startproc were executed.” To use this, I need to add new instructions that move the value from the vector back into the gpr after the .cfi_startproc section. However, when I tried this, the instructions were executed on entry to the function before the vector registers have been assigned. How do I add these instructions so they appear after .cfi_startproc but are not executed on entry to the function? Or is there another approach I need to take?

Thanks,
Zaara Syeda

Hi Zaara,

I've made changes to the prologue to not spill callee saved gprs to the
stack but rather spill them to unused vector registers. I'm not sure how to
handle this in the cfi directives.

It sounds like you want the ".cfi_register" directive. There's no way
you can write code that sensibly actually restores the register at any
point it might be needed.

It looks like there's already at least some support for this
directive, but I wouldn't bet on it being handled well (by either LLVM
or your debugger/unwinder) since it's not really used in anger as far
as I know.

Cheers.

Tim.

(Adding llvm-dev back in case someone else comes along with similar
questions later).

Thanks for the suggestion. If I use the cfi_register directive, don't the
registers need to be of the same register class? Otherwise, how will the
value be moved out of the vector register back into the gpr?

LLVM itself doesn't care. It's just using these directives to emit
some metadata telling debuggers and unwinders where to find values.

As for those other components, just what .cfi_register means is a
matter for the platform's ABI to define in an ideal world. In the case
where the sizes mismatch (and possibly even otherwise) it should say
which bits of the source register correspond to those of the
destination. You'd then follow that spec when implementing your spill
code.

In the real world, hardly anyone uses this method of spilling and I'm
not aware of an ABI document that describes how it should be done. So
as the (possibly) first implementor on your platform you probably get
to choose what the convention is. Choose wisely.

Cheers.

Tim.