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