LLVM  8.0.1
XCoreInstrInfo.cpp
Go to the documentation of this file.
1 //===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the XCore implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "XCoreInstrInfo.h"
15 #include "XCore.h"
17 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/Support/Debug.h"
28 
29 using namespace llvm;
30 
31 #define GET_INSTRINFO_CTOR_DTOR
32 #include "XCoreGenInstrInfo.inc"
33 
34 namespace llvm {
35 namespace XCore {
36 
37  // XCore Condition Codes
38  enum CondCode {
42  };
43 }
44 }
45 
46 // Pin the vtable to this file.
47 void XCoreInstrInfo::anchor() {}
48 
50  : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP),
51  RI() {
52 }
53 
54 static bool isZeroImm(const MachineOperand &op) {
55  return op.isImm() && op.getImm() == 0;
56 }
57 
58 /// isLoadFromStackSlot - If the specified machine instruction is a direct
59 /// load from a stack slot, return the virtual or physical register number of
60 /// the destination along with the FrameIndex of the loaded stack slot. If
61 /// not, return 0. This predicate must return 0 if the instruction has
62 /// any side effects other than loading from the stack slot.
64  int &FrameIndex) const {
65  int Opcode = MI.getOpcode();
66  if (Opcode == XCore::LDWFI)
67  {
68  if ((MI.getOperand(1).isFI()) && // is a stack slot
69  (MI.getOperand(2).isImm()) && // the imm is zero
70  (isZeroImm(MI.getOperand(2)))) {
71  FrameIndex = MI.getOperand(1).getIndex();
72  return MI.getOperand(0).getReg();
73  }
74  }
75  return 0;
76 }
77 
78  /// isStoreToStackSlot - If the specified machine instruction is a direct
79  /// store to a stack slot, return the virtual or physical register number of
80  /// the source reg along with the FrameIndex of the loaded stack slot. If
81  /// not, return 0. This predicate must return 0 if the instruction has
82  /// any side effects other than storing to the stack slot.
84  int &FrameIndex) const {
85  int Opcode = MI.getOpcode();
86  if (Opcode == XCore::STWFI)
87  {
88  if ((MI.getOperand(1).isFI()) && // is a stack slot
89  (MI.getOperand(2).isImm()) && // the imm is zero
90  (isZeroImm(MI.getOperand(2)))) {
91  FrameIndex = MI.getOperand(1).getIndex();
92  return MI.getOperand(0).getReg();
93  }
94  }
95  return 0;
96 }
97 
98 //===----------------------------------------------------------------------===//
99 // Branch Analysis
100 //===----------------------------------------------------------------------===//
101 
102 static inline bool IsBRU(unsigned BrOpc) {
103  return BrOpc == XCore::BRFU_u6
104  || BrOpc == XCore::BRFU_lu6
105  || BrOpc == XCore::BRBU_u6
106  || BrOpc == XCore::BRBU_lu6;
107 }
108 
109 static inline bool IsBRT(unsigned BrOpc) {
110  return BrOpc == XCore::BRFT_ru6
111  || BrOpc == XCore::BRFT_lru6
112  || BrOpc == XCore::BRBT_ru6
113  || BrOpc == XCore::BRBT_lru6;
114 }
115 
116 static inline bool IsBRF(unsigned BrOpc) {
117  return BrOpc == XCore::BRFF_ru6
118  || BrOpc == XCore::BRFF_lru6
119  || BrOpc == XCore::BRBF_ru6
120  || BrOpc == XCore::BRBF_lru6;
121 }
122 
123 static inline bool IsCondBranch(unsigned BrOpc) {
124  return IsBRF(BrOpc) || IsBRT(BrOpc);
125 }
126 
127 static inline bool IsBR_JT(unsigned BrOpc) {
128  return BrOpc == XCore::BR_JT
129  || BrOpc == XCore::BR_JT32;
130 }
131 
132 /// GetCondFromBranchOpc - Return the XCore CC that matches
133 /// the correspondent Branch instruction opcode.
134 static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
135 {
136  if (IsBRT(BrOpc)) {
137  return XCore::COND_TRUE;
138  } else if (IsBRF(BrOpc)) {
139  return XCore::COND_FALSE;
140  } else {
141  return XCore::COND_INVALID;
142  }
143 }
144 
145 /// GetCondBranchFromCond - Return the Branch instruction
146 /// opcode that matches the cc.
147 static inline unsigned GetCondBranchFromCond(XCore::CondCode CC)
148 {
149  switch (CC) {
150  default: llvm_unreachable("Illegal condition code!");
151  case XCore::COND_TRUE : return XCore::BRFT_lru6;
152  case XCore::COND_FALSE : return XCore::BRFF_lru6;
153  }
154 }
155 
156 /// GetOppositeBranchCondition - Return the inverse of the specified
157 /// condition, e.g. turning COND_E to COND_NE.
159 {
160  switch (CC) {
161  default: llvm_unreachable("Illegal condition code!");
162  case XCore::COND_TRUE : return XCore::COND_FALSE;
163  case XCore::COND_FALSE : return XCore::COND_TRUE;
164  }
165 }
166 
167 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
168 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
169 /// implemented for a target). Upon success, this returns false and returns
170 /// with the following information in various cases:
171 ///
172 /// 1. If this block ends with no branches (it just falls through to its succ)
173 /// just return false, leaving TBB/FBB null.
174 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
175 /// the destination block.
176 /// 3. If this block ends with an conditional branch and it falls through to
177 /// an successor block, it sets TBB to be the branch destination block and a
178 /// list of operands that evaluate the condition. These
179 /// operands can be passed to other TargetInstrInfo methods to create new
180 /// branches.
181 /// 4. If this block ends with an conditional branch and an unconditional
182 /// block, it returns the 'true' destination in TBB, the 'false' destination
183 /// in FBB, and a list of operands that evaluate the condition. These
184 /// operands can be passed to other TargetInstrInfo methods to create new
185 /// branches.
186 ///
187 /// Note that removeBranch and insertBranch must be implemented to support
188 /// cases where this method returns success.
189 ///
191  MachineBasicBlock *&TBB,
192  MachineBasicBlock *&FBB,
194  bool AllowModify) const {
195  // If the block has no terminators, it just falls into the block after it.
197  if (I == MBB.end())
198  return false;
199 
200  if (!isUnpredicatedTerminator(*I))
201  return false;
202 
203  // Get the last instruction in the block.
204  MachineInstr *LastInst = &*I;
205 
206  // If there is only one terminator instruction, process it.
207  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
208  if (IsBRU(LastInst->getOpcode())) {
209  TBB = LastInst->getOperand(0).getMBB();
210  return false;
211  }
212 
213  XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode());
214  if (BranchCode == XCore::COND_INVALID)
215  return true; // Can't handle indirect branch.
216 
217  // Conditional branch
218  // Block ends with fall-through condbranch.
219 
220  TBB = LastInst->getOperand(1).getMBB();
221  Cond.push_back(MachineOperand::CreateImm(BranchCode));
222  Cond.push_back(LastInst->getOperand(0));
223  return false;
224  }
225 
226  // Get the instruction before it if it's a terminator.
227  MachineInstr *SecondLastInst = &*I;
228 
229  // If there are three terminators, we don't know what sort of block this is.
230  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
231  return true;
232 
233  unsigned SecondLastOpc = SecondLastInst->getOpcode();
234  XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc);
235 
236  // If the block ends with conditional branch followed by unconditional,
237  // handle it.
238  if (BranchCode != XCore::COND_INVALID
239  && IsBRU(LastInst->getOpcode())) {
240 
241  TBB = SecondLastInst->getOperand(1).getMBB();
242  Cond.push_back(MachineOperand::CreateImm(BranchCode));
243  Cond.push_back(SecondLastInst->getOperand(0));
244 
245  FBB = LastInst->getOperand(0).getMBB();
246  return false;
247  }
248 
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();
254  I = LastInst;
255  if (AllowModify)
256  I->eraseFromParent();
257  return false;
258  }
259 
260  // Likewise if it ends with a branch table followed by an unconditional branch.
261  if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) {
262  I = LastInst;
263  if (AllowModify)
264  I->eraseFromParent();
265  return true;
266  }
267 
268  // Otherwise, can't handle this.
269  return true;
270 }
271 
273  MachineBasicBlock *TBB,
274  MachineBasicBlock *FBB,
276  const DebugLoc &DL,
277  int *BytesAdded) const {
278  // Shouldn't be a fall through.
279  assert(TBB && "insertBranch must not be told to insert a fallthrough");
280  assert((Cond.size() == 2 || Cond.size() == 0) &&
281  "Unexpected number of components!");
282  assert(!BytesAdded && "code size not handled");
283 
284  if (!FBB) { // One way branch.
285  if (Cond.empty()) {
286  // Unconditional branch
287  BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB);
288  } else {
289  // Conditional branch.
290  unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
291  BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
292  .addMBB(TBB);
293  }
294  return 1;
295  }
296 
297  // Two-way Conditional branch.
298  assert(Cond.size() == 2 && "Unexpected number of components!");
299  unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm());
300  BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg())
301  .addMBB(TBB);
302  BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB);
303  return 2;
304 }
305 
306 unsigned
307 XCoreInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const {
308  assert(!BytesRemoved && "code size not handled");
309 
311  if (I == MBB.end())
312  return 0;
313 
314  if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode()))
315  return 0;
316 
317  // Remove the branch.
318  I->eraseFromParent();
319 
320  I = MBB.end();
321 
322  if (I == MBB.begin()) return 1;
323  --I;
324  if (!IsCondBranch(I->getOpcode()))
325  return 1;
326 
327  // Remove the branch.
328  I->eraseFromParent();
329  return 2;
330 }
331 
334  const DebugLoc &DL, unsigned DestReg,
335  unsigned SrcReg, bool KillSrc) const {
336  bool GRDest = XCore::GRRegsRegClass.contains(DestReg);
337  bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg);
338 
339  if (GRDest && GRSrc) {
340  BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg)
341  .addReg(SrcReg, getKillRegState(KillSrc))
342  .addImm(0);
343  return;
344  }
345 
346  if (GRDest && SrcReg == XCore::SP) {
347  BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0);
348  return;
349  }
350 
351  if (DestReg == XCore::SP && GRSrc) {
352  BuildMI(MBB, I, DL, get(XCore::SETSP_1r))
353  .addReg(SrcReg, getKillRegState(KillSrc));
354  return;
355  }
356  llvm_unreachable("Impossible reg-to-reg copy");
357 }
358 
361  unsigned SrcReg, bool isKill,
362  int FrameIndex,
363  const TargetRegisterClass *RC,
364  const TargetRegisterInfo *TRI) const
365 {
366  DebugLoc DL;
367  if (I != MBB.end() && !I->isDebugInstr())
368  DL = I->getDebugLoc();
369  MachineFunction *MF = MBB.getParent();
370  const MachineFrameInfo &MFI = MF->getFrameInfo();
372  MachinePointerInfo::getFixedStack(*MF, FrameIndex),
373  MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex),
374  MFI.getObjectAlignment(FrameIndex));
375  BuildMI(MBB, I, DL, get(XCore::STWFI))
376  .addReg(SrcReg, getKillRegState(isKill))
377  .addFrameIndex(FrameIndex)
378  .addImm(0)
379  .addMemOperand(MMO);
380 }
381 
384  unsigned DestReg, int FrameIndex,
385  const TargetRegisterClass *RC,
386  const TargetRegisterInfo *TRI) const
387 {
388  DebugLoc DL;
389  if (I != MBB.end() && !I->isDebugInstr())
390  DL = I->getDebugLoc();
391  MachineFunction *MF = MBB.getParent();
392  const MachineFrameInfo &MFI = MF->getFrameInfo();
394  MachinePointerInfo::getFixedStack(*MF, FrameIndex),
395  MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex),
396  MFI.getObjectAlignment(FrameIndex));
397  BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg)
398  .addFrameIndex(FrameIndex)
399  .addImm(0)
400  .addMemOperand(MMO);
401 }
402 
403 bool XCoreInstrInfo::
405  assert((Cond.size() == 2) &&
406  "Invalid XCore branch condition!");
407  Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm()));
408  return false;
409 }
410 
411 static inline bool isImmU6(unsigned val) {
412  return val < (1 << 6);
413 }
414 
415 static inline bool isImmU16(unsigned val) {
416  return val < (1 << 16);
417 }
418 
419 static bool isImmMskBitp(unsigned val) {
420  if (!isMask_32(val)) {
421  return false;
422  }
423  int N = Log2_32(val) + 1;
424  return (N >= 1 && N <= 8) || N == 16 || N == 24 || N == 32;
425 }
426 
428  MachineBasicBlock &MBB,
430  unsigned Reg, uint64_t Value) const {
431  DebugLoc dl;
432  if (MI != MBB.end() && !MI->isDebugInstr())
433  dl = MI->getDebugLoc();
434  if (isImmMskBitp(Value)) {
435  int N = Log2_32(Value) + 1;
436  return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg)
437  .addImm(N)
438  .getInstr();
439  }
440  if (isImmU16(Value)) {
441  int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
442  return BuildMI(MBB, MI, dl, get(Opcode), Reg).addImm(Value).getInstr();
443  }
445  const Constant *C = ConstantInt::get(
446  Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), Value);
447  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
448  return BuildMI(MBB, MI, dl, get(XCore::LDWCP_lru6), Reg)
450  .getInstr();
451 }
uint64_t CallInst * C
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
static bool IsBRT(unsigned BrOpc)
MachineBasicBlock * getMBB() const
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot...
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static bool isImmMskBitp(unsigned val)
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
static XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC)
GetOppositeBranchCondition - Return the inverse of the specified condition, e.g.
#define op(i)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition: MathExtras.h:405
A description of a memory reference used in the backend.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static bool IsBRF(unsigned BrOpc)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
static bool IsBRU(unsigned BrOpc)
static bool isImmU16(unsigned val)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getKillRegState(bool B)
MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
static bool isImmU6(unsigned val)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
This is an important base class in LLVM.
Definition: Constant.h:42
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addFrameIndex(int Idx) const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
static unsigned GetCondBranchFromCond(XCore::CondCode CC)
GetCondBranchFromCond - Return the Branch instruction opcode that matches the cc. ...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:53
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The memory access writes data.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
MachineOperand class - Representation of each machine instruction operand.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
AnalyzeBranch - Analyze the branching code at the end of MBB, returning true if it cannot be understo...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:622
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot...
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:539
static bool IsCondBranch(unsigned BrOpc)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:638
Representation of each machine instruction.
Definition: MachineInstr.h:64
static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
GetCondFromBranchOpc - Return the XCore CC that matches the correspondent Branch instruction opcode...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
IRTranslator LLVM IR MI
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
static bool IsBR_JT(unsigned BrOpc)
static bool isZeroImm(const MachineOperand &op)
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144