1234353Sdim//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9193323Sed// This file contains the MSP430 implementation of the TargetInstrInfo class.
10193323Sed//
11193323Sed//===----------------------------------------------------------------------===//
12193323Sed
13234353Sdim#include "MSP430InstrInfo.h"
14193323Sed#include "MSP430.h"
15193323Sed#include "MSP430MachineFunctionInfo.h"
16193323Sed#include "MSP430TargetMachine.h"
17193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
18193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
19193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
20249423Sdim#include "llvm/IR/Function.h"
21198090Srdivacky#include "llvm/Support/ErrorHandling.h"
22226633Sdim#include "llvm/Support/TargetRegistry.h"
23193323Sed
24276479Sdimusing namespace llvm;
25276479Sdim
26261991Sdim#define GET_INSTRINFO_CTOR_DTOR
27224145Sdim#include "MSP430GenInstrInfo.inc"
28224145Sdim
29261991Sdim// Pin the vtable to this file.
30261991Sdimvoid MSP430InstrInfo::anchor() {}
31261991Sdim
32276479SdimMSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
33224145Sdim  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34276479Sdim    RI() {}
35193323Sed
36193323Sedvoid MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
37193323Sed                                          MachineBasicBlock::iterator MI,
38193323Sed                                    unsigned SrcReg, bool isKill, int FrameIdx,
39208599Srdivacky                                          const TargetRegisterClass *RC,
40208599Srdivacky                                          const TargetRegisterInfo *TRI) const {
41206124Srdivacky  DebugLoc DL;
42193323Sed  if (MI != MBB.end()) DL = MI->getDebugLoc();
43199481Srdivacky  MachineFunction &MF = *MBB.getParent();
44314564Sdim  MachineFrameInfo &MFI = MF.getFrameInfo();
45193323Sed
46296417Sdim  MachineMemOperand *MMO = MF.getMachineMemOperand(
47296417Sdim      MachinePointerInfo::getFixedStack(MF, FrameIdx),
48296417Sdim      MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
49296417Sdim      MFI.getObjectAlignment(FrameIdx));
50199481Srdivacky
51193323Sed  if (RC == &MSP430::GR16RegClass)
52193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
53193323Sed      .addFrameIndex(FrameIdx).addImm(0)
54199481Srdivacky      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
55193323Sed  else if (RC == &MSP430::GR8RegClass)
56193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
57193323Sed      .addFrameIndex(FrameIdx).addImm(0)
58199481Srdivacky      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
59193323Sed  else
60198090Srdivacky    llvm_unreachable("Cannot store this register to stack slot!");
61193323Sed}
62193323Sed
63193323Sedvoid MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
64193323Sed                                           MachineBasicBlock::iterator MI,
65193323Sed                                           unsigned DestReg, int FrameIdx,
66208599Srdivacky                                           const TargetRegisterClass *RC,
67208599Srdivacky                                           const TargetRegisterInfo *TRI) const{
68206124Srdivacky  DebugLoc DL;
69193323Sed  if (MI != MBB.end()) DL = MI->getDebugLoc();
70199481Srdivacky  MachineFunction &MF = *MBB.getParent();
71314564Sdim  MachineFrameInfo &MFI = MF.getFrameInfo();
72193323Sed
73296417Sdim  MachineMemOperand *MMO = MF.getMachineMemOperand(
74296417Sdim      MachinePointerInfo::getFixedStack(MF, FrameIdx),
75296417Sdim      MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
76296417Sdim      MFI.getObjectAlignment(FrameIdx));
77199481Srdivacky
78193323Sed  if (RC == &MSP430::GR16RegClass)
79193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
80309124Sdim      .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
81309124Sdim      .addImm(0).addMemOperand(MMO);
82193323Sed  else if (RC == &MSP430::GR8RegClass)
83193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
84309124Sdim      .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
85309124Sdim      .addImm(0).addMemOperand(MMO);
86193323Sed  else
87198090Srdivacky    llvm_unreachable("Cannot store this register to stack slot!");
88193323Sed}
89193323Sed
90210299Sedvoid MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
91309124Sdim                                  MachineBasicBlock::iterator I,
92360784Sdim                                  const DebugLoc &DL, MCRegister DestReg,
93360784Sdim                                  MCRegister SrcReg, bool KillSrc) const {
94210299Sed  unsigned Opc;
95210299Sed  if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
96210299Sed    Opc = MSP430::MOV16rr;
97210299Sed  else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
98210299Sed    Opc = MSP430::MOV8rr;
99210299Sed  else
100210299Sed    llvm_unreachable("Impossible reg-to-reg copy");
101193323Sed
102210299Sed  BuildMI(MBB, I, DL, get(Opc), DestReg)
103210299Sed    .addReg(SrcReg, getKillRegState(KillSrc));
104193323Sed}
105193323Sed
106314564Sdimunsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,
107314564Sdim                                       int *BytesRemoved) const {
108314564Sdim  assert(!BytesRemoved && "code size not handled");
109314564Sdim
110198396Srdivacky  MachineBasicBlock::iterator I = MBB.end();
111198396Srdivacky  unsigned Count = 0;
112198396Srdivacky
113198396Srdivacky  while (I != MBB.begin()) {
114198396Srdivacky    --I;
115341825Sdim    if (I->isDebugInstr())
116206083Srdivacky      continue;
117198396Srdivacky    if (I->getOpcode() != MSP430::JMP &&
118207618Srdivacky        I->getOpcode() != MSP430::JCC &&
119207618Srdivacky        I->getOpcode() != MSP430::Br &&
120207618Srdivacky        I->getOpcode() != MSP430::Bm)
121198396Srdivacky      break;
122198396Srdivacky    // Remove the branch.
123198396Srdivacky    I->eraseFromParent();
124198396Srdivacky    I = MBB.end();
125198396Srdivacky    ++Count;
126198396Srdivacky  }
127198396Srdivacky
128198396Srdivacky  return Count;
129198396Srdivacky}
130198396Srdivacky
131198396Srdivackybool MSP430InstrInfo::
132314564SdimreverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
133198396Srdivacky  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
134198396Srdivacky
135198396Srdivacky  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
136198396Srdivacky
137198396Srdivacky  switch (CC) {
138234353Sdim  default: llvm_unreachable("Invalid branch condition!");
139198396Srdivacky  case MSP430CC::COND_E:
140198396Srdivacky    CC = MSP430CC::COND_NE;
141198396Srdivacky    break;
142198396Srdivacky  case MSP430CC::COND_NE:
143198396Srdivacky    CC = MSP430CC::COND_E;
144198396Srdivacky    break;
145198396Srdivacky  case MSP430CC::COND_L:
146198396Srdivacky    CC = MSP430CC::COND_GE;
147198396Srdivacky    break;
148198396Srdivacky  case MSP430CC::COND_GE:
149198396Srdivacky    CC = MSP430CC::COND_L;
150198396Srdivacky    break;
151198396Srdivacky  case MSP430CC::COND_HS:
152198396Srdivacky    CC = MSP430CC::COND_LO;
153198396Srdivacky    break;
154198396Srdivacky  case MSP430CC::COND_LO:
155198396Srdivacky    CC = MSP430CC::COND_HS;
156198396Srdivacky    break;
157198396Srdivacky  }
158198396Srdivacky
159198396Srdivacky  Cond[0].setImm(CC);
160198396Srdivacky  return false;
161198396Srdivacky}
162198396Srdivacky
163309124Sdimbool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
164309124Sdim  if (!MI.isTerminator())
165309124Sdim    return false;
166198396Srdivacky
167198396Srdivacky  // Conditional branch is a special case.
168309124Sdim  if (MI.isBranch() && !MI.isBarrier())
169198396Srdivacky    return true;
170309124Sdim  if (!MI.isPredicable())
171198396Srdivacky    return true;
172198396Srdivacky  return !isPredicated(MI);
173198396Srdivacky}
174198396Srdivacky
175309124Sdimbool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
176198396Srdivacky                                    MachineBasicBlock *&TBB,
177198396Srdivacky                                    MachineBasicBlock *&FBB,
178198396Srdivacky                                    SmallVectorImpl<MachineOperand> &Cond,
179198396Srdivacky                                    bool AllowModify) const {
180198396Srdivacky  // Start from the bottom of the block and work up, examining the
181198396Srdivacky  // terminator instructions.
182198396Srdivacky  MachineBasicBlock::iterator I = MBB.end();
183198396Srdivacky  while (I != MBB.begin()) {
184198396Srdivacky    --I;
185341825Sdim    if (I->isDebugInstr())
186206083Srdivacky      continue;
187206083Srdivacky
188198396Srdivacky    // Working from the bottom, when we see a non-terminator
189198396Srdivacky    // instruction, we're done.
190309124Sdim    if (!isUnpredicatedTerminator(*I))
191198396Srdivacky      break;
192198396Srdivacky
193198396Srdivacky    // A terminator that isn't a branch can't easily be handled
194198396Srdivacky    // by this analysis.
195234353Sdim    if (!I->isBranch())
196198396Srdivacky      return true;
197198396Srdivacky
198207618Srdivacky    // Cannot handle indirect branches.
199207618Srdivacky    if (I->getOpcode() == MSP430::Br ||
200207618Srdivacky        I->getOpcode() == MSP430::Bm)
201207618Srdivacky      return true;
202207618Srdivacky
203198396Srdivacky    // Handle unconditional branches.
204198396Srdivacky    if (I->getOpcode() == MSP430::JMP) {
205198396Srdivacky      if (!AllowModify) {
206198396Srdivacky        TBB = I->getOperand(0).getMBB();
207198396Srdivacky        continue;
208198396Srdivacky      }
209198396Srdivacky
210198396Srdivacky      // If the block has any instructions after a JMP, delete them.
211276479Sdim      while (std::next(I) != MBB.end())
212276479Sdim        std::next(I)->eraseFromParent();
213198396Srdivacky      Cond.clear();
214276479Sdim      FBB = nullptr;
215198396Srdivacky
216198396Srdivacky      // Delete the JMP if it's equivalent to a fall-through.
217198396Srdivacky      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
218276479Sdim        TBB = nullptr;
219198396Srdivacky        I->eraseFromParent();
220198396Srdivacky        I = MBB.end();
221198396Srdivacky        continue;
222198396Srdivacky      }
223198396Srdivacky
224198396Srdivacky      // TBB is used to indicate the unconditinal destination.
225198396Srdivacky      TBB = I->getOperand(0).getMBB();
226198396Srdivacky      continue;
227198396Srdivacky    }
228198396Srdivacky
229198396Srdivacky    // Handle conditional branches.
230198396Srdivacky    assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
231198396Srdivacky    MSP430CC::CondCodes BranchCode =
232198396Srdivacky      static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
233198396Srdivacky    if (BranchCode == MSP430CC::COND_INVALID)
234198396Srdivacky      return true;  // Can't handle weird stuff.
235198396Srdivacky
236198396Srdivacky    // Working from the bottom, handle the first conditional branch.
237198396Srdivacky    if (Cond.empty()) {
238198396Srdivacky      FBB = TBB;
239198396Srdivacky      TBB = I->getOperand(0).getMBB();
240198396Srdivacky      Cond.push_back(MachineOperand::CreateImm(BranchCode));
241198396Srdivacky      continue;
242198396Srdivacky    }
243198396Srdivacky
244198396Srdivacky    // Handle subsequent conditional branches. Only handle the case where all
245198396Srdivacky    // conditional branches branch to the same destination.
246198396Srdivacky    assert(Cond.size() == 1);
247198396Srdivacky    assert(TBB);
248198396Srdivacky
249198396Srdivacky    // Only handle the case where all conditional branches branch to
250198396Srdivacky    // the same destination.
251198396Srdivacky    if (TBB != I->getOperand(0).getMBB())
252198396Srdivacky      return true;
253198396Srdivacky
254198396Srdivacky    MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
255198396Srdivacky    // If the conditions are the same, we can leave them alone.
256198396Srdivacky    if (OldBranchCode == BranchCode)
257198396Srdivacky      continue;
258198396Srdivacky
259198396Srdivacky    return true;
260198396Srdivacky  }
261198396Srdivacky
262198396Srdivacky  return false;
263198396Srdivacky}
264198396Srdivacky
265314564Sdimunsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
266309124Sdim                                       MachineBasicBlock *TBB,
267309124Sdim                                       MachineBasicBlock *FBB,
268309124Sdim                                       ArrayRef<MachineOperand> Cond,
269314564Sdim                                       const DebugLoc &DL,
270314564Sdim                                       int *BytesAdded) const {
271193323Sed  // Shouldn't be a fall through.
272314564Sdim  assert(TBB && "insertBranch must not be told to insert a fallthrough");
273193323Sed  assert((Cond.size() == 1 || Cond.size() == 0) &&
274193323Sed         "MSP430 branch conditions have one component!");
275314564Sdim  assert(!BytesAdded && "code size not handled");
276193323Sed
277193323Sed  if (Cond.empty()) {
278193323Sed    // Unconditional branch?
279193323Sed    assert(!FBB && "Unconditional branch with multiple successors!");
280206124Srdivacky    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
281193323Sed    return 1;
282193323Sed  }
283193323Sed
284193323Sed  // Conditional branch.
285193323Sed  unsigned Count = 0;
286206124Srdivacky  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
287198396Srdivacky  ++Count;
288193323Sed
289198396Srdivacky  if (FBB) {
290198396Srdivacky    // Two-way Conditional branch. Insert the second branch.
291206124Srdivacky    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
292198396Srdivacky    ++Count;
293198396Srdivacky  }
294193323Sed  return Count;
295193323Sed}
296202878Srdivacky
297202878Srdivacky/// GetInstSize - Return the number of bytes of code the specified
298202878Srdivacky/// instruction may be.  This returns the maximum number of bytes.
299202878Srdivacky///
300314564Sdimunsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
301309124Sdim  const MCInstrDesc &Desc = MI.getDesc();
302202878Srdivacky
303344779Sdim  switch (Desc.getOpcode()) {
304344779Sdim  case TargetOpcode::CFI_INSTRUCTION:
305344779Sdim  case TargetOpcode::EH_LABEL:
306344779Sdim  case TargetOpcode::IMPLICIT_DEF:
307344779Sdim  case TargetOpcode::KILL:
308344779Sdim  case TargetOpcode::DBG_VALUE:
309344779Sdim    return 0;
310353358Sdim  case TargetOpcode::INLINEASM:
311353358Sdim  case TargetOpcode::INLINEASM_BR: {
312344779Sdim    const MachineFunction *MF = MI.getParent()->getParent();
313344779Sdim    const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
314344779Sdim    return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
315344779Sdim                                  *MF->getTarget().getMCAsmInfo());
316202878Srdivacky  }
317344779Sdim  }
318344779Sdim
319344779Sdim  return Desc.getSize();
320202878Srdivacky}
321