================ @@ -200,6 +203,149 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, CFIInstBuilder(MBB, MI, MachineInstr::FrameDestroy).buildRestore(SCSPReg); } +// Insert instruction to swap mscratchsw with sp +static void emitSiFiveCLICStackSwap(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + const DebugLoc &DL) { + auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); + + if (!RVFI->isSiFiveStackSwapInterrupt(MF)) + return; + + const auto &STI = MF.getSubtarget<RISCVSubtarget>(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); + + assert(STI.hasVendorXSfmclic() && "Stack Swapping Requires XSfmclic"); + + BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRW)) + .addReg(SPReg, RegState::Define) + .addImm(RISCVSysReg::sf_mscratchcsw) + .addReg(SPReg, RegState::Kill) + .setMIFlag(MachineInstr::FrameSetup); + + // FIXME: CFI Information for this swap. +} + +static void +createSiFivePreemptibleInterruptFrameEntries(MachineFunction &MF, + RISCVMachineFunctionInfo &RVFI) { + if (!RVFI.isSiFivePreemptibleInterrupt(MF)) + return; + + const TargetRegisterClass &RC = RISCV::GPRRegClass; + const TargetRegisterInfo &TRI = + *MF.getSubtarget<RISCVSubtarget>().getRegisterInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + + // Create two frame objects for spilling X8 and X9, which will be done in + // `emitSiFiveCLICPreemptibleSaves`. This is in addition to any other stack + // objects we might have for X8 and X9, as they might be saved twice. + for (int I = 0; I < 2; ++I) { + int FI = MFI.CreateStackObject(TRI.getSpillSize(RC), TRI.getSpillAlign(RC), + true); + RVFI.pushInterruptCSRFrameIndex(FI); + } +} + +static void emitSiFiveCLICPreemptibleSaves(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + const DebugLoc &DL) { + auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); + + if (!RVFI->isSiFivePreemptibleInterrupt(MF)) + return; + + const auto &STI = MF.getSubtarget<RISCVSubtarget>(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); + + // FIXME: CFI Information here is nonexistent/wrong. + + // X8 and X9 might be stored into the stack twice, initially into the + // `interruptCSRFrameIndex` here, and then maybe again into their CSI frame + // index. + // + // This is done instead of telling the register allocator that we need two + // VRegs to store the value of `mcause` and `mepc` through the instruction, + // which affects other passes. + TII->storeRegToStackSlot(MBB, MBBI, RISCV::X8, /* IsKill=*/true, + RVFI->getInterruptCSRFrameIndex(0), + &RISCV::GPRRegClass, STI.getRegisterInfo(), + Register(), MachineInstr::FrameSetup); + TII->storeRegToStackSlot(MBB, MBBI, RISCV::X9, /* IsKill=*/true, + RVFI->getInterruptCSRFrameIndex(1), + &RISCV::GPRRegClass, STI.getRegisterInfo(), + Register(), MachineInstr::FrameSetup); + + // Put `mcause` into X8 (s0), and `mepc` into X9 (s1). If either of these are + // used in the function, then they will appear in `getUnmanagedCSI` and will + // be saved again. + BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRS)) + .addReg(RISCV::X8, RegState::Define) + .addImm(RISCVSysReg::mcause) + .addReg(RISCV::X0) + .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRS)) + .addReg(RISCV::X9, RegState::Define) + .addImm(RISCVSysReg::lookupSysRegByName("MEPC")->Encoding) ---------------- topperc wrote:
Can we use `RISCVSysReg::mepc` here to avoid the table lookup? https://github.com/llvm/llvm-project/pull/132481 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits