================ @@ -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) + .addReg(BufReg) + .addImm(FPOffset) + .addReg(0); + } + + // store SP. + BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG)) + .addReg(SystemZ::R15D) + .addReg(BufReg) + .addImm(SPOffset) + .addReg(0); + + // Slot 3(Offset = 2) Backchain value (if building with -mbackchain). + bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain(); + if (BackChain) { + const int64_t BCOffset = 2 * PVT.getStoreSize(); + Register BCReg = MRI.createVirtualRegister(RC); + MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LG), BCReg) + .addReg(SystemZ::R15D) + .addImm(0) + .addReg(0); + + BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG)) + .addReg(BCReg) + .addReg(BufReg) + .addImm(BCOffset) + .addReg(0); + } + + // Setup. + MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::EH_SjLj_Setup)) + .addMBB(restoreMBB); + + const SystemZRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); + MIB.addRegMask(RegInfo->getNoPreservedMask()); + + thisMBB->addSuccessor(mainMBB); + thisMBB->addSuccessor(restoreMBB); + + // mainMBB: + BuildMI(mainMBB, DL, TII->get(SystemZ::LHI), mainDstReg).addImm(0); + mainMBB->addSuccessor(sinkMBB); + + // sinkMBB: + BuildMI(*sinkMBB, sinkMBB->begin(), DL, TII->get(SystemZ::PHI), DstReg) + .addReg(mainDstReg) + .addMBB(mainMBB) + .addReg(restoreDstReg) + .addMBB(restoreMBB); + + // restoreMBB. + BuildMI(restoreMBB, DL, TII->get(SystemZ::LHI), restoreDstReg).addImm(1); + BuildMI(restoreMBB, DL, TII->get(SystemZ::J)).addMBB(sinkMBB); + restoreMBB->addSuccessor(sinkMBB); + + MI.eraseFromParent(); + + return sinkMBB; +} + +MachineBasicBlock * +SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI, + MachineBasicBlock *MBB) const { + + DebugLoc DL = MI.getDebugLoc(); + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + + MachineFunction *MF = MBB->getParent(); + MachineRegisterInfo &MRI = MF->getRegInfo(); + + MVT PVT = getPointerTy(MF->getDataLayout()); + assert((PVT == MVT::i64 || PVT == MVT::i32) && + "Invalid Pointer Size!"); + Register BufReg = MI.getOperand(0).getReg(); + const TargetRegisterClass *RC = MRI.getRegClass(BufReg); + + Register Tmp = MRI.createVirtualRegister(RC); + Register BCReg = MRI.createVirtualRegister(RC); + + MachineInstrBuilder MIB; + + const int64_t FPOffset = 0; + const int64_t LabelOffset = 1 * PVT.getStoreSize(); + const int64_t SPOffset = 3 * PVT.getStoreSize(); + const int64_t LPOffset = 4 * PVT.getStoreSize(); + + MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), Tmp) + .addReg(BufReg) + .addImm(LabelOffset) + .addReg(0); + + MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R11D) ---------------- uweigand wrote:
See above about not hard-coding R11, R15 or the backchain offset here as well. 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