[LLVMdev] Pairing Registers on a Target Similar to Mips?

ryan baird ryanrbaird at gmail.com
Sat Oct 6 15:18:37 PDT 2012

I'm working on a target based on the MIPS target, and when I copy f64
values into 32 bit registers for calling functions, I need the operation to
work on a of 32 bit registers (because the language I'm translating to
isn't actually mips).  I've been looking at how to do this, but I haven't
been able to figure it out.  Since the Mips target code is still really
close to mine, I'll use it's code to explain relavent details.  Any help
would be highly appreciated.

The idea I tried to implement to accomplish this is to create a 64 bit
register class that is set up to span two 32 bit registers in the same way
as the 64 bit floats span two 32 bit floating point registers in mips.
Creating the register class is easy enough to implement in the
RegisterInfo.td file.

The next thing I wanted to do is create a Pseudo-Element similar to the
ExtractElementF64 in mips. I added the following Code to InstrFPU.td (and
added the CopyF64 ISD to another file):

    def SDT_MipsCopyF64 : SDTypeProfile<1, 1, [SDTCisVT<0, i64>,
                                          SDTCisVT<1, f64>]>;

    def MipsCopyF64 : SDNode<"MIPSISD::CopyF64",

I also changed CPU64Regs to CPU64PRegs ( My 64 bit paired register class)
in the DMFC1 rule for testing.

Next, I added the code in ExpandPseudo to use the following pseudo
instruction expansion:

    void MipsExpandPseudo::ExpandCopyF64(MachineBasicBlock& MBB,
I) {
      unsigned DstReg = I->getOperand(0).getReg();
      unsigned SrcReg = I->getOperand(1).getReg();
      const MCInstrDesc& Dmfc1Tdd = TII->get(MIPS::DMFC1);

      DebugLoc dl = I->getDebugLoc();
      const uint16_t* SubReg =

      BuildMI(MBB, I, dl, Dmfc1Tdd, DstReg).addReg(*SubReg);

Finally, I want to add the rule to ISelLowering to actually use these
rules.  Under the CCValAssign::Full case in the LowerCall function, here is
the old code:
          SDValue Lo = DAG.getNode(MIPSISD::ExtractElementF64, dl, MVT::i32,
                                   Arg, DAG.getConstant(0, MVT::i32));
          SDValue Hi = DAG.getNode(MIPSISD::ExtractElementF64, dl, MVT::i32,
                                   Arg, DAG.getConstant(1, MVT::i32));

          if (!Subtarget->isLittle())
            std::swap(Lo, Hi);

          unsigned LocRegLo = VA.getLocReg();
          unsigned LocRegHigh = getNextIntArgReg(LocRegLo);

          RegsToPass.push_back(std::make_pair(LocRegLo, Lo));
          RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));

I added this SDValue:
    SDValue Num = DAG.getNode(MIPSISD::CopyF64,dl,MVT::i32, Arg);

But I need to create a Hi and a Lo SDValue to add to the RegsToPass pairs
seen in the code above.  If someone would help me figure out what goes
here, I would be very thankful:
    SDValue Hi = ?
    SDValue Lo = ?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121006/18039fc6/attachment.html>

More information about the llvm-dev mailing list