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                                    Register 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.getObjectAlign(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                                           Register 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.getObjectAlign(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::analyzeBranch(MachineBasicBlock &MBB,
164                                    MachineBasicBlock *&TBB,
165                                    MachineBasicBlock *&FBB,
166                                    SmallVectorImpl<MachineOperand> &Cond,
167                                    bool AllowModify) const {
168  // Start from the bottom of the block and work up, examining the
169  // terminator instructions.
170  MachineBasicBlock::iterator I = MBB.end();
171  while (I != MBB.begin()) {
172    --I;
173    if (I->isDebugInstr())
174      continue;
175
176    // Working from the bottom, when we see a non-terminator
177    // instruction, we're done.
178    if (!isUnpredicatedTerminator(*I))
179      break;
180
181    // A terminator that isn't a branch can't easily be handled
182    // by this analysis.
183    if (!I->isBranch())
184      return true;
185
186    // Cannot handle indirect branches.
187    if (I->getOpcode() == MSP430::Br ||
188        I->getOpcode() == MSP430::Bm)
189      return true;
190
191    // Handle unconditional branches.
192    if (I->getOpcode() == MSP430::JMP) {
193      if (!AllowModify) {
194        TBB = I->getOperand(0).getMBB();
195        continue;
196      }
197
198      // If the block has any instructions after a JMP, delete them.
199      while (std::next(I) != MBB.end())
200        std::next(I)->eraseFromParent();
201      Cond.clear();
202      FBB = nullptr;
203
204      // Delete the JMP if it's equivalent to a fall-through.
205      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
206        TBB = nullptr;
207        I->eraseFromParent();
208        I = MBB.end();
209        continue;
210      }
211
212      // TBB is used to indicate the unconditinal destination.
213      TBB = I->getOperand(0).getMBB();
214      continue;
215    }
216
217    // Handle conditional branches.
218    assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
219    MSP430CC::CondCodes BranchCode =
220      static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
221    if (BranchCode == MSP430CC::COND_INVALID)
222      return true;  // Can't handle weird stuff.
223
224    // Working from the bottom, handle the first conditional branch.
225    if (Cond.empty()) {
226      FBB = TBB;
227      TBB = I->getOperand(0).getMBB();
228      Cond.push_back(MachineOperand::CreateImm(BranchCode));
229      continue;
230    }
231
232    // Handle subsequent conditional branches. Only handle the case where all
233    // conditional branches branch to the same destination.
234    assert(Cond.size() == 1);
235    assert(TBB);
236
237    // Only handle the case where all conditional branches branch to
238    // the same destination.
239    if (TBB != I->getOperand(0).getMBB())
240      return true;
241
242    MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
243    // If the conditions are the same, we can leave them alone.
244    if (OldBranchCode == BranchCode)
245      continue;
246
247    return true;
248  }
249
250  return false;
251}
252
253unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
254                                       MachineBasicBlock *TBB,
255                                       MachineBasicBlock *FBB,
256                                       ArrayRef<MachineOperand> Cond,
257                                       const DebugLoc &DL,
258                                       int *BytesAdded) const {
259  // Shouldn't be a fall through.
260  assert(TBB && "insertBranch must not be told to insert a fallthrough");
261  assert((Cond.size() == 1 || Cond.size() == 0) &&
262         "MSP430 branch conditions have one component!");
263  assert(!BytesAdded && "code size not handled");
264
265  if (Cond.empty()) {
266    // Unconditional branch?
267    assert(!FBB && "Unconditional branch with multiple successors!");
268    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
269    return 1;
270  }
271
272  // Conditional branch.
273  unsigned Count = 0;
274  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
275  ++Count;
276
277  if (FBB) {
278    // Two-way Conditional branch. Insert the second branch.
279    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
280    ++Count;
281  }
282  return Count;
283}
284
285/// GetInstSize - Return the number of bytes of code the specified
286/// instruction may be.  This returns the maximum number of bytes.
287///
288unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
289  const MCInstrDesc &Desc = MI.getDesc();
290
291  switch (Desc.getOpcode()) {
292  case TargetOpcode::CFI_INSTRUCTION:
293  case TargetOpcode::EH_LABEL:
294  case TargetOpcode::IMPLICIT_DEF:
295  case TargetOpcode::KILL:
296  case TargetOpcode::DBG_VALUE:
297    return 0;
298  case TargetOpcode::INLINEASM:
299  case TargetOpcode::INLINEASM_BR: {
300    const MachineFunction *MF = MI.getParent()->getParent();
301    const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
302    return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
303                                  *MF->getTarget().getMCAsmInfo());
304  }
305  }
306
307  return Desc.getSize();
308}
309