37#define DEBUG_TYPE "mips16-instrinfo"
52 int &FrameIndex)
const {
62 int &FrameIndex)
const {
70 bool RenamableDest,
bool RenamableSrc)
const {
73 if (Mips::CPU16RegsRegClass.
contains(DestReg) &&
74 Mips::GPR32RegClass.
contains(SrcReg))
75 Opc = Mips::MoveR3216;
76 else if (Mips::GPR32RegClass.
contains(DestReg) &&
77 Mips::CPU16RegsRegClass.
contains(SrcReg))
78 Opc = Mips::Move32R16;
79 else if ((SrcReg == Mips::HI0) &&
80 (Mips::CPU16RegsRegClass.
contains(DestReg)))
81 Opc = Mips::Mfhi16, SrcReg = 0;
82 else if ((SrcReg == Mips::LO0) &&
83 (Mips::CPU16RegsRegClass.
contains(DestReg)))
84 Opc = Mips::Mflo16, SrcReg = 0;
86 assert(Opc &&
"Cannot copy registers");
97std::optional<DestSourcePair>
106 Register SrcReg,
bool isKill,
int FI,
115 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
116 Opc = Mips::SwRxSpImmX16;
117 assert(Opc &&
"Register class not handled!");
132 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
133 Opc = Mips::LwRxSpImmX16;
134 assert(Opc &&
"Register class not handled!");
141 switch (
MI.getDesc().getOpcode()) {
145 ExpandRetRA16(
MBB,
MI, Mips::JrcRa16);
157 case Mips::BeqzRxImmX16:
return Mips::BnezRxImmX16;
158 case Mips::BnezRxImmX16:
return Mips::BeqzRxImmX16;
159 case Mips::BeqzRxImm16:
return Mips::BnezRxImm16;
160 case Mips::BnezRxImm16:
return Mips::BeqzRxImm16;
161 case Mips::BteqzT8CmpX16:
return Mips::BtnezT8CmpX16;
162 case Mips::BteqzT8SltX16:
return Mips::BtnezT8SltX16;
163 case Mips::BteqzT8SltiX16:
return Mips::BtnezT8SltiX16;
164 case Mips::Btnez16:
return Mips::Bteqz16;
165 case Mips::BtnezX16:
return Mips::BteqzX16;
166 case Mips::BtnezT8CmpiX16:
return Mips::BteqzT8CmpiX16;
167 case Mips::BtnezT8SltuX16:
return Mips::BteqzT8SltuX16;
168 case Mips::BtnezT8SltiuX16:
return Mips::BteqzT8SltiuX16;
169 case Mips::Bteqz16:
return Mips::Btnez16;
170 case Mips::BteqzX16:
return Mips::BtnezX16;
171 case Mips::BteqzT8CmpiX16:
return Mips::BtnezT8CmpiX16;
172 case Mips::BteqzT8SltuX16:
return Mips::BtnezT8SltuX16;
173 case Mips::BteqzT8SltiuX16:
return Mips::BtnezT8SltiuX16;
174 case Mips::BtnezT8CmpX16:
return Mips::BteqzT8CmpX16;
175 case Mips::BtnezT8SltX16:
return Mips::BteqzT8SltX16;
176 case Mips::BtnezT8SltiX16:
return Mips::BteqzT8SltiX16;
183 unsigned Flags = 0) {
184 for (
unsigned i = 0, e = CSI.
size(); i != e; ++i) {
216 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16;
222 if (isUInt<11>(FrameSize))
227 int64_t Remainder = FrameSize -
Base;
229 if (isInt<16>(-Remainder))
232 adjustStackPtrBig(SP, -Remainder,
MBB,
I, Mips::V0, Mips::V1);
246 unsigned Opc = ((FrameSize <= 128) && !SaveS2)?
247 Mips::Restore16:Mips::RestoreX16;
249 if (!isUInt<11>(FrameSize)) {
250 unsigned Base = 2040;
251 int64_t Remainder = FrameSize -
Base;
255 if (isInt<16>(Remainder))
258 adjustStackPtrBig(SP, Remainder,
MBB,
I, Mips::A0, Mips::A1);
272void Mips16InstrInfo::adjustStackPtrBig(
unsigned SP, int64_t Amount,
275 unsigned Reg1,
unsigned Reg2)
const {
296void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
309 if (isInt<16>(Amount))
312 adjustStackPtrBigUnrestricted(SP, Amount,
MBB,
I);
321 unsigned &NewImm)
const {
335 int32_t lo = Imm & 0xFFFF;
349 (*
II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
352 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
353 !MO.getReg().isVirtual())
354 Candidates.
reset(MO.getReg());
367 if (MO.isReg() && MO.isDef()) {
368 DefReg = MO.getReg();
379 unsigned FirstRegSaved =0, SecondRegSaved=0;
380 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
386 Candidates.
reset(Reg);
389 FirstRegSavedTo = Mips::T0;
397 if (FrameReg == Mips::SP) {
402 if (DefReg!= SpReg) {
403 SecondRegSaved = SpReg;
404 SecondRegSavedTo = Mips::T1;
419 if (FirstRegSaved || SecondRegSaved) {
429unsigned Mips16InstrInfo::getAnalyzableBrOpc(
unsigned Opc)
const {
430 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 ||
431 Opc == Mips::Bimm16 ||
432 Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 ||
433 Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 ||
434 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 ||
435 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 ||
436 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 ||
437 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
438 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 ||
439 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
440 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
441 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
446 unsigned Opc)
const {
452 return get(Mips::AddiuSpImm16);
454 return get(Mips::AddiuSpImmX16);
470 case Mips::LbRxRyOffMemX16:
471 case Mips::LbuRxRyOffMemX16:
472 case Mips::LhRxRyOffMemX16:
473 case Mips::LhuRxRyOffMemX16:
474 case Mips::SbRxRyOffMemX16:
475 case Mips::ShRxRyOffMemX16:
476 case Mips::LwRxRyOffMemX16:
477 case Mips::SwRxRyOffMemX16:
478 case Mips::SwRxSpImmX16:
479 case Mips::LwRxSpImmX16:
480 return isInt<16>(Amount);
481 case Mips::AddiuRxRyOffMemX16:
482 if ((Reg == Mips::PC) || (Reg == Mips::SP))
483 return isInt<16>(Amount);
484 return isInt<15>(Amount);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
@ Available
We know the block is fully available. This is a fixpoint.
unsigned const TargetRegisterInfo * TRI
static void addSaveRestoreRegs(MachineInstrBuilder &MIB, ArrayRef< CalleeSavedInfo > CSI, unsigned Flags=0)
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
bool expandPostRAPseudo(MachineInstr &MI) const override
static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount)
const MCInstrDesc & AddiuSpImm(int64_t Imm) const
void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
void BuildAddiuSpImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const
unsigned getOppositeBranchOpc(unsigned Opc) const override
GetOppositeBranchOpc - Return the inverse of the specified opcode, e.g.
void storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
If the specific machine instruction is a instruction that moves/copies value from one register to ano...
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
static bool validSpImm8(int offset)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
void loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Mips16InstrInfo(const MipsSubtarget &STI)
unsigned loadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, unsigned &NewImm) const
Emit a series of instructions to load an immediate.
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
Adjust SP by Amount bytes.
const MipsRegisterInfo & getRegisterInfo() const override
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, MachineMemOperand::Flags Flags) const
BitVector getReservedRegs(const MachineFunction &MF) const override
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void backward()
Update internal register state and move MBB iterator backwards.
BitVector getRegsAvailable(const TargetRegisterClass *RC)
Return all available registers in the register class in Mask.
Wrapper class representing virtual and physical registers.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.