[llvm-dev] [Sparc] Load address with SETHI

Chris.Dewhurst via llvm-dev llvm-dev at lists.llvm.org
Fri Apr 15 09:19:58 PDT 2016


Some more information on what I have so far. I'll actually focus on the longjmp side, as the problem is probably easier.

I need to get the SETHI / OR combination inserted where the comment "*** Need to use the SETHI / OR combination here. ***" appears in the code below, but I'm not sure that this is done anywhere near this piece of code, so I'll include all the relevant parts that I can find of my current implementation.

First, some def's in SparcInstrInfo.td:

def SPsjlj_longjmp: SDNode<"SPISD::EH_SJLJ_LONGJMP",
                           SDTSPeh_sjlj_longjmp,
                           [SDNPHasChain, SDNPSideEffect]>;

let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
  let isTerminator = 1 in
  def EH_SJLJ_LONGJMP32ri : Pseudo<(outs), (ins MEMri:$buf),
                            "#EH_SJLJ_LONGJMP32",
                            [(SPsjlj_longjmp ADDRri:$buf)]>,
                            Requires<[Is32Bit]>;
  def EH_SJLJ_LONGJMP32rr : Pseudo<(outs), (ins MEMrr:$buf),
                            "#EH_SJLJ_LONGJMP32",
                            [(SPsjlj_longjmp ADDRrr:$buf)]>,
                            Requires<[Is32Bit]>;
}

SparcISelLowering.cpp, of course, sets this as setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);

I also have these functions in SparcISelLowering.cpp:

SDValue SparcTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG,
    const SparcTargetLowering &TLI, bool hasHardQuad) const {
  SDLoc DL(Op);
  return DAG.getNode(SPISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0));
}

MachineBasicBlock * SparcTargetLowering::
EmitInstrWithCustomInserter(MachineInstr *MI,
                            MachineBasicBlock *BB) const
{
  switch (MI->getOpcode()) {
... [ Other code first]
  case SP::EH_SJLJ_LONGJMP32rr:
  case SP::EH_SJLJ_LONGJMP32ri:
    return emitEHSjLjLongJmp(MI, BB);
  }
}

MachineBasicBlock* SparcTargetLowering::
emitEHSjLjLongJmp(MachineInstr *MI,
                  MachineBasicBlock *MBB) const
{
  DebugLoc DL = MI->getDebugLoc();
  const TargetInstrInfo *TII = Subtarget->getInstrInfo();

  MachineFunction *MF = MBB->getParent();
  MachineRegisterInfo &MRI = MF->getRegInfo();
  MachineInstrBuilder MIB;

  // Memory Reference
  MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin();
  MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();

  MVT PVT = getPointerTy(MF->getDataLayout());
  unsigned PtrSize = PVT.getStoreSize();
  assert(PVT == MVT::i32 && "Invalid Pointer Size!");

  unsigned ArgReg = MI->getOperand(0).getReg();
  unsigned Buf = MRI.createVirtualRegister(&SP::IntRegsRegClass);
  unsigned JmpLoc = MRI.createVirtualRegister(&SP::IntRegsRegClass);

  // *** Need to use the SETHI / OR combination here. ***

//  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::ORri))
//            .addReg(Buf)
//            .addReg(ArgReg)
//            .addImm(0);
//  MIB.setMemRefs(MMOBegin, MMOEnd);

  // Instruction to load jmp location
  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
            .addReg(JmpLoc)
            .addReg(Buf)
            .addImm(PtrSize);
  MIB.setMemRefs(MMOBegin, MMOEnd);

  // TO DO: If we do 64-bit handling, this perhaps should be FLUSHW, not TA 3
  const long int TRAP_COND_ALWAYS = 0x08;
  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::TRAPri), SP::G0).addImm(3).addImm(TRAP_COND_ALWAYS);

  // Instruction to restore FP
  const unsigned FP  = SP::I6;
  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
            .addReg(FP)
            .addReg(Buf)
            .addImm(0);
  MIB.setMemRefs(MMOBegin, MMOEnd);

  // Instruction to restore SP
  const unsigned SP  = SP::O6;
  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
            .addReg(SP)
            .addReg(Buf)
            .addImm(2 * PtrSize);
  MIB.setMemRefs(MMOBegin, MMOEnd);

  // Instruction to restore I7
  MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
            .addReg(SP::I7)
            .addReg(Buf)
            .addImm(3 * PtrSize);
  MIB.setMemRefs(MMOBegin, MMOEnd);

  // Jump to I7
  BuildMI(*MBB, MI, DL, TII->get(SP::JMPLrr)).addReg(SP::G0).addReg(JmpLoc).addReg(SP::G0);

  MI->eraseFromParent();
  return MBB;
}


________________________________
From: Chris.Dewhurst
Sent: 15 April 2016 15:15
To: llvm-dev at lists.llvm.org
Subject: [Sparc] Load address with SETHI

Hi,

I'm trying to implement __builtin_setjmp / __builtin_longjmp for Sparc processors. I think I'm very close, but I can't work out how to issue BuildMI-type instructions to load the address of the recovery location (set in setjmp) into a register using the SETHI / OR combination. I can't see any equivalent code anywhere else in Sparc.

I imagine this is similar if I try to make a CALLRi or CALLrr call, but looking through the code there isn't yielding any obvious solution to me.

Would anyone be able to point me at a relevant piece of code that can do this, or is already doing it for Sparc?

Best Regards,
Chris Dewhurst / Lero, University of Limerick, Ireland.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160415/1fd6b74a/attachment.html>


More information about the llvm-dev mailing list