[LLVMdev] returning a double in two registers

Chris Lattner
2006-10-02T22:14:05Z

On Mon, 2 Oct 2006, [UTF-8] Rafael Esp?ndola wrote:
> I have started to add support for FP in the ARM backend.

cool.

> According to the ABI, 32 bit floating point numbers should be returned
> in R0 and 64bit ones in R0/R1.

Ok.

> I have solved the 32 bit case by inserting bit_converts in LowerRET.

Yep.

> For the 64bit case I considered two options:
>
> 1) Creating two nodes. fp_lo and fp_hi. I could then select fmrdh and fmrdl
with
> (set IntRegs:$dst (bitconvert (fp_hi DFPRegs:$src))) and
> (set IntRegs:$dst (bitconvert (fp_lo DFPRegs:$src)))

Alternatively, you could merge bitconvert into the fp_hi/lo flags.  That
would make the pattern simpler, and eliminate the need to have to match a
bare fp_hi/fp_lo node without the bitconvert.

> 2) Create a node similar to copytoreg that has two results. This has
> the advantage that it is possible to select fmrrd.
>
> I am currently trying to implement 2, but I am not sure how to declare
> an instruction that has two results. There are some combined mod/rem
> instruction like idivl, but they have fixed defs (EAX, EDX).

Unfortunately, you can't do this elegantly in tblgen.  You'd want to
create an arm-local node at lowering time, then use custom C++ code to
match it.  The X86 backend has some examples of how to write the custom
matching code, but it's not for the faint of heart.

Extending tblgen to support instructions with multiple results is on the
long term todo list, but we probably won't get to it in the near future.

> I have just committed a partial version that doesn't declare fmrrd as
> defining its two integer arguments. Currently this is only used during
> returns and the function is marked as defining R0 and R1, so this
> shouldn't be a problem,
>
> How can I fix the declaration of fmrrd so that it can be used in other
contexts?

You defined your armfmmrd node as taking three inputs: two integer and one
double.  Shouldn't it produce two outputs and take one input?  If so, you
need to write custom c++ matching code.  Alternatively, you can avoid this
by doing the two pieces separately, as you describe in 1).

-Chris

--