xref: /llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp (revision 32bd75716c27d1a094c2436529b596ce1547f6eb)
1cf78715cSZi Xuan Wu //===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- C++ -*---===//
2cf78715cSZi Xuan Wu //
3cf78715cSZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cf78715cSZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
5cf78715cSZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf78715cSZi Xuan Wu //
7cf78715cSZi Xuan Wu //===----------------------------------------------------------------------===//
8cf78715cSZi Xuan Wu //
9cf78715cSZi Xuan Wu // This file contains the CSKY implementation of the TargetRegisterInfo class.
10cf78715cSZi Xuan Wu //
11cf78715cSZi Xuan Wu //===----------------------------------------------------------------------===//
12cf78715cSZi Xuan Wu 
13cf78715cSZi Xuan Wu #include "CSKYRegisterInfo.h"
14cf78715cSZi Xuan Wu #include "CSKY.h"
15cf78715cSZi Xuan Wu #include "CSKYSubtarget.h"
16989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
17cf78715cSZi Xuan Wu #include "llvm/CodeGen/MachineFunction.h"
18cf78715cSZi Xuan Wu #include "llvm/CodeGen/RegisterScavenging.h"
19cf78715cSZi Xuan Wu #include "llvm/MC/MCContext.h"
20cf78715cSZi Xuan Wu 
21cf78715cSZi Xuan Wu #define GET_REGINFO_TARGET_DESC
22cf78715cSZi Xuan Wu #include "CSKYGenRegisterInfo.inc"
23cf78715cSZi Xuan Wu 
24cf78715cSZi Xuan Wu using namespace llvm;
25cf78715cSZi Xuan Wu 
CSKYRegisterInfo()26cf78715cSZi Xuan Wu CSKYRegisterInfo::CSKYRegisterInfo()
27cf78715cSZi Xuan Wu     : CSKYGenRegisterInfo(CSKY::R15, 0, 0, 0) {}
28cf78715cSZi Xuan Wu 
29cf78715cSZi Xuan Wu const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID Id) const30cf78715cSZi Xuan Wu CSKYRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
31cf78715cSZi Xuan Wu                                        CallingConv::ID Id) const {
32cf78715cSZi Xuan Wu   const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
33a190fcdfSZi Xuan Wu   if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
34a190fcdfSZi Xuan Wu     return CSR_GPR_FPR64_RegMask;
35a190fcdfSZi Xuan Wu   if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
36a190fcdfSZi Xuan Wu     return CSR_GPR_FPR32_RegMask;
37cf78715cSZi Xuan Wu   return CSR_I32_RegMask;
38cf78715cSZi Xuan Wu }
39cf78715cSZi Xuan Wu 
getFrameRegister(const MachineFunction & MF) const40cf78715cSZi Xuan Wu Register CSKYRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
41cf78715cSZi Xuan Wu   const TargetFrameLowering *TFI = getFrameLowering(MF);
42cf78715cSZi Xuan Wu   return TFI->hasFP(MF) ? CSKY::R8 : CSKY::R14;
43cf78715cSZi Xuan Wu }
44cf78715cSZi Xuan Wu 
getReservedRegs(const MachineFunction & MF) const45cf78715cSZi Xuan Wu BitVector CSKYRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
46cf78715cSZi Xuan Wu   const CSKYFrameLowering *TFI = getFrameLowering(MF);
47cf78715cSZi Xuan Wu   const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
48cf78715cSZi Xuan Wu   BitVector Reserved(getNumRegs());
49cf78715cSZi Xuan Wu 
50cf78715cSZi Xuan Wu   // Reserve the base register if we need to allocate
51cf78715cSZi Xuan Wu   // variable-sized objects at runtime.
52cf78715cSZi Xuan Wu   if (TFI->hasBP(MF))
53cf78715cSZi Xuan Wu     markSuperRegs(Reserved, CSKY::R7); // bp
54cf78715cSZi Xuan Wu 
55cf78715cSZi Xuan Wu   if (TFI->hasFP(MF))
56cf78715cSZi Xuan Wu     markSuperRegs(Reserved, CSKY::R8); // fp
57cf78715cSZi Xuan Wu 
58cf78715cSZi Xuan Wu   if (!STI.hasE2()) {
59cf78715cSZi Xuan Wu     for (unsigned i = 0; i < 6; i++)
60cf78715cSZi Xuan Wu       markSuperRegs(Reserved, CSKY::R8 + i); // R8 - R13
61cf78715cSZi Xuan Wu   }
62cf78715cSZi Xuan Wu 
63cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R14); // sp
64cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R15); // lr
65cf78715cSZi Xuan Wu 
66cf78715cSZi Xuan Wu   if (!STI.hasHighRegisters()) {
67cf78715cSZi Xuan Wu     for (unsigned i = 0; i < 10; i++)
68cf78715cSZi Xuan Wu       markSuperRegs(Reserved, CSKY::R16 + i); // R16 - R25
69cf78715cSZi Xuan Wu   }
70cf78715cSZi Xuan Wu 
71cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R26);
72cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R27);
73cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R28); // gp
74cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R29);
75cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R30);
76cf78715cSZi Xuan Wu   markSuperRegs(Reserved, CSKY::R31); // tp
77cf78715cSZi Xuan Wu 
78cf78715cSZi Xuan Wu   assert(checkAllSuperRegsMarked(Reserved));
79cf78715cSZi Xuan Wu   return Reserved;
80cf78715cSZi Xuan Wu }
81cf78715cSZi Xuan Wu 
getNoPreservedMask() const82cf78715cSZi Xuan Wu const uint32_t *CSKYRegisterInfo::getNoPreservedMask() const {
83cf78715cSZi Xuan Wu   return CSR_NoRegs_RegMask;
84cf78715cSZi Xuan Wu }
85cf78715cSZi Xuan Wu 
86cf78715cSZi Xuan Wu const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const87cf78715cSZi Xuan Wu CSKYRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
88cf78715cSZi Xuan Wu   const CSKYSubtarget &STI = MF->getSubtarget<CSKYSubtarget>();
89cf78715cSZi Xuan Wu   if (MF->getFunction().hasFnAttribute("interrupt")) {
90a190fcdfSZi Xuan Wu     if (STI.hasFPUv3DoubleFloat())
91a190fcdfSZi Xuan Wu       return CSR_GPR_FPR64v3_ISR_SaveList;
92a190fcdfSZi Xuan Wu     if (STI.hasFPUv3SingleFloat())
93a190fcdfSZi Xuan Wu       return CSR_GPR_FPR32v3_ISR_SaveList;
94a190fcdfSZi Xuan Wu     if (STI.hasFPUv2DoubleFloat())
95a190fcdfSZi Xuan Wu       return CSR_GPR_FPR64_ISR_SaveList;
96a190fcdfSZi Xuan Wu     if (STI.hasFPUv2SingleFloat())
97a190fcdfSZi Xuan Wu       return CSR_GPR_FPR32_ISR_SaveList;
98cf78715cSZi Xuan Wu     return CSR_GPR_ISR_SaveList;
99cf78715cSZi Xuan Wu   }
100cf78715cSZi Xuan Wu 
101a190fcdfSZi Xuan Wu   if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
102a190fcdfSZi Xuan Wu     return CSR_GPR_FPR64_SaveList;
103a190fcdfSZi Xuan Wu   if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
104a190fcdfSZi Xuan Wu     return CSR_GPR_FPR32_SaveList;
105cf78715cSZi Xuan Wu   return CSR_I32_SaveList;
106cf78715cSZi Xuan Wu }
107cf78715cSZi Xuan Wu 
IsLegalOffset(const CSKYInstrInfo * TII,MachineInstr * MI,int & Offset)108a556ec88SZi Xuan Wu static bool IsLegalOffset(const CSKYInstrInfo *TII, MachineInstr *MI,
109a556ec88SZi Xuan Wu                           int &Offset) {
110a556ec88SZi Xuan Wu   const MCInstrDesc &Desc = MI->getDesc();
111a556ec88SZi Xuan Wu   unsigned AddrMode = (Desc.TSFlags & CSKYII::AddrModeMask);
112a556ec88SZi Xuan Wu   unsigned i = 0;
113a556ec88SZi Xuan Wu   for (; !MI->getOperand(i).isFI(); ++i) {
114a556ec88SZi Xuan Wu     assert(i + 1 < MI->getNumOperands() &&
115a556ec88SZi Xuan Wu            "Instr doesn't have FrameIndex operand!");
116a556ec88SZi Xuan Wu   }
117a556ec88SZi Xuan Wu 
118a556ec88SZi Xuan Wu   if (MI->getOpcode() == CSKY::ADDI32) {
119a556ec88SZi Xuan Wu     if (!isUInt<12>(std::abs(Offset) - 1))
120a556ec88SZi Xuan Wu       return false;
121a556ec88SZi Xuan Wu     if (Offset < 0) {
122a556ec88SZi Xuan Wu       MI->setDesc(TII->get(CSKY::SUBI32));
123a556ec88SZi Xuan Wu       Offset = -Offset;
124a556ec88SZi Xuan Wu     }
125a556ec88SZi Xuan Wu 
126a556ec88SZi Xuan Wu     return true;
127a556ec88SZi Xuan Wu   }
128a556ec88SZi Xuan Wu 
129a556ec88SZi Xuan Wu   if (MI->getOpcode() == CSKY::ADDI16XZ)
130a556ec88SZi Xuan Wu     return false;
131a556ec88SZi Xuan Wu 
132a556ec88SZi Xuan Wu   if (Offset < 0)
133a556ec88SZi Xuan Wu     return false;
134a556ec88SZi Xuan Wu 
135a556ec88SZi Xuan Wu   unsigned NumBits = 0;
136a556ec88SZi Xuan Wu   unsigned Scale = 1;
137a556ec88SZi Xuan Wu   switch (AddrMode) {
138a556ec88SZi Xuan Wu   case CSKYII::AddrMode32B:
139a556ec88SZi Xuan Wu     Scale = 1;
140a556ec88SZi Xuan Wu     NumBits = 12;
141a556ec88SZi Xuan Wu     break;
142a556ec88SZi Xuan Wu   case CSKYII::AddrMode32H:
143a556ec88SZi Xuan Wu     Scale = 2;
144a556ec88SZi Xuan Wu     NumBits = 12;
145a556ec88SZi Xuan Wu     break;
146a556ec88SZi Xuan Wu   case CSKYII::AddrMode32WD:
147a556ec88SZi Xuan Wu     Scale = 4;
148a556ec88SZi Xuan Wu     NumBits = 12;
149a556ec88SZi Xuan Wu     break;
150a556ec88SZi Xuan Wu   case CSKYII::AddrMode16B:
151a556ec88SZi Xuan Wu     Scale = 1;
152a556ec88SZi Xuan Wu     NumBits = 5;
153a556ec88SZi Xuan Wu     break;
154a556ec88SZi Xuan Wu   case CSKYII::AddrMode16H:
155a556ec88SZi Xuan Wu     Scale = 2;
156a556ec88SZi Xuan Wu     NumBits = 5;
157a556ec88SZi Xuan Wu     break;
158a556ec88SZi Xuan Wu   case CSKYII::AddrMode16W:
159a556ec88SZi Xuan Wu     Scale = 4;
160a556ec88SZi Xuan Wu     NumBits = 5;
161a556ec88SZi Xuan Wu     break;
162a556ec88SZi Xuan Wu   case CSKYII::AddrMode32SDF:
163a556ec88SZi Xuan Wu     Scale = 4;
164a556ec88SZi Xuan Wu     NumBits = 8;
165a556ec88SZi Xuan Wu     break;
166a556ec88SZi Xuan Wu   default:
167a556ec88SZi Xuan Wu     llvm_unreachable("Unsupported addressing mode!");
168a556ec88SZi Xuan Wu   }
169a556ec88SZi Xuan Wu 
170a556ec88SZi Xuan Wu   // Cannot encode offset.
171a556ec88SZi Xuan Wu   if ((Offset & (Scale - 1)) != 0)
172a556ec88SZi Xuan Wu     return false;
173a556ec88SZi Xuan Wu 
174a556ec88SZi Xuan Wu   unsigned Mask = (1 << NumBits) - 1;
175a556ec88SZi Xuan Wu   if ((unsigned)Offset <= Mask * Scale)
176a556ec88SZi Xuan Wu     return true;
177a556ec88SZi Xuan Wu 
178a556ec88SZi Xuan Wu   // Offset out of range.
179a556ec88SZi Xuan Wu   return false;
180a556ec88SZi Xuan Wu }
181a556ec88SZi Xuan Wu 
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const182*32bd7571SAlexander Timofeev bool CSKYRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
183cf78715cSZi Xuan Wu                                            int SPAdj, unsigned FIOperandNum,
184cf78715cSZi Xuan Wu                                            RegScavenger *RS) const {
185cf78715cSZi Xuan Wu   assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
186a556ec88SZi Xuan Wu 
187a556ec88SZi Xuan Wu   MachineInstr *MI = &*II;
188a556ec88SZi Xuan Wu   MachineBasicBlock &MBB = *MI->getParent();
189a556ec88SZi Xuan Wu   MachineFunction &MF = *MI->getParent()->getParent();
190a556ec88SZi Xuan Wu   MachineRegisterInfo &MRI = MF.getRegInfo();
191a556ec88SZi Xuan Wu   const CSKYInstrInfo *TII = MF.getSubtarget<CSKYSubtarget>().getInstrInfo();
192a556ec88SZi Xuan Wu   DebugLoc DL = MI->getDebugLoc();
193a556ec88SZi Xuan Wu   const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>();
194a556ec88SZi Xuan Wu 
195a556ec88SZi Xuan Wu   switch (MI->getOpcode()) {
196a556ec88SZi Xuan Wu   default:
197a556ec88SZi Xuan Wu     break;
198a556ec88SZi Xuan Wu   case CSKY::RESTORE_CARRY: {
199a556ec88SZi Xuan Wu     Register NewReg = STI.hasE2()
200a556ec88SZi Xuan Wu                           ? MRI.createVirtualRegister(&CSKY::GPRRegClass)
201a556ec88SZi Xuan Wu                           : MRI.createVirtualRegister(&CSKY::mGPRRegClass);
202a556ec88SZi Xuan Wu 
203a556ec88SZi Xuan Wu     auto *Temp = BuildMI(MBB, II, DL, TII->get(CSKY::LD32W), NewReg)
204a556ec88SZi Xuan Wu                      .add(MI->getOperand(1))
205a556ec88SZi Xuan Wu                      .add(MI->getOperand(2))
206a556ec88SZi Xuan Wu                      .getInstr();
207a556ec88SZi Xuan Wu 
208a556ec88SZi Xuan Wu     BuildMI(MBB, II, DL, TII->get(STI.hasE2() ? CSKY::BTSTI32 : CSKY::BTSTI16),
209a556ec88SZi Xuan Wu             MI->getOperand(0).getReg())
210a556ec88SZi Xuan Wu         .addReg(NewReg, getKillRegState(true))
211a556ec88SZi Xuan Wu         .addImm(0);
212a556ec88SZi Xuan Wu 
213a556ec88SZi Xuan Wu     MI = Temp;
214a556ec88SZi Xuan Wu 
215a556ec88SZi Xuan Wu     MBB.erase(II);
216a556ec88SZi Xuan Wu     break;
217a556ec88SZi Xuan Wu   }
218a556ec88SZi Xuan Wu   case CSKY::SPILL_CARRY: {
219a556ec88SZi Xuan Wu     Register NewReg;
220a556ec88SZi Xuan Wu     if (STI.hasE2()) {
221a556ec88SZi Xuan Wu       NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
222a556ec88SZi Xuan Wu       BuildMI(MBB, II, DL, TII->get(CSKY::MVC32), NewReg)
223a556ec88SZi Xuan Wu           .add(MI->getOperand(0));
224a556ec88SZi Xuan Wu     } else {
225a556ec88SZi Xuan Wu       NewReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
226a556ec88SZi Xuan Wu       BuildMI(MBB, II, DL, TII->get(CSKY::MOVI16), NewReg).addImm(0);
227a556ec88SZi Xuan Wu       BuildMI(MBB, II, DL, TII->get(CSKY::ADDC16))
228a556ec88SZi Xuan Wu           .addReg(NewReg, RegState::Define)
229a556ec88SZi Xuan Wu           .addReg(MI->getOperand(0).getReg(), RegState::Define)
230a556ec88SZi Xuan Wu           .addReg(NewReg, getKillRegState(true))
231a556ec88SZi Xuan Wu           .addReg(NewReg, getKillRegState(true))
232a556ec88SZi Xuan Wu           .addReg(MI->getOperand(0).getReg());
233a556ec88SZi Xuan Wu 
234a556ec88SZi Xuan Wu       BuildMI(MBB, II, DL, TII->get(CSKY::BTSTI16), MI->getOperand(0).getReg())
235a556ec88SZi Xuan Wu           .addReg(NewReg)
236a556ec88SZi Xuan Wu           .addImm(0);
237a556ec88SZi Xuan Wu     }
238a556ec88SZi Xuan Wu 
239a556ec88SZi Xuan Wu     MI = BuildMI(MBB, II, DL, TII->get(CSKY::ST32W))
240a556ec88SZi Xuan Wu              .addReg(NewReg, getKillRegState(true))
241a556ec88SZi Xuan Wu              .add(MI->getOperand(1))
242a556ec88SZi Xuan Wu              .add(MI->getOperand(2))
243a556ec88SZi Xuan Wu              .getInstr();
244a556ec88SZi Xuan Wu 
245a556ec88SZi Xuan Wu     MBB.erase(II);
246a556ec88SZi Xuan Wu 
247a556ec88SZi Xuan Wu     break;
248a556ec88SZi Xuan Wu   }
249a556ec88SZi Xuan Wu   }
250a556ec88SZi Xuan Wu 
251a556ec88SZi Xuan Wu   int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
252a556ec88SZi Xuan Wu   Register FrameReg;
253a556ec88SZi Xuan Wu   int Offset = getFrameLowering(MF)
254a556ec88SZi Xuan Wu                    ->getFrameIndexReference(MF, FrameIndex, FrameReg)
255a556ec88SZi Xuan Wu                    .getFixed() +
256a556ec88SZi Xuan Wu                MI->getOperand(FIOperandNum + 1).getImm();
257a556ec88SZi Xuan Wu 
258a556ec88SZi Xuan Wu   if (!isInt<32>(Offset))
259a556ec88SZi Xuan Wu     report_fatal_error(
260a556ec88SZi Xuan Wu         "Frame offsets outside of the signed 32-bit range not supported");
261a556ec88SZi Xuan Wu 
262a556ec88SZi Xuan Wu   bool FrameRegIsKill = false;
263a556ec88SZi Xuan Wu   MachineBasicBlock::iterator NewII(MI);
264a556ec88SZi Xuan Wu   if (!IsLegalOffset(TII, MI, Offset)) {
265a556ec88SZi Xuan Wu     assert(isInt<32>(Offset) && "Int32 expected");
266a556ec88SZi Xuan Wu     // The offset won't fit in an immediate, so use a scratch register instead
267a556ec88SZi Xuan Wu     // Modify Offset and FrameReg appropriately
268a556ec88SZi Xuan Wu     Register ScratchReg = TII->movImm(MBB, NewII, DL, Offset);
269a556ec88SZi Xuan Wu     BuildMI(MBB, NewII, DL,
270a556ec88SZi Xuan Wu             TII->get(STI.hasE2() ? CSKY::ADDU32 : CSKY::ADDU16XZ), ScratchReg)
271a556ec88SZi Xuan Wu         .addReg(ScratchReg, RegState::Kill)
272a556ec88SZi Xuan Wu         .addReg(FrameReg);
273a556ec88SZi Xuan Wu 
274a556ec88SZi Xuan Wu     Offset = 0;
275a556ec88SZi Xuan Wu     FrameReg = ScratchReg;
276a556ec88SZi Xuan Wu     FrameRegIsKill = true;
277a556ec88SZi Xuan Wu   }
278a556ec88SZi Xuan Wu 
279a556ec88SZi Xuan Wu   if (Offset == 0 &&
280a556ec88SZi Xuan Wu       (MI->getOpcode() == CSKY::ADDI32 || MI->getOpcode() == CSKY::ADDI16XZ)) {
281a556ec88SZi Xuan Wu     MI->setDesc(TII->get(TargetOpcode::COPY));
282a556ec88SZi Xuan Wu     MI->getOperand(FIOperandNum)
283a556ec88SZi Xuan Wu         .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
28437b37838SShengchen Kan     MI->removeOperand(FIOperandNum + 1);
285a556ec88SZi Xuan Wu   } else {
286a556ec88SZi Xuan Wu     MI->getOperand(FIOperandNum)
287a556ec88SZi Xuan Wu         .ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
288a556ec88SZi Xuan Wu     MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
289a556ec88SZi Xuan Wu   }
290*32bd7571SAlexander Timofeev   return false;
291cf78715cSZi Xuan Wu }
292