1 //===- XCoreInstrInfo.cpp - XCore 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 XCore implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "XCoreMachineFunctionInfo.h"
15 #include "XCoreInstrInfo.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineLocation.h"
21 #include "XCoreGenInstrInfo.inc"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/ErrorHandling.h"
29 // XCore Condition Codes
40 XCoreInstrInfo::XCoreInstrInfo()
41 : TargetInstrInfoImpl(XCoreInsts
, array_lengthof(XCoreInsts
)),
45 static bool isZeroImm(const MachineOperand
&op
) {
46 return op
.isImm() && op
.getImm() == 0;
49 /// isLoadFromStackSlot - If the specified machine instruction is a direct
50 /// load from a stack slot, return the virtual or physical register number of
51 /// the destination along with the FrameIndex of the loaded stack slot. If
52 /// not, return 0. This predicate must return 0 if the instruction has
53 /// any side effects other than loading from the stack slot.
55 XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const{
56 int Opcode
= MI
->getOpcode();
57 if (Opcode
== XCore::LDWFI
)
59 if ((MI
->getOperand(1).isFI()) && // is a stack slot
60 (MI
->getOperand(2).isImm()) && // the imm is zero
61 (isZeroImm(MI
->getOperand(2))))
63 FrameIndex
= MI
->getOperand(1).getIndex();
64 return MI
->getOperand(0).getReg();
70 /// isStoreToStackSlot - If the specified machine instruction is a direct
71 /// store to a stack slot, return the virtual or physical register number of
72 /// the source reg along with the FrameIndex of the loaded stack slot. If
73 /// not, return 0. This predicate must return 0 if the instruction has
74 /// any side effects other than storing to the stack slot.
76 XCoreInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
77 int &FrameIndex
) const {
78 int Opcode
= MI
->getOpcode();
79 if (Opcode
== XCore::STWFI
)
81 if ((MI
->getOperand(1).isFI()) && // is a stack slot
82 (MI
->getOperand(2).isImm()) && // the imm is zero
83 (isZeroImm(MI
->getOperand(2))))
85 FrameIndex
= MI
->getOperand(1).getIndex();
86 return MI
->getOperand(0).getReg();
92 //===----------------------------------------------------------------------===//
94 //===----------------------------------------------------------------------===//
96 static inline bool IsBRU(unsigned BrOpc
) {
97 return BrOpc
== XCore::BRFU_u6
98 || BrOpc
== XCore::BRFU_lu6
99 || BrOpc
== XCore::BRBU_u6
100 || BrOpc
== XCore::BRBU_lu6
;
103 static inline bool IsBRT(unsigned BrOpc
) {
104 return BrOpc
== XCore::BRFT_ru6
105 || BrOpc
== XCore::BRFT_lru6
106 || BrOpc
== XCore::BRBT_ru6
107 || BrOpc
== XCore::BRBT_lru6
;
110 static inline bool IsBRF(unsigned BrOpc
) {
111 return BrOpc
== XCore::BRFF_ru6
112 || BrOpc
== XCore::BRFF_lru6
113 || BrOpc
== XCore::BRBF_ru6
114 || BrOpc
== XCore::BRBF_lru6
;
117 static inline bool IsCondBranch(unsigned BrOpc
) {
118 return IsBRF(BrOpc
) || IsBRT(BrOpc
);
121 static inline bool IsBR_JT(unsigned BrOpc
) {
122 return BrOpc
== XCore::BR_JT
123 || BrOpc
== XCore::BR_JT32
;
126 /// GetCondFromBranchOpc - Return the XCore CC that matches
127 /// the correspondent Branch instruction opcode.
128 static XCore::CondCode
GetCondFromBranchOpc(unsigned BrOpc
)
131 return XCore::COND_TRUE
;
132 } else if (IsBRF(BrOpc
)) {
133 return XCore::COND_FALSE
;
135 return XCore::COND_INVALID
;
139 /// GetCondBranchFromCond - Return the Branch instruction
140 /// opcode that matches the cc.
141 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC
)
144 default: llvm_unreachable("Illegal condition code!");
145 case XCore::COND_TRUE
: return XCore::BRFT_lru6
;
146 case XCore::COND_FALSE
: return XCore::BRFF_lru6
;
150 /// GetOppositeBranchCondition - Return the inverse of the specified
151 /// condition, e.g. turning COND_E to COND_NE.
152 static inline XCore::CondCode
GetOppositeBranchCondition(XCore::CondCode CC
)
155 default: llvm_unreachable("Illegal condition code!");
156 case XCore::COND_TRUE
: return XCore::COND_FALSE
;
157 case XCore::COND_FALSE
: return XCore::COND_TRUE
;
161 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
162 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
163 /// implemented for a target). Upon success, this returns false and returns
164 /// with the following information in various cases:
166 /// 1. If this block ends with no branches (it just falls through to its succ)
167 /// just return false, leaving TBB/FBB null.
168 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
169 /// the destination block.
170 /// 3. If this block ends with an conditional branch and it falls through to
171 /// an successor block, it sets TBB to be the branch destination block and a
172 /// list of operands that evaluate the condition. These
173 /// operands can be passed to other TargetInstrInfo methods to create new
175 /// 4. If this block ends with an conditional branch and an unconditional
176 /// block, it returns the 'true' destination in TBB, the 'false' destination
177 /// in FBB, and a list of operands that evaluate the condition. These
178 /// operands can be passed to other TargetInstrInfo methods to create new
181 /// Note that RemoveBranch and InsertBranch must be implemented to support
182 /// cases where this method returns success.
185 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
186 MachineBasicBlock
*&FBB
,
187 SmallVectorImpl
<MachineOperand
> &Cond
,
188 bool AllowModify
) const {
189 // If the block has no terminators, it just falls into the block after it.
190 MachineBasicBlock::iterator I
= MBB
.end();
191 if (I
== MBB
.begin())
194 while (I
->isDebugValue()) {
195 if (I
== MBB
.begin())
199 if (!isUnpredicatedTerminator(I
))
202 // Get the last instruction in the block.
203 MachineInstr
*LastInst
= I
;
205 // If there is only one terminator instruction, process it.
206 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
)) {
207 if (IsBRU(LastInst
->getOpcode())) {
208 TBB
= LastInst
->getOperand(0).getMBB();
212 XCore::CondCode BranchCode
= GetCondFromBranchOpc(LastInst
->getOpcode());
213 if (BranchCode
== XCore::COND_INVALID
)
214 return true; // Can't handle indirect branch.
216 // Conditional branch
217 // Block ends with fall-through condbranch.
219 TBB
= LastInst
->getOperand(1).getMBB();
220 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
221 Cond
.push_back(LastInst
->getOperand(0));
225 // Get the instruction before it if it's a terminator.
226 MachineInstr
*SecondLastInst
= I
;
228 // If there are three terminators, we don't know what sort of block this is.
229 if (SecondLastInst
&& I
!= MBB
.begin() &&
230 isUnpredicatedTerminator(--I
))
233 unsigned SecondLastOpc
= SecondLastInst
->getOpcode();
234 XCore::CondCode BranchCode
= GetCondFromBranchOpc(SecondLastOpc
);
236 // If the block ends with conditional branch followed by unconditional,
238 if (BranchCode
!= XCore::COND_INVALID
239 && IsBRU(LastInst
->getOpcode())) {
241 TBB
= SecondLastInst
->getOperand(1).getMBB();
242 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
243 Cond
.push_back(SecondLastInst
->getOperand(0));
245 FBB
= LastInst
->getOperand(0).getMBB();
249 // If the block ends with two unconditional branches, handle it. The second
250 // one is not executed, so remove it.
251 if (IsBRU(SecondLastInst
->getOpcode()) &&
252 IsBRU(LastInst
->getOpcode())) {
253 TBB
= SecondLastInst
->getOperand(0).getMBB();
256 I
->eraseFromParent();
260 // Likewise if it ends with a branch table followed by an unconditional branch.
261 if (IsBR_JT(SecondLastInst
->getOpcode()) && IsBRU(LastInst
->getOpcode())) {
264 I
->eraseFromParent();
268 // Otherwise, can't handle this.
273 XCoreInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*TBB
,
274 MachineBasicBlock
*FBB
,
275 const SmallVectorImpl
<MachineOperand
> &Cond
,
277 // Shouldn't be a fall through.
278 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
279 assert((Cond
.size() == 2 || Cond
.size() == 0) &&
280 "Unexpected number of components!");
282 if (FBB
== 0) { // One way branch.
284 // Unconditional branch
285 BuildMI(&MBB
, DL
, get(XCore::BRFU_lu6
)).addMBB(TBB
);
287 // Conditional branch.
288 unsigned Opc
= GetCondBranchFromCond((XCore::CondCode
)Cond
[0].getImm());
289 BuildMI(&MBB
, DL
, get(Opc
)).addReg(Cond
[1].getReg())
295 // Two-way Conditional branch.
296 assert(Cond
.size() == 2 && "Unexpected number of components!");
297 unsigned Opc
= GetCondBranchFromCond((XCore::CondCode
)Cond
[0].getImm());
298 BuildMI(&MBB
, DL
, get(Opc
)).addReg(Cond
[1].getReg())
300 BuildMI(&MBB
, DL
, get(XCore::BRFU_lu6
)).addMBB(FBB
);
305 XCoreInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
306 MachineBasicBlock::iterator I
= MBB
.end();
307 if (I
== MBB
.begin()) return 0;
309 while (I
->isDebugValue()) {
310 if (I
== MBB
.begin())
314 if (!IsBRU(I
->getOpcode()) && !IsCondBranch(I
->getOpcode()))
317 // Remove the branch.
318 I
->eraseFromParent();
322 if (I
== MBB
.begin()) return 1;
324 if (!IsCondBranch(I
->getOpcode()))
327 // Remove the branch.
328 I
->eraseFromParent();
332 void XCoreInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
333 MachineBasicBlock::iterator I
, DebugLoc DL
,
334 unsigned DestReg
, unsigned SrcReg
,
335 bool KillSrc
) const {
336 bool GRDest
= XCore::GRRegsRegClass
.contains(DestReg
);
337 bool GRSrc
= XCore::GRRegsRegClass
.contains(SrcReg
);
339 if (GRDest
&& GRSrc
) {
340 BuildMI(MBB
, I
, DL
, get(XCore::ADD_2rus
), DestReg
)
341 .addReg(SrcReg
, getKillRegState(KillSrc
))
346 if (GRDest
&& SrcReg
== XCore::SP
) {
347 BuildMI(MBB
, I
, DL
, get(XCore::LDAWSP_ru6
), DestReg
).addImm(0);
351 if (DestReg
== XCore::SP
&& GRSrc
) {
352 BuildMI(MBB
, I
, DL
, get(XCore::SETSP_1r
))
353 .addReg(SrcReg
, getKillRegState(KillSrc
));
356 llvm_unreachable("Impossible reg-to-reg copy");
359 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
360 MachineBasicBlock::iterator I
,
361 unsigned SrcReg
, bool isKill
,
363 const TargetRegisterClass
*RC
,
364 const TargetRegisterInfo
*TRI
) const
367 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
368 BuildMI(MBB
, I
, DL
, get(XCore::STWFI
))
369 .addReg(SrcReg
, getKillRegState(isKill
))
370 .addFrameIndex(FrameIndex
)
374 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
375 MachineBasicBlock::iterator I
,
376 unsigned DestReg
, int FrameIndex
,
377 const TargetRegisterClass
*RC
,
378 const TargetRegisterInfo
*TRI
) const
381 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
382 BuildMI(MBB
, I
, DL
, get(XCore::LDWFI
), DestReg
)
383 .addFrameIndex(FrameIndex
)
387 /// ReverseBranchCondition - Return the inverse opcode of the
388 /// specified Branch instruction.
389 bool XCoreInstrInfo::
390 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
391 assert((Cond
.size() == 2) &&
392 "Invalid XCore branch condition!");
393 Cond
[0].setImm(GetOppositeBranchCondition((XCore::CondCode
)Cond
[0].getImm()));