]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
Import Intel Processor Trace decoder library from
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Lanai / LanaiRegisterInfo.cpp
1 //===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the Lanai implementation of the TargetRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "LanaiRegisterInfo.h"
15 #include "Lanai.h"
16 #include "LanaiSubtarget.h"
17 #include "llvm/ADT/BitVector.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23 #include "llvm/CodeGen/TargetFrameLowering.h"
24 #include "llvm/CodeGen/TargetInstrInfo.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/Type.h"
27 #include "llvm/Support/ErrorHandling.h"
28
29 #define GET_REGINFO_TARGET_DESC
30 #include "LanaiGenRegisterInfo.inc"
31
32 using namespace llvm;
33
34 LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {}
35
36 const uint16_t *
37 LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const {
38   return CSR_SaveList;
39 }
40
41 BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
42   BitVector Reserved(getNumRegs());
43
44   Reserved.set(Lanai::R0);
45   Reserved.set(Lanai::R1);
46   Reserved.set(Lanai::PC);
47   Reserved.set(Lanai::R2);
48   Reserved.set(Lanai::SP);
49   Reserved.set(Lanai::R4);
50   Reserved.set(Lanai::FP);
51   Reserved.set(Lanai::R5);
52   Reserved.set(Lanai::RR1);
53   Reserved.set(Lanai::R10);
54   Reserved.set(Lanai::RR2);
55   Reserved.set(Lanai::R11);
56   Reserved.set(Lanai::RCA);
57   Reserved.set(Lanai::R15);
58   if (hasBasePointer(MF))
59     Reserved.set(getBaseRegister());
60   return Reserved;
61 }
62
63 bool LanaiRegisterInfo::requiresRegisterScavenging(
64     const MachineFunction & /*MF*/) const {
65   return true;
66 }
67
68 bool LanaiRegisterInfo::trackLivenessAfterRegAlloc(
69     const MachineFunction & /*MF*/) const {
70   return true;
71 }
72
73 static bool isALUArithLoOpcode(unsigned Opcode) {
74   switch (Opcode) {
75   case Lanai::ADD_I_LO:
76   case Lanai::SUB_I_LO:
77   case Lanai::ADD_F_I_LO:
78   case Lanai::SUB_F_I_LO:
79   case Lanai::ADDC_I_LO:
80   case Lanai::SUBB_I_LO:
81   case Lanai::ADDC_F_I_LO:
82   case Lanai::SUBB_F_I_LO:
83     return true;
84   default:
85     return false;
86   }
87 }
88
89 static unsigned getOppositeALULoOpcode(unsigned Opcode) {
90   switch (Opcode) {
91   case Lanai::ADD_I_LO:
92     return Lanai::SUB_I_LO;
93   case Lanai::SUB_I_LO:
94     return Lanai::ADD_I_LO;
95   case Lanai::ADD_F_I_LO:
96     return Lanai::SUB_F_I_LO;
97   case Lanai::SUB_F_I_LO:
98     return Lanai::ADD_F_I_LO;
99   case Lanai::ADDC_I_LO:
100     return Lanai::SUBB_I_LO;
101   case Lanai::SUBB_I_LO:
102     return Lanai::ADDC_I_LO;
103   case Lanai::ADDC_F_I_LO:
104     return Lanai::SUBB_F_I_LO;
105   case Lanai::SUBB_F_I_LO:
106     return Lanai::ADDC_F_I_LO;
107   default:
108     llvm_unreachable("Invalid ALU lo opcode");
109   }
110 }
111
112 static unsigned getRRMOpcodeVariant(unsigned Opcode) {
113   switch (Opcode) {
114   case Lanai::LDBs_RI:
115     return Lanai::LDBs_RR;
116   case Lanai::LDBz_RI:
117     return Lanai::LDBz_RR;
118   case Lanai::LDHs_RI:
119     return Lanai::LDHs_RR;
120   case Lanai::LDHz_RI:
121     return Lanai::LDHz_RR;
122   case Lanai::LDW_RI:
123     return Lanai::LDW_RR;
124   case Lanai::STB_RI:
125     return Lanai::STB_RR;
126   case Lanai::STH_RI:
127     return Lanai::STH_RR;
128   case Lanai::SW_RI:
129     return Lanai::SW_RR;
130   default:
131     llvm_unreachable("Opcode has no RRM variant");
132   }
133 }
134
135 void LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
136                                             int SPAdj, unsigned FIOperandNum,
137                                             RegScavenger *RS) const {
138   assert(SPAdj == 0 && "Unexpected");
139
140   MachineInstr &MI = *II;
141   MachineFunction &MF = *MI.getParent()->getParent();
142   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
143   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
144   bool HasFP = TFI->hasFP(MF);
145   DebugLoc DL = MI.getDebugLoc();
146
147   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
148
149   int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
150                MI.getOperand(FIOperandNum + 1).getImm();
151
152   // Addressable stack objects are addressed using neg. offsets from fp
153   // or pos. offsets from sp/basepointer
154   if (!HasFP || (needsStackRealignment(MF) && FrameIndex >= 0))
155     Offset += MF.getFrameInfo().getStackSize();
156
157   unsigned FrameReg = getFrameRegister(MF);
158   if (FrameIndex >= 0) {
159     if (hasBasePointer(MF))
160       FrameReg = getBaseRegister();
161     else if (needsStackRealignment(MF))
162       FrameReg = Lanai::SP;
163   }
164
165   // Replace frame index with a frame pointer reference.
166   // If the offset is small enough to fit in the immediate field, directly
167   // encode it.
168   // Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.
169   if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) ||
170       !isInt<16>(Offset)) {
171     assert(RS && "Register scavenging must be on");
172     unsigned Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);
173     if (!Reg)
174       Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj);
175     assert(Reg && "Register scavenger failed");
176
177     bool HasNegOffset = false;
178     // ALU ops have unsigned immediate values. If the Offset is negative, we
179     // negate it here and reverse the opcode later.
180     if (Offset < 0) {
181       HasNegOffset = true;
182       Offset = -Offset;
183     }
184
185     if (!isInt<16>(Offset)) {
186       // Reg = hi(offset) | lo(offset)
187       BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)
188           .addImm(static_cast<uint32_t>(Offset) >> 16);
189       BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)
190           .addReg(Reg)
191           .addImm(Offset & 0xffffU);
192     } else {
193       // Reg = mov(offset)
194       BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
195           .addImm(0)
196           .addImm(Offset);
197     }
198     // Reg = FrameReg OP Reg
199     if (MI.getOpcode() == Lanai::ADD_I_LO) {
200       BuildMI(*MI.getParent(), II, DL,
201               HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
202               MI.getOperand(0).getReg())
203           .addReg(FrameReg)
204           .addReg(Reg)
205           .addImm(LPCC::ICC_T);
206       MI.eraseFromParent();
207       return;
208     }
209     if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
210       MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
211       if (HasNegOffset) {
212         // Change the ALU op (operand 3) from LPAC::ADD (the default) to
213         // LPAC::SUB with the already negated offset.
214         assert((MI.getOperand(3).getImm() == LPAC::ADD) &&
215                "Unexpected ALU op in RRM instruction");
216         MI.getOperand(3).setImm(LPAC::SUB);
217       }
218     } else
219       llvm_unreachable("Unexpected opcode in frame index operation");
220
221     MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
222     MI.getOperand(FIOperandNum + 1)
223         .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
224                           /*isKill=*/true);
225     return;
226   }
227
228   // ALU arithmetic ops take unsigned immediates. If the offset is negative,
229   // we replace the instruction with one that inverts the opcode and negates
230   // the immediate.
231   if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) {
232     unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());
233     // We know this is an ALU op, so we know the operands are as follows:
234     // 0: destination register
235     // 1: source register (frame register)
236     // 2: immediate
237     BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
238             MI.getOperand(0).getReg())
239         .addReg(FrameReg)
240         .addImm(-Offset);
241     MI.eraseFromParent();
242   } else {
243     MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
244     MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
245   }
246 }
247
248 bool LanaiRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
249   const MachineFrameInfo &MFI = MF.getFrameInfo();
250   // When we need stack realignment and there are dynamic allocas, we can't
251   // reference off of the stack pointer, so we reserve a base pointer.
252   if (needsStackRealignment(MF) && MFI.hasVarSizedObjects())
253     return true;
254
255   return false;
256 }
257
258 unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
259
260 unsigned
261 LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const {
262   return Lanai::FP;
263 }
264
265 unsigned LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
266
267 const uint32_t *
268 LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,
269                                         CallingConv::ID /*CC*/) const {
270   return CSR_RegMask;
271 }