MSP430InstrInfo.cpp revision 360784
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"
15#include "MSP430MachineFunctionInfo.h"
16#include "MSP430TargetMachine.h"
17#include "llvm/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/IR/Function.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/TargetRegistry.h"
23
24using namespace llvm;
25
26#define GET_INSTRINFO_CTOR_DTOR
27#include "MSP430GenInstrInfo.inc"
28
29// Pin the vtable to this file.
30void MSP430InstrInfo::anchor() {}
31
32MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
33  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34    RI() {}
35
36void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
37                                          MachineBasicBlock::iterator MI,
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
46  MachineMemOperand *MMO = MF.getMachineMemOperand(
47      MachinePointerInfo::getFixedStack(MF, FrameIdx),
48      MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
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
63void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
64                                           MachineBasicBlock::iterator MI,
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
73  MachineMemOperand *MMO = MF.getMachineMemOperand(
74      MachinePointerInfo::getFixedStack(MF, FrameIdx),
75      MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
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
90void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
91                                  MachineBasicBlock::iterator I,
92                                  const DebugLoc &DL, MCRegister DestReg,
93                                  MCRegister 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
106unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,
107                                       int *BytesRemoved) const {
108  assert(!BytesRemoved && "code size not handled");
109
110  MachineBasicBlock::iterator I = MBB.end();
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
131bool MSP430InstrInfo::
132reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
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
163bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
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
175bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
176                                    MachineBasicBlock *&TBB,
177                                    MachineBasicBlock *&FBB,
178                                    SmallVectorImpl<MachineOperand> &Cond,
179                                    bool AllowModify) const {
180  // Start from the bottom of the block and work up, examining the
181  // terminator instructions.
182  MachineBasicBlock::iterator I = MBB.end();
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
265unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
266                                       MachineBasicBlock *TBB,
267                                       MachineBasicBlock *FBB,
268                                       ArrayRef<MachineOperand> Cond,
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///
300unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
301  const MCInstrDesc &Desc = MI.getDesc();
302
303  switch (Desc.getOpcode()) {
304  case TargetOpcode::CFI_INSTRUCTION:
305  case TargetOpcode::EH_LABEL:
306  case TargetOpcode::IMPLICIT_DEF:
307  case TargetOpcode::KILL:
308  case TargetOpcode::DBG_VALUE:
309    return 0;
310  case TargetOpcode::INLINEASM:
311  case TargetOpcode::INLINEASM_BR: {
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}
321