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/ADT/STLExtras.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineLocation.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "XCoreGenInstrInfo.inc"
23 #include "llvm/Support/Debug.h"
28 // XCore Condition Codes
39 XCoreInstrInfo::XCoreInstrInfo(void)
40 : TargetInstrInfoImpl(XCoreInsts
, array_lengthof(XCoreInsts
)),
44 static bool isZeroImm(const MachineOperand
&op
) {
45 return op
.isImm() && op
.getImm() == 0;
48 /// Return true if the instruction is a register to register move and
49 /// leave the source and dest operands in the passed parameters.
51 bool XCoreInstrInfo::isMoveInstr(const MachineInstr
&MI
,
52 unsigned &SrcReg
, unsigned &DstReg
,
53 unsigned &SrcSR
, unsigned &DstSR
) const {
54 SrcSR
= DstSR
= 0; // No sub-registers.
56 // We look for 4 kinds of patterns here:
61 if ((MI
.getOpcode() == XCore::ADD_2rus
|| MI
.getOpcode() == XCore::SUB_2rus
)
62 && isZeroImm(MI
.getOperand(2))) {
63 DstReg
= MI
.getOperand(0).getReg();
64 SrcReg
= MI
.getOperand(1).getReg();
66 } else if ((MI
.getOpcode() == XCore::OR_3r
|| MI
.getOpcode() == XCore::AND_3r
)
67 && MI
.getOperand(1).getReg() == MI
.getOperand(2).getReg()) {
68 DstReg
= MI
.getOperand(0).getReg();
69 SrcReg
= MI
.getOperand(1).getReg();
75 /// isLoadFromStackSlot - If the specified machine instruction is a direct
76 /// load from a stack slot, return the virtual or physical register number of
77 /// the destination along with the FrameIndex of the loaded stack slot. If
78 /// not, return 0. This predicate must return 0 if the instruction has
79 /// any side effects other than loading from the stack slot.
81 XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const{
82 int Opcode
= MI
->getOpcode();
83 if (Opcode
== XCore::LDWFI
)
85 if ((MI
->getOperand(1).isFI()) && // is a stack slot
86 (MI
->getOperand(2).isImm()) && // the imm is zero
87 (isZeroImm(MI
->getOperand(2))))
89 FrameIndex
= MI
->getOperand(1).getIndex();
90 return MI
->getOperand(0).getReg();
96 /// isStoreToStackSlot - If the specified machine instruction is a direct
97 /// store to a stack slot, return the virtual or physical register number of
98 /// the source reg along with the FrameIndex of the loaded stack slot. If
99 /// not, return 0. This predicate must return 0 if the instruction has
100 /// any side effects other than storing to the stack slot.
102 XCoreInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
103 int &FrameIndex
) const {
104 int Opcode
= MI
->getOpcode();
105 if (Opcode
== XCore::STWFI
)
107 if ((MI
->getOperand(1).isFI()) && // is a stack slot
108 (MI
->getOperand(2).isImm()) && // the imm is zero
109 (isZeroImm(MI
->getOperand(2))))
111 FrameIndex
= MI
->getOperand(1).getIndex();
112 return MI
->getOperand(0).getReg();
118 /// isInvariantLoad - Return true if the specified instruction (which is marked
119 /// mayLoad) is loading from a location whose value is invariant across the
120 /// function. For example, loading a value from the constant pool or from
121 /// from the argument area of a function if it does not change. This should
122 /// only return true of *all* loads the instruction does are invariant (if it
123 /// does multiple loads).
125 XCoreInstrInfo::isInvariantLoad(const MachineInstr
*MI
) const {
126 // Loads from constants pools and loads from invariant argument slots are
128 int Opcode
= MI
->getOpcode();
129 if (Opcode
== XCore::LDWCP_ru6
|| Opcode
== XCore::LDWCP_lru6
) {
130 return MI
->getOperand(1).isCPI();
133 if (isLoadFromStackSlot(MI
, FrameIndex
)) {
134 const MachineFrameInfo
&MFI
=
135 *MI
->getParent()->getParent()->getFrameInfo();
136 return MFI
.isFixedObjectIndex(FrameIndex
) &&
137 MFI
.isImmutableObjectIndex(FrameIndex
);
142 //===----------------------------------------------------------------------===//
144 //===----------------------------------------------------------------------===//
146 static inline bool IsBRU(unsigned BrOpc
) {
147 return BrOpc
== XCore::BRFU_u6
148 || BrOpc
== XCore::BRFU_lu6
149 || BrOpc
== XCore::BRBU_u6
150 || BrOpc
== XCore::BRBU_lu6
;
153 static inline bool IsBRT(unsigned BrOpc
) {
154 return BrOpc
== XCore::BRFT_ru6
155 || BrOpc
== XCore::BRFT_lru6
156 || BrOpc
== XCore::BRBT_ru6
157 || BrOpc
== XCore::BRBT_lru6
;
160 static inline bool IsBRF(unsigned BrOpc
) {
161 return BrOpc
== XCore::BRFF_ru6
162 || BrOpc
== XCore::BRFF_lru6
163 || BrOpc
== XCore::BRBF_ru6
164 || BrOpc
== XCore::BRBF_lru6
;
167 static inline bool IsCondBranch(unsigned BrOpc
) {
168 return IsBRF(BrOpc
) || IsBRT(BrOpc
);
171 /// GetCondFromBranchOpc - Return the XCore CC that matches
172 /// the correspondent Branch instruction opcode.
173 static XCore::CondCode
GetCondFromBranchOpc(unsigned BrOpc
)
176 return XCore::COND_TRUE
;
177 } else if (IsBRF(BrOpc
)) {
178 return XCore::COND_FALSE
;
180 return XCore::COND_INVALID
;
184 /// GetCondBranchFromCond - Return the Branch instruction
185 /// opcode that matches the cc.
186 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC
)
189 default: assert(0 && "Illegal condition code!");
190 case XCore::COND_TRUE
: return XCore::BRFT_lru6
;
191 case XCore::COND_FALSE
: return XCore::BRFF_lru6
;
195 /// GetOppositeBranchCondition - Return the inverse of the specified
196 /// condition, e.g. turning COND_E to COND_NE.
197 static inline XCore::CondCode
GetOppositeBranchCondition(XCore::CondCode CC
)
200 default: assert(0 && "Illegal condition code!");
201 case XCore::COND_TRUE
: return XCore::COND_FALSE
;
202 case XCore::COND_FALSE
: return XCore::COND_TRUE
;
206 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
207 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
208 /// implemented for a target). Upon success, this returns false and returns
209 /// with the following information in various cases:
211 /// 1. If this block ends with no branches (it just falls through to its succ)
212 /// just return false, leaving TBB/FBB null.
213 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
214 /// the destination block.
215 /// 3. If this block ends with an conditional branch and it falls through to
216 /// an successor block, it sets TBB to be the branch destination block and a
217 /// list of operands that evaluate the condition. These
218 /// operands can be passed to other TargetInstrInfo methods to create new
220 /// 4. If this block ends with an conditional branch and an unconditional
221 /// block, it returns the 'true' destination in TBB, the 'false' destination
222 /// in FBB, and a list of operands that evaluate the condition. These
223 /// operands can be passed to other TargetInstrInfo methods to create new
226 /// Note that RemoveBranch and InsertBranch must be implemented to support
227 /// cases where this method returns success.
230 XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
231 MachineBasicBlock
*&FBB
,
232 SmallVectorImpl
<MachineOperand
> &Cond
,
233 bool AllowModify
) const {
234 // If the block has no terminators, it just falls into the block after it.
235 MachineBasicBlock::iterator I
= MBB
.end();
236 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
))
239 // Get the last instruction in the block.
240 MachineInstr
*LastInst
= I
;
242 // If there is only one terminator instruction, process it.
243 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
)) {
244 if (IsBRU(LastInst
->getOpcode())) {
245 TBB
= LastInst
->getOperand(0).getMBB();
249 XCore::CondCode BranchCode
= GetCondFromBranchOpc(LastInst
->getOpcode());
250 if (BranchCode
== XCore::COND_INVALID
)
251 return true; // Can't handle indirect branch.
253 // Conditional branch
254 // Block ends with fall-through condbranch.
256 TBB
= LastInst
->getOperand(1).getMBB();
257 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
258 Cond
.push_back(LastInst
->getOperand(0));
262 // Get the instruction before it if it's a terminator.
263 MachineInstr
*SecondLastInst
= I
;
265 // If there are three terminators, we don't know what sort of block this is.
266 if (SecondLastInst
&& I
!= MBB
.begin() &&
267 isUnpredicatedTerminator(--I
))
270 unsigned SecondLastOpc
= SecondLastInst
->getOpcode();
271 XCore::CondCode BranchCode
= GetCondFromBranchOpc(SecondLastOpc
);
273 // If the block ends with conditional branch followed by unconditional,
275 if (BranchCode
!= XCore::COND_INVALID
276 && IsBRU(LastInst
->getOpcode())) {
278 TBB
= SecondLastInst
->getOperand(1).getMBB();
279 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
280 Cond
.push_back(SecondLastInst
->getOperand(0));
282 FBB
= LastInst
->getOperand(0).getMBB();
286 // If the block ends with two unconditional branches, handle it. The second
287 // one is not executed, so remove it.
288 if (IsBRU(SecondLastInst
->getOpcode()) &&
289 IsBRU(LastInst
->getOpcode())) {
290 TBB
= SecondLastInst
->getOperand(0).getMBB();
293 I
->eraseFromParent();
297 // Otherwise, can't handle this.
302 XCoreInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*TBB
,
303 MachineBasicBlock
*FBB
,
304 const SmallVectorImpl
<MachineOperand
> &Cond
)const{
305 // FIXME there should probably be a DebugLoc argument here
306 DebugLoc dl
= DebugLoc::getUnknownLoc();
307 // Shouldn't be a fall through.
308 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
309 assert((Cond
.size() == 2 || Cond
.size() == 0) &&
310 "Unexpected number of components!");
312 if (FBB
== 0) { // One way branch.
314 // Unconditional branch
315 BuildMI(&MBB
, dl
, get(XCore::BRFU_lu6
)).addMBB(TBB
);
317 // Conditional branch.
318 unsigned Opc
= GetCondBranchFromCond((XCore::CondCode
)Cond
[0].getImm());
319 BuildMI(&MBB
, dl
, get(Opc
)).addReg(Cond
[1].getReg())
325 // Two-way Conditional branch.
326 assert(Cond
.size() == 2 && "Unexpected number of components!");
327 unsigned Opc
= GetCondBranchFromCond((XCore::CondCode
)Cond
[0].getImm());
328 BuildMI(&MBB
, dl
, get(Opc
)).addReg(Cond
[1].getReg())
330 BuildMI(&MBB
, dl
, get(XCore::BRFU_lu6
)).addMBB(FBB
);
335 XCoreInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
336 MachineBasicBlock::iterator I
= MBB
.end();
337 if (I
== MBB
.begin()) return 0;
339 if (!IsBRU(I
->getOpcode()) && !IsCondBranch(I
->getOpcode()))
342 // Remove the branch.
343 I
->eraseFromParent();
347 if (I
== MBB
.begin()) return 1;
349 if (!IsCondBranch(I
->getOpcode()))
352 // Remove the branch.
353 I
->eraseFromParent();
357 bool XCoreInstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
358 MachineBasicBlock::iterator I
,
359 unsigned DestReg
, unsigned SrcReg
,
360 const TargetRegisterClass
*DestRC
,
361 const TargetRegisterClass
*SrcRC
) const {
362 DebugLoc DL
= DebugLoc::getUnknownLoc();
363 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
365 if (DestRC
== SrcRC
) {
366 if (DestRC
== XCore::GRRegsRegisterClass
) {
367 BuildMI(MBB
, I
, DL
, get(XCore::ADD_2rus
), DestReg
)
376 if (SrcRC
== XCore::RRegsRegisterClass
&& SrcReg
== XCore::SP
&&
377 DestRC
== XCore::GRRegsRegisterClass
) {
378 BuildMI(MBB
, I
, DL
, get(XCore::LDAWSP_ru6
), DestReg
)
382 if (DestRC
== XCore::RRegsRegisterClass
&& DestReg
== XCore::SP
&&
383 SrcRC
== XCore::GRRegsRegisterClass
) {
384 BuildMI(MBB
, I
, DL
, get(XCore::SETSP_1r
))
391 void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
392 MachineBasicBlock::iterator I
,
393 unsigned SrcReg
, bool isKill
,
395 const TargetRegisterClass
*RC
) const
397 DebugLoc DL
= DebugLoc::getUnknownLoc();
398 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
399 BuildMI(MBB
, I
, DL
, get(XCore::STWFI
))
400 .addReg(SrcReg
, false, false, isKill
)
401 .addFrameIndex(FrameIndex
)
405 void XCoreInstrInfo::storeRegToAddr(MachineFunction
&MF
, unsigned SrcReg
,
406 bool isKill
, SmallVectorImpl
<MachineOperand
> &Addr
,
407 const TargetRegisterClass
*RC
,
408 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const
410 assert(0 && "unimplemented\n");
413 void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
414 MachineBasicBlock::iterator I
,
415 unsigned DestReg
, int FrameIndex
,
416 const TargetRegisterClass
*RC
) const
418 DebugLoc DL
= DebugLoc::getUnknownLoc();
419 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
420 BuildMI(MBB
, I
, DL
, get(XCore::LDWFI
), DestReg
)
421 .addFrameIndex(FrameIndex
)
425 void XCoreInstrInfo::loadRegFromAddr(MachineFunction
&MF
, unsigned DestReg
,
426 SmallVectorImpl
<MachineOperand
> &Addr
,
427 const TargetRegisterClass
*RC
,
428 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const
430 assert(0 && "unimplemented\n");
433 bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
434 MachineBasicBlock::iterator MI
,
435 const std::vector
<CalleeSavedInfo
> &CSI
) const
440 MachineFunction
*MF
= MBB
.getParent();
441 const MachineFrameInfo
*MFI
= MF
->getFrameInfo();
442 MachineModuleInfo
*MMI
= MFI
->getMachineModuleInfo();
443 XCoreFunctionInfo
*XFI
= MF
->getInfo
<XCoreFunctionInfo
>();
445 bool emitFrameMoves
= XCoreRegisterInfo::needsFrameMoves(*MF
);
447 DebugLoc DL
= DebugLoc::getUnknownLoc();
448 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
450 for (std::vector
<CalleeSavedInfo
>::const_iterator it
= CSI
.begin();
451 it
!= CSI
.end(); ++it
) {
452 // Add the callee-saved register as live-in. It's killed at the spill.
453 MBB
.addLiveIn(it
->getReg());
455 storeRegToStackSlot(MBB
, MI
, it
->getReg(), true,
456 it
->getFrameIdx(), it
->getRegClass());
457 if (emitFrameMoves
) {
458 unsigned SaveLabelId
= MMI
->NextLabelID();
459 BuildMI(MBB
, MI
, DL
, get(XCore::DBG_LABEL
)).addImm(SaveLabelId
);
460 XFI
->getSpillLabels().push_back(
461 std::pair
<unsigned, CalleeSavedInfo
>(SaveLabelId
, *it
));
467 bool XCoreInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
468 MachineBasicBlock::iterator MI
,
469 const std::vector
<CalleeSavedInfo
> &CSI
) const
471 bool AtStart
= MI
== MBB
.begin();
472 MachineBasicBlock::iterator BeforeI
= MI
;
475 for (std::vector
<CalleeSavedInfo
>::const_iterator it
= CSI
.begin();
476 it
!= CSI
.end(); ++it
) {
478 loadRegFromStackSlot(MBB
, MI
, it
->getReg(),
481 assert(MI
!= MBB
.begin() &&
482 "loadRegFromStackSlot didn't insert any code!");
483 // Insert in reverse order. loadRegFromStackSlot can insert multiple
495 /// BlockHasNoFallThrough - Analyse if MachineBasicBlock does not
496 /// fall-through into its successor block.
497 bool XCoreInstrInfo::
498 BlockHasNoFallThrough(const MachineBasicBlock
&MBB
) const
500 if (MBB
.empty()) return false;
502 switch (MBB
.back().getOpcode()) {
503 case XCore::RETSP_u6
: // Return.
504 case XCore::RETSP_lu6
:
505 case XCore::BAU_1r
: // Indirect branch.
506 case XCore::BRFU_u6
: // Uncond branch.
507 case XCore::BRFU_lu6
:
509 case XCore::BRBU_lu6
:
511 default: return false;
515 /// ReverseBranchCondition - Return the inverse opcode of the
516 /// specified Branch instruction.
517 bool XCoreInstrInfo::
518 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const
520 assert((Cond
.size() == 2) &&
521 "Invalid XCore branch condition!");
522 Cond
[0].setImm(GetOppositeBranchCondition((XCore::CondCode
)Cond
[0].getImm()));