Mips16InstrInfo.cpp revision 249423
1239310Sdim//===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file contains the Mips16 implementation of the TargetInstrInfo class.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#include "Mips16InstrInfo.h"
15249423Sdim#include "InstPrinter/MipsInstPrinter.h"
16249423Sdim#include "MipsMachineFunction.h"
17239310Sdim#include "MipsTargetMachine.h"
18249423Sdim#include "llvm/ADT/STLExtras.h"
19249423Sdim#include "llvm/ADT/StringRef.h"
20239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
21239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
22249423Sdim#include "llvm/CodeGen/RegisterScavenging.h"
23249423Sdim#include "llvm/Support/CommandLine.h"
24249423Sdim#include "llvm/Support/Debug.h"
25239310Sdim#include "llvm/Support/ErrorHandling.h"
26239310Sdim#include "llvm/Support/TargetRegistry.h"
27239310Sdim
28239310Sdimusing namespace llvm;
29239310Sdim
30249423Sdimstatic cl::opt<bool> NeverUseSaveRestore(
31249423Sdim  "mips16-never-use-save-restore",
32249423Sdim  cl::init(false),
33249423Sdim  cl::desc("For testing ability to adjust stack pointer "
34249423Sdim           "without save/restore instruction"),
35249423Sdim  cl::Hidden);
36249423Sdim
37249423Sdim
38239310SdimMips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm)
39243830Sdim  : MipsInstrInfo(tm, Mips::BimmX16),
40239310Sdim    RI(*tm.getSubtargetImpl(), *this) {}
41239310Sdim
42239310Sdimconst MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const {
43239310Sdim  return RI;
44239310Sdim}
45239310Sdim
46239310Sdim/// isLoadFromStackSlot - If the specified machine instruction is a direct
47239310Sdim/// load from a stack slot, return the virtual or physical register number of
48239310Sdim/// the destination along with the FrameIndex of the loaded stack slot.  If
49239310Sdim/// not, return 0.  This predicate must return 0 if the instruction has
50239310Sdim/// any side effects other than loading from the stack slot.
51239310Sdimunsigned Mips16InstrInfo::
52239310SdimisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
53239310Sdim{
54239310Sdim  return 0;
55239310Sdim}
56239310Sdim
57239310Sdim/// isStoreToStackSlot - If the specified machine instruction is a direct
58239310Sdim/// store to a stack slot, return the virtual or physical register number of
59239310Sdim/// the source reg along with the FrameIndex of the loaded stack slot.  If
60239310Sdim/// not, return 0.  This predicate must return 0 if the instruction has
61239310Sdim/// any side effects other than storing to the stack slot.
62239310Sdimunsigned Mips16InstrInfo::
63239310SdimisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
64239310Sdim{
65239310Sdim  return 0;
66239310Sdim}
67239310Sdim
68239310Sdimvoid Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
69239310Sdim                                  MachineBasicBlock::iterator I, DebugLoc DL,
70239310Sdim                                  unsigned DestReg, unsigned SrcReg,
71239310Sdim                                  bool KillSrc) const {
72243830Sdim  unsigned Opc = 0;
73239310Sdim
74243830Sdim  if (Mips::CPU16RegsRegClass.contains(DestReg) &&
75243830Sdim      Mips::CPURegsRegClass.contains(SrcReg))
76243830Sdim    Opc = Mips::MoveR3216;
77243830Sdim  else if (Mips::CPURegsRegClass.contains(DestReg) &&
78243830Sdim           Mips::CPU16RegsRegClass.contains(SrcReg))
79243830Sdim    Opc = Mips::Move32R16;
80243830Sdim  else if ((SrcReg == Mips::HI) &&
81243830Sdim           (Mips::CPU16RegsRegClass.contains(DestReg)))
82243830Sdim    Opc = Mips::Mfhi16, SrcReg = 0;
83239310Sdim
84243830Sdim  else if ((SrcReg == Mips::LO) &&
85243830Sdim           (Mips::CPU16RegsRegClass.contains(DestReg)))
86243830Sdim    Opc = Mips::Mflo16, SrcReg = 0;
87243830Sdim
88243830Sdim
89239310Sdim  assert(Opc && "Cannot copy registers");
90239310Sdim
91239310Sdim  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
92239310Sdim
93239310Sdim  if (DestReg)
94239310Sdim    MIB.addReg(DestReg, RegState::Define);
95239310Sdim
96239310Sdim  if (SrcReg)
97239310Sdim    MIB.addReg(SrcReg, getKillRegState(KillSrc));
98239310Sdim}
99239310Sdim
100239310Sdimvoid Mips16InstrInfo::
101249423SdimstoreRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
102249423Sdim                unsigned SrcReg, bool isKill, int FI,
103249423Sdim                const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
104249423Sdim                int64_t Offset) const {
105243830Sdim  DebugLoc DL;
106243830Sdim  if (I != MBB.end()) DL = I->getDebugLoc();
107243830Sdim  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
108243830Sdim  unsigned Opc = 0;
109243830Sdim  if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
110243830Sdim    Opc = Mips::SwRxSpImmX16;
111243830Sdim  assert(Opc && "Register class not handled!");
112243830Sdim  BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
113249423Sdim    .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
114239310Sdim}
115239310Sdim
116239310Sdimvoid Mips16InstrInfo::
117249423SdimloadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
118249423Sdim                 unsigned DestReg, int FI, const TargetRegisterClass *RC,
119249423Sdim                 const TargetRegisterInfo *TRI, int64_t Offset) const {
120243830Sdim  DebugLoc DL;
121243830Sdim  if (I != MBB.end()) DL = I->getDebugLoc();
122243830Sdim  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
123243830Sdim  unsigned Opc = 0;
124243830Sdim
125243830Sdim  if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
126243830Sdim    Opc = Mips::LwRxSpImmX16;
127243830Sdim  assert(Opc && "Register class not handled!");
128249423Sdim  BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset)
129243830Sdim    .addMemOperand(MMO);
130239310Sdim}
131239310Sdim
132239310Sdimbool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
133239310Sdim  MachineBasicBlock &MBB = *MI->getParent();
134239310Sdim  switch(MI->getDesc().getOpcode()) {
135239310Sdim  default:
136239310Sdim    return false;
137239310Sdim  case Mips::RetRA16:
138243830Sdim    ExpandRetRA16(MBB, MI, Mips::JrcRa16);
139239310Sdim    break;
140239310Sdim  }
141239310Sdim
142239310Sdim  MBB.erase(MI);
143239310Sdim  return true;
144239310Sdim}
145239310Sdim
146239310Sdim/// GetOppositeBranchOpc - Return the inverse of the specified
147239310Sdim/// opcode, e.g. turning BEQ to BNE.
148239310Sdimunsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const {
149243830Sdim  switch (Opc) {
150243830Sdim  default:  llvm_unreachable("Illegal opcode!");
151243830Sdim  case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16;
152243830Sdim  case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16;
153243830Sdim  case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16;
154243830Sdim  case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16;
155243830Sdim  case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16;
156243830Sdim  case Mips::BtnezX16: return Mips::BteqzX16;
157243830Sdim  case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16;
158243830Sdim  case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16;
159243830Sdim  case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16;
160243830Sdim  case Mips::BteqzX16: return Mips::BtnezX16;
161243830Sdim  case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16;
162243830Sdim  case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16;
163243830Sdim  case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16;
164243830Sdim  case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16;
165243830Sdim  case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16;
166243830Sdim  case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16;
167243830Sdim  }
168239310Sdim  assert(false && "Implement this function.");
169239310Sdim  return 0;
170239310Sdim}
171239310Sdim
172249423Sdim// Adjust SP by FrameSize bytes. Save RA, S0, S1
173249423Sdimvoid Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
174249423Sdim                    MachineBasicBlock &MBB,
175249423Sdim                    MachineBasicBlock::iterator I) const {
176249423Sdim  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
177249423Sdim  if (!NeverUseSaveRestore) {
178249423Sdim    if (isUInt<11>(FrameSize))
179249423Sdim      BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize);
180249423Sdim    else {
181249423Sdim      int Base = 2040; // should create template function like isUInt that
182249423Sdim                       // returns largest possible n bit unsigned integer
183249423Sdim      int64_t Remainder = FrameSize - Base;
184249423Sdim      BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base);
185249423Sdim      if (isInt<16>(-Remainder))
186249423Sdim        BuildAddiuSpImm(MBB, I, -Remainder);
187249423Sdim      else
188249423Sdim        adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
189249423Sdim    }
190249423Sdim
191249423Sdim  }
192249423Sdim  else {
193249423Sdim    //
194249423Sdim    // sw ra, -4[sp]
195249423Sdim    // sw s1, -8[sp]
196249423Sdim    // sw s0, -12[sp]
197249423Sdim
198249423Sdim    MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
199249423Sdim                                       Mips::RA);
200249423Sdim    MIB1.addReg(Mips::SP);
201249423Sdim    MIB1.addImm(-4);
202249423Sdim    MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
203249423Sdim                                       Mips::S1);
204249423Sdim    MIB2.addReg(Mips::SP);
205249423Sdim    MIB2.addImm(-8);
206249423Sdim    MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
207249423Sdim                                       Mips::S0);
208249423Sdim    MIB3.addReg(Mips::SP);
209249423Sdim    MIB3.addImm(-12);
210249423Sdim    adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1);
211249423Sdim  }
212249423Sdim}
213249423Sdim
214249423Sdim// Adjust SP by FrameSize bytes. Restore RA, S0, S1
215249423Sdimvoid Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
216249423Sdim                                   MachineBasicBlock &MBB,
217249423Sdim                                   MachineBasicBlock::iterator I) const {
218249423Sdim  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
219249423Sdim  if (!NeverUseSaveRestore) {
220249423Sdim    if (isUInt<11>(FrameSize))
221249423Sdim      BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize);
222249423Sdim    else {
223249423Sdim      int Base = 2040; // should create template function like isUInt that
224249423Sdim                       // returns largest possible n bit unsigned integer
225249423Sdim      int64_t Remainder = FrameSize - Base;
226249423Sdim      if (isInt<16>(Remainder))
227249423Sdim        BuildAddiuSpImm(MBB, I, Remainder);
228249423Sdim      else
229249423Sdim        adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
230249423Sdim      BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base);
231249423Sdim    }
232249423Sdim  }
233249423Sdim  else {
234249423Sdim    adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1);
235249423Sdim    // lw ra, -4[sp]
236249423Sdim    // lw s1, -8[sp]
237249423Sdim    // lw s0, -12[sp]
238249423Sdim    MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
239249423Sdim                                       Mips::A0);
240249423Sdim    MIB1.addReg(Mips::SP);
241249423Sdim    MIB1.addImm(-4);
242249423Sdim    MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16),
243249423Sdim                                       Mips::RA);
244249423Sdim     MIB0.addReg(Mips::A0);
245249423Sdim    MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
246249423Sdim                                       Mips::S1);
247249423Sdim    MIB2.addReg(Mips::SP);
248249423Sdim    MIB2.addImm(-8);
249249423Sdim    MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
250249423Sdim                                       Mips::S0);
251249423Sdim    MIB3.addReg(Mips::SP);
252249423Sdim    MIB3.addImm(-12);
253249423Sdim  }
254249423Sdim
255249423Sdim}
256249423Sdim
257249423Sdim// Adjust SP by Amount bytes where bytes can be up to 32bit number.
258249423Sdim// This can only be called at times that we know that there is at least one free
259249423Sdim// register.
260249423Sdim// This is clearly safe at prologue and epilogue.
261249423Sdim//
262249423Sdimvoid Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount,
263249423Sdim                                        MachineBasicBlock &MBB,
264249423Sdim                                        MachineBasicBlock::iterator I,
265249423Sdim                                        unsigned Reg1, unsigned Reg2) const {
266249423Sdim  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
267249423Sdim//  MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
268249423Sdim//  unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass);
269249423Sdim//  unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass);
270249423Sdim  //
271249423Sdim  // li reg1, constant
272249423Sdim  // move reg2, sp
273249423Sdim  // add reg1, reg1, reg2
274249423Sdim  // move sp, reg1
275249423Sdim  //
276249423Sdim  //
277249423Sdim  MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1);
278249423Sdim  MIB1.addImm(Amount);
279249423Sdim  MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2);
280249423Sdim  MIB2.addReg(Mips::SP, RegState::Kill);
281249423Sdim  MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1);
282249423Sdim  MIB3.addReg(Reg1);
283249423Sdim  MIB3.addReg(Reg2, RegState::Kill);
284249423Sdim  MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16),
285249423Sdim                                                     Mips::SP);
286249423Sdim  MIB4.addReg(Reg1, RegState::Kill);
287249423Sdim}
288249423Sdim
289249423Sdimvoid Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount,
290249423Sdim                    MachineBasicBlock &MBB,
291249423Sdim                    MachineBasicBlock::iterator I) const {
292249423Sdim   assert(false && "adjust stack pointer amount exceeded");
293249423Sdim}
294249423Sdim
295243830Sdim/// Adjust SP by Amount bytes.
296243830Sdimvoid Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
297243830Sdim                                     MachineBasicBlock &MBB,
298243830Sdim                                     MachineBasicBlock::iterator I) const {
299249423Sdim  if (isInt<16>(Amount))  // need to change to addiu sp, ....and isInt<16>
300249423Sdim    BuildAddiuSpImm(MBB, I, Amount);
301249423Sdim  else
302249423Sdim    adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
303249423Sdim}
304249423Sdim
305249423Sdim/// This function generates the sequence of instructions needed to get the
306249423Sdim/// result of adding register REG and immediate IMM.
307249423Sdimunsigned
308249423SdimMips16InstrInfo::loadImmediate(unsigned FrameReg,
309249423Sdim                               int64_t Imm, MachineBasicBlock &MBB,
310249423Sdim                               MachineBasicBlock::iterator II, DebugLoc DL,
311249423Sdim                               unsigned &NewImm) const {
312249423Sdim  //
313249423Sdim  // given original instruction is:
314249423Sdim  // Instr rx, T[offset] where offset is too big.
315249423Sdim  //
316249423Sdim  // lo = offset & 0xFFFF
317249423Sdim  // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
318249423Sdim  //
319249423Sdim  // let T = temporary register
320249423Sdim  // li T, hi
321249423Sdim  // shl T, 16
322249423Sdim  // add T, Rx, T
323249423Sdim  //
324249423Sdim  RegScavenger rs;
325249423Sdim  int32_t lo = Imm & 0xFFFF;
326249423Sdim  int32_t hi = ((Imm >> 16) + (lo >> 15)) & 0xFFFF;
327249423Sdim  NewImm = lo;
328249423Sdim  unsigned Reg =0;
329249423Sdim  unsigned SpReg = 0;
330249423Sdim  rs.enterBasicBlock(&MBB);
331249423Sdim  rs.forward(II);
332249423Sdim  //
333249423Sdim  // we use T0 for the first register, if we need to save something away.
334249423Sdim  // we use T1 for the second register, if we need to save something away.
335249423Sdim  //
336249423Sdim  unsigned FirstRegSaved =0, SecondRegSaved=0;
337249423Sdim  unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
338249423Sdim
339249423Sdim  Reg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass);
340249423Sdim  if (Reg == 0) {
341249423Sdim    FirstRegSaved = Reg = Mips::V0;
342249423Sdim    FirstRegSavedTo = Mips::T0;
343249423Sdim    copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true);
344243830Sdim  }
345243830Sdim  else
346249423Sdim    rs.setUsed(Reg);
347249423Sdim  BuildMI(MBB, II, DL, get(Mips::LiRxImmX16), Reg).addImm(hi);
348249423Sdim  BuildMI(MBB, II, DL, get(Mips::SllX16), Reg).addReg(Reg).
349249423Sdim    addImm(16);
350249423Sdim  if (FrameReg == Mips::SP) {
351249423Sdim    SpReg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass);
352249423Sdim    if (SpReg == 0) {
353249423Sdim      if (Reg != Mips::V1) {
354249423Sdim        SecondRegSaved = SpReg = Mips::V1;
355249423Sdim        SecondRegSavedTo = Mips::T1;
356249423Sdim      }
357249423Sdim      else {
358249423Sdim        SecondRegSaved = SpReg = Mips::V0;
359249423Sdim        SecondRegSavedTo = Mips::T0;
360249423Sdim      }
361249423Sdim      copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true);
362249423Sdim    }
363249423Sdim    else
364249423Sdim      rs.setUsed(SpReg);
365249423Sdim
366249423Sdim    copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false);
367249423Sdim    BuildMI(MBB, II, DL, get(Mips::  AdduRxRyRz16), Reg).addReg(SpReg)
368249423Sdim      .addReg(Reg);
369249423Sdim  }
370249423Sdim  else
371249423Sdim    BuildMI(MBB, II, DL, get(Mips::  AdduRxRyRz16), Reg).addReg(FrameReg)
372249423Sdim      .addReg(Reg, RegState::Kill);
373249423Sdim  if (FirstRegSaved || SecondRegSaved) {
374249423Sdim    II = llvm::next(II);
375249423Sdim    if (FirstRegSaved)
376249423Sdim      copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true);
377249423Sdim    if (SecondRegSaved)
378249423Sdim      copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true);
379249423Sdim  }
380249423Sdim  return Reg;
381243830Sdim}
382243830Sdim
383239310Sdimunsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const {
384243830Sdim  return (Opc == Mips::BeqzRxImmX16   || Opc == Mips::BimmX16  ||
385243830Sdim          Opc == Mips::BnezRxImmX16   || Opc == Mips::BteqzX16 ||
386243830Sdim          Opc == Mips::BteqzT8CmpX16  || Opc == Mips::BteqzT8CmpiX16 ||
387243830Sdim          Opc == Mips::BteqzT8SltX16  || Opc == Mips::BteqzT8SltuX16  ||
388243830Sdim          Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
389243830Sdim          Opc == Mips::BtnezX16       || Opc == Mips::BtnezT8CmpX16 ||
390243830Sdim          Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
391243830Sdim          Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
392243830Sdim          Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
393239310Sdim}
394239310Sdim
395239310Sdimvoid Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB,
396239310Sdim                                  MachineBasicBlock::iterator I,
397239310Sdim                                  unsigned Opc) const {
398239310Sdim  BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
399239310Sdim}
400239310Sdim
401249423Sdim
402249423Sdimconst MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const {
403249423Sdim  if (validSpImm8(Imm))
404249423Sdim    return get(Mips::AddiuSpImm16);
405249423Sdim  else
406249423Sdim    return get(Mips::AddiuSpImmX16);
407249423Sdim}
408249423Sdim
409249423Sdimvoid Mips16InstrInfo::BuildAddiuSpImm
410249423Sdim  (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const {
411249423Sdim  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
412249423Sdim  BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm);
413249423Sdim}
414249423Sdim
415239310Sdimconst MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) {
416239310Sdim  return new Mips16InstrInfo(TM);
417239310Sdim}
418