LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSP430InstrInfo.cpp
Go to the documentation of this file.
1 //===-- MSP430InstrInfo.cpp - MSP430 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 MSP430 implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MSP430InstrInfo.h"
15 #include "MSP430.h"
17 #include "MSP430TargetMachine.h"
21 #include "llvm/IR/Function.h"
24 
25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "MSP430GenInstrInfo.inc"
27 
28 using namespace llvm;
29 
30 // Pin the vtable to this file.
31 void MSP430InstrInfo::anchor() {}
32 
34  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
35  RI(tm) {}
36 
39  unsigned SrcReg, bool isKill, int FrameIdx,
40  const TargetRegisterClass *RC,
41  const TargetRegisterInfo *TRI) const {
42  DebugLoc DL;
43  if (MI != MBB.end()) DL = MI->getDebugLoc();
44  MachineFunction &MF = *MBB.getParent();
45  MachineFrameInfo &MFI = *MF.getFrameInfo();
46 
47  MachineMemOperand *MMO =
50  MFI.getObjectSize(FrameIdx),
51  MFI.getObjectAlignment(FrameIdx));
52 
53  if (RC == &MSP430::GR16RegClass)
54  BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
55  .addFrameIndex(FrameIdx).addImm(0)
56  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
57  else if (RC == &MSP430::GR8RegClass)
58  BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
59  .addFrameIndex(FrameIdx).addImm(0)
60  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
61  else
62  llvm_unreachable("Cannot store this register to stack slot!");
63 }
64 
67  unsigned DestReg, int FrameIdx,
68  const TargetRegisterClass *RC,
69  const TargetRegisterInfo *TRI) const{
70  DebugLoc DL;
71  if (MI != MBB.end()) DL = MI->getDebugLoc();
72  MachineFunction &MF = *MBB.getParent();
73  MachineFrameInfo &MFI = *MF.getFrameInfo();
74 
75  MachineMemOperand *MMO =
78  MFI.getObjectSize(FrameIdx),
79  MFI.getObjectAlignment(FrameIdx));
80 
81  if (RC == &MSP430::GR16RegClass)
82  BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
83  .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
84  else if (RC == &MSP430::GR8RegClass)
85  BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
86  .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
87  else
88  llvm_unreachable("Cannot store this register to stack slot!");
89 }
90 
93  unsigned DestReg, unsigned SrcReg,
94  bool KillSrc) const {
95  unsigned Opc;
96  if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
97  Opc = MSP430::MOV16rr;
98  else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
99  Opc = MSP430::MOV8rr;
100  else
101  llvm_unreachable("Impossible reg-to-reg copy");
102 
103  BuildMI(MBB, I, DL, get(Opc), DestReg)
104  .addReg(SrcReg, getKillRegState(KillSrc));
105 }
106 
109  unsigned Count = 0;
110 
111  while (I != MBB.begin()) {
112  --I;
113  if (I->isDebugValue())
114  continue;
115  if (I->getOpcode() != MSP430::JMP &&
116  I->getOpcode() != MSP430::JCC &&
117  I->getOpcode() != MSP430::Br &&
118  I->getOpcode() != MSP430::Bm)
119  break;
120  // Remove the branch.
121  I->eraseFromParent();
122  I = MBB.end();
123  ++Count;
124  }
125 
126  return Count;
127 }
128 
131  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
132 
133  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
134 
135  switch (CC) {
136  default: llvm_unreachable("Invalid branch condition!");
137  case MSP430CC::COND_E:
138  CC = MSP430CC::COND_NE;
139  break;
140  case MSP430CC::COND_NE:
141  CC = MSP430CC::COND_E;
142  break;
143  case MSP430CC::COND_L:
144  CC = MSP430CC::COND_GE;
145  break;
146  case MSP430CC::COND_GE:
147  CC = MSP430CC::COND_L;
148  break;
149  case MSP430CC::COND_HS:
150  CC = MSP430CC::COND_LO;
151  break;
152  case MSP430CC::COND_LO:
153  CC = MSP430CC::COND_HS;
154  break;
155  }
156 
157  Cond[0].setImm(CC);
158  return false;
159 }
160 
162  if (!MI->isTerminator()) return false;
163 
164  // Conditional branch is a special case.
165  if (MI->isBranch() && !MI->isBarrier())
166  return true;
167  if (!MI->isPredicable())
168  return true;
169  return !isPredicated(MI);
170 }
171 
173  MachineBasicBlock *&TBB,
174  MachineBasicBlock *&FBB,
176  bool AllowModify) const {
177  // Start from the bottom of the block and work up, examining the
178  // terminator instructions.
180  while (I != MBB.begin()) {
181  --I;
182  if (I->isDebugValue())
183  continue;
184 
185  // Working from the bottom, when we see a non-terminator
186  // instruction, we're done.
187  if (!isUnpredicatedTerminator(I))
188  break;
189 
190  // A terminator that isn't a branch can't easily be handled
191  // by this analysis.
192  if (!I->isBranch())
193  return true;
194 
195  // Cannot handle indirect branches.
196  if (I->getOpcode() == MSP430::Br ||
197  I->getOpcode() == MSP430::Bm)
198  return true;
199 
200  // Handle unconditional branches.
201  if (I->getOpcode() == MSP430::JMP) {
202  if (!AllowModify) {
203  TBB = I->getOperand(0).getMBB();
204  continue;
205  }
206 
207  // If the block has any instructions after a JMP, delete them.
208  while (llvm::next(I) != MBB.end())
209  llvm::next(I)->eraseFromParent();
210  Cond.clear();
211  FBB = 0;
212 
213  // Delete the JMP if it's equivalent to a fall-through.
214  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
215  TBB = 0;
216  I->eraseFromParent();
217  I = MBB.end();
218  continue;
219  }
220 
221  // TBB is used to indicate the unconditinal destination.
222  TBB = I->getOperand(0).getMBB();
223  continue;
224  }
225 
226  // Handle conditional branches.
227  assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
228  MSP430CC::CondCodes BranchCode =
229  static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
230  if (BranchCode == MSP430CC::COND_INVALID)
231  return true; // Can't handle weird stuff.
232 
233  // Working from the bottom, handle the first conditional branch.
234  if (Cond.empty()) {
235  FBB = TBB;
236  TBB = I->getOperand(0).getMBB();
237  Cond.push_back(MachineOperand::CreateImm(BranchCode));
238  continue;
239  }
240 
241  // Handle subsequent conditional branches. Only handle the case where all
242  // conditional branches branch to the same destination.
243  assert(Cond.size() == 1);
244  assert(TBB);
245 
246  // Only handle the case where all conditional branches branch to
247  // the same destination.
248  if (TBB != I->getOperand(0).getMBB())
249  return true;
250 
251  MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
252  // If the conditions are the same, we can leave them alone.
253  if (OldBranchCode == BranchCode)
254  continue;
255 
256  return true;
257  }
258 
259  return false;
260 }
261 
262 unsigned
264  MachineBasicBlock *FBB,
266  DebugLoc DL) const {
267  // Shouldn't be a fall through.
268  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
269  assert((Cond.size() == 1 || Cond.size() == 0) &&
270  "MSP430 branch conditions have one component!");
271 
272  if (Cond.empty()) {
273  // Unconditional branch?
274  assert(!FBB && "Unconditional branch with multiple successors!");
275  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
276  return 1;
277  }
278 
279  // Conditional branch.
280  unsigned Count = 0;
281  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
282  ++Count;
283 
284  if (FBB) {
285  // Two-way Conditional branch. Insert the second branch.
286  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
287  ++Count;
288  }
289  return Count;
290 }
291 
292 /// GetInstSize - Return the number of bytes of code the specified
293 /// instruction may be. This returns the maximum number of bytes.
294 ///
296  const MCInstrDesc &Desc = MI->getDesc();
297 
298  switch (Desc.TSFlags & MSP430II::SizeMask) {
299  default:
300  switch (Desc.getOpcode()) {
301  default: llvm_unreachable("Unknown instruction size!");
305  case TargetOpcode::KILL:
307  return 0;
309  const MachineFunction *MF = MI->getParent()->getParent();
310  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
311  return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
312  *MF->getTarget().getMCAsmInfo());
313  }
314  }
316  switch (MI->getOpcode()) {
317  default: llvm_unreachable("Unknown instruction size!");
318  case MSP430::SAR8r1c:
319  case MSP430::SAR16r1c:
320  return 4;
321  }
323  return 2;
325  return 4;
327  return 6;
328  }
329 }
The memory access reads data.
const MachineFunction * getParent() const
The memory access writes data.
bool isBranch(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:374
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
bool isUnpredicatedTerminator(const MachineInstr *MI) const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
unsigned RemoveBranch(MachineBasicBlock &MBB) const
bool isPredicable(QueryType Type=AllInBundle) const
Definition: MachineInstr.h:404
MSP430InstrInfo(MSP430TargetMachine &TM)
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
const char * getSymbolName() const
bool isTerminator(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:366
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
const HexagonInstrInfo * TII
const MCAsmInfo * getMCAsmInfo() const
#define llvm_unreachable(msg)
Abstract Stack Frame Information.
const MachineInstrBuilder & addImm(int64_t Val) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
int getOpcode() const
Definition: MachineInstr.h:261
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
unsigned getKillRegState(bool B)
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:181
virtual const TargetInstrInfo * getInstrInfo() const
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
const MachineInstrBuilder & addFrameIndex(int Idx) const
virtual unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
Definition: TargetOpcodes.h:52
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
Definition: TargetOpcodes.h:69
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
CondCodes
Definition: MSP430.h:23
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
int64_t getObjectSize(int ObjectIdx) const
bool isBarrier(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:356