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