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