================
@@ -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)
----------------
lenary wrote:

Oh, I thought I had got these. Yes definitely.

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

Reply via email to