1 //===- AlphaInstrInfo.cpp - Alpha Instruction 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 Alpha implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "AlphaInstrInfo.h"
16 #include "AlphaMachineFunctionInfo.h"
17 #include "AlphaGenInstrInfo.inc"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/Support/ErrorHandling.h"
25 AlphaInstrInfo::AlphaInstrInfo()
26 : TargetInstrInfoImpl(AlphaInsts
, array_lengthof(AlphaInsts
)),
31 AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
32 int &FrameIndex
) const {
33 switch (MI
->getOpcode()) {
40 if (MI
->getOperand(1).isFI()) {
41 FrameIndex
= MI
->getOperand(1).getIndex();
42 return MI
->getOperand(0).getReg();
50 AlphaInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
51 int &FrameIndex
) const {
52 switch (MI
->getOpcode()) {
59 if (MI
->getOperand(1).isFI()) {
60 FrameIndex
= MI
->getOperand(1).getIndex();
61 return MI
->getOperand(0).getReg();
68 static bool isAlphaIntCondCode(unsigned Opcode
) {
84 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,
85 MachineBasicBlock
*TBB
,
86 MachineBasicBlock
*FBB
,
87 const SmallVectorImpl
<MachineOperand
> &Cond
,
89 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
90 assert((Cond
.size() == 2 || Cond
.size() == 0) &&
91 "Alpha branch conditions have two components!");
95 if (Cond
.empty()) // Unconditional branch
96 BuildMI(&MBB
, DL
, get(Alpha::BR
)).addMBB(TBB
);
97 else // Conditional branch
98 if (isAlphaIntCondCode(Cond
[0].getImm()))
99 BuildMI(&MBB
, DL
, get(Alpha::COND_BRANCH_I
))
100 .addImm(Cond
[0].getImm()).addReg(Cond
[1].getReg()).addMBB(TBB
);
102 BuildMI(&MBB
, DL
, get(Alpha::COND_BRANCH_F
))
103 .addImm(Cond
[0].getImm()).addReg(Cond
[1].getReg()).addMBB(TBB
);
107 // Two-way Conditional Branch.
108 if (isAlphaIntCondCode(Cond
[0].getImm()))
109 BuildMI(&MBB
, DL
, get(Alpha::COND_BRANCH_I
))
110 .addImm(Cond
[0].getImm()).addReg(Cond
[1].getReg()).addMBB(TBB
);
112 BuildMI(&MBB
, DL
, get(Alpha::COND_BRANCH_F
))
113 .addImm(Cond
[0].getImm()).addReg(Cond
[1].getReg()).addMBB(TBB
);
114 BuildMI(&MBB
, DL
, get(Alpha::BR
)).addMBB(FBB
);
118 void AlphaInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
119 MachineBasicBlock::iterator MI
, DebugLoc DL
,
120 unsigned DestReg
, unsigned SrcReg
,
121 bool KillSrc
) const {
122 if (Alpha::GPRCRegClass
.contains(DestReg
, SrcReg
)) {
123 BuildMI(MBB
, MI
, DL
, get(Alpha::BISr
), DestReg
)
125 .addReg(SrcReg
, getKillRegState(KillSrc
));
126 } else if (Alpha::F4RCRegClass
.contains(DestReg
, SrcReg
)) {
127 BuildMI(MBB
, MI
, DL
, get(Alpha::CPYSS
), DestReg
)
129 .addReg(SrcReg
, getKillRegState(KillSrc
));
130 } else if (Alpha::F8RCRegClass
.contains(DestReg
, SrcReg
)) {
131 BuildMI(MBB
, MI
, DL
, get(Alpha::CPYST
), DestReg
)
133 .addReg(SrcReg
, getKillRegState(KillSrc
));
135 llvm_unreachable("Attempt to copy register that is not GPR or FPR");
140 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
141 MachineBasicBlock::iterator MI
,
142 unsigned SrcReg
, bool isKill
, int FrameIdx
,
143 const TargetRegisterClass
*RC
,
144 const TargetRegisterInfo
*TRI
) const {
145 //cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
146 // << FrameIdx << "\n";
147 //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
150 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
152 if (RC
== Alpha::F4RCRegisterClass
)
153 BuildMI(MBB
, MI
, DL
, get(Alpha::STS
))
154 .addReg(SrcReg
, getKillRegState(isKill
))
155 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
156 else if (RC
== Alpha::F8RCRegisterClass
)
157 BuildMI(MBB
, MI
, DL
, get(Alpha::STT
))
158 .addReg(SrcReg
, getKillRegState(isKill
))
159 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
160 else if (RC
== Alpha::GPRCRegisterClass
)
161 BuildMI(MBB
, MI
, DL
, get(Alpha::STQ
))
162 .addReg(SrcReg
, getKillRegState(isKill
))
163 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
165 llvm_unreachable("Unhandled register class");
169 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
170 MachineBasicBlock::iterator MI
,
171 unsigned DestReg
, int FrameIdx
,
172 const TargetRegisterClass
*RC
,
173 const TargetRegisterInfo
*TRI
) const {
174 //cerr << "Trying to load " << getPrettyName(DestReg) << " to "
175 // << FrameIdx << "\n";
177 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
179 if (RC
== Alpha::F4RCRegisterClass
)
180 BuildMI(MBB
, MI
, DL
, get(Alpha::LDS
), DestReg
)
181 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
182 else if (RC
== Alpha::F8RCRegisterClass
)
183 BuildMI(MBB
, MI
, DL
, get(Alpha::LDT
), DestReg
)
184 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
185 else if (RC
== Alpha::GPRCRegisterClass
)
186 BuildMI(MBB
, MI
, DL
, get(Alpha::LDQ
), DestReg
)
187 .addFrameIndex(FrameIdx
).addReg(Alpha::F31
);
189 llvm_unreachable("Unhandled register class");
192 static unsigned AlphaRevCondCode(unsigned Opcode
) {
194 case Alpha::BEQ
: return Alpha::BNE
;
195 case Alpha::BNE
: return Alpha::BEQ
;
196 case Alpha::BGE
: return Alpha::BLT
;
197 case Alpha::BGT
: return Alpha::BLE
;
198 case Alpha::BLE
: return Alpha::BGT
;
199 case Alpha::BLT
: return Alpha::BGE
;
200 case Alpha::BLBC
: return Alpha::BLBS
;
201 case Alpha::BLBS
: return Alpha::BLBC
;
202 case Alpha::FBEQ
: return Alpha::FBNE
;
203 case Alpha::FBNE
: return Alpha::FBEQ
;
204 case Alpha::FBGE
: return Alpha::FBLT
;
205 case Alpha::FBGT
: return Alpha::FBLE
;
206 case Alpha::FBLE
: return Alpha::FBGT
;
207 case Alpha::FBLT
: return Alpha::FBGE
;
209 llvm_unreachable("Unknown opcode");
211 return 0; // Not reached
215 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*&TBB
,
216 MachineBasicBlock
*&FBB
,
217 SmallVectorImpl
<MachineOperand
> &Cond
,
218 bool AllowModify
) const {
219 // If the block has no terminators, it just falls into the block after it.
220 MachineBasicBlock::iterator I
= MBB
.end();
221 if (I
== MBB
.begin())
224 while (I
->isDebugValue()) {
225 if (I
== MBB
.begin())
229 if (!isUnpredicatedTerminator(I
))
232 // Get the last instruction in the block.
233 MachineInstr
*LastInst
= I
;
235 // If there is only one terminator instruction, process it.
236 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
)) {
237 if (LastInst
->getOpcode() == Alpha::BR
) {
238 TBB
= LastInst
->getOperand(0).getMBB();
240 } else if (LastInst
->getOpcode() == Alpha::COND_BRANCH_I
||
241 LastInst
->getOpcode() == Alpha::COND_BRANCH_F
) {
242 // Block ends with fall-through condbranch.
243 TBB
= LastInst
->getOperand(2).getMBB();
244 Cond
.push_back(LastInst
->getOperand(0));
245 Cond
.push_back(LastInst
->getOperand(1));
248 // Otherwise, don't know what this is.
252 // Get the instruction before it if it's a terminator.
253 MachineInstr
*SecondLastInst
= I
;
255 // If there are three terminators, we don't know what sort of block this is.
256 if (SecondLastInst
&& I
!= MBB
.begin() &&
257 isUnpredicatedTerminator(--I
))
260 // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
261 if ((SecondLastInst
->getOpcode() == Alpha::COND_BRANCH_I
||
262 SecondLastInst
->getOpcode() == Alpha::COND_BRANCH_F
) &&
263 LastInst
->getOpcode() == Alpha::BR
) {
264 TBB
= SecondLastInst
->getOperand(2).getMBB();
265 Cond
.push_back(SecondLastInst
->getOperand(0));
266 Cond
.push_back(SecondLastInst
->getOperand(1));
267 FBB
= LastInst
->getOperand(0).getMBB();
271 // If the block ends with two Alpha::BRs, handle it. The second one is not
272 // executed, so remove it.
273 if (SecondLastInst
->getOpcode() == Alpha::BR
&&
274 LastInst
->getOpcode() == Alpha::BR
) {
275 TBB
= SecondLastInst
->getOperand(0).getMBB();
278 I
->eraseFromParent();
282 // Otherwise, can't handle this.
286 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
287 MachineBasicBlock::iterator I
= MBB
.end();
288 if (I
== MBB
.begin()) return 0;
290 while (I
->isDebugValue()) {
291 if (I
== MBB
.begin())
295 if (I
->getOpcode() != Alpha::BR
&&
296 I
->getOpcode() != Alpha::COND_BRANCH_I
&&
297 I
->getOpcode() != Alpha::COND_BRANCH_F
)
300 // Remove the branch.
301 I
->eraseFromParent();
305 if (I
== MBB
.begin()) return 1;
307 if (I
->getOpcode() != Alpha::COND_BRANCH_I
&&
308 I
->getOpcode() != Alpha::COND_BRANCH_F
)
311 // Remove the branch.
312 I
->eraseFromParent();
316 void AlphaInstrInfo::insertNoop(MachineBasicBlock
&MBB
,
317 MachineBasicBlock::iterator MI
) const {
319 BuildMI(MBB
, MI
, DL
, get(Alpha::BISr
), Alpha::R31
)
324 bool AlphaInstrInfo::
325 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
326 assert(Cond
.size() == 2 && "Invalid Alpha branch opcode!");
327 Cond
[0].setImm(AlphaRevCondCode(Cond
[0].getImm()));
331 /// getGlobalBaseReg - Return a virtual register initialized with the
332 /// the global base register value. Output instructions required to
333 /// initialize the register in the function entry block, if necessary.
335 unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction
*MF
) const {
336 AlphaMachineFunctionInfo
*AlphaFI
= MF
->getInfo
<AlphaMachineFunctionInfo
>();
337 unsigned GlobalBaseReg
= AlphaFI
->getGlobalBaseReg();
338 if (GlobalBaseReg
!= 0)
339 return GlobalBaseReg
;
341 // Insert the set of GlobalBaseReg into the first MBB of the function
342 MachineBasicBlock
&FirstMBB
= MF
->front();
343 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
344 MachineRegisterInfo
&RegInfo
= MF
->getRegInfo();
345 const TargetInstrInfo
*TII
= MF
->getTarget().getInstrInfo();
347 GlobalBaseReg
= RegInfo
.createVirtualRegister(&Alpha::GPRCRegClass
);
348 BuildMI(FirstMBB
, MBBI
, DebugLoc(), TII
->get(TargetOpcode::COPY
),
349 GlobalBaseReg
).addReg(Alpha::R29
);
350 RegInfo
.addLiveIn(Alpha::R29
);
352 AlphaFI
->setGlobalBaseReg(GlobalBaseReg
);
353 return GlobalBaseReg
;
356 /// getGlobalRetAddr - Return a virtual register initialized with the
357 /// the global base register value. Output instructions required to
358 /// initialize the register in the function entry block, if necessary.
360 unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction
*MF
) const {
361 AlphaMachineFunctionInfo
*AlphaFI
= MF
->getInfo
<AlphaMachineFunctionInfo
>();
362 unsigned GlobalRetAddr
= AlphaFI
->getGlobalRetAddr();
363 if (GlobalRetAddr
!= 0)
364 return GlobalRetAddr
;
366 // Insert the set of GlobalRetAddr into the first MBB of the function
367 MachineBasicBlock
&FirstMBB
= MF
->front();
368 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
369 MachineRegisterInfo
&RegInfo
= MF
->getRegInfo();
370 const TargetInstrInfo
*TII
= MF
->getTarget().getInstrInfo();
372 GlobalRetAddr
= RegInfo
.createVirtualRegister(&Alpha::GPRCRegClass
);
373 BuildMI(FirstMBB
, MBBI
, DebugLoc(), TII
->get(TargetOpcode::COPY
),
374 GlobalRetAddr
).addReg(Alpha::R26
);
375 RegInfo
.addLiveIn(Alpha::R26
);
377 AlphaFI
->setGlobalRetAddr(GlobalRetAddr
);
378 return GlobalRetAddr
;