[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