LLVM  8.0.1
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 using namespace llvm;
26 
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "MSP430GenInstrInfo.inc"
29 
30 // Pin the vtable to this file.
31 void MSP430InstrInfo::anchor() {}
32 
34  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
35  RI() {}
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 
50  MFI.getObjectAlignment(FrameIdx));
51 
52  if (RC == &MSP430::GR16RegClass)
53  BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
54  .addFrameIndex(FrameIdx).addImm(0)
55  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
56  else if (RC == &MSP430::GR8RegClass)
57  BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
58  .addFrameIndex(FrameIdx).addImm(0)
59  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
60  else
61  llvm_unreachable("Cannot store this register to stack slot!");
62 }
63 
66  unsigned DestReg, int FrameIdx,
67  const TargetRegisterClass *RC,
68  const TargetRegisterInfo *TRI) const{
69  DebugLoc DL;
70  if (MI != MBB.end()) DL = MI->getDebugLoc();
71  MachineFunction &MF = *MBB.getParent();
72  MachineFrameInfo &MFI = MF.getFrameInfo();
73 
77  MFI.getObjectAlignment(FrameIdx));
78 
79  if (RC == &MSP430::GR16RegClass)
80  BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
81  .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
82  .addImm(0).addMemOperand(MMO);
83  else if (RC == &MSP430::GR8RegClass)
84  BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
85  .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
86  .addImm(0).addMemOperand(MMO);
87  else
88  llvm_unreachable("Cannot store this register to stack slot!");
89 }
90 
93  const DebugLoc &DL, unsigned DestReg,
94  unsigned SrcReg, 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 
108  int *BytesRemoved) const {
109  assert(!BytesRemoved && "code size not handled");
110 
112  unsigned Count = 0;
113 
114  while (I != MBB.begin()) {
115  --I;
116  if (I->isDebugInstr())
117  continue;
118  if (I->getOpcode() != MSP430::JMP &&
119  I->getOpcode() != MSP430::JCC &&
120  I->getOpcode() != MSP430::Br &&
121  I->getOpcode() != MSP430::Bm)
122  break;
123  // Remove the branch.
124  I->eraseFromParent();
125  I = MBB.end();
126  ++Count;
127  }
128 
129  return Count;
130 }
131 
134  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
135 
136  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
137 
138  switch (CC) {
139  default: llvm_unreachable("Invalid branch condition!");
140  case MSP430CC::COND_E:
141  CC = MSP430CC::COND_NE;
142  break;
143  case MSP430CC::COND_NE:
144  CC = MSP430CC::COND_E;
145  break;
146  case MSP430CC::COND_L:
147  CC = MSP430CC::COND_GE;
148  break;
149  case MSP430CC::COND_GE:
150  CC = MSP430CC::COND_L;
151  break;
152  case MSP430CC::COND_HS:
153  CC = MSP430CC::COND_LO;
154  break;
155  case MSP430CC::COND_LO:
156  CC = MSP430CC::COND_HS;
157  break;
158  }
159 
160  Cond[0].setImm(CC);
161  return false;
162 }
163 
165  if (!MI.isTerminator())
166  return false;
167 
168  // Conditional branch is a special case.
169  if (MI.isBranch() && !MI.isBarrier())
170  return true;
171  if (!MI.isPredicable())
172  return true;
173  return !isPredicated(MI);
174 }
175 
177  MachineBasicBlock *&TBB,
178  MachineBasicBlock *&FBB,
180  bool AllowModify) const {
181  // Start from the bottom of the block and work up, examining the
182  // terminator instructions.
184  while (I != MBB.begin()) {
185  --I;
186  if (I->isDebugInstr())
187  continue;
188 
189  // Working from the bottom, when we see a non-terminator
190  // instruction, we're done.
191  if (!isUnpredicatedTerminator(*I))
192  break;
193 
194  // A terminator that isn't a branch can't easily be handled
195  // by this analysis.
196  if (!I->isBranch())
197  return true;
198 
199  // Cannot handle indirect branches.
200  if (I->getOpcode() == MSP430::Br ||
201  I->getOpcode() == MSP430::Bm)
202  return true;
203 
204  // Handle unconditional branches.
205  if (I->getOpcode() == MSP430::JMP) {
206  if (!AllowModify) {
207  TBB = I->getOperand(0).getMBB();
208  continue;
209  }
210 
211  // If the block has any instructions after a JMP, delete them.
212  while (std::next(I) != MBB.end())
213  std::next(I)->eraseFromParent();
214  Cond.clear();
215  FBB = nullptr;
216 
217  // Delete the JMP if it's equivalent to a fall-through.
218  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
219  TBB = nullptr;
220  I->eraseFromParent();
221  I = MBB.end();
222  continue;
223  }
224 
225  // TBB is used to indicate the unconditinal destination.
226  TBB = I->getOperand(0).getMBB();
227  continue;
228  }
229 
230  // Handle conditional branches.
231  assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
232  MSP430CC::CondCodes BranchCode =
233  static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
234  if (BranchCode == MSP430CC::COND_INVALID)
235  return true; // Can't handle weird stuff.
236 
237  // Working from the bottom, handle the first conditional branch.
238  if (Cond.empty()) {
239  FBB = TBB;
240  TBB = I->getOperand(0).getMBB();
241  Cond.push_back(MachineOperand::CreateImm(BranchCode));
242  continue;
243  }
244 
245  // Handle subsequent conditional branches. Only handle the case where all
246  // conditional branches branch to the same destination.
247  assert(Cond.size() == 1);
248  assert(TBB);
249 
250  // Only handle the case where all conditional branches branch to
251  // the same destination.
252  if (TBB != I->getOperand(0).getMBB())
253  return true;
254 
255  MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
256  // If the conditions are the same, we can leave them alone.
257  if (OldBranchCode == BranchCode)
258  continue;
259 
260  return true;
261  }
262 
263  return false;
264 }
265 
267  MachineBasicBlock *TBB,
268  MachineBasicBlock *FBB,
270  const DebugLoc &DL,
271  int *BytesAdded) const {
272  // Shouldn't be a fall through.
273  assert(TBB && "insertBranch must not be told to insert a fallthrough");
274  assert((Cond.size() == 1 || Cond.size() == 0) &&
275  "MSP430 branch conditions have one component!");
276  assert(!BytesAdded && "code size not handled");
277 
278  if (Cond.empty()) {
279  // Unconditional branch?
280  assert(!FBB && "Unconditional branch with multiple successors!");
281  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
282  return 1;
283  }
284 
285  // Conditional branch.
286  unsigned Count = 0;
287  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
288  ++Count;
289 
290  if (FBB) {
291  // Two-way Conditional branch. Insert the second branch.
292  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
293  ++Count;
294  }
295  return Count;
296 }
297 
298 /// GetInstSize - Return the number of bytes of code the specified
299 /// instruction may be. This returns the maximum number of bytes.
300 ///
302  const MCInstrDesc &Desc = MI.getDesc();
303 
304  switch (Desc.getOpcode()) {
305  case TargetOpcode::CFI_INSTRUCTION:
307  case TargetOpcode::IMPLICIT_DEF:
308  case TargetOpcode::KILL:
309  case TargetOpcode::DBG_VALUE:
310  return 0;
312  const MachineFunction *MF = MI.getParent()->getParent();
313  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
314  return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
315  *MF->getTarget().getMCAsmInfo());
316  }
317  }
318 
319  return Desc.getSize();
320 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:164
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
Definition: MachineInstr.h:687
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
bool isUnpredicatedTerminator(const MachineInstr &MI) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
return AArch64::GPR64RegClass contains(Reg)
A description of a memory reference used in the backend.
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Definition: MachineInstr.h:649
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
const char * getSymbolName() const
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.
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:667
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:406
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
virtual const TargetInstrInfo * getInstrInfo() const
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MachineInstr.h:657
unsigned getKillRegState(bool B)
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDefRegState(bool B)
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.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
virtual unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const
Measure the specified inline asm to determine an approximation of its length.
const MachineInstrBuilder & addFrameIndex(int Idx) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
Definition: ISDOpcodes.h:672
The memory access writes data.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MSP430InstrInfo(MSP430Subtarget &STI)
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
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.
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:58
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
CondCodes
Definition: MSP430.h:23
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:204
IRTranslator LLVM IR MI
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
Definition: MachineInstr.h:640
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:581