Silence -Wunused-variable in release builds.
[llvm/stm8.git] / lib / Target / Blackfin / BlackfinRegisterInfo.cpp
blob2f4a453ec0454c798c69cd1a3e947979068bfdcc
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.
13 //===----------------------------------------------------------------------===//
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"
33 #define GET_REGINFO_MC_DESC
34 #define GET_REGINFO_TARGET_DESC
35 #include "BlackfinGenRegisterInfo.inc"
37 using namespace llvm;
39 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
40 const TargetInstrInfo &tii)
41 : BlackfinGenRegisterInfo(), Subtarget(st), TII(tii) {}
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;
54 BitVector
55 BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
56 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
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;
83 bool BlackfinRegisterInfo::
84 requiresRegisterScavenging(const MachineFunction &MF) const {
85 return true;
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;
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);
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;
134 if (isUInt<16>(value)) {
135 BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
136 return;
139 if (isInt<16>(value)) {
140 BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
141 return;
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);
156 void BlackfinRegisterInfo::
157 eliminateCallFramePseudoInstr(MachineFunction &MF,
158 MachineBasicBlock &MBB,
159 MachineBasicBlock::iterator I) const {
160 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
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);
175 MBB.erase(I);
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;
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();
200 unsigned FIPos;
201 for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
202 assert(FIPos < MI.getNumOperands() &&
203 "Instr doesn't have FrameIndex operand!");
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;
217 bool isStore = false;
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;
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;
240 if (isInt<18>(Offset)) {
241 MI.setDesc(TII.get(isStore
242 ? BF::STORE32p_imm18m4
243 : BF::LOAD32p_imm18m4));
244 return;
246 // Use RegScavenger to calculate proper offset...
247 MI.dump();
248 llvm_unreachable("Stack frame offset too big");
249 break;
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;
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;
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);
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;
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);
323 break;
325 default:
326 llvm_unreachable("Cannot eliminate frame index");
327 break;
331 unsigned BlackfinRegisterInfo::getRARegister() const {
332 return BF::RETS;
335 unsigned
336 BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
337 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
339 return TFI->hasFP(MF) ? BF::FP : BF::SP;
342 unsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
343 llvm_unreachable("What is the exception register");
344 return 0;
347 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
348 llvm_unreachable("What is the exception handler register");
349 return 0;
352 int BlackfinRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
353 llvm_unreachable("What is the dwarf register number");
354 return -1;
357 int BlackfinRegisterInfo::getLLVMRegNum(unsigned DwarfRegNum,
358 bool isEH) const {
359 llvm_unreachable("What is the dwarf register number");
360 return -1;