32 #define DEBUG_TYPE "mips16-instrinfo"
63 unsigned DestReg,
unsigned SrcReg,
67 if (Mips::CPU16RegsRegClass.
contains(DestReg) &&
68 Mips::GPR32RegClass.
contains(SrcReg))
69 Opc = Mips::MoveR3216;
70 else if (Mips::GPR32RegClass.
contains(DestReg) &&
71 Mips::CPU16RegsRegClass.
contains(SrcReg))
72 Opc = Mips::Move32R16;
73 else if ((SrcReg == Mips::HI0) &&
74 (Mips::CPU16RegsRegClass.
contains(DestReg)))
75 Opc = Mips::Mfhi16, SrcReg = 0;
77 else if ((SrcReg == Mips::LO0) &&
78 (Mips::CPU16RegsRegClass.
contains(DestReg)))
79 Opc = Mips::Mflo16, SrcReg = 0;
82 assert(Opc &&
"Cannot copy registers");
95 unsigned SrcReg,
bool isKill,
int FI,
98 int64_t Offset)
const {
100 if (I != MBB.
end()) DL = I->getDebugLoc();
103 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
104 Opc = Mips::SwRxSpImmX16;
105 assert(Opc &&
"Register class not handled!");
107 addFrameIndex(FI).
addImm(Offset)
113 unsigned DestReg,
int FI,
116 int64_t Offset)
const {
118 if (I != MBB.
end()) DL = I->getDebugLoc();
122 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
123 Opc = Mips::LwRxSpImmX16;
124 assert(Opc &&
"Register class not handled!");
131 switch(MI->getDesc().getOpcode()) {
135 ExpandRetRA16(MBB, MI, Mips::JrcRa16);
147 case Mips::BeqzRxImmX16:
return Mips::BnezRxImmX16;
148 case Mips::BnezRxImmX16:
return Mips::BeqzRxImmX16;
149 case Mips::BeqzRxImm16:
return Mips::BnezRxImm16;
150 case Mips::BnezRxImm16:
return Mips::BeqzRxImm16;
151 case Mips::BteqzT8CmpX16:
return Mips::BtnezT8CmpX16;
152 case Mips::BteqzT8SltX16:
return Mips::BtnezT8SltX16;
153 case Mips::BteqzT8SltiX16:
return Mips::BtnezT8SltiX16;
154 case Mips::Btnez16:
return Mips::Bteqz16;
155 case Mips::BtnezX16:
return Mips::BteqzX16;
156 case Mips::BtnezT8CmpiX16:
return Mips::BteqzT8CmpiX16;
157 case Mips::BtnezT8SltuX16:
return Mips::BteqzT8SltuX16;
158 case Mips::BtnezT8SltiuX16:
return Mips::BteqzT8SltiuX16;
159 case Mips::Bteqz16:
return Mips::Btnez16;
160 case Mips::BteqzX16:
return Mips::BtnezX16;
161 case Mips::BteqzT8CmpiX16:
return Mips::BtnezT8CmpiX16;
162 case Mips::BteqzT8SltuX16:
return Mips::BtnezT8SltuX16;
163 case Mips::BteqzT8SltiuX16:
return Mips::BtnezT8SltiuX16;
164 case Mips::BtnezT8CmpX16:
return Mips::BteqzT8CmpX16;
165 case Mips::BtnezT8SltX16:
return Mips::BteqzT8SltX16;
166 case Mips::BtnezT8SltiX16:
return Mips::BteqzT8SltiX16;
172 const std::vector<CalleeSavedInfo> &CSI,
173 unsigned Flags = 0) {
174 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
180 unsigned Reg = CSI[e-i-1].getReg();
203 bool SaveS2 = Reserved[Mips::S2];
205 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16;
206 MIB =
BuildMI(MBB, I, DL,
get(Opc));
211 if (isUInt<11>(FrameSize))
216 int64_t Remainder = FrameSize - Base;
221 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
233 bool SaveS2 = Reserved[Mips::S2];
235 unsigned Opc = ((FrameSize <= 128) && !SaveS2)?
236 Mips::Restore16:Mips::RestoreX16;
238 if (!isUInt<11>(FrameSize)) {
239 unsigned Base = 2040;
240 int64_t Remainder = FrameSize - Base;
247 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
249 MIB =
BuildMI(MBB, I, DL,
get(Opc));
262 void Mips16InstrInfo::adjustStackPtrBig(
unsigned SP, int64_t Amount,
265 unsigned Reg1,
unsigned Reg2)
const {
286 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
302 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
310 DebugLoc DL,
unsigned &NewImm)
const {
324 int32_t lo = Imm & 0xFFFF;
338 (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
340 for (
unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
356 for (
unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
365 Available &= Candidates;
370 unsigned FirstRegSaved =0, SecondRegSaved=0;
371 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
377 Candidates.
reset(Reg);
380 FirstRegSavedTo = Mips::T0;
381 copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved,
true);
385 Available.
reset(Reg);
388 if (FrameReg == Mips::SP) {
393 if (DefReg!= SpReg) {
394 SecondRegSaved = SpReg;
398 copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved,
true);
401 Available.
reset(SpReg);
407 BuildMI(MBB, II, DL,
get(Mips:: AdduRxRyRz16), Reg).
addReg(FrameReg)
409 if (FirstRegSaved || SecondRegSaved) {
412 copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo,
true);
414 copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo,
true);
419 unsigned Mips16InstrInfo::getAnalyzableBrOpc(
unsigned Opc)
const {
420 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 ||
421 Opc == Mips::Bimm16 ||
422 Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 ||
423 Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 ||
424 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 ||
425 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 ||
426 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 ||
427 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
428 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 ||
429 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
430 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
431 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
436 unsigned Opc)
const {
437 BuildMI(MBB, I, I->getDebugLoc(),
get(Opc));
442 return get(Mips::AddiuSpImm16);
444 return get(Mips::AddiuSpImmX16);
460 case Mips::LbRxRyOffMemX16:
461 case Mips::LbuRxRyOffMemX16:
462 case Mips::LhRxRyOffMemX16:
463 case Mips::LhuRxRyOffMemX16:
464 case Mips::SbRxRyOffMemX16:
465 case Mips::ShRxRyOffMemX16:
466 case Mips::LwRxRyOffMemX16:
467 case Mips::SwRxRyOffMemX16:
468 case Mips::SwRxSpImmX16:
469 case Mips::LwRxSpImmX16:
471 case Mips::AddiuRxRyOffMemX16:
472 if ((Reg == Mips::PC) || (Reg == Mips::SP))
474 return isInt<15>(Amount);
495 bool atInsnStart =
true;
497 for (; *Str; ++Str) {
501 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
502 if (strncmp(Str,
".space", 6)==0) {
504 Sz = strtol(Str+6, &EStr, 10);
505 while (isspace(*EStr)) ++EStr;
507 DEBUG(
dbgs() <<
"parsed .space " << Sz <<
'\n');
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
The memory access reads data.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
The memory access writes data.
Describe properties that are true of each instruction in the target description file.
void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
unsigned loadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, DebugLoc DL, unsigned &NewImm) const
Emit a series of instructions to load an immediate.
const MCInstrDesc & AddiuSpImm(int64_t Imm) const
static void addSaveRestoreRegs(MachineInstrBuilder &MIB, const std::vector< CalleeSavedInfo > &CSI, unsigned Flags=0)
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
MachineMemOperand - A description of a memory reference used in the backend.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot...
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
void forward()
Move the internal MBB iterator and update register states.
BitVector getRegsAvailable(const TargetRegisterClass *RC)
Return all available registers in the register class in Mask.
void BuildAddiuSpImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const
BitVector getReservedRegs(const MachineFunction &MF) const override
void enterBasicBlock(MachineBasicBlock *mbb)
Start tracking liveness from the begin of the specific basic block.
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
Adjust SP by Amount bytes.
unsigned getKillRegState(bool B)
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
This class is intended to be used as a base class for asm properties and features specific to the tar...
bundle_iterator< MachineInstr, instr_iterator > iterator
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool validSpImm8(int offset)
const MipsRegisterInfo & getRegisterInfo() const override
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const override
Measure the specified inline asm to determine an approximation of its length.
MachineOperand class - Representation of each machine instruction operand.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineInstrBuilder & addFrameIndex(int Idx) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Representation of each machine instruction.
void loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset) const override
const char * getSeparatorString() const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isInt< 16 >(int64_t x)
Mips16InstrInfo(const MipsSubtarget &STI)
unsigned getReg() const
getReg - Returns the register number.
unsigned getMaxInstLength() const
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, unsigned Flag) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
const char * getCommentString() const
void storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset) const override
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot...
unsigned getOppositeBranchOpc(unsigned Opc) const override
GetOppositeBranchOpc - Return the inverse of the specified opcode, e.g.