1//===- Mips16InstrInfo.cpp - Mips16 Instruction Information ---------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file contains the Mips16 implementation of the TargetInstrInfo class. 11//===----------------------------------------------------------------------===// 37#define DEBUG_TYPE "mips16-instrinfo" 46/// isLoadFromStackSlot - If the specified machine instruction is a direct 47/// load from a stack slot, return the virtual or physical register number of 48/// the destination along with the FrameIndex of the loaded stack slot. If 49/// not, return 0. This predicate must return 0 if the instruction has 50/// any side effects other than loading from the stack slot. 52int &FrameIndex)
const{
56/// isStoreToStackSlot - If the specified machine instruction is a direct 57/// store to a stack slot, return the virtual or physical register number of 58/// the source reg along with the FrameIndex of the loaded stack slot. If 59/// not, return 0. This predicate must return 0 if the instruction has 60/// any side effects other than storing to the stack slot. 62int &FrameIndex)
const{
70bool RenamableDest,
bool RenamableSrc)
const{
73if (Mips::CPU16RegsRegClass.
contains(DestReg) &&
74 Mips::GPR32RegClass.
contains(SrcReg))
75 Opc = Mips::MoveR3216;
76elseif (Mips::GPR32RegClass.
contains(DestReg) &&
77 Mips::CPU16RegsRegClass.
contains(SrcReg))
78 Opc = Mips::Move32R16;
79elseif ((SrcReg == Mips::HI0) &&
80 (Mips::CPU16RegsRegClass.
contains(DestReg)))
81 Opc = Mips::Mfhi16, SrcReg = 0;
82elseif ((SrcReg == Mips::LO0) &&
83 (Mips::CPU16RegsRegClass.
contains(DestReg)))
84 Opc = Mips::Mflo16, SrcReg = 0;
86assert(Opc &&
"Cannot copy registers");
97std::optional<DestSourcePair>
115if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
116 Opc = Mips::SwRxSpImmX16;
117assert(Opc &&
"Register class not handled!");
132if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
133 Opc = Mips::LwRxSpImmX16;
134assert(Opc &&
"Register class not handled!");
141switch (
MI.getDesc().getOpcode()) {
145 ExpandRetRA16(
MBB,
MI, Mips::JrcRa16);
153/// GetOppositeBranchOpc - Return the inverse of the specified 154/// opcode, e.g. turning BEQ to BNE. 157case Mips::BeqzRxImmX16:
return Mips::BnezRxImmX16;
158case Mips::BnezRxImmX16:
return Mips::BeqzRxImmX16;
159case Mips::BeqzRxImm16:
return Mips::BnezRxImm16;
160case Mips::BnezRxImm16:
return Mips::BeqzRxImm16;
161case Mips::BteqzT8CmpX16:
return Mips::BtnezT8CmpX16;
162case Mips::BteqzT8SltX16:
return Mips::BtnezT8SltX16;
163case Mips::BteqzT8SltiX16:
return Mips::BtnezT8SltiX16;
164case Mips::Btnez16:
return Mips::Bteqz16;
165case Mips::BtnezX16:
return Mips::BteqzX16;
166case Mips::BtnezT8CmpiX16:
return Mips::BteqzT8CmpiX16;
167case Mips::BtnezT8SltuX16:
return Mips::BteqzT8SltuX16;
168case Mips::BtnezT8SltiuX16:
return Mips::BteqzT8SltiuX16;
169case Mips::Bteqz16:
return Mips::Btnez16;
170case Mips::BteqzX16:
return Mips::BtnezX16;
171case Mips::BteqzT8CmpiX16:
return Mips::BtnezT8CmpiX16;
172case Mips::BteqzT8SltuX16:
return Mips::BtnezT8SltuX16;
173case Mips::BteqzT8SltiuX16:
return Mips::BtnezT8SltiuX16;
174case Mips::BtnezT8CmpX16:
return Mips::BteqzT8CmpX16;
175case Mips::BtnezT8SltX16:
return Mips::BteqzT8SltX16;
176case Mips::BtnezT8SltiX16:
return Mips::BteqzT8SltiX16;
184for (
unsigned i = 0, e = CSI.
size(); i != e; ++i) {
185// Add the callee-saved register as live-in. Do not add if the register is 186// RA and return address is taken, because it has already been added in 187// method MipsTargetLowering::lowerRETURNADDR. 188// It's killed at the spill, unless the register is RA and return address 206// Adjust SP by FrameSize bytes. Save RA, S0, S1 216unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16;
222if (isUInt<11>(FrameSize))
225intBase = 2040;
// should create template function like isUInt that 226// returns largest possible n bit unsigned integer 227 int64_t Remainder = FrameSize -
Base;
229if (isInt<16>(-Remainder))
232 adjustStackPtrBig(SP, -Remainder,
MBB,
I, Mips::V0, Mips::V1);
236// Adjust SP by FrameSize bytes. Restore RA, S0, S1 246unsigned Opc = ((FrameSize <= 128) && !SaveS2)?
247 Mips::Restore16:Mips::RestoreX16;
249if (!isUInt<11>(FrameSize)) {
251 int64_t Remainder = FrameSize -
Base;
252 FrameSize =
Base;
// should create template function like isUInt that 253// returns largest possible n bit unsigned integer 255if (isInt<16>(Remainder))
258 adjustStackPtrBig(SP, Remainder,
MBB,
I, Mips::A0, Mips::A1);
268// Adjust SP by Amount bytes where bytes can be up to 32bit number. 269// This can only be called at times that we know that there is at least one free 271// This is clearly safe at prologue and epilogue. 272void Mips16InstrInfo::adjustStackPtrBig(
unsigned SP, int64_t Amount,
275unsigned Reg1,
unsigned Reg2)
const{
280// add reg1, reg1, reg2 296void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
302/// Adjust SP by Amount bytes. 309if (isInt<16>(Amount))
// need to change to addiu sp, ....and isInt<16> 312 adjustStackPtrBigUnrestricted(SP, Amount,
MBB,
I);
315/// This function generates the sequence of instructions needed to get the 316/// result of adding register REG and immediate IMM. 321unsigned &NewImm)
const{
323// given original instruction is: 324// Instr rx, T[offset] where offset is too big. 326// lo = offset & 0xFFFF 327// hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; 329// let T = temporary register 335 int32_t lo = Imm & 0xFFFF;
343// We need to know which registers can be used, in the case where there 344// are not enough free registers. We exclude all registers that 345// are used in the instruction that we are helping. 346// // Consider all allocatable registers in the register class initially 349 (*
II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
350// Exclude all the registers being used by the instruction. 352if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
353 !MO.getReg().isVirtual())
354 Candidates.
reset(MO.getReg());
357// If the same register was used and defined in an instruction, then 358// it will not be in the list of candidates. 360// we need to analyze the instruction that we are helping. 361// we need to know if it defines register x but register x is not 362// present as an operand of the instruction. this tells 363// whether the register is live before the instruction. if it's not 364// then we don't need to save it in case there are no free registers. 367if (MO.isReg() && MO.isDef()) {
368 DefReg = MO.getReg();
376// we use T0 for the first register, if we need to save something away. 377// we use T1 for the second register, if we need to save something away. 379unsigned FirstRegSaved =0, SecondRegSaved=0;
380unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
386 Candidates.
reset(Reg);
389 FirstRegSavedTo = Mips::T0;
397if (FrameReg == Mips::SP) {
401// Candidates.reset(SpReg); // not really needed 403 SecondRegSaved = SpReg;
404 SecondRegSavedTo = Mips::T1;
419if (FirstRegSaved || SecondRegSaved) {
429unsigned Mips16InstrInfo::getAnalyzableBrOpc(
unsigned Opc)
const{
430return (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;
452returnget(Mips::AddiuSpImm16);
454returnget(Mips::AddiuSpImmX16);
470case Mips::LbRxRyOffMemX16:
471case Mips::LbuRxRyOffMemX16:
472case Mips::LhRxRyOffMemX16:
473case Mips::LhuRxRyOffMemX16:
474case Mips::SbRxRyOffMemX16:
475case Mips::ShRxRyOffMemX16:
476case Mips::LwRxRyOffMemX16:
477case Mips::SwRxRyOffMemX16:
478case Mips::SwRxSpImmX16:
479case Mips::LwRxSpImmX16:
480return isInt<16>(Amount);
481case Mips::AddiuRxRyOffMemX16:
482if ((Reg == Mips::PC) || (Reg == Mips::SP))
483return isInt<16>(Amount);
484return 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.