Use %ull here.
[llvm/stm8.git] / lib / Target / Blackfin / BlackfinRegisterInfo.cpp
blobb4a9b84f9e4355a019dcdb5ec910b55913762f65
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"
32 using namespace llvm;
34 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
35 const TargetInstrInfo &tii)
36 : BlackfinGenRegisterInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP),
37 Subtarget(st),
38 TII(tii) {}
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;
51 BitVector
52 BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
53 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
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;
80 bool BlackfinRegisterInfo::
81 requiresRegisterScavenging(const MachineFunction &MF) const {
82 return true;
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;
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);
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;
131 if (isUInt<16>(value)) {
132 BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
133 return;
136 if (isInt<16>(value)) {
137 BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
138 return;
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);
153 void BlackfinRegisterInfo::
154 eliminateCallFramePseudoInstr(MachineFunction &MF,
155 MachineBasicBlock &MBB,
156 MachineBasicBlock::iterator I) const {
157 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
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);
172 MBB.erase(I);
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;
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();
197 unsigned FIPos;
198 for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
199 assert(FIPos < MI.getNumOperands() &&
200 "Instr doesn't have FrameIndex operand!");
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;
214 bool isStore = false;
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;
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;
237 if (isInt<18>(Offset)) {
238 MI.setDesc(TII.get(isStore
239 ? BF::STORE32p_imm18m4
240 : BF::LOAD32p_imm18m4));
241 return;
243 // Use RegScavenger to calculate proper offset...
244 MI.dump();
245 llvm_unreachable("Stack frame offset too big");
246 break;
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;
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;
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);
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;
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);
320 break;
322 default:
323 llvm_unreachable("Cannot eliminate frame index");
324 break;
328 unsigned BlackfinRegisterInfo::getRARegister() const {
329 return BF::RETS;
332 unsigned
333 BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
334 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
336 return TFI->hasFP(MF) ? BF::FP : BF::SP;
339 unsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
340 llvm_unreachable("What is the exception register");
341 return 0;
344 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
345 llvm_unreachable("What is the exception handler register");
346 return 0;
349 int BlackfinRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
350 llvm_unreachable("What is the dwarf register number");
351 return -1;
354 #include "BlackfinGenRegisterInfo.inc"