Hide more details in tablegen generated MCRegisterInfo ctor function.
[oota-llvm.git] / lib / Target / Blackfin / BlackfinRegisterInfo.cpp
1 //===- BlackfinRegisterInfo.cpp - Blackfin 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 Blackfin implementation of the TargetRegisterInfo
11 // class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "Blackfin.h"
16 #include "BlackfinRegisterInfo.h"
17 #include "BlackfinSubtarget.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineLocation.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/Target/TargetFrameLowering.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Target/TargetOptions.h"
28 #include "llvm/Target/TargetInstrInfo.h"
29 #include "llvm/Type.h"
30 #include "llvm/ADT/BitVector.h"
31 #include "llvm/ADT/STLExtras.h"
32
33 #define GET_REGINFO_MC_DESC
34 #define GET_REGINFO_TARGET_DESC
35 #include "BlackfinGenRegisterInfo.inc"
36
37 using namespace llvm;
38
39 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
40                                            const TargetInstrInfo &tii)
41   : BlackfinGenRegisterInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP),
42     Subtarget(st),
43     TII(tii) {}
44
45 const unsigned*
46 BlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
47   using namespace BF;
48   static const unsigned CalleeSavedRegs[] = {
49     FP,
50     R4, R5, R6, R7,
51     P3, P4, P5,
52     0 };
53   return  CalleeSavedRegs;
54 }
55
56 BitVector
57 BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
58   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
59
60   using namespace BF;
61   BitVector Reserved(getNumRegs());
62   Reserved.set(AZ);
63   Reserved.set(AN);
64   Reserved.set(AQ);
65   Reserved.set(AC0);
66   Reserved.set(AC1);
67   Reserved.set(AV0);
68   Reserved.set(AV0S);
69   Reserved.set(AV1);
70   Reserved.set(AV1S);
71   Reserved.set(V);
72   Reserved.set(VS);
73   Reserved.set(CYCLES).set(CYCLES2);
74   Reserved.set(L0);
75   Reserved.set(L1);
76   Reserved.set(L2);
77   Reserved.set(L3);
78   Reserved.set(SP);
79   Reserved.set(RETS);
80   if (TFI->hasFP(MF))
81     Reserved.set(FP);
82   return Reserved;
83 }
84
85 bool BlackfinRegisterInfo::
86 requiresRegisterScavenging(const MachineFunction &MF) const {
87   return true;
88 }
89
90 // Emit instructions to add delta to D/P register. ScratchReg must be of the
91 // same class as Reg (P).
92 void BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB,
93                                           MachineBasicBlock::iterator I,
94                                           DebugLoc DL,
95                                           unsigned Reg,
96                                           unsigned ScratchReg,
97                                           int delta) const {
98   if (!delta)
99     return;
100   if (isInt<7>(delta)) {
101     BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg)
102       .addReg(Reg)              // No kill on two-addr operand
103       .addImm(delta);
104     return;
105   }
106
107   // We must load delta into ScratchReg and add that.
108   loadConstant(MBB, I, DL, ScratchReg, delta);
109   if (BF::PRegClass.contains(Reg)) {
110     assert(BF::PRegClass.contains(ScratchReg) &&
111            "ScratchReg must be a P register");
112     BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg)
113       .addReg(Reg, RegState::Kill)
114       .addReg(ScratchReg, RegState::Kill);
115   } else {
116     assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register");
117     assert(BF::DRegClass.contains(ScratchReg) &&
118            "ScratchReg must be a D register");
119     BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg)
120       .addReg(Reg, RegState::Kill)
121       .addReg(ScratchReg, RegState::Kill);
122   }
123 }
124
125 // Emit instructions to load a constant into D/P register
126 void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
127                                         MachineBasicBlock::iterator I,
128                                         DebugLoc DL,
129                                         unsigned Reg,
130                                         int value) const {
131   if (isInt<7>(value)) {
132     BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value);
133     return;
134   }
135
136   if (isUInt<16>(value)) {
137     BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
138     return;
139   }
140
141   if (isInt<16>(value)) {
142     BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
143     return;
144   }
145
146   // We must split into halves
147   BuildMI(MBB, I, DL,
148           TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
149     .addImm((value >> 16) & 0xffff)
150     .addReg(Reg, RegState::ImplicitDefine);
151   BuildMI(MBB, I, DL,
152           TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
153     .addImm(value & 0xffff)
154     .addReg(Reg, RegState::ImplicitKill)
155     .addReg(Reg, RegState::ImplicitDefine);
156 }
157
158 void BlackfinRegisterInfo::
159 eliminateCallFramePseudoInstr(MachineFunction &MF,
160                               MachineBasicBlock &MBB,
161                               MachineBasicBlock::iterator I) const {
162   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
163
164   if (!TFI->hasReservedCallFrame(MF)) {
165     int64_t Amount = I->getOperand(0).getImm();
166     if (Amount != 0) {
167       assert(Amount%4 == 0 && "Unaligned call frame size");
168       if (I->getOpcode() == BF::ADJCALLSTACKDOWN) {
169         adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount);
170       } else {
171         assert(I->getOpcode() == BF::ADJCALLSTACKUP &&
172                "Unknown call frame pseudo instruction");
173         adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount);
174       }
175     }
176   }
177   MBB.erase(I);
178 }
179
180 /// findScratchRegister - Find a 'free' register. Try for a call-clobbered
181 /// register first and then a spilled callee-saved register if that fails.
182 static unsigned findScratchRegister(MachineBasicBlock::iterator II,
183                                     RegScavenger *RS,
184                                     const TargetRegisterClass *RC,
185                                     int SPAdj) {
186   assert(RS && "Register scavenging must be on");
187   unsigned Reg = RS->FindUnusedReg(RC);
188   if (Reg == 0)
189     Reg = RS->scavengeRegister(RC, II, SPAdj);
190   return Reg;
191 }
192
193 void
194 BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
195                                           int SPAdj, RegScavenger *RS) const {
196   MachineInstr &MI = *II;
197   MachineBasicBlock &MBB = *MI.getParent();
198   MachineFunction &MF = *MBB.getParent();
199   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
200   DebugLoc DL = MI.getDebugLoc();
201
202   unsigned FIPos;
203   for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
204     assert(FIPos < MI.getNumOperands() &&
205            "Instr doesn't have FrameIndex operand!");
206   }
207   int FrameIndex = MI.getOperand(FIPos).getIndex();
208   assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm());
209   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex)
210     + MI.getOperand(FIPos+1).getImm();
211   unsigned BaseReg = BF::FP;
212   if (TFI->hasFP(MF)) {
213     assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer");
214   } else {
215     BaseReg = BF::SP;
216     Offset += MF.getFrameInfo()->getStackSize() + SPAdj;
217   }
218
219   bool isStore = false;
220
221   switch (MI.getOpcode()) {
222   case BF::STORE32fi:
223     isStore = true;
224   case BF::LOAD32fi: {
225     assert(Offset%4 == 0 && "Unaligned i32 stack access");
226     assert(FIPos==1 && "Bad frame index operand");
227     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
228     MI.getOperand(FIPos+1).setImm(Offset);
229     if (isUInt<6>(Offset)) {
230       MI.setDesc(TII.get(isStore
231                          ? BF::STORE32p_uimm6m4
232                          : BF::LOAD32p_uimm6m4));
233       return;
234     }
235     if (BaseReg == BF::FP && isUInt<7>(-Offset)) {
236       MI.setDesc(TII.get(isStore
237                          ? BF::STORE32fp_nimm7m4
238                          : BF::LOAD32fp_nimm7m4));
239       MI.getOperand(FIPos+1).setImm(-Offset);
240       return;
241     }
242     if (isInt<18>(Offset)) {
243       MI.setDesc(TII.get(isStore
244                          ? BF::STORE32p_imm18m4
245                          : BF::LOAD32p_imm18m4));
246       return;
247     }
248     // Use RegScavenger to calculate proper offset...
249     MI.dump();
250     llvm_unreachable("Stack frame offset too big");
251     break;
252   }
253   case BF::ADDpp: {
254     assert(MI.getOperand(0).isReg() && "ADD instruction needs a register");
255     unsigned DestReg = MI.getOperand(0).getReg();
256     // We need to produce a stack offset in a P register. We emit:
257     // P0 = offset;
258     // P0 = BR + P0;
259     assert(FIPos==1 && "Bad frame index operand");
260     loadConstant(MBB, II, DL, DestReg, Offset);
261     MI.getOperand(1).ChangeToRegister(DestReg, false, false, true);
262     MI.getOperand(2).ChangeToRegister(BaseReg, false);
263     break;
264   }
265   case BF::STORE16fi:
266     isStore = true;
267   case BF::LOAD16fi: {
268     assert(Offset%2 == 0 && "Unaligned i16 stack access");
269     assert(FIPos==1 && "Bad frame index operand");
270     // We need a P register to use as an address
271     unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj);
272     assert(ScratchReg && "Could not scavenge register");
273     loadConstant(MBB, II, DL, ScratchReg, Offset);
274     BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg)
275       .addReg(ScratchReg, RegState::Kill)
276       .addReg(BaseReg);
277     MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi));
278     MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true);
279     MI.RemoveOperand(2);
280     break;
281   }
282   case BF::STORE8fi: {
283     // This is an AnyCC spill, we need a scratch register.
284     assert(FIPos==1 && "Bad frame index operand");
285     MachineOperand SpillReg = MI.getOperand(0);
286     unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
287     assert(ScratchReg && "Could not scavenge register");
288     if (SpillReg.getReg()==BF::NCC) {
289       BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg)
290         .addOperand(SpillReg);
291       BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg)
292         .addReg(ScratchReg).addImm(0);
293     } else {
294       BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg)
295         .addOperand(SpillReg);
296     }
297     // STORE D
298     MI.setDesc(TII.get(BF::STORE8p_imm16));
299     MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true);
300     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
301     MI.getOperand(FIPos+1).setImm(Offset);
302     break;
303   }
304   case BF::LOAD8fi: {
305     // This is an restore, we need a scratch register.
306     assert(FIPos==1 && "Bad frame index operand");
307     MachineOperand SpillReg = MI.getOperand(0);
308     unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
309     assert(ScratchReg && "Could not scavenge register");
310     MI.setDesc(TII.get(BF::LOAD32p_imm16_8z));
311     MI.getOperand(0).ChangeToRegister(ScratchReg, true);
312     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
313     MI.getOperand(FIPos+1).setImm(Offset);
314     ++II;
315     if (SpillReg.getReg()==BF::CC) {
316       // CC = D
317       BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC)
318         .addReg(ScratchReg, RegState::Kill);
319     } else {
320       // Restore NCC (CC = D==0)
321       BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC)
322         .addReg(ScratchReg, RegState::Kill)
323         .addImm(0);
324     }
325     break;
326   }
327   default:
328     llvm_unreachable("Cannot eliminate frame index");
329     break;
330   }
331 }
332
333 unsigned BlackfinRegisterInfo::getRARegister() const {
334   return BF::RETS;
335 }
336
337 unsigned
338 BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
339   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
340
341   return TFI->hasFP(MF) ? BF::FP : BF::SP;
342 }
343
344 unsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
345   llvm_unreachable("What is the exception register");
346   return 0;
347 }
348
349 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
350   llvm_unreachable("What is the exception handler register");
351   return 0;
352 }
353
354 int BlackfinRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
355   llvm_unreachable("What is the dwarf register number");
356   return -1;
357 }
358
359 int BlackfinRegisterInfo::getLLVMRegNum(unsigned DwarfRegNum,
360                                         bool isEH) const {
361   llvm_unreachable("What is the dwarf register number");
362   return -1;
363 }