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