X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMips16InstrInfo.cpp;h=da8ada4e53917f793257ee94a942f5564d0c7b16;hb=16d4cc83c30485f28bb37715930c4302749d23b1;hp=ab1258a1638f8ddd5dce57770cb46107e2746ef2;hpb=bb01b3cb936f110fc20700b4c4447e3e7214cab3;p=oota-llvm.git diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index ab1258a1638..da8ada4e539 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -10,7 +10,6 @@ // This file contains the Mips16 implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// - #include "Mips16InstrInfo.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMachineFunction.h" @@ -20,24 +19,20 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" +#include using namespace llvm; -static cl::opt NeverUseSaveRestore( - "mips16-never-use-save-restore", - cl::init(false), - cl::desc("For testing ability to adjust stack pointer " - "without save/restore instruction"), - cl::Hidden); - +#define DEBUG_TYPE "mips16-instrinfo" -Mips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) - : MipsInstrInfo(tm, Mips::BimmX16), - RI(*tm.getSubtargetImpl(), *this) {} +Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI) + : MipsInstrInfo(STI, Mips::Bimm16), RI() {} const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { return RI; @@ -48,9 +43,8 @@ const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. -unsigned Mips16InstrInfo:: -isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ +unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } @@ -59,9 +53,8 @@ isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned Mips16InstrInfo:: -isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ +unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } @@ -72,16 +65,16 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, unsigned Opc = 0; if (Mips::CPU16RegsRegClass.contains(DestReg) && - Mips::CPURegsRegClass.contains(SrcReg)) + Mips::GPR32RegClass.contains(SrcReg)) Opc = Mips::MoveR3216; - else if (Mips::CPURegsRegClass.contains(DestReg) && + else if (Mips::GPR32RegClass.contains(DestReg) && Mips::CPU16RegsRegClass.contains(SrcReg)) Opc = Mips::Move32R16; - else if ((SrcReg == Mips::HI) && + else if ((SrcReg == Mips::HI0) && (Mips::CPU16RegsRegClass.contains(DestReg))) Opc = Mips::Mfhi16, SrcReg = 0; - else if ((SrcReg == Mips::LO) && + else if ((SrcReg == Mips::LO0) && (Mips::CPU16RegsRegClass.contains(DestReg))) Opc = Mips::Mflo16, SrcReg = 0; @@ -97,11 +90,12 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, MIB.addReg(SrcReg, getKillRegState(KillSrc)); } -void Mips16InstrInfo:: -storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, bool isKill, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { +void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned SrcReg, bool isKill, int FI, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI, + int64_t Offset) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); @@ -109,15 +103,17 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) Opc = Mips::SwRxSpImmX16; assert(Opc && "Register class not handled!"); - BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addImm(0).addMemOperand(MMO); + BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). + addFrameIndex(FI).addImm(Offset) + .addMemOperand(MMO); } -void Mips16InstrInfo:: -loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { +void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, int FI, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI, + int64_t Offset) const { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); @@ -126,38 +122,15 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) Opc = Mips::LwRxSpImmX16; assert(Opc && "Register class not handled!"); - BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(0) + BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) .addMemOperand(MMO); } bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { MachineBasicBlock &MBB = *MI->getParent(); - switch(MI->getDesc().getOpcode()) { default: return false; - case Mips::BteqzT8CmpX16: - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BteqzX16, Mips::CmpRxRy16); - break; - case Mips::BteqzT8SltX16: - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BteqzX16, Mips::SltRxRy16); - break; - case Mips::BteqzT8SltuX16: - // TBD: figure out a way to get this or remove the instruction - // altogether. - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BteqzX16, Mips::SltuRxRy16); - break; - case Mips::BtnezT8CmpX16: - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BtnezX16, Mips::CmpRxRy16); - break; - case Mips::BtnezT8SltX16: - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BtnezX16, Mips::SltRxRy16); - break; - case Mips::BtnezT8SltuX16: - // TBD: figure out a way to get this or remove the instruction - // altogether. - ExpandFEXT_T8I816_ins(MBB, MI, Mips::BtnezX16, Mips::SltuRxRy16); - break; case Mips::RetRA16: ExpandRetRA16(MBB, MI, Mips::JrcRa16); break; @@ -169,18 +142,21 @@ bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { /// GetOppositeBranchOpc - Return the inverse of the specified /// opcode, e.g. turning BEQ to BNE. -unsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { +unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { switch (Opc) { - default: llvm_unreachable("Illegal opcode!"); case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; + case Mips::BeqzRxImm16: return Mips::BnezRxImm16; + case Mips::BnezRxImm16: return Mips::BeqzRxImm16; case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; + case Mips::Btnez16: return Mips::Bteqz16; case Mips::BtnezX16: return Mips::BteqzX16; case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; + case Mips::Bteqz16: return Mips::Btnez16; case Mips::BteqzX16: return Mips::BtnezX16; case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; @@ -189,49 +165,60 @@ unsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; } - assert(false && "Implement this function."); - return 0; + llvm_unreachable("Illegal opcode!"); } -// Adjust SP by FrameSize bytes. Save RA, S0, S1 -void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); - if (!NeverUseSaveRestore) { - if (isUInt<11>(FrameSize)) - BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); - else { - int Base = 2040; // should create template function like isUInt that - // returns largest possible n bit unsigned integer - int64_t Remainder = FrameSize - Base; - BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base); - if (isInt<16>(-Remainder)) - BuildAddiuSpImm(MBB, I, -Remainder); - else - adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); - } +static void addSaveRestoreRegs(MachineInstrBuilder &MIB, + const std::vector &CSI, + unsigned Flags = 0) { + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + // Add the callee-saved register as live-in. Do not add if the register is + // RA and return address is taken, because it has already been added in + // method MipsTargetLowering::LowerRETURNADDR. + // It's killed at the spill, unless the register is RA and return address + // is taken. + unsigned Reg = CSI[e-i-1].getReg(); + switch (Reg) { + case Mips::RA: + case Mips::S0: + case Mips::S1: + MIB.addReg(Reg, Flags); + break; + case Mips::S2: + break; + default: + llvm_unreachable("unexpected mips16 callee saved register"); + } } +} +// Adjust SP by FrameSize bytes. Save RA, S0, S1 +void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + DebugLoc DL; + MachineFunction &MF = *MBB.getParent(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const BitVector Reserved = RI.getReservedRegs(MF); + bool SaveS2 = Reserved[Mips::S2]; + MachineInstrBuilder MIB; + unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16; + MIB = BuildMI(MBB, I, DL, get(Opc)); + const std::vector &CSI = MFI->getCalleeSavedInfo(); + addSaveRestoreRegs(MIB, CSI); + if (SaveS2) + MIB.addReg(Mips::S2); + if (isUInt<11>(FrameSize)) + MIB.addImm(FrameSize); else { - // - // sw ra, -4[sp] - // sw s1, -8[sp] - // sw s0, -12[sp] - - MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), - Mips::RA); - MIB1.addReg(Mips::SP); - MIB1.addImm(-4); - MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), - Mips::S1); - MIB2.addReg(Mips::SP); - MIB2.addImm(-8); - MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16), - Mips::S0); - MIB3.addReg(Mips::SP); - MIB3.addImm(-12); - adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1); + int Base = 2040; // should create template function like isUInt that + // returns largest possible n bit unsigned integer + int64_t Remainder = FrameSize - Base; + MIB.addImm(Base); + if (isInt<16>(-Remainder)) + BuildAddiuSpImm(MBB, I, -Remainder); + else + adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); } } @@ -240,42 +227,31 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); - if (!NeverUseSaveRestore) { - if (isUInt<11>(FrameSize)) - BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize); - else { - int Base = 2040; // should create template function like isUInt that - // returns largest possible n bit unsigned integer - int64_t Remainder = FrameSize - Base; - if (isInt<16>(Remainder)) - BuildAddiuSpImm(MBB, I, Remainder); - else - adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); - BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base); - } - } - else { - adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1); - // lw ra, -4[sp] - // lw s1, -8[sp] - // lw s0, -12[sp] - MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), - Mips::A0); - MIB1.addReg(Mips::SP); - MIB1.addImm(-4); - MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16), - Mips::RA); - MIB0.addReg(Mips::A0); - MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), - Mips::S1); - MIB2.addReg(Mips::SP); - MIB2.addImm(-8); - MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16), - Mips::S0); - MIB3.addReg(Mips::SP); - MIB3.addImm(-12); + MachineFunction *MF = MBB.getParent(); + MachineFrameInfo *MFI = MF->getFrameInfo(); + const BitVector Reserved = RI.getReservedRegs(*MF); + bool SaveS2 = Reserved[Mips::S2]; + MachineInstrBuilder MIB; + unsigned Opc = ((FrameSize <= 128) && !SaveS2)? + Mips::Restore16:Mips::RestoreX16; + + if (!isUInt<11>(FrameSize)) { + unsigned Base = 2040; + int64_t Remainder = FrameSize - Base; + FrameSize = Base; // should create template function like isUInt that + // returns largest possible n bit unsigned integer + + if (isInt<16>(Remainder)) + BuildAddiuSpImm(MBB, I, Remainder); + else + adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); } - + MIB = BuildMI(MBB, I, DL, get(Opc)); + const std::vector &CSI = MFI->getCalleeSavedInfo(); + addSaveRestoreRegs(MIB, CSI, RegState::Define); + if (SaveS2) + MIB.addReg(Mips::S2, RegState::Define); + MIB.addImm(FrameSize); } // Adjust SP by Amount bytes where bytes can be up to 32bit number. @@ -287,10 +263,7 @@ void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Reg1, unsigned Reg2) const { - DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); -// MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); -// unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); -// unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass); + DebugLoc DL; // // li reg1, constant // move reg2, sp @@ -299,7 +272,7 @@ void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, // // MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); - MIB1.addImm(Amount); + MIB1.addImm(Amount).addImm(-1); MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); MIB2.addReg(Mips::SP, RegState::Kill); MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); @@ -310,16 +283,19 @@ void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, MIB4.addReg(Reg1, RegState::Kill); } -void Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - assert(false && "adjust stack pointer amount exceeded"); +void Mips16InstrInfo::adjustStackPtrBigUnrestricted( + unsigned SP, int64_t Amount, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + llvm_unreachable("adjust stack pointer amount exceeded"); } /// Adjust SP by Amount bytes. void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { + if (Amount == 0) + return; + if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> BuildAddiuSpImm(MBB, I, Amount); else @@ -328,11 +304,10 @@ void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, /// This function generates the sequence of instructions needed to get the /// result of adding register REG and immediate IMM. -unsigned -Mips16InstrInfo::loadImmediate(unsigned FrameReg, - int64_t Imm, MachineBasicBlock &MBB, - MachineBasicBlock::iterator II, DebugLoc DL, - unsigned &NewImm) const { +unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, + DebugLoc DL, unsigned &NewImm) const { // // given original instruction is: // Instr rx, T[offset] where offset is too big. @@ -347,55 +322,92 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg, // RegScavenger rs; int32_t lo = Imm & 0xFFFF; - int32_t hi = ((Imm >> 16) + (lo >> 15)) & 0xFFFF; NewImm = lo; - unsigned Reg =0; - unsigned SpReg = 0; + int Reg =0; + int SpReg = 0; + rs.enterBasicBlock(&MBB); rs.forward(II); // + // We need to know which registers can be used, in the case where there + // are not enough free registers. We exclude all registers that + // are used in the instruction that we are helping. + // // Consider all allocatable registers in the register class initially + BitVector Candidates = + RI.getAllocatableSet + (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); + // Exclude all the registers being used by the instruction. + for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { + MachineOperand &MO = II->getOperand(i); + if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && + !TargetRegisterInfo::isVirtualRegister(MO.getReg())) + Candidates.reset(MO.getReg()); + } + + // If the same register was used and defined in an instruction, then + // it will not be in the list of candidates. + // + // we need to analyze the instruction that we are helping. + // we need to know if it defines register x but register x is not + // present as an operand of the instruction. this tells + // whether the register is live before the instruction. if it's not + // then we don't need to save it in case there are no free registers. + int DefReg = 0; + for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { + MachineOperand &MO = II->getOperand(i); + if (MO.isReg() && MO.isDef()) { + DefReg = MO.getReg(); + break; + } + } + + BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); + Available &= Candidates; + // // we use T0 for the first register, if we need to save something away. // we use T1 for the second register, if we need to save something away. // unsigned FirstRegSaved =0, SecondRegSaved=0; unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; - Reg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); - if (Reg == 0) { - FirstRegSaved = Reg = Mips::V0; - FirstRegSavedTo = Mips::T0; - copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); + Reg = Available.find_first(); + + if (Reg == -1) { + Reg = Candidates.find_first(); + Candidates.reset(Reg); + if (DefReg != Reg) { + FirstRegSaved = Reg; + FirstRegSavedTo = Mips::T0; + copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); + } } else - rs.setUsed(Reg); - BuildMI(MBB, II, DL, get(Mips::LiRxImmX16), Reg).addImm(hi); - BuildMI(MBB, II, DL, get(Mips::SllX16), Reg).addReg(Reg). - addImm(16); + Available.reset(Reg); + BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1); + NewImm = 0; if (FrameReg == Mips::SP) { - SpReg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass); - if (SpReg == 0) { - if (Reg != Mips::V1) { - SecondRegSaved = SpReg = Mips::V1; + SpReg = Available.find_first(); + if (SpReg == -1) { + SpReg = Candidates.find_first(); + // Candidates.reset(SpReg); // not really needed + if (DefReg!= SpReg) { + SecondRegSaved = SpReg; SecondRegSavedTo = Mips::T1; } - else { - SecondRegSaved = SpReg = Mips::V0; - SecondRegSavedTo = Mips::T0; - } - copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); + if (SecondRegSaved) + copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); } - else - rs.setUsed(SpReg); - + else + Available.reset(SpReg); copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); - BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg) + BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) .addReg(Reg); } else BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) .addReg(Reg, RegState::Kill); if (FirstRegSaved || SecondRegSaved) { - II = llvm::next(II); + II = std::next(II); if (FirstRegSaved) copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); if (SecondRegSaved) @@ -404,8 +416,11 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg, return Reg; } -unsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { +unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || + Opc == Mips::Bimm16 || + Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 || + Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 || Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || @@ -422,17 +437,6 @@ void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); } - -void Mips16InstrInfo::ExpandFEXT_T8I816_ins( - MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned BtOpc, unsigned CmpOpc) const { - unsigned regX = I->getOperand(0).getReg(); - unsigned regY = I->getOperand(1).getReg(); - MachineBasicBlock *target = I->getOperand(2).getMBB(); - BuildMI(MBB, I, I->getDebugLoc(), get(CmpOpc)).addReg(regX).addReg(regY); - BuildMI(MBB, I, I->getDebugLoc(), get(BtOpc)).addMBB(target); - -} const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { if (validSpImm8(Imm)) return get(Mips::AddiuSpImm16); @@ -442,10 +446,75 @@ const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { void Mips16InstrInfo::BuildAddiuSpImm (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { - DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); + DebugLoc DL; BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); } -const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) { - return new Mips16InstrInfo(TM); +const MipsInstrInfo *llvm::createMips16InstrInfo(const MipsSubtarget &STI) { + return new Mips16InstrInfo(STI); +} + +bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, + int64_t Amount) { + switch (Opcode) { + case Mips::LbRxRyOffMemX16: + case Mips::LbuRxRyOffMemX16: + case Mips::LhRxRyOffMemX16: + case Mips::LhuRxRyOffMemX16: + case Mips::SbRxRyOffMemX16: + case Mips::ShRxRyOffMemX16: + case Mips::LwRxRyOffMemX16: + case Mips::SwRxRyOffMemX16: + case Mips::SwRxSpImmX16: + case Mips::LwRxSpImmX16: + return isInt<16>(Amount); + case Mips::AddiuRxRyOffMemX16: + if ((Reg == Mips::PC) || (Reg == Mips::SP)) + return isInt<16>(Amount); + return isInt<15>(Amount); + } + llvm_unreachable("unexpected Opcode in validImmediate"); +} + +/// Measure the specified inline asm to determine an approximation of its +/// length. +/// Comments (which run till the next SeparatorString or newline) do not +/// count as an instruction. +/// Any other non-whitespace text is considered an instruction, with +/// multiple instructions separated by SeparatorString or newlines. +/// Variable-length instructions are not handled here; this function +/// may be overloaded in the target code to do that. +/// We implement the special case of the .space directive taking only an +/// integer argument, which is the size in bytes. This is used for creating +/// inline code spacing for testing purposes using inline assembly. +/// +unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str, + const MCAsmInfo &MAI) const { + + // Count the number of instructions in the asm. + bool atInsnStart = true; + unsigned Length = 0; + for (; *Str; ++Str) { + if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), + strlen(MAI.getSeparatorString())) == 0) + atInsnStart = true; + if (atInsnStart && !std::isspace(static_cast(*Str))) { + if (strncmp(Str, ".space", 6)==0) { + char *EStr; int Sz; + Sz = strtol(Str+6, &EStr, 10); + while (isspace(*EStr)) ++EStr; + if (*EStr=='\0') { + DEBUG(dbgs() << "parsed .space " << Sz << '\n'); + return Sz; + } + } + Length += MAI.getMaxInstLength(); + atInsnStart = false; + } + if (atInsnStart && strncmp(Str, MAI.getCommentString(), + strlen(MAI.getCommentString())) == 0) + atInsnStart = false; + } + + return Length; }