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