1 //===-- CSKYFrameLowering.cpp - CSKY Frame Information ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the CSKY implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CSKYFrameLowering.h"
14 #include "CSKYMachineFunctionInfo.h"
15 #include "CSKYSubtarget.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/RegisterScavenging.h"
21 #include "llvm/IR/DiagnosticInfo.h"
22 #include "llvm/MC/MCDwarf.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "csky-frame-lowering"
27 
28 // Returns the register used to hold the frame pointer.
29 static Register getFPReg(const CSKYSubtarget &STI) { return CSKY::R8; }
30 
31 // To avoid the BP value clobbered by a function call, we need to choose a
32 // callee saved register to save the value.
33 static Register getBPReg(const CSKYSubtarget &STI) { return CSKY::R7; }
34 
35 bool CSKYFrameLowering::hasFP(const MachineFunction &MF) const {
36   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
37 
38   const MachineFrameInfo &MFI = MF.getFrameInfo();
39   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
40          RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
41          MFI.isFrameAddressTaken();
42 }
43 
44 bool CSKYFrameLowering::hasBP(const MachineFunction &MF) const {
45   const MachineFrameInfo &MFI = MF.getFrameInfo();
46 
47   return MFI.hasVarSizedObjects();
48 }
49 
50 // Determines the size of the frame and maximum call frame size.
51 void CSKYFrameLowering::determineFrameLayout(MachineFunction &MF) const {
52   MachineFrameInfo &MFI = MF.getFrameInfo();
53   const CSKYRegisterInfo *RI = STI.getRegisterInfo();
54 
55   // Get the number of bytes to allocate from the FrameInfo.
56   uint64_t FrameSize = MFI.getStackSize();
57 
58   // Get the alignment.
59   Align StackAlign = getStackAlign();
60   if (RI->hasStackRealignment(MF)) {
61     Align MaxStackAlign = std::max(StackAlign, MFI.getMaxAlign());
62     FrameSize += (MaxStackAlign.value() - StackAlign.value());
63     StackAlign = MaxStackAlign;
64   }
65 
66   // Set Max Call Frame Size
67   uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);
68   MFI.setMaxCallFrameSize(MaxCallSize);
69 
70   // Make sure the frame is aligned.
71   FrameSize = alignTo(FrameSize, StackAlign);
72 
73   // Update frame info.
74   MFI.setStackSize(FrameSize);
75 }
76 
77 void CSKYFrameLowering::emitPrologue(MachineFunction &MF,
78                                      MachineBasicBlock &MBB) const {
79   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
80   MachineFrameInfo &MFI = MF.getFrameInfo();
81   const CSKYRegisterInfo *RI = STI.getRegisterInfo();
82   const CSKYInstrInfo *TII = STI.getInstrInfo();
83   MachineBasicBlock::iterator MBBI = MBB.begin();
84   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
85   const MachineRegisterInfo &MRI = MF.getRegInfo();
86 
87   Register FPReg = getFPReg(STI);
88   Register SPReg = CSKY::R14;
89   Register BPReg = getBPReg(STI);
90 
91   // Debug location must be unknown since the first debug location is used
92   // to determine the end of the prologue.
93   DebugLoc DL;
94 
95   if (MF.getFunction().hasFnAttribute("interrupt"))
96     BuildMI(MBB, MBBI, DL, TII->get(CSKY::NIE));
97 
98   // Determine the correct frame layout
99   determineFrameLayout(MF);
100 
101   // FIXME (note copied from Lanai): This appears to be overallocating.  Needs
102   // investigation. Get the number of bytes to allocate from the FrameInfo.
103   uint64_t StackSize = MFI.getStackSize();
104 
105   // Early exit if there is no need to allocate on the stack
106   if (StackSize == 0 && !MFI.adjustsStack())
107     return;
108 
109   const auto &CSI = MFI.getCalleeSavedInfo();
110 
111   unsigned spillAreaSize = CFI->getCalleeSaveAreaSize();
112 
113   uint64_t ActualSize = spillAreaSize + CFI->getVarArgsSaveSize();
114 
115   // First part stack allocation.
116   adjustReg(MBB, MBBI, DL, SPReg, SPReg, -(static_cast<int64_t>(ActualSize)),
117             MachineInstr::NoFlags);
118 
119   // Emit ".cfi_def_cfa_offset FirstSPAdjustAmount"
120   unsigned CFIIndex =
121       MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, ActualSize));
122   BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
123       .addCFIIndex(CFIIndex);
124 
125   // The frame pointer is callee-saved, and code has been generated for us to
126   // save it to the stack. We need to skip over the storing of callee-saved
127   // registers as the frame pointer must be modified after it has been saved
128   // to the stack, not before.
129   // FIXME: assumes exactly one instruction is used to save each callee-saved
130   // register.
131   std::advance(MBBI, CSI.size());
132 
133   // Iterate over list of callee-saved registers and emit .cfi_offset
134   // directives.
135   for (const auto &Entry : CSI) {
136     int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx());
137     Register Reg = Entry.getReg();
138 
139     unsigned Num = TRI->getRegSizeInBits(Reg, MRI) / 32;
140     for (unsigned i = 0; i < Num; i++) {
141       unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
142           nullptr, RI->getDwarfRegNum(Reg, true) + i, Offset + i * 4));
143       BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
144           .addCFIIndex(CFIIndex);
145     }
146   }
147 
148   // Generate new FP.
149   if (hasFP(MF)) {
150     BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), FPReg)
151         .addReg(SPReg)
152         .setMIFlag(MachineInstr::FrameSetup);
153 
154     // Emit ".cfi_def_cfa_register $fp"
155     unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
156         nullptr, RI->getDwarfRegNum(FPReg, true)));
157     BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
158         .addCFIIndex(CFIIndex);
159 
160     // Second part stack allocation.
161     adjustReg(MBB, MBBI, DL, SPReg, SPReg,
162               -(static_cast<int64_t>(StackSize - ActualSize)),
163               MachineInstr::NoFlags);
164 
165     // Realign Stack
166     const CSKYRegisterInfo *RI = STI.getRegisterInfo();
167     if (RI->hasStackRealignment(MF)) {
168       Align MaxAlignment = MFI.getMaxAlign();
169 
170       const CSKYInstrInfo *TII = STI.getInstrInfo();
171       if (STI.hasE2() && isUInt<12>(~(-(int)MaxAlignment.value()))) {
172         BuildMI(MBB, MBBI, DL, TII->get(CSKY::ANDNI32), SPReg)
173             .addReg(SPReg)
174             .addImm(~(-(int)MaxAlignment.value()));
175       } else {
176         unsigned ShiftAmount = Log2(MaxAlignment);
177 
178         if (STI.hasE2()) {
179           Register VR =
180               MF.getRegInfo().createVirtualRegister(&CSKY::GPRRegClass);
181           BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI32), VR)
182               .addReg(SPReg)
183               .addImm(ShiftAmount);
184           BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI32), SPReg)
185               .addReg(VR)
186               .addImm(ShiftAmount);
187         } else {
188           Register VR =
189               MF.getRegInfo().createVirtualRegister(&CSKY::mGPRRegClass);
190           BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), VR).addReg(SPReg);
191           BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI16), VR)
192               .addReg(VR)
193               .addImm(ShiftAmount);
194           BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI16), VR)
195               .addReg(VR)
196               .addImm(ShiftAmount);
197           BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), SPReg).addReg(VR);
198         }
199       }
200     }
201 
202     // FP will be used to restore the frame in the epilogue, so we need
203     // another base register BP to record SP after re-alignment. SP will
204     // track the current stack after allocating variable sized objects.
205     if (hasBP(MF)) {
206       // move BP, SP
207       BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), BPReg).addReg(SPReg);
208     }
209 
210   } else {
211     adjustReg(MBB, MBBI, DL, SPReg, SPReg,
212               -(static_cast<int64_t>(StackSize - ActualSize)),
213               MachineInstr::NoFlags);
214     // Emit ".cfi_def_cfa_offset StackSize"
215     unsigned CFIIndex = MF.addFrameInst(
216         MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));
217     BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
218         .addCFIIndex(CFIIndex);
219   }
220 }
221 
222 void CSKYFrameLowering::emitEpilogue(MachineFunction &MF,
223                                      MachineBasicBlock &MBB) const {
224   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
225 
226   MachineFrameInfo &MFI = MF.getFrameInfo();
227   Register FPReg = getFPReg(STI);
228   Register SPReg = CSKY::R14;
229 
230   // Get the insert location for the epilogue. If there were no terminators in
231   // the block, get the last instruction.
232   MachineBasicBlock::iterator MBBI = MBB.end();
233   DebugLoc DL;
234   if (!MBB.empty()) {
235     MBBI = MBB.getFirstTerminator();
236     if (MBBI == MBB.end())
237       MBBI = MBB.getLastNonDebugInstr();
238     DL = MBBI->getDebugLoc();
239 
240     // If this is not a terminator, the actual insert location should be after
241     // the last instruction.
242     if (!MBBI->isTerminator())
243       MBBI = std::next(MBBI);
244   }
245 
246   const auto &CSI = MFI.getCalleeSavedInfo();
247   uint64_t StackSize = MFI.getStackSize();
248 
249   uint64_t ActualSize =
250       CFI->getCalleeSaveAreaSize() + CFI->getVarArgsSaveSize();
251 
252   // Skip to before the restores of callee-saved registers
253   // FIXME: assumes exactly one instruction is used to restore each
254   // callee-saved register.
255   auto LastFrameDestroy = MBBI;
256   if (!CSI.empty())
257     LastFrameDestroy = std::prev(MBBI, CSI.size());
258 
259   if (hasFP(MF)) {
260     const CSKYInstrInfo *TII = STI.getInstrInfo();
261     BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::COPY), SPReg)
262         .addReg(FPReg)
263         .setMIFlag(MachineInstr::NoFlags);
264   } else {
265     adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, (StackSize - ActualSize),
266               MachineInstr::FrameDestroy);
267   }
268 
269   adjustReg(MBB, MBBI, DL, SPReg, SPReg, ActualSize,
270             MachineInstr::FrameDestroy);
271 }
272 
273 static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
274                                          const CSKYSubtarget &STI) {
275   unsigned Limit = (1 << 12) - 1;
276 
277   for (auto &MBB : MF) {
278     for (auto &MI : MBB) {
279       if (MI.isDebugInstr())
280         continue;
281 
282       for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
283         if (!MI.getOperand(i).isFI())
284           continue;
285 
286         if (MI.getOpcode() == CSKY::SPILL_CARRY ||
287             MI.getOpcode() == CSKY::RESTORE_CARRY ||
288             MI.getOpcode() == CSKY::STORE_PAIR ||
289             MI.getOpcode() == CSKY::LOAD_PAIR) {
290           Limit = std::min(Limit, ((1U << 12) - 1) * 4);
291           break;
292         }
293 
294         if (MI.getOpcode() == CSKY::ADDI32) {
295           Limit = std::min(Limit, (1U << 12));
296           break;
297         }
298 
299         if (MI.getOpcode() == CSKY::ADDI16XZ) {
300           Limit = std::min(Limit, (1U << 3));
301           break;
302         }
303 
304         // ADDI16 will not require an extra register,
305         // it can reuse the destination.
306         if (MI.getOpcode() == CSKY::ADDI16)
307           break;
308 
309         // Otherwise check the addressing mode.
310         switch (MI.getDesc().TSFlags & CSKYII::AddrModeMask) {
311         default:
312           LLVM_DEBUG(MI.dump());
313           llvm_unreachable(
314               "Unhandled addressing mode in stack size limit calculation");
315         case CSKYII::AddrMode32B:
316           Limit = std::min(Limit, (1U << 12) - 1);
317           break;
318         case CSKYII::AddrMode32H:
319           Limit = std::min(Limit, ((1U << 12) - 1) * 2);
320           break;
321         case CSKYII::AddrMode32WD:
322           Limit = std::min(Limit, ((1U << 12) - 1) * 4);
323           break;
324         case CSKYII::AddrMode16B:
325           Limit = std::min(Limit, (1U << 5) - 1);
326           break;
327         case CSKYII::AddrMode16H:
328           Limit = std::min(Limit, ((1U << 5) - 1) * 2);
329           break;
330         case CSKYII::AddrMode16W:
331           Limit = std::min(Limit, ((1U << 5) - 1) * 4);
332           break;
333         case CSKYII::AddrMode32SDF:
334           Limit = std::min(Limit, ((1U << 8) - 1) * 4);
335           break;
336         }
337         break; // At most one FI per instruction
338       }
339     }
340   }
341 
342   return Limit;
343 }
344 
345 void CSKYFrameLowering::determineCalleeSaves(MachineFunction &MF,
346                                              BitVector &SavedRegs,
347                                              RegScavenger *RS) const {
348   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
349 
350   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
351   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
352   const MachineRegisterInfo &MRI = MF.getRegInfo();
353   MachineFrameInfo &MFI = MF.getFrameInfo();
354 
355   if (hasFP(MF))
356     SavedRegs.set(CSKY::R8);
357 
358   // Mark BP as used if function has dedicated base pointer.
359   if (hasBP(MF))
360     SavedRegs.set(CSKY::R7);
361 
362   // If interrupt is enabled and there are calls in the handler,
363   // unconditionally save all Caller-saved registers and
364   // all FP registers, regardless whether they are used.
365   if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {
366 
367     static const MCPhysReg CSRegs[] = {CSKY::R0,  CSKY::R1,  CSKY::R2, CSKY::R3,
368                                        CSKY::R12, CSKY::R13, 0};
369 
370     for (unsigned i = 0; CSRegs[i]; ++i)
371       SavedRegs.set(CSRegs[i]);
372 
373     if (STI.hasHighRegisters()) {
374 
375       static const MCPhysReg CSHRegs[] = {CSKY::R18, CSKY::R19, CSKY::R20,
376                                           CSKY::R21, CSKY::R22, CSKY::R23,
377                                           CSKY::R24, CSKY::R25, 0};
378 
379       for (unsigned i = 0; CSHRegs[i]; ++i)
380         SavedRegs.set(CSHRegs[i]);
381     }
382 
383     static const MCPhysReg CSF32Regs[] = {
384         CSKY::F8_32,  CSKY::F9_32,  CSKY::F10_32,
385         CSKY::F11_32, CSKY::F12_32, CSKY::F13_32,
386         CSKY::F14_32, CSKY::F15_32, 0};
387     static const MCPhysReg CSF64Regs[] = {
388         CSKY::F8_64,  CSKY::F9_64,  CSKY::F10_64,
389         CSKY::F11_64, CSKY::F12_64, CSKY::F13_64,
390         CSKY::F14_64, CSKY::F15_64, 0};
391 
392     const MCPhysReg *FRegs = NULL;
393     if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
394       FRegs = CSF64Regs;
395     else if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
396       FRegs = CSF32Regs;
397 
398     if (FRegs != NULL) {
399       const MCPhysReg *Regs = MF.getRegInfo().getCalleeSavedRegs();
400 
401       for (unsigned i = 0; Regs[i]; ++i)
402         if (CSKY::FPR32RegClass.contains(Regs[i]) ||
403             CSKY::FPR64RegClass.contains(Regs[i])) {
404           unsigned x = 0;
405           for (; FRegs[x]; ++x)
406             if (FRegs[x] == Regs[i])
407               break;
408           if (FRegs[x] == 0)
409             SavedRegs.set(Regs[i]);
410         }
411     }
412   }
413 
414   CFI->setLRIsSpilled(SavedRegs.test(CSKY::R15));
415 
416   unsigned CSStackSize = 0;
417   for (unsigned Reg : SavedRegs.set_bits()) {
418     auto RegSize = TRI->getRegSizeInBits(Reg, MRI) / 8;
419     CSStackSize += RegSize;
420   }
421 
422   CFI->setCalleeSaveAreaSize(CSStackSize);
423 
424   uint64_t Limit = estimateRSStackSizeLimit(MF, STI);
425 
426   bool BigFrame = (MFI.estimateStackSize(MF) + CSStackSize >= Limit);
427 
428   if (BigFrame || CFI->isCRSpilled() || !STI.hasE2()) {
429     const TargetRegisterClass *RC = &CSKY::GPRRegClass;
430     unsigned size = TRI->getSpillSize(*RC);
431     Align align = TRI->getSpillAlign(*RC);
432 
433     RS->addScavengingFrameIndex(MFI.CreateStackObject(size, align, false));
434   }
435 }
436 
437 // Not preserve stack space within prologue for outgoing variables when the
438 // function contains variable size objects and let eliminateCallFramePseudoInstr
439 // preserve stack space for it.
440 bool CSKYFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
441   return !MF.getFrameInfo().hasVarSizedObjects();
442 }
443 
444 bool CSKYFrameLowering::spillCalleeSavedRegisters(
445     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
446     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
447   if (CSI.empty())
448     return true;
449 
450   MachineFunction *MF = MBB.getParent();
451   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
452   DebugLoc DL;
453   if (MI != MBB.end() && !MI->isDebugInstr())
454     DL = MI->getDebugLoc();
455 
456   for (auto &CS : CSI) {
457     // Insert the spill to the stack frame.
458     Register Reg = CS.getReg();
459     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
460     TII.storeRegToStackSlot(MBB, MI, Reg, true, CS.getFrameIdx(), RC, TRI);
461   }
462 
463   return true;
464 }
465 
466 bool CSKYFrameLowering::restoreCalleeSavedRegisters(
467     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
468     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
469   if (CSI.empty())
470     return true;
471 
472   MachineFunction *MF = MBB.getParent();
473   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
474   DebugLoc DL;
475   if (MI != MBB.end() && !MI->isDebugInstr())
476     DL = MI->getDebugLoc();
477 
478   for (auto &CS : reverse(CSI)) {
479     Register Reg = CS.getReg();
480     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
481     TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI);
482     assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!");
483   }
484 
485   return true;
486 }
487 
488 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
489 MachineBasicBlock::iterator CSKYFrameLowering::eliminateCallFramePseudoInstr(
490     MachineFunction &MF, MachineBasicBlock &MBB,
491     MachineBasicBlock::iterator MI) const {
492   Register SPReg = CSKY::R14;
493   DebugLoc DL = MI->getDebugLoc();
494 
495   if (!hasReservedCallFrame(MF)) {
496     // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
497     // ADJCALLSTACKUP must be converted to instructions manipulating the stack
498     // pointer. This is necessary when there is a variable length stack
499     // allocation (e.g. alloca), which means it's not possible to allocate
500     // space for outgoing arguments from within the function prologue.
501     int64_t Amount = MI->getOperand(0).getImm();
502 
503     if (Amount != 0) {
504       // Ensure the stack remains aligned after adjustment.
505       Amount = alignSPAdjust(Amount);
506 
507       if (MI->getOpcode() == CSKY::ADJCALLSTACKDOWN)
508         Amount = -Amount;
509 
510       adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags);
511     }
512   }
513 
514   return MBB.erase(MI);
515 }
516 
517 void CSKYFrameLowering::adjustReg(MachineBasicBlock &MBB,
518                                   MachineBasicBlock::iterator MBBI,
519                                   const DebugLoc &DL, Register DestReg,
520                                   Register SrcReg, int64_t Val,
521                                   MachineInstr::MIFlag Flag) const {
522   const CSKYInstrInfo *TII = STI.getInstrInfo();
523 
524   if (DestReg == SrcReg && Val == 0)
525     return;
526 
527   // TODO: Add 16-bit instruction support with immediate num
528   if (STI.hasE2() && isUInt<12>(std::abs(Val) - 1)) {
529     BuildMI(MBB, MBBI, DL, TII->get(Val < 0 ? CSKY::SUBI32 : CSKY::ADDI32),
530             DestReg)
531         .addReg(SrcReg)
532         .addImm(std::abs(Val))
533         .setMIFlag(Flag);
534   } else if (!STI.hasE2() && isShiftedUInt<7, 2>(std::abs(Val))) {
535     BuildMI(MBB, MBBI, DL,
536             TII->get(Val < 0 ? CSKY::SUBI16SPSP : CSKY::ADDI16SPSP), CSKY::R14)
537         .addReg(CSKY::R14, RegState::Kill)
538         .addImm(std::abs(Val))
539         .setMIFlag(Flag);
540   } else {
541 
542     unsigned Op = 0;
543 
544     if (STI.hasE2()) {
545       Op = Val < 0 ? CSKY::SUBU32 : CSKY::ADDU32;
546     } else {
547       assert(SrcReg == DestReg);
548       Op = Val < 0 ? CSKY::SUBU16XZ : CSKY::ADDU16XZ;
549     }
550 
551     Register ScratchReg = TII->movImm(MBB, MBBI, DL, std::abs(Val), Flag);
552 
553     BuildMI(MBB, MBBI, DL, TII->get(Op), DestReg)
554         .addReg(SrcReg)
555         .addReg(ScratchReg, RegState::Kill)
556         .setMIFlag(Flag);
557   }
558 }
559 
560 StackOffset
561 CSKYFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
562                                           Register &FrameReg) const {
563   const CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
564   const MachineFrameInfo &MFI = MF.getFrameInfo();
565   const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
566   const auto &CSI = MFI.getCalleeSavedInfo();
567 
568   int MinCSFI = 0;
569   int MaxCSFI = -1;
570 
571   int Offset = MFI.getObjectOffset(FI) + MFI.getOffsetAdjustment();
572 
573   if (CSI.size()) {
574     MinCSFI = CSI[0].getFrameIdx();
575     MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
576   }
577 
578   if (FI >= MinCSFI && FI <= MaxCSFI) {
579     FrameReg = CSKY::R14;
580     Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
581   } else if (RI->hasStackRealignment(MF)) {
582     assert(hasFP(MF));
583     if (!MFI.isFixedObjectIndex(FI)) {
584       FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;
585       Offset += MFI.getStackSize();
586     } else {
587       FrameReg = getFPReg(STI);
588       Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
589     }
590   } else {
591     if (MFI.isFixedObjectIndex(FI) && hasFP(MF)) {
592       FrameReg = getFPReg(STI);
593       Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
594     } else {
595       FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;
596       Offset += MFI.getStackSize();
597     }
598   }
599 
600   return StackOffset::getFixed(Offset);
601 }
602