Chris.Dewhurst via llvm-dev
2016-Apr-15 14:15 UTC
[llvm-dev] [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/43d52775/attachment.html>
Joerg Sonnenberger via llvm-dev
2016-Apr-15 14:46 UTC
[llvm-dev] [Sparc] Load address with SETHI
On Fri, Apr 15, 2016 at 02:15:21PM +0000, Chris.Dewhurst via llvm-dev wrote:> Would anyone be able to point me at a relevant piece of code that can do this, or is already doing it for Sparc?SparcAsmParser::expandSET and SparcTargetLowering::makeAddress are the two variants I can think of immediately. Joerg
Chris.Dewhurst via llvm-dev
2016-Apr-15 16:19 UTC
[llvm-dev] [Sparc] Load address with SETHI
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>
Joerg Sonnenberger via llvm-dev
2016-Apr-15 16:27 UTC
[llvm-dev] [Sparc] Load address with SETHI
On Fri, Apr 15, 2016 at 04:19:58PM +0000, Chris.Dewhurst via llvm-dev wrote:> 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.I don't understand what exactly you want to materialize here. Shouldn't the address of the buffer already be an operand at this point? Joerg
Reasonably Related Threads
- [Sparc] builtin setjmp / longjmp - need help to get past last problem
- [LLVMdev] How to enable use of 64bit load/store for 32bit architecture
- [LLVMdev] How to enable use of 64bit load/store for 32bit architecture
- Change prototype for TargetInstrInfo::foldMemoryOperandImpl
- ISelDAGToDAG breaks node ordering