LLVM  9.0.0svn
MSP430InstrInfo.cpp
Go to the documentation of this file.
1 //===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the MSP430 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MSP430InstrInfo.h"
14 #include "MSP430.h"
16 #include "MSP430TargetMachine.h"
20 #include "llvm/IR/Function.h"
23 
24 using namespace llvm;
25 
26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "MSP430GenInstrInfo.inc"
28 
29 // Pin the vtable to this file.
30 void MSP430InstrInfo::anchor() {}
31 
33  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34  RI() {}
35 
38  unsigned SrcReg, bool isKill, int FrameIdx,
39  const TargetRegisterClass *RC,
40  const TargetRegisterInfo *TRI) const {
41  DebugLoc DL;
42  if (MI != MBB.end()) DL = MI->getDebugLoc();
43  MachineFunction &MF = *MBB.getParent();
44  MachineFrameInfo &MFI = MF.getFrameInfo();
45 
49  MFI.getObjectAlignment(FrameIdx));
50 
51  if (RC == &MSP430::GR16RegClass)
52  BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
53  .addFrameIndex(FrameIdx).addImm(0)
54  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
55  else if (RC == &MSP430::GR8RegClass)
56  BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
57  .addFrameIndex(FrameIdx).addImm(0)
58  .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
59  else
60  llvm_unreachable("Cannot store this register to stack slot!");
61 }
62 
65  unsigned DestReg, int FrameIdx,
66  const TargetRegisterClass *RC,
67  const TargetRegisterInfo *TRI) const{
68  DebugLoc DL;
69  if (MI != MBB.end()) DL = MI->getDebugLoc();
70  MachineFunction &MF = *MBB.getParent();
71  MachineFrameInfo &MFI = MF.getFrameInfo();
72 
76  MFI.getObjectAlignment(FrameIdx));
77 
78  if (RC == &MSP430::GR16RegClass)
79  BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
80  .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
81  .addImm(0).addMemOperand(MMO);
82  else if (RC == &MSP430::GR8RegClass)
83  BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
84  .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
85  .addImm(0).addMemOperand(MMO);
86  else
87  llvm_unreachable("Cannot store this register to stack slot!");
88 }
89 
92  const DebugLoc &DL, unsigned DestReg,
93  unsigned SrcReg, bool KillSrc) const {
94  unsigned Opc;
95  if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
96  Opc = MSP430::MOV16rr;
97  else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
98  Opc = MSP430::MOV8rr;
99  else
100  llvm_unreachable("Impossible reg-to-reg copy");
101 
102  BuildMI(MBB, I, DL, get(Opc), DestReg)
103  .addReg(SrcReg, getKillRegState(KillSrc));
104 }
105 
107  int *BytesRemoved) const {
108  assert(!BytesRemoved && "code size not handled");
109 
111  unsigned Count = 0;
112 
113  while (I != MBB.begin()) {
114  --I;
115  if (I->isDebugInstr())
116  continue;
117  if (I->getOpcode() != MSP430::JMP &&
118  I->getOpcode() != MSP430::JCC &&
119  I->getOpcode() != MSP430::Br &&
120  I->getOpcode() != MSP430::Bm)
121  break;
122  // Remove the branch.
123  I->eraseFromParent();
124  I = MBB.end();
125  ++Count;
126  }
127 
128  return Count;
129 }
130 
133  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
134 
135  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
136 
137  switch (CC) {
138  default: llvm_unreachable("Invalid branch condition!");
139  case MSP430CC::COND_E:
140  CC = MSP430CC::COND_NE;
141  break;
142  case MSP430CC::COND_NE:
143  CC = MSP430CC::COND_E;
144  break;
145  case MSP430CC::COND_L:
146  CC = MSP430CC::COND_GE;
147  break;
148  case MSP430CC::COND_GE:
149  CC = MSP430CC::COND_L;
150  break;
151  case MSP430CC::COND_HS:
152  CC = MSP430CC::COND_LO;
153  break;
154  case MSP430CC::COND_LO:
155  CC = MSP430CC::COND_HS;
156  break;
157  }
158 
159  Cond[0].setImm(CC);
160  return false;
161 }
162 
164  if (!MI.isTerminator())
165  return false;
166 
167  // Conditional branch is a special case.
168  if (MI.isBranch() && !MI.isBarrier())
169  return true;
170  if (!MI.isPredicable())
171  return true;
172  return !isPredicated(MI);
173 }
174 
176  MachineBasicBlock *&TBB,
177  MachineBasicBlock *&FBB,
179  bool AllowModify) const {
180  // Start from the bottom of the block and work up, examining the
181  // terminator instructions.
183  while (I != MBB.begin()) {
184  --I;
185  if (I->isDebugInstr())
186  continue;
187 
188  // Working from the bottom, when we see a non-terminator
189  // instruction, we're done.
190  if (!isUnpredicatedTerminator(*I))
191  break;
192 
193  // A terminator that isn't a branch can't easily be handled
194  // by this analysis.
195  if (!I->isBranch())
196  return true;
197 
198  // Cannot handle indirect branches.
199  if (I->getOpcode() == MSP430::Br ||
200  I->getOpcode() == MSP430::Bm)
201  return true;
202 
203  // Handle unconditional branches.
204  if (I->getOpcode() == MSP430::JMP) {
205  if (!AllowModify) {
206  TBB = I->getOperand(0).getMBB();
207  continue;
208  }
209 
210  // If the block has any instructions after a JMP, delete them.
211  while (std::next(I) != MBB.end())
212  std::next(I)->eraseFromParent();
213  Cond.clear();
214  FBB = nullptr;
215 
216  // Delete the JMP if it's equivalent to a fall-through.
217  if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
218  TBB = nullptr;
219  I->eraseFromParent();
220  I = MBB.end();
221  continue;
222  }
223 
224  // TBB is used to indicate the unconditinal destination.
225  TBB = I->getOperand(0).getMBB();
226  continue;
227  }
228 
229  // Handle conditional branches.
230  assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
231  MSP430CC::CondCodes BranchCode =
232  static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
233  if (BranchCode == MSP430CC::COND_INVALID)
234  return true; // Can't handle weird stuff.
235 
236  // Working from the bottom, handle the first conditional branch.
237  if (Cond.empty()) {
238  FBB = TBB;
239  TBB = I->getOperand(0).getMBB();
240  Cond.push_back(MachineOperand::CreateImm(BranchCode));
241  continue;
242  }
243 
244  // Handle subsequent conditional branches. Only handle the case where all
245  // conditional branches branch to the same destination.
246  assert(Cond.size() == 1);
247  assert(TBB);
248 
249  // Only handle the case where all conditional branches branch to
250  // the same destination.
251  if (TBB != I->getOperand(0).getMBB())
252  return true;
253 
254  MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
255  // If the conditions are the same, we can leave them alone.
256  if (OldBranchCode == BranchCode)
257  continue;
258 
259  return true;
260  }
261 
262  return false;
263 }
264 
266  MachineBasicBlock *TBB,
267  MachineBasicBlock *FBB,
269  const DebugLoc &DL,
270  int *BytesAdded) const {
271  // Shouldn't be a fall through.
272  assert(TBB && "insertBranch must not be told to insert a fallthrough");
273  assert((Cond.size() == 1 || Cond.size() == 0) &&
274  "MSP430 branch conditions have one component!");
275  assert(!BytesAdded && "code size not handled");
276 
277  if (Cond.empty()) {
278  // Unconditional branch?
279  assert(!FBB && "Unconditional branch with multiple successors!");
280  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
281  return 1;
282  }
283 
284  // Conditional branch.
285  unsigned Count = 0;
286  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
287  ++Count;
288 
289  if (FBB) {
290  // Two-way Conditional branch. Insert the second branch.
291  BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
292  ++Count;
293  }
294  return Count;
295 }
296 
297 /// GetInstSize - Return the number of bytes of code the specified
298 /// instruction may be. This returns the maximum number of bytes.
299 ///
301  const MCInstrDesc &Desc = MI.getDesc();
302 
303  switch (Desc.getOpcode()) {
304  case TargetOpcode::CFI_INSTRUCTION:
306  case TargetOpcode::IMPLICIT_DEF:
307  case TargetOpcode::KILL:
308  case TargetOpcode::DBG_VALUE:
309  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:23
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
Definition: MachineInstr.h:686
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
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:41
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Definition: MachineInstr.h:648
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:668
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:405
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
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:656
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:148
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:52
#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:676
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:253
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:63
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:55
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:22
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INLINEASM_BR - Terminator version of inline asm. Used by asm-goto.
Definition: ISDOpcodes.h:671
unsigned getOpcode() const
Return the opcode number for this descriptor.
Definition: MCInstrDesc.h:203
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:639
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143
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:580