Mips16InstrInfo.cpp revision 243830
1139749Simp//===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===//
2139749Simp//
365312Smsmith//                     The LLVM Compiler Infrastructure
465312Smsmith//
565312Smsmith// This file is distributed under the University of Illinois Open Source
665312Smsmith// License. See LICENSE.TXT for details.
787826Sobrien//
887826Sobrien//===----------------------------------------------------------------------===//
965312Smsmith//
1065312Smsmith// This file contains the Mips16 implementation of the TargetInstrInfo class.
1165312Smsmith//
1296615Sobrien//===----------------------------------------------------------------------===//
1365312Smsmith
1496615Sobrien#include "Mips16InstrInfo.h"
1565312Smsmith#include "MipsTargetMachine.h"
1665312Smsmith#include "MipsMachineFunction.h"
1796554Sobrien#include "InstPrinter/MipsInstPrinter.h"
1896554Sobrien#include "llvm/CodeGen/MachineInstrBuilder.h"
1965312Smsmith#include "llvm/CodeGen/MachineRegisterInfo.h"
2065312Smsmith#include "llvm/Support/ErrorHandling.h"
2165312Smsmith#include "llvm/Support/TargetRegistry.h"
2265312Smsmith#include "llvm/ADT/STLExtras.h"
2365312Smsmith#include "llvm/ADT/StringRef.h"
2496554Sobrien
2565312Smsmithusing namespace llvm;
2696554Sobrien
2796554SobrienMips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm)
2896554Sobrien  : MipsInstrInfo(tm, Mips::BimmX16),
2996554Sobrien    RI(*tm.getSubtargetImpl(), *this) {}
3096554Sobrien
3196554Sobrienconst MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const {
3265312Smsmith  return RI;
3396554Sobrien}
3496554Sobrien
3596554Sobrien/// isLoadFromStackSlot - If the specified machine instruction is a direct
3696554Sobrien/// load from a stack slot, return the virtual or physical register number of
3796554Sobrien/// the destination along with the FrameIndex of the loaded stack slot.  If
3896554Sobrien/// not, return 0.  This predicate must return 0 if the instruction has
3965312Smsmith/// any side effects other than loading from the stack slot.
4065312Smsmithunsigned Mips16InstrInfo::
4165312SmsmithisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
4265312Smsmith{
4396554Sobrien  return 0;
4496554Sobrien}
4565312Smsmith
4696554Sobrien/// isStoreToStackSlot - If the specified machine instruction is a direct
4796554Sobrien/// store to a stack slot, return the virtual or physical register number of
4896554Sobrien/// the source reg along with the FrameIndex of the loaded stack slot.  If
4996554Sobrien/// not, return 0.  This predicate must return 0 if the instruction has
5096554Sobrien/// any side effects other than storing to the stack slot.
5165312Smsmithunsigned Mips16InstrInfo::
5265312SmsmithisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
5365312Smsmith{
5496554Sobrien  return 0;
5596554Sobrien}
5696554Sobrien
5796554Sobrienvoid Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
5896554Sobrien                                  MachineBasicBlock::iterator I, DebugLoc DL,
5965312Smsmith                                  unsigned DestReg, unsigned SrcReg,
6065312Smsmith                                  bool KillSrc) const {
6165312Smsmith  unsigned Opc = 0;
6265312Smsmith
6365312Smsmith  if (Mips::CPU16RegsRegClass.contains(DestReg) &&
6465312Smsmith      Mips::CPURegsRegClass.contains(SrcReg))
6565312Smsmith    Opc = Mips::MoveR3216;
6696615Sobrien  else if (Mips::CPURegsRegClass.contains(DestReg) &&
6796615Sobrien           Mips::CPU16RegsRegClass.contains(SrcReg))
6896615Sobrien    Opc = Mips::Move32R16;
6996615Sobrien  else if ((SrcReg == Mips::HI) &&
7065312Smsmith           (Mips::CPU16RegsRegClass.contains(DestReg)))
7165312Smsmith    Opc = Mips::Mfhi16, SrcReg = 0;
7265312Smsmith
7396554Sobrien  else if ((SrcReg == Mips::LO) &&
7496554Sobrien           (Mips::CPU16RegsRegClass.contains(DestReg)))
7596554Sobrien    Opc = Mips::Mflo16, SrcReg = 0;
7696554Sobrien
7765312Smsmith
7865312Smsmith  assert(Opc && "Cannot copy registers");
7965312Smsmith
8065312Smsmith  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
8196615Sobrien
8265312Smsmith  if (DestReg)
8365312Smsmith    MIB.addReg(DestReg, RegState::Define);
8496615Sobrien
8565312Smsmith  if (SrcReg)
8665312Smsmith    MIB.addReg(SrcReg, getKillRegState(KillSrc));
8765312Smsmith}
8896554Sobrien
8965312Smsmithvoid Mips16InstrInfo::
9065312SmsmithstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
9196554Sobrien                    unsigned SrcReg, bool isKill, int FI,
9265312Smsmith                    const TargetRegisterClass *RC,
9396554Sobrien                    const TargetRegisterInfo *TRI) const {
9465312Smsmith  DebugLoc DL;
9565312Smsmith  if (I != MBB.end()) DL = I->getDebugLoc();
9665312Smsmith  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
9765312Smsmith  unsigned Opc = 0;
9865312Smsmith  if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
9996615Sobrien    Opc = Mips::SwRxSpImmX16;
10065312Smsmith  assert(Opc && "Register class not handled!");
10165312Smsmith  BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
10296554Sobrien    .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
10365312Smsmith}
10465312Smsmith
10565312Smsmithvoid Mips16InstrInfo::
10665312SmsmithloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
10796615Sobrien                     unsigned DestReg, int FI,
10896615Sobrien                     const TargetRegisterClass *RC,
10965312Smsmith                     const TargetRegisterInfo *TRI) const {
11065312Smsmith  DebugLoc DL;
11165312Smsmith  if (I != MBB.end()) DL = I->getDebugLoc();
11296554Sobrien  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
11396554Sobrien  unsigned Opc = 0;
11496554Sobrien
11596554Sobrien  if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
11665312Smsmith    Opc = Mips::LwRxSpImmX16;
11765312Smsmith  assert(Opc && "Register class not handled!");
11865312Smsmith  BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(0)
11965312Smsmith    .addMemOperand(MMO);
12065312Smsmith}
12165312Smsmith
12265312Smsmithbool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
12365312Smsmith  MachineBasicBlock &MBB = *MI->getParent();
12465312Smsmith
12565312Smsmith  switch(MI->getDesc().getOpcode()) {
12696554Sobrien  default:
12765312Smsmith    return false;
12865312Smsmith  case Mips::RetRA16:
12965312Smsmith    ExpandRetRA16(MBB, MI, Mips::JrcRa16);
13065312Smsmith    break;
13165312Smsmith  }
13296615Sobrien
13396615Sobrien  MBB.erase(MI);
13496615Sobrien  return true;
13596615Sobrien}
13696615Sobrien
13796615Sobrien/// GetOppositeBranchOpc - Return the inverse of the specified
13896615Sobrien/// opcode, e.g. turning BEQ to BNE.
13996615Sobrienunsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const {
14096615Sobrien  switch (Opc) {
14196615Sobrien  default:  llvm_unreachable("Illegal opcode!");
14296615Sobrien  case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16;
14396615Sobrien  case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16;
14496615Sobrien  case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16;
14596615Sobrien  case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16;
14665312Smsmith  case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16;
14765312Smsmith  case Mips::BtnezX16: return Mips::BteqzX16;
14865312Smsmith  case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16;
14996615Sobrien  case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16;
15096615Sobrien  case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16;
15196615Sobrien  case Mips::BteqzX16: return Mips::BtnezX16;
15265312Smsmith  case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16;
15396615Sobrien  case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16;
15465312Smsmith  case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16;
15596615Sobrien  case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16;
15696615Sobrien  case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16;
15796615Sobrien  case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16;
15865312Smsmith  }
15996615Sobrien  assert(false && "Implement this function.");
16096615Sobrien  return 0;
16196615Sobrien}
16296615Sobrien
16365312Smsmith/// Adjust SP by Amount bytes.
16496615Sobrienvoid Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
16596615Sobrien                                     MachineBasicBlock &MBB,
16696615Sobrien                                     MachineBasicBlock::iterator I) const {
16796615Sobrien  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
16865312Smsmith  if (isInt<16>(Amount)) {
16996615Sobrien    if (Amount < 0)
17096615Sobrien      BuildMI(MBB, I, DL, get(Mips::SaveDecSpF16)). addImm(-Amount);
17196615Sobrien    else if (Amount > 0)
17265312Smsmith      BuildMI(MBB, I, DL, get(Mips::RestoreIncSpF16)).addImm(Amount);
17365312Smsmith  }
17465312Smsmith  else
17565312Smsmith    // not implemented for large values yet
17696554Sobrien    assert(false && "adjust stack pointer amount exceeded");
17796554Sobrien}
17896554Sobrien
17996554Sobrienunsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const {
18096554Sobrien  return (Opc == Mips::BeqzRxImmX16   || Opc == Mips::BimmX16  ||
18165312Smsmith          Opc == Mips::BnezRxImmX16   || Opc == Mips::BteqzX16 ||
18265312Smsmith          Opc == Mips::BteqzT8CmpX16  || Opc == Mips::BteqzT8CmpiX16 ||
18365312Smsmith          Opc == Mips::BteqzT8SltX16  || Opc == Mips::BteqzT8SltuX16  ||
18496615Sobrien          Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
18565312Smsmith          Opc == Mips::BtnezX16       || Opc == Mips::BtnezT8CmpX16 ||
18665312Smsmith          Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
18765312Smsmith          Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
18865312Smsmith          Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
18996554Sobrien}
19096554Sobrien
19196554Sobrienvoid Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB,
19296554Sobrien                                  MachineBasicBlock::iterator I,
19365312Smsmith                                  unsigned Opc) const {
19465312Smsmith  BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
19565312Smsmith}
19665312Smsmith
19765312Smsmithconst MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) {
198  return new Mips16InstrInfo(TM);
199}
200