10bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka//===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===// 20bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// 30bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// The LLVM Compiler Infrastructure 40bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// 50bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// This file is distributed under the University of Illinois Open Source 60bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// License. See LICENSE.TXT for details. 70bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// 80bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka//===----------------------------------------------------------------------===// 90bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// 100bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// This file contains the Mips16 implementation of the TargetInstrInfo class. 110bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka// 120bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka//===----------------------------------------------------------------------===// 130bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 140bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "Mips16InstrInfo.h" 150bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "InstPrinter/MipsInstPrinter.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsMachineFunction.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsTargetMachine.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h" 200bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "llvm/CodeGen/MachineInstrBuilder.h" 210bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "llvm/CodeGen/MachineRegisterInfo.h" 2261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler#include "llvm/CodeGen/RegisterScavenging.h" 23cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler#include "llvm/Support/CommandLine.h" 24da4afa72f7cbe2801f3876eda33416aa3ba42987Reed Kotler#include "llvm/Support/Debug.h" 250bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "llvm/Support/ErrorHandling.h" 260bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka#include "llvm/Support/TargetRegistry.h" 270bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 280bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakausing namespace llvm; 290bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 30cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotlerstatic cl::opt<bool> NeverUseSaveRestore( 31cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler "mips16-never-use-save-restore", 32cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler cl::init(false), 33e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter cl::desc("For testing ability to adjust stack pointer " 34e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter "without save/restore instruction"), 35cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler cl::Hidden); 36cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 37cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 380bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira HatanakaMips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) 3995a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler : MipsInstrInfo(tm, Mips::BimmX16), 409441125d636dee246acf9cb6c8f264edda92c335Reed Kotler RI(*tm.getSubtargetImpl(), *this) {} 418589010e3d1d5a902992a5039cffa9d4116982c5Akira Hatanaka 428589010e3d1d5a902992a5039cffa9d4116982c5Akira Hatanakaconst MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { 438589010e3d1d5a902992a5039cffa9d4116982c5Akira Hatanaka return RI; 448589010e3d1d5a902992a5039cffa9d4116982c5Akira Hatanaka} 450bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 460bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// isLoadFromStackSlot - If the specified machine instruction is a direct 470bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// load from a stack slot, return the virtual or physical register number of 480bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// the destination along with the FrameIndex of the loaded stack slot. If 490bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// not, return 0. This predicate must return 0 if the instruction has 500bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// any side effects other than loading from the stack slot. 510bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakaunsigned Mips16InstrInfo:: 520bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira HatanakaisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 530bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka{ 540bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka return 0; 550bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 560bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 570bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// isStoreToStackSlot - If the specified machine instruction is a direct 580bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// store to a stack slot, return the virtual or physical register number of 590bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// the source reg along with the FrameIndex of the loaded stack slot. If 600bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// not, return 0. This predicate must return 0 if the instruction has 610bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// any side effects other than storing to the stack slot. 620bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakaunsigned Mips16InstrInfo:: 630bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira HatanakaisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 640bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka{ 650bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka return 0; 660bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 670bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 680bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakavoid Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 690bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MachineBasicBlock::iterator I, DebugLoc DL, 700bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka unsigned DestReg, unsigned SrcReg, 710bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka bool KillSrc) const { 727d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler unsigned Opc = 0; 737d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler 747d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler if (Mips::CPU16RegsRegClass.contains(DestReg) && 757d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Mips::CPURegsRegClass.contains(SrcReg)) 767d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Opc = Mips::MoveR3216; 777d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler else if (Mips::CPURegsRegClass.contains(DestReg) && 787d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Mips::CPU16RegsRegClass.contains(SrcReg)) 797d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Opc = Mips::Move32R16; 807d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler else if ((SrcReg == Mips::HI) && 817d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler (Mips::CPU16RegsRegClass.contains(DestReg))) 827d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Opc = Mips::Mfhi16, SrcReg = 0; 837d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler 847d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler else if ((SrcReg == Mips::LO) && 857d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler (Mips::CPU16RegsRegClass.contains(DestReg))) 867d90d4d709b9053f7214203c34b8be9dbd311aceReed Kotler Opc = Mips::Mflo16, SrcReg = 0; 870bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 880bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 890bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka assert(Opc && "Cannot copy registers"); 900bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 910bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 920bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 930bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka if (DestReg) 940bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MIB.addReg(DestReg, RegState::Define); 950bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 960bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka if (SrcReg) 970bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MIB.addReg(SrcReg, getKillRegState(KillSrc)); 980bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 990bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 1000bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakavoid Mips16InstrInfo:: 1010bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira HatanakastoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1020bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka unsigned SrcReg, bool isKill, int FI, 1030bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka const TargetRegisterClass *RC, 1040bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka const TargetRegisterInfo *TRI) const { 105c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler DebugLoc DL; 106c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler if (I != MBB.end()) DL = I->getDebugLoc(); 107c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 108c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler unsigned Opc = 0; 109c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 110c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler Opc = Mips::SwRxSpImmX16; 111c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler assert(Opc && "Register class not handled!"); 112c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 113c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler .addFrameIndex(FI).addImm(0).addMemOperand(MMO); 1140bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 1150bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 1160bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakavoid Mips16InstrInfo:: 1170bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira HatanakaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1180bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka unsigned DestReg, int FI, 1190bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka const TargetRegisterClass *RC, 1200bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka const TargetRegisterInfo *TRI) const { 121c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler DebugLoc DL; 122c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler if (I != MBB.end()) DL = I->getDebugLoc(); 123c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 124c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler unsigned Opc = 0; 125c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler 126c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 127c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler Opc = Mips::LwRxSpImmX16; 128c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler assert(Opc && "Register class not handled!"); 129c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(0) 130c94a38ff1732b960a551c7c1a4c50ede5c4737b4Reed Kotler .addMemOperand(MMO); 1310bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 1320bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 1330bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakabool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 1340bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MachineBasicBlock &MBB = *MI->getParent(); 1350bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka switch(MI->getDesc().getOpcode()) { 1360bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka default: 1370bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka return false; 1380bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka case Mips::RetRA16: 139c09856b5357af621fcb84a7b2b6bfbf630c244efReed Kotler ExpandRetRA16(MBB, MI, Mips::JrcRa16); 1400bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka break; 1410bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka } 1420bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 1430bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MBB.erase(MI); 1440bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka return true; 1450bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 1460bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 1470bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// GetOppositeBranchOpc - Return the inverse of the specified 1480bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka/// opcode, e.g. turning BEQ to BNE. 1490bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakaunsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { 15095a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler switch (Opc) { 15195a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler default: llvm_unreachable("Illegal opcode!"); 15295a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; 15395a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; 15495a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; 15595a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; 15695a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; 15795a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezX16: return Mips::BteqzX16; 15895a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; 15995a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; 16095a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; 16195a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzX16: return Mips::BtnezX16; 16295a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; 16395a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; 16495a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; 16595a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; 16695a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; 16795a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; 16895a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler } 1690bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka assert(false && "Implement this function."); 1700bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka return 0; 1710bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 1720bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 173cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// Adjust SP by FrameSize bytes. Save RA, S0, S1 174e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Cartervoid Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, 175e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineBasicBlock &MBB, 176cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineBasicBlock::iterator I) const { 177cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 178cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (!NeverUseSaveRestore) { 179cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (isUInt<11>(FrameSize)) 180cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); 181cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else { 182e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter int Base = 2040; // should create template function like isUInt that 183e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter // returns largest possible n bit unsigned integer 184cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler int64_t Remainder = FrameSize - Base; 185cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base); 186cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (isInt<16>(-Remainder)) 1872de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler BuildAddiuSpImm(MBB, I, -Remainder); 188cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else 189cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); 190cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 191cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 192cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 193cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else { 194cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // 195cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // sw ra, -4[sp] 196cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // sw s1, -8[sp] 197cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // sw s0, -12[sp] 198cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 199e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 200e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::RA); 201cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB1.addReg(Mips::SP); 202cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB1.addImm(-4); 203e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 204e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::S1); 205cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB2.addReg(Mips::SP); 206cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB2.addImm(-8); 207e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 208e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::S0); 209cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addReg(Mips::SP); 210cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addImm(-12); 211cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1); 212cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 213cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler} 214cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 215cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// Adjust SP by FrameSize bytes. Restore RA, S0, S1 216e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Cartervoid Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, 217e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineBasicBlock &MBB, 218e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineBasicBlock::iterator I) const { 219cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 220cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (!NeverUseSaveRestore) { 221cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (isUInt<11>(FrameSize)) 222cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize); 223cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else { 224e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter int Base = 2040; // should create template function like isUInt that 225e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter // returns largest possible n bit unsigned integer 226cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler int64_t Remainder = FrameSize - Base; 227cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (isInt<16>(Remainder)) 2282de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler BuildAddiuSpImm(MBB, I, Remainder); 229cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else 230cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); 231cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base); 232cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 233cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 234cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler else { 235cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1); 236cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // lw ra, -4[sp] 237cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // lw s1, -8[sp] 238cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // lw s0, -12[sp] 239e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 240e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::A0); 241cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB1.addReg(Mips::SP); 242cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB1.addImm(-4); 243e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 244e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::RA); 245cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB0.addReg(Mips::A0); 246e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 247e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::S1); 248cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB2.addReg(Mips::SP); 249cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB2.addImm(-8); 250e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 251e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::S0); 252cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addReg(Mips::SP); 253cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addImm(-12); 254cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler } 255cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 256cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler} 257cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 258cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// Adjust SP by Amount bytes where bytes can be up to 32bit number. 259e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter// This can only be called at times that we know that there is at least one free 260e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter// register. 261cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// This is clearly safe at prologue and epilogue. 262cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// 263e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Cartervoid Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, 264e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineBasicBlock &MBB, 265cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineBasicBlock::iterator I, 266cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler unsigned Reg1, unsigned Reg2) const { 267cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 268cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 269cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 270cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler// unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 271cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // 272cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // li reg1, constant 273cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // move reg2, sp 274cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // add reg1, reg1, reg2 275cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // move sp, reg1 276cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // 277cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler // 278cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); 279cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB1.addImm(Amount); 280cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); 281cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB2.addReg(Mips::SP, RegState::Kill); 282cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); 283cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addReg(Reg1); 284cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB3.addReg(Reg2, RegState::Kill); 285e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 286e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter Mips::SP); 287cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MIB4.addReg(Reg1, RegState::Kill); 288cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler} 289cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 290e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Cartervoid Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount, 291e11dda8631f1e65417971ee0c2f7a661fc7d0fd7Jack Carter MachineBasicBlock &MBB, 292cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineBasicBlock::iterator I) const { 293cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler assert(false && "adjust stack pointer amount exceeded"); 294cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler} 295cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 2969441125d636dee246acf9cb6c8f264edda92c335Reed Kotler/// Adjust SP by Amount bytes. 2979441125d636dee246acf9cb6c8f264edda92c335Reed Kotlervoid Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 2989441125d636dee246acf9cb6c8f264edda92c335Reed Kotler MachineBasicBlock &MBB, 2999441125d636dee246acf9cb6c8f264edda92c335Reed Kotler MachineBasicBlock::iterator I) const { 300cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> 3012de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler BuildAddiuSpImm(MBB, I, Amount); 3029441125d636dee246acf9cb6c8f264edda92c335Reed Kotler else 303cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); 304cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler} 305cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 306cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler/// This function generates the sequence of instructions needed to get the 307cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler/// result of adding register REG and immediate IMM. 308cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotlerunsigned 30961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed KotlerMips16InstrInfo::loadImmediate(unsigned FrameReg, 31061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler int64_t Imm, MachineBasicBlock &MBB, 311cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler MachineBasicBlock::iterator II, DebugLoc DL, 31261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler unsigned &NewImm) const { 31361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 31461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // given original instruction is: 31561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // Instr rx, T[offset] where offset is too big. 31661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 31761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // lo = offset & 0xFFFF 31861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; 31961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 32061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // let T = temporary register 32161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // li T, hi 32261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // shl T, 16 32361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // add T, Rx, T 32461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 32561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler RegScavenger rs; 32661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler int32_t lo = Imm & 0xFFFF; 32761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler int32_t hi = ((Imm >> 16) + (lo >> 15)) & 0xFFFF; 32861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler NewImm = lo; 32961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler unsigned Reg =0; 33061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler unsigned SpReg = 0; 33161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler rs.enterBasicBlock(&MBB); 33261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler rs.forward(II); 33361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 33461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // we use T0 for the first register, if we need to save something away. 33561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // we use T1 for the second register, if we need to save something away. 33661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler // 33761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler unsigned FirstRegSaved =0, SecondRegSaved=0; 33861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; 33961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler 34061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler Reg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); 34161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (Reg == 0) { 34261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler FirstRegSaved = Reg = Mips::V0; 34361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler FirstRegSavedTo = Mips::T0; 34461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); 34561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 34661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler else 34761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler rs.setUsed(Reg); 34861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler BuildMI(MBB, II, DL, get(Mips::LiRxImmX16), Reg).addImm(hi); 34961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler BuildMI(MBB, II, DL, get(Mips::SllX16), Reg).addReg(Reg). 35061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler addImm(16); 35161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (FrameReg == Mips::SP) { 35261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler SpReg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); 35361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (SpReg == 0) { 35461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (Reg != Mips::V1) { 35561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler SecondRegSaved = SpReg = Mips::V1; 35661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler SecondRegSavedTo = Mips::T1; 35761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 35861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler else { 35961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler SecondRegSaved = SpReg = Mips::V0; 36061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler SecondRegSavedTo = Mips::T0; 36161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 36261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); 36361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 36461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler else 36561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler rs.setUsed(SpReg); 366cef95f702a5586781e5f812078a5c57f6f0e962bReed Kotler 36761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); 36861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg) 36961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler .addReg(Reg); 37061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 37161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler else 37261b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) 37361b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler .addReg(Reg, RegState::Kill); 37461b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (FirstRegSaved || SecondRegSaved) { 37561b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler II = llvm::next(II); 37661b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (FirstRegSaved) 37761b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); 37861b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler if (SecondRegSaved) 37961b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); 38061b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler } 38161b97b8c1721ba45e5c10ca307ceebe1efdf72a9Reed Kotler return Reg; 3829441125d636dee246acf9cb6c8f264edda92c335Reed Kotler} 3839441125d636dee246acf9cb6c8f264edda92c335Reed Kotler 3840bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakaunsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { 38595a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || 38695a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || 38795a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || 38895a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || 38995a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 || 39095a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 || 39195a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 || 39295a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 || 39395a2bb4cdf48fb927c1c7c640012118c455b6727Reed Kotler Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0; 3940bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 3950bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka 3960bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanakavoid Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, 3970bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka MachineBasicBlock::iterator I, 3980bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka unsigned Opc) const { 3990bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); 4000bc1adbbc4fdc6d85a671ed70a1bbd345dba445dAkira Hatanaka} 401af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka 40265692c809efa46337bf80f12b1795e785a6e7207Reed Kotler 4036a0da011e42e553d497fce2059f43401e854b99dReed Kotlerconst MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { 4046b9d4617800d9450825f8a4b122a9aeb76f2795fReed Kotler if (validSpImm8(Imm)) 4056a0da011e42e553d497fce2059f43401e854b99dReed Kotler return get(Mips::AddiuSpImm16); 4066b9d4617800d9450825f8a4b122a9aeb76f2795fReed Kotler else 4076a0da011e42e553d497fce2059f43401e854b99dReed Kotler return get(Mips::AddiuSpImmX16); 4086b9d4617800d9450825f8a4b122a9aeb76f2795fReed Kotler} 4096b9d4617800d9450825f8a4b122a9aeb76f2795fReed Kotler 4102de893210b0d4178edb4e3f2a965d57e97410341Reed Kotlervoid Mips16InstrInfo::BuildAddiuSpImm 4112de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { 4122de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 4132de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); 4142de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler} 4152de893210b0d4178edb4e3f2a965d57e97410341Reed Kotler 416af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanakaconst MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) { 417af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka return new Mips16InstrInfo(TM); 418af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka} 419