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#include "Mips16InstrInfo.h" 14249423Sdim#include "InstPrinter/MipsInstPrinter.h" 15249423Sdim#include "MipsMachineFunction.h" 16239310Sdim#include "MipsTargetMachine.h" 17249423Sdim#include "llvm/ADT/STLExtras.h" 18249423Sdim#include "llvm/ADT/StringRef.h" 19239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 20239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 21249423Sdim#include "llvm/CodeGen/RegisterScavenging.h" 22263508Sdim#include "llvm/MC/MCAsmInfo.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" 27263508Sdim#include <cctype> 28239310Sdim 29239310Sdimusing namespace llvm; 30239310Sdim 31249423Sdimstatic cl::opt<bool> NeverUseSaveRestore( 32249423Sdim "mips16-never-use-save-restore", 33249423Sdim cl::init(false), 34249423Sdim cl::desc("For testing ability to adjust stack pointer " 35249423Sdim "without save/restore instruction"), 36249423Sdim cl::Hidden); 37249423Sdim 38249423Sdim 39239310SdimMips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) 40263508Sdim : MipsInstrInfo(tm, Mips::Bimm16), 41263508Sdim RI(*tm.getSubtargetImpl()) {} 42239310Sdim 43239310Sdimconst MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { 44239310Sdim return RI; 45239310Sdim} 46239310Sdim 47239310Sdim/// isLoadFromStackSlot - If the specified machine instruction is a direct 48239310Sdim/// load from a stack slot, return the virtual or physical register number of 49239310Sdim/// the destination along with the FrameIndex of the loaded stack slot. If 50239310Sdim/// not, return 0. This predicate must return 0 if the instruction has 51239310Sdim/// any side effects other than loading from the stack slot. 52239310Sdimunsigned Mips16InstrInfo:: 53239310SdimisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 54239310Sdim{ 55239310Sdim return 0; 56239310Sdim} 57239310Sdim 58239310Sdim/// isStoreToStackSlot - If the specified machine instruction is a direct 59239310Sdim/// store to a stack slot, return the virtual or physical register number of 60239310Sdim/// the source reg along with the FrameIndex of the loaded stack slot. If 61239310Sdim/// not, return 0. This predicate must return 0 if the instruction has 62239310Sdim/// any side effects other than storing to the stack slot. 63239310Sdimunsigned Mips16InstrInfo:: 64239310SdimisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 65239310Sdim{ 66239310Sdim return 0; 67239310Sdim} 68239310Sdim 69239310Sdimvoid Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 70239310Sdim MachineBasicBlock::iterator I, DebugLoc DL, 71239310Sdim unsigned DestReg, unsigned SrcReg, 72239310Sdim bool KillSrc) const { 73243830Sdim unsigned Opc = 0; 74239310Sdim 75243830Sdim if (Mips::CPU16RegsRegClass.contains(DestReg) && 76263508Sdim Mips::GPR32RegClass.contains(SrcReg)) 77243830Sdim Opc = Mips::MoveR3216; 78263508Sdim else if (Mips::GPR32RegClass.contains(DestReg) && 79243830Sdim Mips::CPU16RegsRegClass.contains(SrcReg)) 80243830Sdim Opc = Mips::Move32R16; 81263508Sdim else if ((SrcReg == Mips::HI0) && 82243830Sdim (Mips::CPU16RegsRegClass.contains(DestReg))) 83243830Sdim Opc = Mips::Mfhi16, SrcReg = 0; 84239310Sdim 85263508Sdim else if ((SrcReg == Mips::LO0) && 86243830Sdim (Mips::CPU16RegsRegClass.contains(DestReg))) 87243830Sdim Opc = Mips::Mflo16, SrcReg = 0; 88243830Sdim 89243830Sdim 90239310Sdim assert(Opc && "Cannot copy registers"); 91239310Sdim 92239310Sdim MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 93239310Sdim 94239310Sdim if (DestReg) 95239310Sdim MIB.addReg(DestReg, RegState::Define); 96239310Sdim 97239310Sdim if (SrcReg) 98239310Sdim MIB.addReg(SrcReg, getKillRegState(KillSrc)); 99239310Sdim} 100239310Sdim 101239310Sdimvoid Mips16InstrInfo:: 102249423SdimstoreRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 103249423Sdim unsigned SrcReg, bool isKill, int FI, 104249423Sdim const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, 105249423Sdim int64_t Offset) const { 106243830Sdim DebugLoc DL; 107243830Sdim if (I != MBB.end()) DL = I->getDebugLoc(); 108243830Sdim MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 109243830Sdim unsigned Opc = 0; 110243830Sdim if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 111243830Sdim Opc = Mips::SwRxSpImmX16; 112243830Sdim assert(Opc && "Register class not handled!"); 113263508Sdim BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). 114263508Sdim addFrameIndex(FI).addImm(Offset) 115263508Sdim .addMemOperand(MMO); 116239310Sdim} 117239310Sdim 118239310Sdimvoid Mips16InstrInfo:: 119249423SdimloadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 120249423Sdim unsigned DestReg, int FI, const TargetRegisterClass *RC, 121249423Sdim const TargetRegisterInfo *TRI, int64_t Offset) const { 122243830Sdim DebugLoc DL; 123243830Sdim if (I != MBB.end()) DL = I->getDebugLoc(); 124243830Sdim MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 125243830Sdim unsigned Opc = 0; 126243830Sdim 127243830Sdim if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 128243830Sdim Opc = Mips::LwRxSpImmX16; 129243830Sdim assert(Opc && "Register class not handled!"); 130249423Sdim BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) 131243830Sdim .addMemOperand(MMO); 132239310Sdim} 133239310Sdim 134239310Sdimbool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 135239310Sdim MachineBasicBlock &MBB = *MI->getParent(); 136239310Sdim switch(MI->getDesc().getOpcode()) { 137239310Sdim default: 138239310Sdim return false; 139239310Sdim case Mips::RetRA16: 140243830Sdim ExpandRetRA16(MBB, MI, Mips::JrcRa16); 141239310Sdim break; 142239310Sdim } 143239310Sdim 144239310Sdim MBB.erase(MI); 145239310Sdim return true; 146239310Sdim} 147239310Sdim 148239310Sdim/// GetOppositeBranchOpc - Return the inverse of the specified 149239310Sdim/// opcode, e.g. turning BEQ to BNE. 150263508Sdimunsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { 151243830Sdim switch (Opc) { 152243830Sdim default: llvm_unreachable("Illegal opcode!"); 153243830Sdim case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; 154243830Sdim case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; 155263508Sdim case Mips::BeqzRxImm16: return Mips::BnezRxImm16; 156263508Sdim case Mips::BnezRxImm16: return Mips::BeqzRxImm16; 157243830Sdim case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; 158243830Sdim case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; 159243830Sdim case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; 160263508Sdim case Mips::Btnez16: return Mips::Bteqz16; 161243830Sdim case Mips::BtnezX16: return Mips::BteqzX16; 162243830Sdim case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; 163243830Sdim case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; 164243830Sdim case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; 165263508Sdim case Mips::Bteqz16: return Mips::Btnez16; 166243830Sdim case Mips::BteqzX16: return Mips::BtnezX16; 167243830Sdim case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; 168243830Sdim case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; 169243830Sdim case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; 170243830Sdim case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; 171243830Sdim case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; 172243830Sdim case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; 173243830Sdim } 174239310Sdim assert(false && "Implement this function."); 175239310Sdim return 0; 176239310Sdim} 177239310Sdim 178249423Sdim// Adjust SP by FrameSize bytes. Save RA, S0, S1 179249423Sdimvoid Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, 180249423Sdim MachineBasicBlock &MBB, 181249423Sdim MachineBasicBlock::iterator I) const { 182249423Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 183249423Sdim if (!NeverUseSaveRestore) { 184249423Sdim if (isUInt<11>(FrameSize)) 185249423Sdim BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); 186249423Sdim else { 187249423Sdim int Base = 2040; // should create template function like isUInt that 188249423Sdim // returns largest possible n bit unsigned integer 189249423Sdim int64_t Remainder = FrameSize - Base; 190249423Sdim BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base); 191249423Sdim if (isInt<16>(-Remainder)) 192249423Sdim BuildAddiuSpImm(MBB, I, -Remainder); 193249423Sdim else 194249423Sdim adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); 195249423Sdim } 196249423Sdim 197249423Sdim } 198249423Sdim else { 199249423Sdim // 200249423Sdim // sw ra, -4[sp] 201249423Sdim // sw s1, -8[sp] 202249423Sdim // sw s0, -12[sp] 203249423Sdim 204249423Sdim MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 205249423Sdim Mips::RA); 206249423Sdim MIB1.addReg(Mips::SP); 207249423Sdim MIB1.addImm(-4); 208249423Sdim MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 209249423Sdim Mips::S1); 210249423Sdim MIB2.addReg(Mips::SP); 211249423Sdim MIB2.addImm(-8); 212249423Sdim MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), 213249423Sdim Mips::S0); 214249423Sdim MIB3.addReg(Mips::SP); 215249423Sdim MIB3.addImm(-12); 216249423Sdim adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1); 217249423Sdim } 218249423Sdim} 219249423Sdim 220249423Sdim// Adjust SP by FrameSize bytes. Restore RA, S0, S1 221249423Sdimvoid Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, 222249423Sdim MachineBasicBlock &MBB, 223249423Sdim MachineBasicBlock::iterator I) const { 224249423Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 225249423Sdim if (!NeverUseSaveRestore) { 226249423Sdim if (isUInt<11>(FrameSize)) 227249423Sdim BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize); 228249423Sdim else { 229249423Sdim int Base = 2040; // should create template function like isUInt that 230249423Sdim // returns largest possible n bit unsigned integer 231249423Sdim int64_t Remainder = FrameSize - Base; 232249423Sdim if (isInt<16>(Remainder)) 233249423Sdim BuildAddiuSpImm(MBB, I, Remainder); 234249423Sdim else 235249423Sdim adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); 236249423Sdim BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base); 237249423Sdim } 238249423Sdim } 239249423Sdim else { 240249423Sdim adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1); 241249423Sdim // lw ra, -4[sp] 242249423Sdim // lw s1, -8[sp] 243249423Sdim // lw s0, -12[sp] 244249423Sdim MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 245249423Sdim Mips::A0); 246249423Sdim MIB1.addReg(Mips::SP); 247249423Sdim MIB1.addImm(-4); 248249423Sdim MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 249249423Sdim Mips::RA); 250249423Sdim MIB0.addReg(Mips::A0); 251249423Sdim MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 252249423Sdim Mips::S1); 253249423Sdim MIB2.addReg(Mips::SP); 254249423Sdim MIB2.addImm(-8); 255249423Sdim MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), 256249423Sdim Mips::S0); 257249423Sdim MIB3.addReg(Mips::SP); 258249423Sdim MIB3.addImm(-12); 259249423Sdim } 260249423Sdim 261249423Sdim} 262249423Sdim 263249423Sdim// Adjust SP by Amount bytes where bytes can be up to 32bit number. 264249423Sdim// This can only be called at times that we know that there is at least one free 265249423Sdim// register. 266249423Sdim// This is clearly safe at prologue and epilogue. 267249423Sdim// 268249423Sdimvoid Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, 269249423Sdim MachineBasicBlock &MBB, 270249423Sdim MachineBasicBlock::iterator I, 271249423Sdim unsigned Reg1, unsigned Reg2) const { 272249423Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 273249423Sdim// MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 274249423Sdim// unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 275249423Sdim// unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); 276249423Sdim // 277249423Sdim // li reg1, constant 278249423Sdim // move reg2, sp 279249423Sdim // add reg1, reg1, reg2 280249423Sdim // move sp, reg1 281249423Sdim // 282249423Sdim // 283249423Sdim MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); 284249423Sdim MIB1.addImm(Amount); 285249423Sdim MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); 286249423Sdim MIB2.addReg(Mips::SP, RegState::Kill); 287249423Sdim MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); 288249423Sdim MIB3.addReg(Reg1); 289249423Sdim MIB3.addReg(Reg2, RegState::Kill); 290249423Sdim MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 291249423Sdim Mips::SP); 292249423Sdim MIB4.addReg(Reg1, RegState::Kill); 293249423Sdim} 294249423Sdim 295249423Sdimvoid Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount, 296249423Sdim MachineBasicBlock &MBB, 297249423Sdim MachineBasicBlock::iterator I) const { 298249423Sdim assert(false && "adjust stack pointer amount exceeded"); 299249423Sdim} 300249423Sdim 301243830Sdim/// Adjust SP by Amount bytes. 302243830Sdimvoid Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 303243830Sdim MachineBasicBlock &MBB, 304243830Sdim MachineBasicBlock::iterator I) const { 305249423Sdim if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> 306249423Sdim BuildAddiuSpImm(MBB, I, Amount); 307249423Sdim else 308249423Sdim adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); 309249423Sdim} 310249423Sdim 311249423Sdim/// This function generates the sequence of instructions needed to get the 312249423Sdim/// result of adding register REG and immediate IMM. 313249423Sdimunsigned 314249423SdimMips16InstrInfo::loadImmediate(unsigned FrameReg, 315249423Sdim int64_t Imm, MachineBasicBlock &MBB, 316249423Sdim MachineBasicBlock::iterator II, DebugLoc DL, 317249423Sdim unsigned &NewImm) const { 318249423Sdim // 319249423Sdim // given original instruction is: 320249423Sdim // Instr rx, T[offset] where offset is too big. 321249423Sdim // 322249423Sdim // lo = offset & 0xFFFF 323249423Sdim // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; 324249423Sdim // 325249423Sdim // let T = temporary register 326249423Sdim // li T, hi 327249423Sdim // shl T, 16 328249423Sdim // add T, Rx, T 329249423Sdim // 330249423Sdim RegScavenger rs; 331249423Sdim int32_t lo = Imm & 0xFFFF; 332249423Sdim NewImm = lo; 333263508Sdim int Reg =0; 334263508Sdim int SpReg = 0; 335263508Sdim 336249423Sdim rs.enterBasicBlock(&MBB); 337249423Sdim rs.forward(II); 338249423Sdim // 339263508Sdim // We need to know which registers can be used, in the case where there 340263508Sdim // are not enough free registers. We exclude all registers that 341263508Sdim // are used in the instruction that we are helping. 342263508Sdim // // Consider all allocatable registers in the register class initially 343263508Sdim BitVector Candidates = 344263508Sdim RI.getAllocatableSet 345263508Sdim (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); 346263508Sdim // Exclude all the registers being used by the instruction. 347263508Sdim for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 348263508Sdim MachineOperand &MO = II->getOperand(i); 349263508Sdim if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && 350263508Sdim !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 351263508Sdim Candidates.reset(MO.getReg()); 352263508Sdim } 353263508Sdim // 354263508Sdim // If the same register was used and defined in an instruction, then 355263508Sdim // it will not be in the list of candidates. 356263508Sdim // 357263508Sdim // we need to analyze the instruction that we are helping. 358263508Sdim // we need to know if it defines register x but register x is not 359263508Sdim // present as an operand of the instruction. this tells 360263508Sdim // whether the register is live before the instruction. if it's not 361263508Sdim // then we don't need to save it in case there are no free registers. 362263508Sdim // 363263508Sdim int DefReg = 0; 364263508Sdim for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 365263508Sdim MachineOperand &MO = II->getOperand(i); 366263508Sdim if (MO.isReg() && MO.isDef()) { 367263508Sdim DefReg = MO.getReg(); 368263508Sdim break; 369263508Sdim } 370263508Sdim } 371263508Sdim // 372263508Sdim BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); 373263508Sdim 374263508Sdim Available &= Candidates; 375263508Sdim // 376249423Sdim // we use T0 for the first register, if we need to save something away. 377249423Sdim // we use T1 for the second register, if we need to save something away. 378249423Sdim // 379249423Sdim unsigned FirstRegSaved =0, SecondRegSaved=0; 380249423Sdim unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; 381249423Sdim 382263508Sdim 383263508Sdim Reg = Available.find_first(); 384263508Sdim 385263508Sdim if (Reg == -1) { 386263508Sdim Reg = Candidates.find_first(); 387263508Sdim Candidates.reset(Reg); 388263508Sdim if (DefReg != Reg) { 389263508Sdim FirstRegSaved = Reg; 390263508Sdim FirstRegSavedTo = Mips::T0; 391263508Sdim copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); 392263508Sdim } 393243830Sdim } 394243830Sdim else 395263508Sdim Available.reset(Reg); 396263508Sdim BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm); 397263508Sdim NewImm = 0; 398249423Sdim if (FrameReg == Mips::SP) { 399263508Sdim SpReg = Available.find_first(); 400263508Sdim if (SpReg == -1) { 401263508Sdim SpReg = Candidates.find_first(); 402263508Sdim // Candidates.reset(SpReg); // not really needed 403263508Sdim if (DefReg!= SpReg) { 404263508Sdim SecondRegSaved = SpReg; 405249423Sdim SecondRegSavedTo = Mips::T1; 406249423Sdim } 407263508Sdim if (SecondRegSaved) 408263508Sdim copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); 409249423Sdim } 410263508Sdim else 411263508Sdim Available.reset(SpReg); 412249423Sdim copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); 413263508Sdim BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) 414249423Sdim .addReg(Reg); 415249423Sdim } 416249423Sdim else 417249423Sdim BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) 418249423Sdim .addReg(Reg, RegState::Kill); 419249423Sdim if (FirstRegSaved || SecondRegSaved) { 420249423Sdim II = llvm::next(II); 421249423Sdim if (FirstRegSaved) 422249423Sdim copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); 423249423Sdim if (SecondRegSaved) 424249423Sdim copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); 425249423Sdim } 426249423Sdim return Reg; 427243830Sdim} 428243830Sdim 429263508Sdim/// This function generates the sequence of instructions needed to get the 430263508Sdim/// result of adding register REG and immediate IMM. 431263508Sdimunsigned 432263508SdimMips16InstrInfo::basicLoadImmediate( 433263508Sdim unsigned FrameReg, 434263508Sdim int64_t Imm, MachineBasicBlock &MBB, 435263508Sdim MachineBasicBlock::iterator II, DebugLoc DL, 436263508Sdim unsigned &NewImm) const { 437263508Sdim const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass; 438263508Sdim MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 439263508Sdim unsigned Reg = RegInfo.createVirtualRegister(RC); 440263508Sdim BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm); 441263508Sdim NewImm = 0; 442263508Sdim return Reg; 443263508Sdim} 444263508Sdim 445263508Sdimunsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { 446243830Sdim return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || 447263508Sdim Opc == Mips::Bimm16 || 448263508Sdim Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 || 449263508Sdim Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 || 450243830Sdim Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || 451243830Sdim Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || 452243830Sdim Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || 453243830Sdim Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 || 454243830Sdim Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 || 455243830Sdim Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 || 456243830Sdim Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 || 457243830Sdim Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0; 458239310Sdim} 459239310Sdim 460239310Sdimvoid Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, 461239310Sdim MachineBasicBlock::iterator I, 462239310Sdim unsigned Opc) const { 463239310Sdim BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); 464239310Sdim} 465239310Sdim 466249423Sdim 467249423Sdimconst MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { 468249423Sdim if (validSpImm8(Imm)) 469249423Sdim return get(Mips::AddiuSpImm16); 470249423Sdim else 471249423Sdim return get(Mips::AddiuSpImmX16); 472249423Sdim} 473249423Sdim 474249423Sdimvoid Mips16InstrInfo::BuildAddiuSpImm 475249423Sdim (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { 476249423Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 477249423Sdim BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); 478249423Sdim} 479249423Sdim 480239310Sdimconst MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) { 481239310Sdim return new Mips16InstrInfo(TM); 482239310Sdim} 483263508Sdim 484263508Sdimbool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, 485263508Sdim int64_t Amount) { 486263508Sdim switch (Opcode) { 487263508Sdim case Mips::LbRxRyOffMemX16: 488263508Sdim case Mips::LbuRxRyOffMemX16: 489263508Sdim case Mips::LhRxRyOffMemX16: 490263508Sdim case Mips::LhuRxRyOffMemX16: 491263508Sdim case Mips::SbRxRyOffMemX16: 492263508Sdim case Mips::ShRxRyOffMemX16: 493263508Sdim case Mips::LwRxRyOffMemX16: 494263508Sdim case Mips::SwRxRyOffMemX16: 495263508Sdim case Mips::SwRxSpImmX16: 496263508Sdim case Mips::LwRxSpImmX16: 497263508Sdim return isInt<16>(Amount); 498263508Sdim case Mips::AddiuRxRyOffMemX16: 499263508Sdim if ((Reg == Mips::PC) || (Reg == Mips::SP)) 500263508Sdim return isInt<16>(Amount); 501263508Sdim return isInt<15>(Amount); 502263508Sdim } 503263508Sdim llvm_unreachable("unexpected Opcode in validImmediate"); 504263508Sdim} 505263508Sdim 506263508Sdim/// Measure the specified inline asm to determine an approximation of its 507263508Sdim/// length. 508263508Sdim/// Comments (which run till the next SeparatorString or newline) do not 509263508Sdim/// count as an instruction. 510263508Sdim/// Any other non-whitespace text is considered an instruction, with 511263508Sdim/// multiple instructions separated by SeparatorString or newlines. 512263508Sdim/// Variable-length instructions are not handled here; this function 513263508Sdim/// may be overloaded in the target code to do that. 514263508Sdim/// We implement the special case of the .space directive taking only an 515263508Sdim/// integer argument, which is the size in bytes. This is used for creating 516263508Sdim/// inline code spacing for testing purposes using inline assembly. 517263508Sdim/// 518263508Sdimunsigned Mips16InstrInfo::getInlineAsmLength(const char *Str, 519263508Sdim const MCAsmInfo &MAI) const { 520263508Sdim 521263508Sdim 522263508Sdim // Count the number of instructions in the asm. 523263508Sdim bool atInsnStart = true; 524263508Sdim unsigned Length = 0; 525263508Sdim for (; *Str; ++Str) { 526263508Sdim if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), 527263508Sdim strlen(MAI.getSeparatorString())) == 0) 528263508Sdim atInsnStart = true; 529263508Sdim if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { 530263508Sdim if (strncmp(Str, ".space", 6)==0) { 531263508Sdim char *EStr; int Sz; 532263508Sdim Sz = strtol(Str+6, &EStr, 10); 533263508Sdim while (isspace(*EStr)) ++EStr; 534263508Sdim if (*EStr=='\0') { 535263508Sdim DEBUG(dbgs() << "parsed .space " << Sz << '\n'); 536263508Sdim return Sz; 537263508Sdim } 538263508Sdim } 539263508Sdim Length += MAI.getMaxInstLength(); 540263508Sdim atInsnStart = false; 541263508Sdim } 542263508Sdim if (atInsnStart && strncmp(Str, MAI.getCommentString(), 543263508Sdim strlen(MAI.getCommentString())) == 0) 544263508Sdim atInsnStart = false; 545263508Sdim } 546263508Sdim 547263508Sdim return Length; 548263508Sdim} 549