51 if (Mips::ACC64RegClass.
contains(Src))
52 return std::make_pair((
unsigned)Mips::PseudoMFHI,
53 (
unsigned)Mips::PseudoMFLO);
55 if (Mips::ACC64DSPRegClass.
contains(Src))
56 return std::make_pair((
unsigned)Mips::MFHI_DSP, (
unsigned)Mips::MFLO_DSP);
58 if (Mips::ACC128RegClass.
contains(Src))
59 return std::make_pair((
unsigned)Mips::PseudoMFHI64,
60 (
unsigned)Mips::PseudoMFLO64);
62 return std::make_pair(0, 0);
81 unsigned MFLoOpc,
unsigned RegSize);
100 : MF(MF_),
MRI(MF.getRegInfo()),
101 Subtarget(static_cast<const MipsSubtarget &>(MF.getSubtarget())),
102 TII(*static_cast<const MipsSEInstrInfo *>(Subtarget.getInstrInfo())),
103 RegInfo(*Subtarget.getRegisterInfo()) {}
106 bool Expanded =
false;
108 for (
auto &MBB : MF) {
109 for (Iter
I = MBB.begin(), End = MBB.end();
I != End;)
110 Expanded |= expandInstr(MBB,
I++);
117 switch(I->getOpcode()) {
118 case Mips::LOAD_CCOND_DSP:
119 expandLoadCCond(MBB, I);
121 case Mips::STORE_CCOND_DSP:
122 expandStoreCCond(MBB, I);
124 case Mips::LOAD_ACC64:
125 case Mips::LOAD_ACC64DSP:
126 expandLoadACC(MBB, I, 4);
128 case Mips::LOAD_ACC128:
129 expandLoadACC(MBB, I, 8);
131 case Mips::STORE_ACC64:
132 expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
134 case Mips::STORE_ACC64DSP:
135 expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
137 case Mips::STORE_ACC128:
138 expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
141 if (expandBuildPairF64(MBB, I,
false))
144 case Mips::BuildPairF64_64:
145 if (expandBuildPairF64(MBB, I,
true))
149 if (expandExtractElementF64(MBB, I,
false))
152 case Mips::ExtractElementF64_64:
153 if (expandExtractElementF64(MBB, I,
true))
156 case TargetOpcode::COPY:
157 if (!expandCopy(MBB, I))
172 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
175 unsigned VR =
MRI.createVirtualRegister(RC);
176 unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
178 TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
179 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(TargetOpcode::COPY), Dst)
187 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
190 unsigned VR =
MRI.createVirtualRegister(RC);
191 unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
193 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(TargetOpcode::COPY), VR)
195 TII.storeRegToStack(MBB, I, VR,
true, FI, RC, &RegInfo, 0);
205 assert(
I->getOperand(0).isReg() &&
I->getOperand(1).isFI());
208 unsigned VR0 =
MRI.createVirtualRegister(RC);
209 unsigned VR1 =
MRI.createVirtualRegister(RC);
210 unsigned Dst =
I->getOperand(0).getReg(), FI =
I->getOperand(1).getIndex();
211 unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
212 unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
216 TII.loadRegFromStack(MBB,
I, VR0, FI, RC, &RegInfo, 0);
218 TII.loadRegFromStack(MBB,
I, VR1, FI, RC, &RegInfo, RegSize);
223 unsigned MFHiOpc,
unsigned MFLoOpc,
230 assert(
I->getOperand(0).isReg() &&
I->getOperand(1).isFI());
233 unsigned VR0 =
MRI.createVirtualRegister(RC);
234 unsigned VR1 =
MRI.createVirtualRegister(RC);
235 unsigned Src =
I->getOperand(0).getReg(), FI =
I->getOperand(1).getIndex();
239 BuildMI(MBB,
I, DL,
TII.get(MFLoOpc), VR0).addReg(Src);
240 TII.storeRegToStack(MBB,
I, VR0,
true, FI, RC, &RegInfo, 0);
241 BuildMI(MBB,
I, DL,
TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
242 TII.storeRegToStack(MBB,
I, VR1,
true, FI, RC, &RegInfo, RegSize);
246 unsigned Src = I->getOperand(1).getReg();
247 std::pair<unsigned, unsigned> Opcodes =
getMFHiLoOpc(Src);
252 return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
256 unsigned MFHiOpc,
unsigned MFLoOpc) {
262 unsigned Dst =
I->getOperand(0).getReg(), Src =
I->getOperand(1).getReg();
264 unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16;
266 unsigned VR0 =
MRI.createVirtualRegister(RC);
267 unsigned VR1 =
MRI.createVirtualRegister(RC);
269 unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
270 unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
273 BuildMI(MBB,
I, DL,
TII.get(MFLoOpc), VR0).addReg(Src);
274 BuildMI(MBB,
I, DL,
TII.get(TargetOpcode::COPY), DstLo)
276 BuildMI(MBB,
I, DL,
TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
277 BuildMI(MBB,
I, DL,
TII.get(TargetOpcode::COPY), DstHi)
306 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
307 && I->getOperand(3).getReg() == Mips::SP) {
308 unsigned DstReg = I->getOperand(0).getReg();
309 unsigned LoReg = I->getOperand(1).getReg();
310 unsigned HiReg = I->getOperand(2).getReg();
315 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
316 !Subtarget.isFP64bit());
320 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
325 if (!Subtarget.isLittle())
327 TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC,
329 TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC,
331 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, 0);
350 unsigned DstReg = I->getOperand(0).getReg();
351 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(Mips::IMPLICIT_DEF), DstReg);
371 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
372 && I->getOperand(3).getReg() == Mips::SP) {
373 unsigned DstReg = I->getOperand(0).getReg();
374 unsigned SrcReg = Op1.
getReg();
376 int64_t
Offset = 4 * (Subtarget.isLittle() ?
N : (1 -
N));
381 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
382 !Subtarget.isFP64bit());
385 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
391 TII.storeRegToStack(MBB, I, SrcReg, Op1.
isKill(), FI, RC, &RegInfo, 0);
392 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, Offset);
423 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
435 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
440 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
441 .addCFIIndex(CFIIndex);
444 emitInterruptPrologueStub(MF, MBB);
451 for (
unsigned i = 0; i < CSI.size(); ++i)
456 for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
457 E = CSI.end(); I !=
E; ++
I) {
459 unsigned Reg = I->getReg();
463 if (Mips::AFGR64RegClass.
contains(Reg)) {
474 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
475 .addCFIIndex(CFIIndex);
479 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
480 .addCFIIndex(CFIIndex);
481 }
else if (Mips::FGR64RegClass.
contains(Reg)) {
490 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
491 .addCFIIndex(CFIIndex);
495 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
496 .addCFIIndex(CFIIndex);
501 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
502 .addCFIIndex(CFIIndex);
509 for (
int I = 0; I < 4; ++
I) {
512 TII.storeRegToStackSlot(MBB, MBBI, ABI.
GetEhDataReg(I),
false,
517 for (
int I = 0; I < 4; ++
I) {
522 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
523 .addCFIIndex(CFIIndex);
536 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
537 .addCFIIndex(CFIIndex);
539 if (RegInfo.needsStackRealignment(MF)) {
544 "Function's alignment size requirement is not supported.");
561 void MipsSEFrameLowering::emitInterruptPrologueStub(
574 "\"interrupt\" attribute is not supported on pre-MIPS32R2 or " 583 "static relocation model on MIPS at the present time.");
587 "O32 ABI on MIPS32R2+ at the present time.");
596 if (IntKind ==
"eic") {
600 .addReg(Mips::COP013)
614 .addReg(Mips::COP014)
625 .addReg(Mips::COP012)
635 unsigned InsPosition = 8;
636 unsigned InsSize = 0;
637 unsigned SrcReg = Mips::ZERO;
641 if (IntKind ==
"eic") {
656 assert(InsSize != 0 &&
"Unknown interrupt type!");
721 ABI.
ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
729 for (
int J = 0; J < 4; ++J) {
736 emitInterruptEpilogueStub(MF, MBB);
745 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
748 void MipsSEFrameLowering::emitInterruptEpilogueStub(
780 unsigned &FrameReg)
const {
796 const std::vector<CalleeSavedInfo> &CSI,
801 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
807 unsigned Reg = CSI[i].getReg();
808 bool IsRAAndRetAddrIsTaken = (Reg ==
Mips::RA || Reg == Mips::RA_64)
810 if (!IsRAAndRetAddrIsTaken)
815 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
816 Reg == Mips::HI0 || Reg == Mips::HI0_64);
826 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
834 bool IsKill = !IsRAAndRetAddrIsTaken;
837 CSI[i].getFrameIdx(), RC, TRI);
869 unsigned FP = ABI.GetFramePtr();
870 unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
889 if (ExpandPseudo(MF).
expand()) {
894 Mips::GPR64RegClass : Mips::GPR32RegClass;
911 ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;
const MipsFrameLowering * createMipsSEFrameLowering(const MipsSubtarget &ST)
DILocation * get() const
Get the underlying DILocation.
bool hasBP(const MachineFunction &MF) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
const MipsSubtarget & STI
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool ArePtrs64bit() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
const MipsInstrInfo * getInstrInfo() const override
unsigned GetEhDataReg(unsigned I) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
constexpr bool isInt< 16 >(int64_t x)
unsigned const TargetRegisterInfo * TRI
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
MachineModuleInfo & getMMI() const
int getEhDataRegFI(unsigned Reg) const
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
return AArch64::GPR64RegClass contains(Reg)
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
SI optimize exec mask operations pre RA
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
virtual void storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, int64_t Offset) const =0
void createEhDataRegsFI()
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
const MCContext & getContext() const
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
unsigned getKillRegState(bool B)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
A switch()-like statement whose cases are string literals.
MachineInstrBundleIterator< MachineInstr > iterator
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
unsigned GetPtrAddiuOp() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static Expected< BitVector > expand(StringRef S, StringRef Original)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const MipsABIInfo & getABI() const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getISRRegFI(unsigned Reg) const
static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, unsigned Reg)
Mark Reg and all registers aliasing it in the bitset.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
const MipsRegisterInfo * getRegisterInfo() const override
static std::pair< unsigned, unsigned > getMFHiLoOpc(unsigned Src)
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
MachineOperand class - Representation of each machine instruction operand.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
Store the specified register of the given register class to the specified stack frame index...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Bitwise operators - logical and, logical or, logical xor.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MipsSEFrameLowering(const MipsSubtarget &STI)
StringRef getValueAsString() const
Return the attribute's value as a string.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
unsigned GetBasePtr() const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
int getOffsetAdjustment() const
Return the correction for frame offsets.
uint64_t estimateStackSize(const MachineFunction &MF) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned GetGPRMoveOp() const
Reloc::Model getRelocationModel() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool callsEhReturn() const
const MCRegisterInfo * getRegisterInfo() const
unsigned GetStackPtr() const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool useSoftFloat() const
StringRef - Represent a constant reference to a string, i.e.
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
unsigned GetNullPtr() const
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned GetFramePtr() const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
This class contains meta information specific to a module.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override