1 //===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Blackfin implementation of the TargetRegisterInfo
13 //===----------------------------------------------------------------------===//
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"
34 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget
&st
,
35 const TargetInstrInfo
&tii
)
36 : BlackfinGenRegisterInfo(BF::ADJCALLSTACKDOWN
, BF::ADJCALLSTACKUP
),
41 BlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
43 static const unsigned CalleeSavedRegs
[] = {
48 return CalleeSavedRegs
;
52 BlackfinRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
53 const TargetFrameLowering
*TFI
= MF
.getTarget().getFrameLowering();
56 BitVector
Reserved(getNumRegs());
68 Reserved
.set(CYCLES
).set(CYCLES2
);
80 bool BlackfinRegisterInfo::
81 requiresRegisterScavenging(const MachineFunction
&MF
) const {
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
,
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
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
);
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
,
126 if (isInt
<7>(value
)) {
127 BuildMI(MBB
, I
, DL
, TII
.get(BF::LOADimm7
), Reg
).addImm(value
);
131 if (isUInt
<16>(value
)) {
132 BuildMI(MBB
, I
, DL
, TII
.get(BF::LOADuimm16
), Reg
).addImm(value
);
136 if (isInt
<16>(value
)) {
137 BuildMI(MBB
, I
, DL
, TII
.get(BF::LOADimm16
), Reg
).addImm(value
);
141 // We must split into halves
143 TII
.get(BF::LOAD16i
), getSubReg(Reg
, BF::hi16
))
144 .addImm((value
>> 16) & 0xffff)
145 .addReg(Reg
, RegState::ImplicitDefine
);
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();
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
);
166 assert(I
->getOpcode() == BF::ADJCALLSTACKUP
&&
167 "Unknown call frame pseudo instruction");
168 adjustRegister(MBB
, I
, I
->getDebugLoc(), BF::SP
, BF::P1
, Amount
);
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
,
179 const TargetRegisterClass
*RC
,
181 assert(RS
&& "Register scavenging must be on");
182 unsigned Reg
= RS
->FindUnusedReg(RC
);
184 Reg
= RS
->scavengeRegister(RC
, II
, SPAdj
);
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();
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");
211 Offset
+= MF
.getFrameInfo()->getStackSize() + SPAdj
;
214 bool isStore
= false;
216 switch (MI
.getOpcode()) {
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
));
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
);
237 if (isInt
<18>(Offset
)) {
238 MI
.setDesc(TII
.get(isStore
239 ? BF::STORE32p_imm18m4
240 : BF::LOAD32p_imm18m4
));
243 // Use RegScavenger to calculate proper offset...
245 llvm_unreachable("Stack frame offset too big");
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:
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);
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
)
272 MI
.setDesc(TII
.get(isStore
? BF::STORE16pi
: BF::LOAD16pi
));
273 MI
.getOperand(1).ChangeToRegister(ScratchReg
, false, false, true);
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);
289 BuildMI(MBB
, II
, DL
, TII
.get(BF::MOVECC_zext
), ScratchReg
)
290 .addOperand(SpillReg
);
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
);
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
);
310 if (SpillReg
.getReg()==BF::CC
) {
312 BuildMI(MBB
, II
, DL
, TII
.get(BF::MOVECC_nz
), BF::CC
)
313 .addReg(ScratchReg
, RegState::Kill
);
315 // Restore NCC (CC = D==0)
316 BuildMI(MBB
, II
, DL
, TII
.get(BF::SETEQri_not
), BF::NCC
)
317 .addReg(ScratchReg
, RegState::Kill
)
323 llvm_unreachable("Cannot eliminate frame index");
328 unsigned BlackfinRegisterInfo::getRARegister() const {
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");
344 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
345 llvm_unreachable("What is the exception handler register");
349 int BlackfinRegisterInfo::getDwarfRegNum(unsigned RegNum
, bool isEH
) const {
350 llvm_unreachable("What is the dwarf register number");
354 #include "BlackfinGenRegisterInfo.inc"