131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===//
2b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
3b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//                     The LLVM Compiler Infrastructure
4b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
5b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file is distributed under the University of Illinois Open Source
6b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// License. See LICENSE.TXT for details.
7b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
8b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
9b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
10b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file contains the XCore implementation of the TargetInstrInfo class.
11b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//
12b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
13b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
14b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreInstrInfo.h"
15b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCore.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "XCoreMachineFunctionInfo.h"
1766f20c8e82685a699447144dbd659c4e465eccc8Chris Lattner#include "llvm/ADT/STLExtras.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFrameInfo.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCContext.h"
21b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/Debug.h"
22c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
233e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR
2622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "XCoreGenInstrInfo.inc"
2722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
28b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace llvm {
29b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace XCore {
30b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
31b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // XCore Condition Codes
32b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  enum CondCode {
33b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    COND_TRUE,
34b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    COND_FALSE,
35b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    COND_INVALID
36b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  };
37b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
38b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
39b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
40b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm;
41b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
42a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan GohmanXCoreInstrInfo::XCoreInstrInfo()
434db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP),
44b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    RI(*this) {
45b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic bool isZeroImm(const MachineOperand &op) {
48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return op.isImm() && op.getImm() == 0;
49b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
50b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
51b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// isLoadFromStackSlot - If the specified machine instruction is a direct
52b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// load from a stack slot, return the virtual or physical register number of
53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// the destination along with the FrameIndex of the loaded stack slot.  If
54b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// not, return 0.  This predicate must return 0 if the instruction has
55b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// any side effects other than loading from the stack slot.
56b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned
57cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan GohmanXCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{
58b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int Opcode = MI->getOpcode();
5929cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  if (Opcode == XCore::LDWFI)
60b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  {
61b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if ((MI->getOperand(1).isFI()) && // is a stack slot
62b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        (MI->getOperand(2).isImm()) &&  // the imm is zero
63b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        (isZeroImm(MI->getOperand(2))))
64b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    {
65b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      FrameIndex = MI->getOperand(1).getIndex();
66b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      return MI->getOperand(0).getReg();
67b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
68b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
69b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return 0;
70b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
71b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
72b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  /// isStoreToStackSlot - If the specified machine instruction is a direct
73b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  /// store to a stack slot, return the virtual or physical register number of
74b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  /// the source reg along with the FrameIndex of the loaded stack slot.  If
75b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  /// not, return 0.  This predicate must return 0 if the instruction has
76b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  /// any side effects other than storing to the stack slot.
77b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned
78cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan GohmanXCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
79cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan Gohman                                   int &FrameIndex) const {
80b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  int Opcode = MI->getOpcode();
8129cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne  if (Opcode == XCore::STWFI)
82b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  {
83b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if ((MI->getOperand(1).isFI()) && // is a stack slot
84b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne        (MI->getOperand(2).isImm()) &&  // the imm is zero
8529cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne        (isZeroImm(MI->getOperand(2))))
86b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    {
87b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      FrameIndex = MI->getOperand(1).getIndex();
88b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      return MI->getOperand(0).getReg();
89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
90b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
91b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return 0;
92b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
93b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
94b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
95b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// Branch Analysis
96b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===//
97b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
98b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRU(unsigned BrOpc) {
99b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return BrOpc == XCore::BRFU_u6
100b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRFU_lu6
101b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBU_u6
102b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBU_lu6;
103b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
104b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
105b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRT(unsigned BrOpc) {
106b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return BrOpc == XCore::BRFT_ru6
107b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRFT_lru6
108b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBT_ru6
109b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBT_lru6;
110b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
111b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
112b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRF(unsigned BrOpc) {
113b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return BrOpc == XCore::BRFF_ru6
114b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRFF_lru6
115b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBF_ru6
116b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      || BrOpc == XCore::BRBF_lru6;
117b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
118b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
119b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsCondBranch(unsigned BrOpc) {
120b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return IsBRF(BrOpc) || IsBRT(BrOpc);
121b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
122b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
12378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osbornestatic inline bool IsBR_JT(unsigned BrOpc) {
12478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  return BrOpc == XCore::BR_JT
12578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne      || BrOpc == XCore::BR_JT32;
12678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne}
12778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne
128b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetCondFromBranchOpc - Return the XCore CC that matches
129b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// the correspondent Branch instruction opcode.
130b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
131b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{
132b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (IsBRT(BrOpc)) {
133b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return XCore::COND_TRUE;
134b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  } else if (IsBRF(BrOpc)) {
135b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return XCore::COND_FALSE;
136b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  } else {
137b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return XCore::COND_INVALID;
138b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
139b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
140b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
141b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetCondBranchFromCond - Return the Branch instruction
142b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// opcode that matches the cc.
143b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline unsigned GetCondBranchFromCond(XCore::CondCode CC)
144b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{
145b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  switch (CC) {
146c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Illegal condition code!");
147b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case XCore::COND_TRUE   : return XCore::BRFT_lru6;
148b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case XCore::COND_FALSE  : return XCore::BRFF_lru6;
149b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
150b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
151b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
152b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetOppositeBranchCondition - Return the inverse of the specified
153b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// condition, e.g. turning COND_E to COND_NE.
154b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC)
155b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{
156b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  switch (CC) {
157c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Illegal condition code!");
158b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case XCore::COND_TRUE   : return XCore::COND_FALSE;
159b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case XCore::COND_FALSE  : return XCore::COND_TRUE;
160b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
161b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
162b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
163b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
164b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
165b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// implemented for a target).  Upon success, this returns false and returns
166b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// with the following information in various cases:
167b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///
168b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 1. If this block ends with no branches (it just falls through to its succ)
169b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    just return false, leaving TBB/FBB null.
170b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 2. If this block ends with only an unconditional branch, it sets TBB to be
171b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    the destination block.
172b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 3. If this block ends with an conditional branch and it falls through to
173b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    an successor block, it sets TBB to be the branch destination block and a
174b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    list of operands that evaluate the condition. These
175b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    operands can be passed to other TargetInstrInfo methods to create new
176b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    branches.
177b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 4. If this block ends with an conditional branch and an unconditional
178b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    block, it returns the 'true' destination in TBB, the 'false' destination
179b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    in FBB, and a list of operands that evaluate the condition. These
180b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    operands can be passed to other TargetInstrInfo methods to create new
181b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///    branches.
182b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///
183b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// Note that RemoveBranch and InsertBranch must be implemented to support
184b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// cases where this method returns success.
185b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///
186b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool
187b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
188dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng                              MachineBasicBlock *&FBB,
189dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng                              SmallVectorImpl<MachineOperand> &Cond,
190dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng                              bool AllowModify) const {
191b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // If the block has no terminators, it just falls into the block after it.
192b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineBasicBlock::iterator I = MBB.end();
19393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  if (I == MBB.begin())
19493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    return false;
19593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  --I;
19693d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
19793d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
19893d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return false;
19993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
20093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
20193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  if (!isUnpredicatedTerminator(I))
202b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return false;
203b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
204b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Get the last instruction in the block.
205b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineInstr *LastInst = I;
206b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
207b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // If there is only one terminator instruction, process it.
208b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
209b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (IsBRU(LastInst->getOpcode())) {
210b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      TBB = LastInst->getOperand(0).getMBB();
211b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      return false;
212b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
213b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
214b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode());
215b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (BranchCode == XCore::COND_INVALID)
216b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      return true;  // Can't handle indirect branch.
217b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
218b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    // Conditional branch
219b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    // Block ends with fall-through condbranch.
220b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
221b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    TBB = LastInst->getOperand(1).getMBB();
222b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    Cond.push_back(MachineOperand::CreateImm(BranchCode));
223b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    Cond.push_back(LastInst->getOperand(0));
224b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return false;
225b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
226b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
227b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Get the instruction before it if it's a terminator.
228b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineInstr *SecondLastInst = I;
229b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
230b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // If there are three terminators, we don't know what sort of block this is.
231b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (SecondLastInst && I != MBB.begin() &&
232b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      isUnpredicatedTerminator(--I))
233b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return true;
234b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
235b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  unsigned SecondLastOpc    = SecondLastInst->getOpcode();
236b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc);
237b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
238b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // If the block ends with conditional branch followed by unconditional,
239b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // handle it.
240b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (BranchCode != XCore::COND_INVALID
241b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    && IsBRU(LastInst->getOpcode())) {
242b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
243b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    TBB = SecondLastInst->getOperand(1).getMBB();
244b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    Cond.push_back(MachineOperand::CreateImm(BranchCode));
245b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    Cond.push_back(SecondLastInst->getOperand(0));
246b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
247b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    FBB = LastInst->getOperand(0).getMBB();
248b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return false;
249b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
250b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
251b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // If the block ends with two unconditional branches, handle it.  The second
252b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // one is not executed, so remove it.
253b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (IsBRU(SecondLastInst->getOpcode()) &&
254b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      IsBRU(LastInst->getOpcode())) {
255b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    TBB = SecondLastInst->getOperand(0).getMBB();
256b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    I = LastInst;
257dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng    if (AllowModify)
258dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng      I->eraseFromParent();
259b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return false;
260b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
261b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
26278700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  // Likewise if it ends with a branch table followed by an unconditional branch.
26378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) {
26478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    I = LastInst;
26578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    if (AllowModify)
26678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne      I->eraseFromParent();
26778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    return true;
26878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  }
26978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne
270b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Otherwise, can't handle this.
271b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return true;
272b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
273b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
274b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned
275b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
276b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                             MachineBasicBlock *FBB,
2773bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                             const SmallVectorImpl<MachineOperand> &Cond,
2783bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                             DebugLoc DL)const{
279b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Shouldn't be a fall through.
280b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
281b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert((Cond.size() == 2 || Cond.size() == 0) &&
282b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne         "Unexpected number of components!");
283b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
284b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (FBB == 0) { // One way branch.
285b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (Cond.empty()) {
286b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // Unconditional branch
2873bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings      BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB);
288b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    } else {
289b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // Conditional branch.
290b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
2913bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings      BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
292b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                             .addMBB(TBB);
293b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
294b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return 1;
295b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
296b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
297b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Two-way Conditional branch.
298b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert(Cond.size() == 2 && "Unexpected number of components!");
299b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
3003bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings  BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
301b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne                         .addMBB(TBB);
3023bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings  BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB);
303b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return 2;
304b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
305b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
306b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned
307b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
308b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  MachineBasicBlock::iterator I = MBB.end();
309b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (I == MBB.begin()) return 0;
310b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  --I;
31193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
31293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
31393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return 0;
31493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
31593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
316b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode()))
317b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return 0;
318b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
319b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Remove the branch.
320b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  I->eraseFromParent();
321b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
322b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  I = MBB.end();
323b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
324b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (I == MBB.begin()) return 1;
325b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  --I;
326b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  if (!IsCondBranch(I->getOpcode()))
327b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return 1;
328b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
329b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Remove the branch.
330b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  I->eraseFromParent();
331b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return 2;
332b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
333b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
334a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesenvoid XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
335a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen                                 MachineBasicBlock::iterator I, DebugLoc DL,
336a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen                                 unsigned DestReg, unsigned SrcReg,
337a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen                                 bool KillSrc) const {
338a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  bool GRDest = XCore::GRRegsRegClass.contains(DestReg);
339a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  bool GRSrc  = XCore::GRRegsRegClass.contains(SrcReg);
340a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen
341a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  if (GRDest && GRSrc) {
342a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen    BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg)
343a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen      .addReg(SrcReg, getKillRegState(KillSrc))
344a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen      .addImm(0);
345a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen    return;
346b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
347b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
348a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  if (GRDest && SrcReg == XCore::SP) {
349a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen    BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0);
350a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen    return;
351b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
352a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen
353a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  if (DestReg == XCore::SP && GRSrc) {
354d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(XCore::SETSP_1r))
355a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen      .addReg(SrcReg, getKillRegState(KillSrc));
356a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen    return;
357b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
358a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen  llvm_unreachable("Impossible reg-to-reg copy");
359b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
360b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
361b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
362d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling                                         MachineBasicBlock::iterator I,
363d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling                                         unsigned SrcReg, bool isKill,
364d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling                                         int FrameIndex,
365746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                         const TargetRegisterClass *RC,
366746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                         const TargetRegisterInfo *TRI) const
367b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{
368c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
369d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  if (I != MBB.end()) DL = I->getDebugLoc();
370d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  BuildMI(MBB, I, DL, get(XCore::STWFI))
371587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling    .addReg(SrcReg, getKillRegState(isKill))
372d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    .addFrameIndex(FrameIndex)
373d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    .addImm(0);
374b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
375b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
376b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
377d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling                                          MachineBasicBlock::iterator I,
378d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling                                          unsigned DestReg, int FrameIndex,
379746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                          const TargetRegisterClass *RC,
380746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                          const TargetRegisterInfo *TRI) const
381b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{
382c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
383d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  if (I != MBB.end()) DL = I->getDebugLoc();
384d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg)
385d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    .addFrameIndex(FrameIndex)
386d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    .addImm(0);
387b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
388b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
3896c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsborneMachineInstr*
3906c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsborneXCoreInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
3916c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne                                         uint64_t Offset, const MDNode *MDPtr,
3926c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne                                         DebugLoc DL) const {
3936c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne  MachineInstrBuilder MIB = BuildMI(MF, DL, get(XCore::DBG_VALUE))
3946c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne    .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
3956c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne  return &*MIB;
3966c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne}
3976c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne
398b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// ReverseBranchCondition - Return the inverse opcode of the
399b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// specified Branch instruction.
400b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool XCoreInstrInfo::
401cd775ceff0b25a0b026f643a7990c2924bd310a3Anton KorobeynikovReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
402b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  assert((Cond.size() == 2) &&
403b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne          "Invalid XCore branch condition!");
404b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm()));
405b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return false;
406b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
407