32 "mips16-never-use-save-restore",
34 cl::desc(
"For testing ability to adjust stack pointer "
35 "without save/restore instruction"),
41 RI(*tm.getSubtargetImpl()) {}
71 unsigned DestReg,
unsigned SrcReg,
75 if (Mips::CPU16RegsRegClass.contains(DestReg) &&
76 Mips::GPR32RegClass.contains(SrcReg))
77 Opc = Mips::MoveR3216;
78 else if (Mips::GPR32RegClass.contains(DestReg) &&
79 Mips::CPU16RegsRegClass.contains(SrcReg))
80 Opc = Mips::Move32R16;
81 else if ((SrcReg == Mips::HI0) &&
82 (Mips::CPU16RegsRegClass.contains(DestReg)))
83 Opc = Mips::Mfhi16, SrcReg = 0;
85 else if ((SrcReg == Mips::LO0) &&
86 (Mips::CPU16RegsRegClass.contains(DestReg)))
87 Opc = Mips::Mflo16, SrcReg = 0;
90 assert(Opc &&
"Cannot copy registers");
103 unsigned SrcReg,
bool isKill,
int FI,
105 int64_t Offset)
const {
107 if (I != MBB.
end()) DL = I->getDebugLoc();
110 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
111 Opc = Mips::SwRxSpImmX16;
112 assert(Opc &&
"Register class not handled!");
114 addFrameIndex(FI).
addImm(Offset)
123 if (I != MBB.
end()) DL = I->getDebugLoc();
127 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
128 Opc = Mips::LwRxSpImmX16;
129 assert(Opc &&
"Register class not handled!");
136 switch(MI->getDesc().getOpcode()) {
140 ExpandRetRA16(MBB, MI, Mips::JrcRa16);
153 case Mips::BeqzRxImmX16:
return Mips::BnezRxImmX16;
154 case Mips::BnezRxImmX16:
return Mips::BeqzRxImmX16;
155 case Mips::BeqzRxImm16:
return Mips::BnezRxImm16;
156 case Mips::BnezRxImm16:
return Mips::BeqzRxImm16;
157 case Mips::BteqzT8CmpX16:
return Mips::BtnezT8CmpX16;
158 case Mips::BteqzT8SltX16:
return Mips::BtnezT8SltX16;
159 case Mips::BteqzT8SltiX16:
return Mips::BtnezT8SltiX16;
160 case Mips::Btnez16:
return Mips::Bteqz16;
161 case Mips::BtnezX16:
return Mips::BteqzX16;
162 case Mips::BtnezT8CmpiX16:
return Mips::BteqzT8CmpiX16;
163 case Mips::BtnezT8SltuX16:
return Mips::BteqzT8SltuX16;
164 case Mips::BtnezT8SltiuX16:
return Mips::BteqzT8SltiuX16;
165 case Mips::Bteqz16:
return Mips::Btnez16;
166 case Mips::BteqzX16:
return Mips::BtnezX16;
167 case Mips::BteqzT8CmpiX16:
return Mips::BtnezT8CmpiX16;
168 case Mips::BteqzT8SltuX16:
return Mips::BtnezT8SltuX16;
169 case Mips::BteqzT8SltiuX16:
return Mips::BtnezT8SltiuX16;
170 case Mips::BtnezT8CmpX16:
return Mips::BteqzT8CmpX16;
171 case Mips::BtnezT8SltX16:
return Mips::BteqzT8SltX16;
172 case Mips::BtnezT8SltiX16:
return Mips::BteqzT8SltiX16;
174 assert(
false &&
"Implement this function.");
184 if (isUInt<11>(FrameSize))
189 int64_t Remainder = FrameSize - Base;
190 BuildMI(MBB, I, DL,
get(Mips::SaveRaF16)). addImm(Base);
194 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
216 adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1);
226 if (isUInt<11>(FrameSize))
227 BuildMI(MBB, I, DL,
get(Mips::RestoreRaF16)).
addImm(FrameSize);
231 int64_t Remainder = FrameSize - Base;
235 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
236 BuildMI(MBB, I, DL,
get(Mips::RestoreRaF16)). addImm(Base);
240 adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1);
268 void Mips16InstrInfo::adjustStackPtrBig(
unsigned SP, int64_t Amount,
271 unsigned Reg1,
unsigned Reg2)
const {
295 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
unsigned SP, int64_t Amount,
298 assert(
false &&
"adjust stack pointer amount exceeded");
308 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
317 unsigned &NewImm)
const {
331 int32_t lo = Imm & 0xFFFF;
345 (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
347 for (
unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
364 for (
unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
374 Available &= Candidates;
379 unsigned FirstRegSaved =0, SecondRegSaved=0;
380 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
387 Candidates.
reset(Reg);
390 FirstRegSavedTo = Mips::T0;
391 copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved,
true);
395 Available.
reset(Reg);
396 BuildMI(MBB, II, DL,
get(Mips::LwConstant32), Reg).
addImm(Imm);
398 if (FrameReg == Mips::SP) {
403 if (DefReg!= SpReg) {
404 SecondRegSaved = SpReg;
408 copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved,
true);
411 Available.
reset(SpReg);
417 BuildMI(MBB, II, DL,
get(Mips:: AdduRxRyRz16), Reg).
addReg(FrameReg)
419 if (FirstRegSaved || SecondRegSaved) {
422 copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo,
true);
424 copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo,
true);
436 unsigned &NewImm)
const {
440 BuildMI(MBB, II, DL,
get(Mips::LwConstant32), Reg).
addImm(Imm);
445 unsigned Mips16InstrInfo::getAnalyzableBrOpc(
unsigned Opc)
const {
446 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 ||
447 Opc == Mips::Bimm16 ||
448 Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 ||
449 Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 ||
450 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 ||
451 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 ||
452 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 ||
453 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
454 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 ||
455 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
456 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
457 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
462 unsigned Opc)
const {
463 BuildMI(MBB, I, I->getDebugLoc(),
get(Opc));
469 return get(Mips::AddiuSpImm16);
471 return get(Mips::AddiuSpImmX16);
487 case Mips::LbRxRyOffMemX16:
488 case Mips::LbuRxRyOffMemX16:
489 case Mips::LhRxRyOffMemX16:
490 case Mips::LhuRxRyOffMemX16:
491 case Mips::SbRxRyOffMemX16:
492 case Mips::ShRxRyOffMemX16:
493 case Mips::LwRxRyOffMemX16:
494 case Mips::SwRxRyOffMemX16:
495 case Mips::SwRxSpImmX16:
496 case Mips::LwRxSpImmX16:
498 case Mips::AddiuRxRyOffMemX16:
499 if ((Reg == Mips::PC) || (Reg == Mips::SP))
501 return isInt<15>(Amount);
523 bool atInsnStart =
true;
525 for (; *Str; ++Str) {
529 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
530 if (
strncmp(Str,
".space", 6)==0) {
532 Sz =
strtol(Str+6, &EStr, 10);
533 while (isspace(*EStr)) ++EStr;
535 DEBUG(
dbgs() <<
"parsed .space " << Sz <<
'\n');
const MachineFunction * getParent() const
The memory access reads data.
static cl::opt< bool > NeverUseSaveRestore("mips16-never-use-save-restore", cl::init(false), cl::desc("For testing ability to adjust stack pointer ""without save/restore instruction"), cl::Hidden)
instr_iterator erase(instr_iterator I)
The memory access writes data.
const MipsInstrInfo * createMips16InstrInfo(MipsTargetMachine &TM)
Create MipsInstrInfo objects.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
long int strtol(const char *nptr, char **endptr, int base);
void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
static bool isVirtualRegister(unsigned Reg)
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
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
virtual unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount)
const MachineInstrBuilder & addImm(int64_t Val) const
void forward()
forward - Move the internal MBB iterator and update register states.
virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const
unsigned basicLoadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, DebugLoc DL, unsigned &NewImm) const
BitVector getRegsAvailable(const TargetRegisterClass *RC)
void BuildAddiuSpImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const
void enterBasicBlock(MachineBasicBlock *mbb)
unsigned getKillRegState(bool B)
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
virtual void loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset) const
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const
ItTy next(ItTy it, Dist n)
virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
virtual unsigned getOppositeBranchOpc(unsigned Opc) const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
static bool validSpImm8(int offset)
const MachineInstrBuilder & addFrameIndex(int Idx) const
size_t strlen(const char *s);
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
virtual const MipsRegisterInfo & getRegisterInfo() const
Mips16InstrInfo(MipsTargetMachine &TM)
MachineRegisterInfo & getRegInfo()
const char * getSeparatorString() const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isInt< 16 >(int64_t x)
unsigned getReg() const
getReg - Returns the register number.
virtual void storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset) const
unsigned getMaxInstLength() const
int strncmp(const char *s1, const char *s2, size_t n);
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, unsigned Flag) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
const char * getCommentString() const