================ @@ -940,7 +947,242 @@ bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, return SystemZVectorConstantInfo(Imm).isVectorConstantLegal(Subtarget); } -/// Returns true if stack probing through inline assembly is requested. + +MachineBasicBlock * +SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI, + MachineBasicBlock *MBB) const { + + DebugLoc DL = MI.getDebugLoc(); + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + const SystemZRegisterInfo *TRI = Subtarget.getRegisterInfo(); + + MachineFunction *MF = MBB->getParent(); + MachineRegisterInfo &MRI = MF->getRegInfo(); + + const BasicBlock *BB = MBB->getBasicBlock(); + MachineFunction::iterator I = ++MBB->getIterator(); + + Register DstReg = MI.getOperand(0).getReg(); + const TargetRegisterClass *RC = MRI.getRegClass(DstReg); + assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!"); + Register mainDstReg = MRI.createVirtualRegister(RC); + Register restoreDstReg = MRI.createVirtualRegister(RC); + + MVT PVT = getPointerTy(MF->getDataLayout()); + assert((PVT == MVT::i64 || PVT == MVT::i32) && + "Invalid Pointer Size!"); + // For v = setjmp(buf), we generate. + // Algorithm: + // + // --------- + // | thisMBB | + // --------- + // | + // ------------------------ + // | | + // ---------- --------------- + // | mainMBB | | restoreMBB | + // | v = 0 | | v = 1 | + // ---------- --------------- + // | | + // ------------------------- + // | + // ----------------------------- + // | sinkMBB | + // | phi(v_mainMBB,v_restoreMBB) | + // ----------------------------- + // thisMBB: + // buf[0] = Frame Pointer if hasFP. + // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB. + // buf[BCOffset] = Backchain value if building with -mbackchain. + // buf[SPOffset] = Stack Pointer. + // buf[LPOffset] = We never write this slot with R13, gcc stores R13 always. + // SjLjSetup restoreMBB + // mainMBB: + // v_main = 0 + // sinkMBB: + // v = phi(v_main, v_restore) + // restoreMBB: + // v_restore = 1 + + MachineBasicBlock *thisMBB = MBB; + MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB); + MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB); + MachineBasicBlock *restoreMBB = MF->CreateMachineBasicBlock(BB); + + MF->insert(I, mainMBB); + MF->insert(I, sinkMBB); + MF->push_back(restoreMBB); + restoreMBB->setMachineBlockAddressTaken(); + + MachineInstrBuilder MIB; + + // Transfer the remainder of BB and its successor edges to sinkMBB. + sinkMBB->splice(sinkMBB->begin(), MBB, + std::next(MachineBasicBlock::iterator(MI)), MBB->end()); + sinkMBB->transferSuccessorsAndUpdatePHIs(MBB); + + + // thisMBB: + const int64_t LabelOffset = 1 * PVT.getStoreSize(); // Slot 2. + const int64_t SPOffset = 3 * PVT.getStoreSize(); // Slot 4. + + // Buf address. + Register BufReg = MI.getOperand(1).getReg(); + + unsigned LabelReg = 0; + const TargetRegisterClass *PtrRC = getRegClassFor(PVT); + LabelReg = MRI.createVirtualRegister(PtrRC); + + // prepare IP for longjmp. + BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg) + .addMBB(restoreMBB); + + // store IP for return from jmp, slot 2, offset = 1. + BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG)) + .addReg(LabelReg) + .addReg(BufReg) + .addImm(LabelOffset) + .addReg(0); + + bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF); + if (HasFP) { + const int64_t FPOffset = 0; + BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG)) + .addReg(SystemZ::R11D) ---------------- uweigand wrote:
Even though this function will probably only be used on Linux, we still should use `getFramePointerRegister()` (from `Subtarget.getSpecialRegisters()`) here instead of hardcoding R11. https://github.com/llvm/llvm-project/pull/116642 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits