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