1235633Sdim//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the MSP430 implementation of the TargetInstrInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14235633Sdim#include "MSP430InstrInfo.h"
15193323Sed#include "MSP430.h"
16193323Sed#include "MSP430MachineFunctionInfo.h"
17193323Sed#include "MSP430TargetMachine.h"
18193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
19193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
20193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
21252723Sdim#include "llvm/IR/Function.h"
22198090Srdivacky#include "llvm/Support/ErrorHandling.h"
23226890Sdim#include "llvm/Support/TargetRegistry.h"
24193323Sed
25263509Sdim#define GET_INSTRINFO_CTOR_DTOR
26224145Sdim#include "MSP430GenInstrInfo.inc"
27224145Sdim
28193323Sedusing namespace llvm;
29193323Sed
30263509Sdim// Pin the vtable to this file.
31263509Sdimvoid MSP430InstrInfo::anchor() {}
32263509Sdim
33193323SedMSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm)
34224145Sdim  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
35263509Sdim    RI(tm) {}
36193323Sed
37193323Sedvoid MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
38193323Sed                                          MachineBasicBlock::iterator MI,
39193323Sed                                    unsigned SrcReg, bool isKill, int FrameIdx,
40208599Srdivacky                                          const TargetRegisterClass *RC,
41208599Srdivacky                                          const TargetRegisterInfo *TRI) const {
42206124Srdivacky  DebugLoc DL;
43193323Sed  if (MI != MBB.end()) DL = MI->getDebugLoc();
44199481Srdivacky  MachineFunction &MF = *MBB.getParent();
45199481Srdivacky  MachineFrameInfo &MFI = *MF.getFrameInfo();
46193323Sed
47199481Srdivacky  MachineMemOperand *MMO =
48235633Sdim    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
49218893Sdim                            MachineMemOperand::MOStore,
50199481Srdivacky                            MFI.getObjectSize(FrameIdx),
51199481Srdivacky                            MFI.getObjectAlignment(FrameIdx));
52199481Srdivacky
53193323Sed  if (RC == &MSP430::GR16RegClass)
54193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
55193323Sed      .addFrameIndex(FrameIdx).addImm(0)
56199481Srdivacky      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
57193323Sed  else if (RC == &MSP430::GR8RegClass)
58193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
59193323Sed      .addFrameIndex(FrameIdx).addImm(0)
60199481Srdivacky      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
61193323Sed  else
62198090Srdivacky    llvm_unreachable("Cannot store this register to stack slot!");
63193323Sed}
64193323Sed
65193323Sedvoid MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
66193323Sed                                           MachineBasicBlock::iterator MI,
67193323Sed                                           unsigned DestReg, int FrameIdx,
68208599Srdivacky                                           const TargetRegisterClass *RC,
69208599Srdivacky                                           const TargetRegisterInfo *TRI) const{
70206124Srdivacky  DebugLoc DL;
71193323Sed  if (MI != MBB.end()) DL = MI->getDebugLoc();
72199481Srdivacky  MachineFunction &MF = *MBB.getParent();
73199481Srdivacky  MachineFrameInfo &MFI = *MF.getFrameInfo();
74193323Sed
75199481Srdivacky  MachineMemOperand *MMO =
76235633Sdim    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
77218893Sdim                            MachineMemOperand::MOLoad,
78199481Srdivacky                            MFI.getObjectSize(FrameIdx),
79199481Srdivacky                            MFI.getObjectAlignment(FrameIdx));
80199481Srdivacky
81193323Sed  if (RC == &MSP430::GR16RegClass)
82193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
83199481Srdivacky      .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
84193323Sed  else if (RC == &MSP430::GR8RegClass)
85193323Sed    BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
86199481Srdivacky      .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
87193323Sed  else
88198090Srdivacky    llvm_unreachable("Cannot store this register to stack slot!");
89193323Sed}
90193323Sed
91210299Sedvoid MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
92210299Sed                                  MachineBasicBlock::iterator I, DebugLoc DL,
93210299Sed                                  unsigned DestReg, unsigned SrcReg,
94210299Sed                                  bool KillSrc) const {
95210299Sed  unsigned Opc;
96210299Sed  if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
97210299Sed    Opc = MSP430::MOV16rr;
98210299Sed  else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
99210299Sed    Opc = MSP430::MOV8rr;
100210299Sed  else
101210299Sed    llvm_unreachable("Impossible reg-to-reg copy");
102193323Sed
103210299Sed  BuildMI(MBB, I, DL, get(Opc), DestReg)
104210299Sed    .addReg(SrcReg, getKillRegState(KillSrc));
105193323Sed}
106193323Sed
107198396Srdivackyunsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
108198396Srdivacky  MachineBasicBlock::iterator I = MBB.end();
109198396Srdivacky  unsigned Count = 0;
110198396Srdivacky
111198396Srdivacky  while (I != MBB.begin()) {
112198396Srdivacky    --I;
113206083Srdivacky    if (I->isDebugValue())
114206083Srdivacky      continue;
115198396Srdivacky    if (I->getOpcode() != MSP430::JMP &&
116207618Srdivacky        I->getOpcode() != MSP430::JCC &&
117207618Srdivacky        I->getOpcode() != MSP430::Br &&
118207618Srdivacky        I->getOpcode() != MSP430::Bm)
119198396Srdivacky      break;
120198396Srdivacky    // Remove the branch.
121198396Srdivacky    I->eraseFromParent();
122198396Srdivacky    I = MBB.end();
123198396Srdivacky    ++Count;
124198396Srdivacky  }
125198396Srdivacky
126198396Srdivacky  return Count;
127198396Srdivacky}
128198396Srdivacky
129198396Srdivackybool MSP430InstrInfo::
130198396SrdivackyReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
131198396Srdivacky  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
132198396Srdivacky
133198396Srdivacky  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
134198396Srdivacky
135198396Srdivacky  switch (CC) {
136235633Sdim  default: llvm_unreachable("Invalid branch condition!");
137198396Srdivacky  case MSP430CC::COND_E:
138198396Srdivacky    CC = MSP430CC::COND_NE;
139198396Srdivacky    break;
140198396Srdivacky  case MSP430CC::COND_NE:
141198396Srdivacky    CC = MSP430CC::COND_E;
142198396Srdivacky    break;
143198396Srdivacky  case MSP430CC::COND_L:
144198396Srdivacky    CC = MSP430CC::COND_GE;
145198396Srdivacky    break;
146198396Srdivacky  case MSP430CC::COND_GE:
147198396Srdivacky    CC = MSP430CC::COND_L;
148198396Srdivacky    break;
149198396Srdivacky  case MSP430CC::COND_HS:
150198396Srdivacky    CC = MSP430CC::COND_LO;
151198396Srdivacky    break;
152198396Srdivacky  case MSP430CC::COND_LO:
153198396Srdivacky    CC = MSP430CC::COND_HS;
154198396Srdivacky    break;
155198396Srdivacky  }
156198396Srdivacky
157198396Srdivacky  Cond[0].setImm(CC);
158198396Srdivacky  return false;
159198396Srdivacky}
160198396Srdivacky
161198396Srdivackybool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
162235633Sdim  if (!MI->isTerminator()) return false;
163198396Srdivacky
164198396Srdivacky  // Conditional branch is a special case.
165235633Sdim  if (MI->isBranch() && !MI->isBarrier())
166198396Srdivacky    return true;
167235633Sdim  if (!MI->isPredicable())
168198396Srdivacky    return true;
169198396Srdivacky  return !isPredicated(MI);
170198396Srdivacky}
171198396Srdivacky
172198396Srdivackybool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
173198396Srdivacky                                    MachineBasicBlock *&TBB,
174198396Srdivacky                                    MachineBasicBlock *&FBB,
175198396Srdivacky                                    SmallVectorImpl<MachineOperand> &Cond,
176198396Srdivacky                                    bool AllowModify) const {
177198396Srdivacky  // Start from the bottom of the block and work up, examining the
178198396Srdivacky  // terminator instructions.
179198396Srdivacky  MachineBasicBlock::iterator I = MBB.end();
180198396Srdivacky  while (I != MBB.begin()) {
181198396Srdivacky    --I;
182206083Srdivacky    if (I->isDebugValue())
183206083Srdivacky      continue;
184206083Srdivacky
185198396Srdivacky    // Working from the bottom, when we see a non-terminator
186198396Srdivacky    // instruction, we're done.
187198396Srdivacky    if (!isUnpredicatedTerminator(I))
188198396Srdivacky      break;
189198396Srdivacky
190198396Srdivacky    // A terminator that isn't a branch can't easily be handled
191198396Srdivacky    // by this analysis.
192235633Sdim    if (!I->isBranch())
193198396Srdivacky      return true;
194198396Srdivacky
195207618Srdivacky    // Cannot handle indirect branches.
196207618Srdivacky    if (I->getOpcode() == MSP430::Br ||
197207618Srdivacky        I->getOpcode() == MSP430::Bm)
198207618Srdivacky      return true;
199207618Srdivacky
200198396Srdivacky    // Handle unconditional branches.
201198396Srdivacky    if (I->getOpcode() == MSP430::JMP) {
202198396Srdivacky      if (!AllowModify) {
203198396Srdivacky        TBB = I->getOperand(0).getMBB();
204198396Srdivacky        continue;
205198396Srdivacky      }
206198396Srdivacky
207198396Srdivacky      // If the block has any instructions after a JMP, delete them.
208200581Srdivacky      while (llvm::next(I) != MBB.end())
209200581Srdivacky        llvm::next(I)->eraseFromParent();
210198396Srdivacky      Cond.clear();
211198396Srdivacky      FBB = 0;
212198396Srdivacky
213198396Srdivacky      // Delete the JMP if it's equivalent to a fall-through.
214198396Srdivacky      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
215198396Srdivacky        TBB = 0;
216198396Srdivacky        I->eraseFromParent();
217198396Srdivacky        I = MBB.end();
218198396Srdivacky        continue;
219198396Srdivacky      }
220198396Srdivacky
221198396Srdivacky      // TBB is used to indicate the unconditinal destination.
222198396Srdivacky      TBB = I->getOperand(0).getMBB();
223198396Srdivacky      continue;
224198396Srdivacky    }
225198396Srdivacky
226198396Srdivacky    // Handle conditional branches.
227198396Srdivacky    assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
228198396Srdivacky    MSP430CC::CondCodes BranchCode =
229198396Srdivacky      static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
230198396Srdivacky    if (BranchCode == MSP430CC::COND_INVALID)
231198396Srdivacky      return true;  // Can't handle weird stuff.
232198396Srdivacky
233198396Srdivacky    // Working from the bottom, handle the first conditional branch.
234198396Srdivacky    if (Cond.empty()) {
235198396Srdivacky      FBB = TBB;
236198396Srdivacky      TBB = I->getOperand(0).getMBB();
237198396Srdivacky      Cond.push_back(MachineOperand::CreateImm(BranchCode));
238198396Srdivacky      continue;
239198396Srdivacky    }
240198396Srdivacky
241198396Srdivacky    // Handle subsequent conditional branches. Only handle the case where all
242198396Srdivacky    // conditional branches branch to the same destination.
243198396Srdivacky    assert(Cond.size() == 1);
244198396Srdivacky    assert(TBB);
245198396Srdivacky
246198396Srdivacky    // Only handle the case where all conditional branches branch to
247198396Srdivacky    // the same destination.
248198396Srdivacky    if (TBB != I->getOperand(0).getMBB())
249198396Srdivacky      return true;
250198396Srdivacky
251198396Srdivacky    MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
252198396Srdivacky    // If the conditions are the same, we can leave them alone.
253198396Srdivacky    if (OldBranchCode == BranchCode)
254198396Srdivacky      continue;
255198396Srdivacky
256198396Srdivacky    return true;
257198396Srdivacky  }
258198396Srdivacky
259198396Srdivacky  return false;
260198396Srdivacky}
261198396Srdivacky
262193323Sedunsigned
263193323SedMSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
264193323Sed                              MachineBasicBlock *FBB,
265210299Sed                              const SmallVectorImpl<MachineOperand> &Cond,
266210299Sed                              DebugLoc DL) const {
267193323Sed  // Shouldn't be a fall through.
268193323Sed  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
269193323Sed  assert((Cond.size() == 1 || Cond.size() == 0) &&
270193323Sed         "MSP430 branch conditions have one component!");
271193323Sed
272193323Sed  if (Cond.empty()) {
273193323Sed    // Unconditional branch?
274193323Sed    assert(!FBB && "Unconditional branch with multiple successors!");
275206124Srdivacky    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
276193323Sed    return 1;
277193323Sed  }
278193323Sed
279193323Sed  // Conditional branch.
280193323Sed  unsigned Count = 0;
281206124Srdivacky  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
282198396Srdivacky  ++Count;
283193323Sed
284198396Srdivacky  if (FBB) {
285198396Srdivacky    // Two-way Conditional branch. Insert the second branch.
286206124Srdivacky    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
287198396Srdivacky    ++Count;
288198396Srdivacky  }
289193323Sed  return Count;
290193323Sed}
291202878Srdivacky
292202878Srdivacky/// GetInstSize - Return the number of bytes of code the specified
293202878Srdivacky/// instruction may be.  This returns the maximum number of bytes.
294202878Srdivacky///
295202878Srdivackyunsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
296224145Sdim  const MCInstrDesc &Desc = MI->getDesc();
297202878Srdivacky
298202878Srdivacky  switch (Desc.TSFlags & MSP430II::SizeMask) {
299202878Srdivacky  default:
300202878Srdivacky    switch (Desc.getOpcode()) {
301235633Sdim    default: llvm_unreachable("Unknown instruction size!");
302212904Sdim    case TargetOpcode::PROLOG_LABEL:
303203954Srdivacky    case TargetOpcode::EH_LABEL:
304203954Srdivacky    case TargetOpcode::IMPLICIT_DEF:
305203954Srdivacky    case TargetOpcode::KILL:
306207618Srdivacky    case TargetOpcode::DBG_VALUE:
307202878Srdivacky      return 0;
308203954Srdivacky    case TargetOpcode::INLINEASM: {
309202878Srdivacky      const MachineFunction *MF = MI->getParent()->getParent();
310202878Srdivacky      const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
311202878Srdivacky      return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
312202878Srdivacky                                    *MF->getTarget().getMCAsmInfo());
313202878Srdivacky    }
314202878Srdivacky    }
315202878Srdivacky  case MSP430II::SizeSpecial:
316202878Srdivacky    switch (MI->getOpcode()) {
317235633Sdim    default: llvm_unreachable("Unknown instruction size!");
318202878Srdivacky    case MSP430::SAR8r1c:
319202878Srdivacky    case MSP430::SAR16r1c:
320202878Srdivacky      return 4;
321202878Srdivacky    }
322202878Srdivacky  case MSP430II::Size2Bytes:
323202878Srdivacky    return 2;
324202878Srdivacky  case MSP430II::Size4Bytes:
325202878Srdivacky    return 4;
326202878Srdivacky  case MSP430II::Size6Bytes:
327202878Srdivacky    return 6;
328202878Srdivacky  }
329202878Srdivacky}
330