<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" id="owaParaStyle"></style>
</head>
<body fpstyle="1" ocsi="0">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">Hi,
<div><br>
</div>
<div>I'm implementing __builtin_setjmp and __builtin_longjmp for Sparc 32 bit processors (64 bit later, time allowing).</div>
<div><br>
</div>
<div>I'm basing the code on the PowerPC version, which itself is based on the X86 version.</div>
<div><br>
</div>
<div>This code is very nearly working, and I've had it working for -O0 optimisation (with a slightly different version to that below), so I know it's close.</div>
<div><br>
</div>
<div>However, the PowerPC code uses a trick to ensure that optimisations retain the jump targets required, using a Pseudo instruction "EH_SjLj_Setup" that expands simply to an IR comment, but makes the compiler think it needs to preserve the jump target address
- which it does, to ensure that the jump target remains valid after any optimisations. Some of the comments at this URL relating to the PowerPC version help with understanding this: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130325/169366.html<a href="http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130325/169366.html" target="_blank" style="font-size: 10pt;">http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130325/169366.html</a></div>
<div><br>
</div>
<div>However, when compiling for Sparc, I get a "Not supported instr" for the instruction EH_SjLj_Setup. Of course, it doesn't exist in reality, but neither does it for PowerPC, so I can't understand why there's a difference between how it's handled for the
two targets.</div>
<div><br>
</div>
<div>I've included a full diff for the setjmp/longjmp change I'm making, but you'll find the most pertinent lines if you search for the text "EH_SjLj_Setup". You'll find very similar code in the PowerPC backend.</div>
<div><br>
</div>
<div>If anyone spots any other mistakes or has comments, I'd be glad to know about them at this stage too. Note: I'll comment as best I can how this works within the code when I get it working.</div>
<div><br>
</div>
<div>
<div>Index: SparcISelLowering.cpp</div>
<div>===================================================================</div>
<div>*** SparcISelLowering.cpp<span class="Apple-tab-span" style="white-space:pre">
</span>(revision 267677)</div>
<div>--- SparcISelLowering.cpp<span class="Apple-tab-span" style="white-space:pre">
</span>(working copy)</div>
<div>***************</div>
<div>*** 1586,1591 ****</div>
<div>--- 1586,1594 ----</div>
<div> setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);</div>
<div> setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);</div>
<div> </div>
<div>+ setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);</div>
<div>+ setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);</div>
<div>+ </div>
<div> if (Subtarget->is64Bit()) {</div>
<div> setOperationAction(ISD::ADDC, MVT::i64, Custom);</div>
<div> setOperationAction(ISD::ADDE, MVT::i64, Custom);</div>
<div>***************</div>
<div>*** 1808,1835 ****</div>
<div> </div>
<div> const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {</div>
<div> switch ((SPISD::NodeType)Opcode) {</div>
<div>! case SPISD::FIRST_NUMBER: break;</div>
<div>! case SPISD::CMPICC: return "SPISD::CMPICC";</div>
<div>! case SPISD::CMPFCC: return "SPISD::CMPFCC";</div>
<div>! case SPISD::BRICC: return "SPISD::BRICC";</div>
<div>! case SPISD::BRXCC: return "SPISD::BRXCC";</div>
<div>! case SPISD::BRFCC: return "SPISD::BRFCC";</div>
<div>! case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";</div>
<div>! case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";</div>
<div>! case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";</div>
<div>! case SPISD::Hi: return "SPISD::Hi";</div>
<div>! case SPISD::Lo: return "SPISD::Lo";</div>
<div>! case SPISD::FTOI: return "SPISD::FTOI";</div>
<div>! case SPISD::ITOF: return "SPISD::ITOF";</div>
<div>! case SPISD::FTOX: return "SPISD::FTOX";</div>
<div>! case SPISD::XTOF: return "SPISD::XTOF";</div>
<div>! case SPISD::CALL: return "SPISD::CALL";</div>
<div>! case SPISD::RET_FLAG: return "SPISD::RET_FLAG";</div>
<div> case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";</div>
<div>! case SPISD::FLUSHW: return "SPISD::FLUSHW";</div>
<div>! case SPISD::TLS_ADD: return "SPISD::TLS_ADD";</div>
<div>! case SPISD::TLS_LD: return "SPISD::TLS_LD";</div>
<div>! case SPISD::TLS_CALL: return "SPISD::TLS_CALL";</div>
<div> }</div>
<div> return nullptr;</div>
<div> }</div>
<div>--- 1811,1840 ----</div>
<div> </div>
<div> const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {</div>
<div> switch ((SPISD::NodeType)Opcode) {</div>
<div>! case SPISD::FIRST_NUMBER: break;</div>
<div>! case SPISD::CMPICC: return "SPISD::CMPICC";</div>
<div>! case SPISD::CMPFCC: return "SPISD::CMPFCC";</div>
<div>! case SPISD::BRICC: return "SPISD::BRICC";</div>
<div>! case SPISD::BRXCC: return "SPISD::BRXCC";</div>
<div>! case SPISD::BRFCC: return "SPISD::BRFCC";</div>
<div>! case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";</div>
<div>! case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";</div>
<div>! case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";</div>
<div>! case SPISD::EH_SJLJ_SETJMP: return "SPISD::EH_SJLJ_SETJMP";</div>
<div>! case SPISD::EH_SJLJ_LONGJMP: return "SPISD::EH_SJLJ_LONGJMP";</div>
<div>! case SPISD::Hi: return "SPISD::Hi";</div>
<div>! case SPISD::Lo: return "SPISD::Lo";</div>
<div>! case SPISD::FTOI: return "SPISD::FTOI";</div>
<div>! case SPISD::ITOF: return "SPISD::ITOF";</div>
<div>! case SPISD::FTOX: return "SPISD::FTOX";</div>
<div>! case SPISD::XTOF: return "SPISD::XTOF";</div>
<div>! case SPISD::CALL: return "SPISD::CALL";</div>
<div>! case SPISD::RET_FLAG: return "SPISD::RET_FLAG";</div>
<div> case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";</div>
<div>! case SPISD::FLUSHW: return "SPISD::FLUSHW";</div>
<div>! case SPISD::TLS_ADD: return "SPISD::TLS_ADD";</div>
<div>! case SPISD::TLS_LD: return "SPISD::TLS_LD";</div>
<div>! case SPISD::TLS_CALL: return "SPISD::TLS_CALL";</div>
<div> }</div>
<div> return nullptr;</div>
<div> }</div>
<div>***************</div>
<div>*** 2492,2497 ****</div>
<div>--- 2497,2516 ----</div>
<div> DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);</div>
<div> }</div>
<div> </div>
<div>+ SDValue SparcTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG,</div>
<div>+ const SparcTargetLowering &TLI) const {</div>
<div>+ SDLoc DL(Op);</div>
<div>+ return DAG.getNode(SPISD::EH_SJLJ_SETJMP, DL,</div>
<div>+ DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0), Op.getOperand(1));</div>
<div>+ </div>
<div>+ }</div>
<div>+ </div>
<div>+ SDValue SparcTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG,</div>
<div>+ const SparcTargetLowering &TLI) const {</div>
<div>+ SDLoc DL(Op);</div>
<div>+ return DAG.getNode(SPISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0), Op.getOperand(1));</div>
<div>+ }</div>
<div>+ </div>
<div> static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,</div>
<div> const SparcTargetLowering &TLI) {</div>
<div> MachineFunction &MF = DAG.getMachineFunction();</div>
<div>***************</div>
<div>*** 3004,3009 ****</div>
<div>--- 3023,3030 ----</div>
<div> hasHardQuad);</div>
<div> case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, *this,</div>
<div> hasHardQuad);</div>
<div>+ case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG, *this);</div>
<div>+ case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG, *this);</div>
<div> case ISD::VASTART: return LowerVASTART(Op, DAG, *this);</div>
<div> case ISD::VAARG: return LowerVAARG(Op, DAG);</div>
<div> case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,</div>
<div>***************</div>
<div>*** 3052,3057 ****</div>
<div>--- 3073,3085 ----</div>
<div> case SP::SELECT_CC_DFP_FCC:</div>
<div> case SP::SELECT_CC_QFP_FCC:</div>
<div> return expandSelectCC(MI, BB, SP::FBCOND);</div>
<div>+ case SP::EH_SJLJ_SETJMP32ri:</div>
<div>+ case SP::EH_SJLJ_SETJMP32rr:</div>
<div>+ return emitEHSjLjSetJmp(MI, BB);</div>
<div>+ case SP::EH_SJLJ_LONGJMP32rr:</div>
<div>+ case SP::EH_SJLJ_LONGJMP32ri:</div>
<div>+ return emitEHSjLjLongJmp(MI, BB);</div>
<div>+ </div>
<div> }</div>
<div> }</div>
<div> </div>
<div>***************</div>
<div>*** 3114,3119 ****</div>
<div>--- 3142,3352 ----</div>
<div> return BB;</div>
<div> }</div>
<div> </div>
<div>+ MachineBasicBlock* SparcTargetLowering::</div>
<div>+ emitEHSjLjLongJmp(MachineInstr *MI,</div>
<div>+ MachineBasicBlock *MBB) const</div>
<div>+ {</div>
<div>+ DebugLoc DL = MI->getDebugLoc();</div>
<div>+ const TargetInstrInfo *TII = Subtarget->getInstrInfo();</div>
<div>+ </div>
<div>+ MachineFunction *MF = MBB->getParent();</div>
<div>+ MachineRegisterInfo &MRI = MF->getRegInfo();</div>
<div>+ MachineInstrBuilder MIB;</div>
<div>+ </div>
<div>+ // Memory Reference</div>
<div>+ MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin();</div>
<div>+ MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();</div>
<div>+ </div>
<div>+ MVT PVT = getPointerTy(MF->getDataLayout());</div>
<div>+ unsigned PtrSize = PVT.getStoreSize();</div>
<div>+ assert(PVT == MVT::i32 && "Invalid Pointer Size!");</div>
<div>+ </div>
<div>+ unsigned Buf = MI->getOperand(0).getReg();</div>
<div>+ unsigned JmpLoc = MRI.createVirtualRegister(&SP::IntRegsRegClass);</div>
<div>+ </div>
<div>+ // Instruction to load jmp location</div>
<div>+ MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))</div>
<div>+ .addReg(JmpLoc, RegState::Define)</div>
<div>+ .addReg(Buf)</div>
<div>+ .addImm(PtrSize);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // TO DO: If we do 64-bit handling, this perhaps should be FLUSHW, not TA 3</div>
<div>+ const long int TRAP_COND_ALWAYS = 0x08;</div>
<div>+ MIB = BuildMI(*MBB, MI, DL, TII->get(SP::TRAPri), SP::G0).addImm(3).addImm(TRAP_COND_ALWAYS);</div>
<div>+ </div>
<div>+ // Instruction to restore FP</div>
<div>+ const unsigned FP = SP::I6;</div>
<div>+ MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))</div>
<div>+ .addReg(FP)</div>
<div>+ .addReg(Buf)</div>
<div>+ .addImm(0);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to restore SP</div>
<div>+ const unsigned SP = SP::O6;</div>
<div>+ MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))</div>
<div>+ .addReg(SP)</div>
<div>+ .addReg(Buf)</div>
<div>+ .addImm(2 * PtrSize);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to restore I7</div>
<div>+ MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))</div>
<div>+ .addReg(SP::I7)</div>
<div>+ .addReg(Buf, RegState::Kill)</div>
<div>+ .addImm(3 * PtrSize);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Jump to JmpLoc</div>
<div>+ BuildMI(*MBB, MI, DL, TII->get(SP::JMPLrr)).addReg(SP::G0).addReg(JmpLoc, RegState::Kill).addReg(SP::G0);</div>
<div>+ </div>
<div>+ MI->eraseFromParent();</div>
<div>+ return MBB;</div>
<div>+ }</div>
<div>+ </div>
<div>+ MachineBasicBlock* SparcTargetLowering::</div>
<div>+ emitEHSjLjSetJmp(MachineInstr *MI,</div>
<div>+ MachineBasicBlock *MBB) const</div>
<div>+ {</div>
<div>+ DebugLoc DL = MI->getDebugLoc();</div>
<div>+ const TargetInstrInfo *TII = Subtarget->getInstrInfo();</div>
<div>+ </div>
<div>+ MachineFunction *MF = MBB->getParent();</div>
<div>+ MachineRegisterInfo &MRI = MF->getRegInfo();</div>
<div>+ </div>
<div>+ // Memory Reference</div>
<div>+ MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin();</div>
<div>+ MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();</div>
<div>+ </div>
<div>+ MVT PVT = getPointerTy(MF->getDataLayout());</div>
<div>+ unsigned PtrSize = PVT.getStoreSize();</div>
<div>+ assert(PVT == MVT::i32 && "Invalid Pointer Size!");</div>
<div>+ </div>
<div>+ // Need to "fix-up" this value later.</div>
<div>+ unsigned DstReg = MI->getOperand(0).getReg();</div>
<div>+ const TargetRegisterClass *RC = MRI.getRegClass(DstReg);</div>
<div>+ assert(RC->hasType(MVT::i32) && "Invalid destination!");</div>
<div>+ unsigned mainDstReg = MRI.createVirtualRegister(RC);</div>
<div>+ unsigned restoreDstReg = MRI.createVirtualRegister(RC);</div>
<div>+ </div>
<div>+ // For v = setjmp(buf), we generate</div>
<div>+ //</div>
<div>+ // thisMBB:</div>
<div>+ // SjLjSetup mainMBB</div>
<div>+ // bl mainMBB</div>
<div>+ // v_restore = 1</div>
<div>+ // b sinkMBB</div>
<div>+ //</div>
<div>+ // mainMBB:</div>
<div>+ // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB</div>
<div>+ // v_main = 0</div>
<div>+ //</div>
<div>+ // sinkMBB:</div>
<div>+ // v = phi(main, restore)</div>
<div>+ </div>
<div>+ </div>
<div>+ const BasicBlock *BB = MBB->getBasicBlock();</div>
<div>+ MachineFunction::iterator It = ++MBB->getIterator();</div>
<div>+ MachineBasicBlock *thisMBB = MBB;</div>
<div>+ const BasicBlock* mainBB = BasicBlock::Create(BB->getContext(), "setjmp.main");</div>
<div>+ MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(mainBB);</div>
<div>+ mainMBB->setHasAddressTaken();</div>
<div>+ const BasicBlock* sinkBB = BasicBlock::Create(BB->getContext(), "setjmp.sink");</div>
<div>+ MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(sinkBB);</div>
<div>+ sinkMBB->setHasAddressTaken();</div>
<div>+ </div>
<div>+ MF->insert(It, mainMBB);</div>
<div>+ MF->insert(It, sinkMBB);</div>
<div>+ </div>
<div>+ // Transfer the remainder of BB and its successor edges to sinkMBB.</div>
<div>+ sinkMBB->splice(sinkMBB->begin(), MBB,</div>
<div>+ std::next(MachineBasicBlock::iterator(MI)),</div>
<div>+ MBB->end());</div>
<div>+ sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);</div>
<div>+ </div>
<div>+ MachineInstrBuilder MIB;</div>
<div>+ </div>
<div>+ unsigned LabelReg = MRI.createVirtualRegister(&SP::IntRegsRegClass);</div>
<div>+ unsigned BufReg = MI->getOperand(1).getReg();</div>
<div>+ </div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::SETHIi))</div>
<div>+ .addReg(LabelReg, RegState::Define)</div>
<div>+ .addMBB(sinkMBB, SparcMCExpr::VK_Sparc_HI);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::ADDri))</div>
<div>+ .addReg(LabelReg)</div>
<div>+ .addReg(LabelReg)</div>
<div>+ .addMBB(sinkMBB, SparcMCExpr::VK_Sparc_LO);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to store FP</div>
<div>+ const unsigned FP = SP::I6;</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::STri))</div>
<div>+ .addReg(BufReg)</div>
<div>+ .addImm(0)</div>
<div>+ .addReg(FP);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to store jmp location</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::STri))</div>
<div>+ .addReg(BufReg)</div>
<div>+ .addImm(PtrSize)</div>
<div>+ .addReg(LabelReg, RegState::Kill);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to store SP</div>
<div>+ const unsigned SP = SP::O6;</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::STri))</div>
<div>+ .addReg(BufReg)</div>
<div>+ .addImm(2 * PtrSize)</div>
<div>+ .addReg(SP);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ // Instruction to store I7</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::STri))</div>
<div>+ .addReg(BufReg)</div>
<div>+ .addImm(3 * PtrSize)</div>
<div>+ .addReg(SP::I7);</div>
<div>+ MIB.setMemRefs(MMOBegin, MMOEnd);</div>
<div>+ </div>
<div>+ </div>
<div>+ // Setup</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::BCOND)).addMBB(mainMBB).addImm(SPCC::ICC_A);</div>
<div>+ const SparcRegisterInfo* TRI = Subtarget->getRegisterInfo();</div>
<div>+ MIB.addRegMask(TRI->getNoPreservedMask());</div>
<div>+ </div>
<div>+ BuildMI(thisMBB, DL, TII->get(SP::LDri))</div>
<div>+ .addReg(restoreDstReg, RegState::Define)</div>
<div>+ .addImm(1)</div>
<div>+ .addReg(SP::G0);</div>
<div>+ </div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::EH_SjLj_Setup)).addMBB(mainMBB);</div>
<div>+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SP::BCOND)).addMBB(sinkMBB).addImm(SPCC::ICC_A);</div>
<div>+ </div>
<div>+ thisMBB->addSuccessor(mainMBB, BranchProbability::getZero());</div>
<div>+ thisMBB->addSuccessor(sinkMBB, BranchProbability::getOne());</div>
<div>+ </div>
<div>+ </div>
<div>+ // mainMBB:</div>
<div>+ BuildMI(mainMBB, DL, TII->get(SP::ORrr))</div>
<div>+ .addReg(mainDstReg, RegState::Define)</div>
<div>+ .addReg(SP::G0)</div>
<div>+ .addReg(SP::G0);</div>
<div>+ mainMBB->addSuccessor(sinkMBB);</div>
<div>+ </div>
<div>+ </div>
<div>+ // sinkMBB:</div>
<div>+ BuildMI(*sinkMBB, sinkMBB->begin(), DL,</div>
<div>+ TII->get(SP::PHI), DstReg)</div>
<div>+ .addReg(mainDstReg).addMBB(mainMBB)</div>
<div>+ .addReg(restoreDstReg).addMBB(thisMBB);</div>
<div>+ </div>
<div>+ MI->eraseFromParent();</div>
<div>+ return sinkMBB;</div>
<div>+ }</div>
<div>+ </div>
<div> //===----------------------------------------------------------------------===//</div>
<div> // Sparc Inline Assembly Support</div>
<div> //===----------------------------------------------------------------------===//</div>
<div>Index: SparcISelLowering.h</div>
<div>===================================================================</div>
<div>*** SparcISelLowering.h<span class="Apple-tab-span" style="white-space:pre">
</span>(revision 267677)</div>
<div>--- SparcISelLowering.h<span class="Apple-tab-span" style="white-space:pre">
</span>(working copy)</div>
<div>***************</div>
<div>*** 33,38 ****</div>
<div>--- 33,41 ----</div>
<div> SELECT_XCC, // Select between two values using the current XCC flags.</div>
<div> SELECT_FCC, // Select between two values using the current FCC flags.</div>
<div> </div>
<div>+ EH_SJLJ_SETJMP, // builtin setjmp operation</div>
<div>+ EH_SJLJ_LONGJMP, // builtin longjmp operation</div>
<div>+ </div>
<div> Hi, Lo, // Hi/Lo operations, typically on a global address.</div>
<div> </div>
<div> FTOI, // FP to Int within a FP register.</div>
<div>***************</div>
<div>*** 161,166 ****</div>
<div>--- 164,174 ----</div>
<div> SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;</div>
<div> SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;</div>
<div> </div>
<div>+ SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG,</div>
<div>+ const SparcTargetLowering &TLI) const ;</div>
<div>+ SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG,</div>
<div>+ const SparcTargetLowering &TLI) const ;</div>
<div>+ </div>
<div> unsigned getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const;</div>
<div> SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;</div>
<div> SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,</div>
<div>***************</div>
<div>*** 205,210 ****</div>
<div>--- 213,222 ----</div>
<div> MachineBasicBlock *BB,</div>
<div> unsigned Opcode,</div>
<div> unsigned CondCode = 0) const;</div>
<div>+ MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr *MI,</div>
<div>+ MachineBasicBlock *MBB) const;</div>
<div>+ MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr *MI,</div>
<div>+ MachineBasicBlock *MBB) const;</div>
<div> };</div>
<div> } // end namespace llvm</div>
<div> </div>
<div>Index: SparcInstrInfo.td</div>
<div>===================================================================</div>
<div>*** SparcInstrInfo.td<span class="Apple-tab-span" style="white-space:pre"> </span>
(revision 267677)</div>
<div>--- SparcInstrInfo.td<span class="Apple-tab-span" style="white-space:pre"> </span>
(working copy)</div>
<div>***************</div>
<div>*** 154,159 ****</div>
<div>--- 154,162 ----</div>
<div> def SDTSPtlsld :</div>
<div> SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>;</div>
<div> </div>
<div>+ def SDTSPeh_sjlj_setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;</div>
<div>+ def SDTSPeh_sjlj_longjmp: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;</div>
<div>+ </div>
<div> def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>;</div>
<div> def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;</div>
<div> def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;</div>
<div>***************</div>
<div>*** 172,177 ****</div>
<div>--- 175,187 ----</div>
<div> def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>;</div>
<div> def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>;</div>
<div> </div>
<div>+ def SPsjlj_setjmp: SDNode<"SPISD::EH_SJLJ_SETJMP",</div>
<div>+ SDTSPeh_sjlj_setjmp,</div>
<div>+ [SDNPHasChain, SDNPSideEffect]>;</div>
<div>+ def SPsjlj_longjmp: SDNode<"SPISD::EH_SJLJ_LONGJMP",</div>
<div>+ SDTSPeh_sjlj_longjmp,</div>
<div>+ [SDNPHasChain, SDNPSideEffect]>;</div>
<div>+ </div>
<div> // These are target-independent nodes, but have target-specific formats.</div>
<div> def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;</div>
<div> def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,</div>
<div>***************</div>
<div>*** 447,452 ****</div>
<div>--- 457,489 ----</div>
<div> [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>;</div>
<div> }</div>
<div> </div>
<div>+ let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {</div>
<div>+ let Defs = [WIM] in</div>
<div>+ def EH_SJLJ_SETJMP32ri : Pseudo<(outs IntRegs:$dst), (ins MEMri:$buf),</div>
<div>+ "#EH_SJLJ_SETJMP32",</div>
<div>+ [(set i32:$dst, (SPsjlj_setjmp ADDRri:$buf))]>,</div>
<div>+ Requires<[Is32Bit]>;</div>
<div>+ def EH_SJLJ_SETJMP32rr : Pseudo<(outs IntRegs:$dst), (ins MEMrr:$buf),</div>
<div>+ "#EH_SJLJ_SETJMP32",</div>
<div>+ [(set i32:$dst, (SPsjlj_setjmp ADDRrr:$buf))]>,</div>
<div>+ Requires<[Is32Bit]>;</div>
<div>+ let isTerminator = 1 in</div>
<div>+ def EH_SJLJ_LONGJMP32ri : Pseudo<(outs), (ins MEMri:$buf),</div>
<div>+ "#EH_SJLJ_LONGJMP32",</div>
<div>+ [(SPsjlj_longjmp ADDRri:$buf)]>,</div>
<div>+ Requires<[Is32Bit]>;</div>
<div>+ def EH_SJLJ_LONGJMP32rr : Pseudo<(outs), (ins MEMrr:$buf),</div>
<div>+ "#EH_SJLJ_LONGJMP32",</div>
<div>+ [(SPsjlj_longjmp ADDRrr:$buf)]>,</div>
<div>+ Requires<[Is32Bit]>;</div>
<div>+ }</div>
<div>+ </div>
<div>+ let isBranch = 1, isTerminator = 1 in {</div>
<div>+ def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget:$ptr),</div>
<div>+ "#EH_SjLj_Setup\t$ptr", []>,</div>
<div>+ Requires<[Is32Bit]>;</div>
<div>+ }</div>
<div>+ </div>
<div> // Section B.1 - Load Integer Instructions, p. 90</div>
<div> let DecoderMethod = "DecodeLoadInt" in {</div>
<div> defm LDSB : LoadA<"ldsb", 0b001001, 0b011001, sextloadi8, IntRegs, i32>;</div>
</div>
<div><br>
</div>
<div><br>
</div>
</div>
</body>
</html>