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