Revert r247692: Replace Triple with a new TargetTuple in MCTargetDesc/* and related...
[oota-llvm.git] / lib / Target / Hexagon / HexagonRegisterInfo.cpp
1 //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
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 Hexagon implementation of the TargetRegisterInfo
11 // class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "HexagonRegisterInfo.h"
16 #include "Hexagon.h"
17 #include "HexagonMachineFunctionInfo.h"
18 #include "HexagonSubtarget.h"
19 #include "HexagonTargetMachine.h"
20 #include "llvm/ADT/BitVector.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/PseudoSourceValue.h"
28 #include "llvm/CodeGen/RegisterScavenging.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/MC/MachineLocation.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Target/TargetInstrInfo.h"
37 #include "llvm/Target/TargetMachine.h"
38 #include "llvm/Target/TargetOptions.h"
39
40 using namespace llvm;
41
42 HexagonRegisterInfo::HexagonRegisterInfo()
43     : HexagonGenRegisterInfo(Hexagon::R31) {}
44
45
46 bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
47   return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
48          R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
49 }
50
51 bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const {
52   return Hexagon::R16 <= Reg && Reg <= Hexagon::R27;
53 }
54
55
56 const MCPhysReg *
57 HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF) const {
58   static const MCPhysReg CallerSavedRegsV4[] = {
59     Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
60     Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
61     Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
62     Hexagon::R15, 0
63   };
64
65   auto &HST = static_cast<const HexagonSubtarget&>(MF->getSubtarget());
66   switch (HST.getHexagonArchVersion()) {
67   case HexagonSubtarget::V4:
68   case HexagonSubtarget::V5:
69     return CallerSavedRegsV4;
70   }
71   llvm_unreachable(
72     "Callee saved registers requested for unknown archtecture version");
73 }
74
75
76 const MCPhysReg *
77 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
78   static const MCPhysReg CalleeSavedRegsV3[] = {
79     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
80     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
81     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
82   };
83
84   switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
85   case HexagonSubtarget::V4:
86   case HexagonSubtarget::V5:
87     return CalleeSavedRegsV3;
88   }
89   llvm_unreachable("Callee saved registers requested for unknown architecture "
90                    "version");
91 }
92
93 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
94   const {
95   BitVector Reserved(getNumRegs());
96   Reserved.set(HEXAGON_RESERVED_REG_1);
97   Reserved.set(HEXAGON_RESERVED_REG_2);
98   Reserved.set(Hexagon::R29);
99   Reserved.set(Hexagon::R30);
100   Reserved.set(Hexagon::R31);
101   Reserved.set(Hexagon::D14);
102   Reserved.set(Hexagon::D15);
103   Reserved.set(Hexagon::LC0);
104   Reserved.set(Hexagon::LC1);
105   Reserved.set(Hexagon::SA0);
106   Reserved.set(Hexagon::SA1);
107   return Reserved;
108 }
109
110
111 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
112                                               int SPAdj, unsigned FIOp,
113                                               RegScavenger *RS) const {
114   //
115   // Hexagon_TODO: Do we need to enforce this for Hexagon?
116   assert(SPAdj == 0 && "Unexpected");
117
118   MachineInstr &MI = *II;
119
120   MachineBasicBlock &MB = *MI.getParent();
121   MachineFunction &MF = *MB.getParent();
122   MachineFrameInfo &MFI = *MF.getFrameInfo();
123   auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
124   auto &HII = *HST.getInstrInfo();
125   auto &HFI = *HST.getFrameLowering();
126
127   int FI = MI.getOperand(FIOp).getIndex();
128   int Offset = MFI.getObjectOffset(FI) + MI.getOperand(FIOp+1).getImm();
129   bool HasAlloca = MFI.hasVarSizedObjects();
130   bool HasAlign = needsStackRealignment(MF);
131
132   // XXX: Fixed objects cannot be accessed through SP if there are aligned
133   // objects in the local frame, or if there are dynamically allocated objects.
134   // In such cases, there has to be FP available.
135   if (!HFI.hasFP(MF)) {
136     assert(!HasAlloca && !HasAlign && "This function must have frame pointer");
137     // We will not reserve space on the stack for the lr and fp registers.
138     Offset -= 8;
139   }
140
141   unsigned SP = getStackRegister(), FP = getFrameRegister();
142   unsigned AP = 0;
143   if (MachineInstr *AI = HFI.getAlignaInstr(MF))
144     AP = AI->getOperand(0).getReg();
145   unsigned FrameSize = MFI.getStackSize();
146
147   // Special handling of dbg_value instructions and INLINEASM.
148   if (MI.isDebugValue() || MI.isInlineAsm()) {
149     MI.getOperand(FIOp).ChangeToRegister(SP, false /*isDef*/);
150     MI.getOperand(FIOp+1).ChangeToImmediate(Offset+FrameSize);
151     return;
152   }
153
154   bool UseFP = false, UseAP = false;  // Default: use SP.
155   if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) {
156     UseFP = HasAlloca || HasAlign;
157   } else {
158     if (HasAlloca) {
159       if (HasAlign)
160         UseAP = true;
161       else
162         UseFP = true;
163     }
164   }
165
166   unsigned Opc = MI.getOpcode();
167   bool ValidSP = HII.isValidOffset(Opc, FrameSize+Offset);
168   bool ValidFP = HII.isValidOffset(Opc, Offset);
169
170   // Calculate the actual offset in the instruction.
171   int64_t RealOffset = Offset;
172   if (!UseFP && !UseAP)
173     RealOffset = FrameSize+Offset;
174
175   switch (Opc) {
176     case Hexagon::TFR_FIA:
177       MI.setDesc(HII.get(Hexagon::A2_addi));
178       MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
179       MI.RemoveOperand(FIOp+1);
180       return;
181     case Hexagon::TFR_FI:
182       // Set up the instruction for updating below.
183       MI.setDesc(HII.get(Hexagon::A2_addi));
184       break;
185   }
186
187   unsigned BP = 0;
188   bool Valid = false;
189   if (UseFP) {
190     BP = FP;
191     Valid = ValidFP;
192   } else if (UseAP) {
193     BP = AP;
194     Valid = ValidFP;
195   } else {
196     BP = SP;
197     Valid = ValidSP;
198   }
199
200   if (Valid) {
201     MI.getOperand(FIOp).ChangeToRegister(BP, false);
202     MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
203     return;
204   }
205
206 #ifndef NDEBUG
207   const Function *F = MF.getFunction();
208   dbgs() << "In function ";
209   if (F) dbgs() << F->getName();
210   else   dbgs() << "<?>";
211   dbgs() << ", BB#" << MB.getNumber() << "\n" << MI;
212 #endif
213   llvm_unreachable("Unhandled instruction");
214 }
215
216
217 unsigned HexagonRegisterInfo::getRARegister() const {
218   return Hexagon::R31;
219 }
220
221
222 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
223                                                &MF) const {
224   const HexagonFrameLowering *TFI = getFrameLowering(MF);
225   if (TFI->hasFP(MF))
226     return Hexagon::R30;
227   return Hexagon::R29;
228 }
229
230
231 unsigned HexagonRegisterInfo::getFrameRegister() const {
232   return Hexagon::R30;
233 }
234
235
236 unsigned HexagonRegisterInfo::getStackRegister() const {
237   return Hexagon::R29;
238 }
239
240
241 bool
242 HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
243   const HexagonFrameLowering *TFI = getFrameLowering(MF);
244   return TFI->hasFP(MF);
245 }
246
247
248 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
249   return Hexagon::R6;
250 }
251
252
253 #define GET_REGINFO_TARGET_DESC
254 #include "HexagonGenRegisterInfo.inc"