35 static std::pair<unsigned, unsigned> getMFHiLoOpc(
unsigned Src) {
36 if (Mips::ACC64RegClass.
contains(Src))
37 return std::make_pair((
unsigned)Mips::PseudoMFHI,
38 (
unsigned)Mips::PseudoMFLO);
40 if (Mips::ACC64DSPRegClass.
contains(Src))
41 return std::make_pair((
unsigned)Mips::MFHI_DSP, (
unsigned)Mips::MFLO_DSP);
43 if (Mips::ACC128RegClass.
contains(Src))
44 return std::make_pair((
unsigned)Mips::PseudoMFHI64,
45 (
unsigned)Mips::PseudoMFLO64);
47 return std::make_pair(0, 0);
62 unsigned MFLoOpc,
unsigned RegSize);
80 : MF(MF_),
MRI(MF.getRegInfo()),
83 RegInfo(*Subtarget.getRegisterInfo()) {}
86 bool Expanded =
false;
88 for (
auto &
MBB : MF) {
90 Expanded |= expandInstr(
MBB,
I++);
97 switch(I->getOpcode()) {
98 case Mips::LOAD_CCOND_DSP:
99 expandLoadCCond(MBB, I);
101 case Mips::STORE_CCOND_DSP:
102 expandStoreCCond(MBB, I);
104 case Mips::LOAD_ACC64:
105 case Mips::LOAD_ACC64DSP:
106 expandLoadACC(MBB, I, 4);
108 case Mips::LOAD_ACC128:
109 expandLoadACC(MBB, I, 8);
111 case Mips::STORE_ACC64:
112 expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
114 case Mips::STORE_ACC64DSP:
115 expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
117 case Mips::STORE_ACC128:
118 expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
121 if (expandBuildPairF64(MBB, I,
false))
124 case Mips::BuildPairF64_64:
125 if (expandBuildPairF64(MBB, I,
true))
129 if (expandExtractElementF64(MBB, I,
false))
132 case Mips::ExtractElementF64_64:
133 if (expandExtractElementF64(MBB, I,
true))
136 case TargetOpcode::COPY:
137 if (!expandCopy(MBB, I))
152 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
155 unsigned VR =
MRI.createVirtualRegister(RC);
156 unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
158 TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
159 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(TargetOpcode::COPY), Dst)
167 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
170 unsigned VR =
MRI.createVirtualRegister(RC);
171 unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
173 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(TargetOpcode::COPY), VR)
175 TII.storeRegToStack(MBB, I, VR,
true, FI, RC, &RegInfo, 0);
185 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
188 unsigned VR0 =
MRI.createVirtualRegister(RC);
189 unsigned VR1 =
MRI.createVirtualRegister(RC);
190 unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
191 unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
192 unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
196 TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
198 TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
203 unsigned MFHiOpc,
unsigned MFLoOpc,
210 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
213 unsigned VR0 =
MRI.createVirtualRegister(RC);
214 unsigned VR1 =
MRI.createVirtualRegister(RC);
215 unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
219 BuildMI(MBB, I, DL,
TII.get(MFLoOpc), VR0).addReg(Src);
220 TII.storeRegToStack(MBB, I, VR0,
true, FI, RC, &RegInfo, 0);
221 BuildMI(MBB, I, DL,
TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
222 TII.storeRegToStack(MBB, I, VR1,
true, FI, RC, &RegInfo, RegSize);
226 unsigned Src = I->getOperand(1).getReg();
227 std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);
232 return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
236 unsigned MFHiOpc,
unsigned MFLoOpc) {
242 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
243 unsigned VRegSize = RegInfo.getMinimalPhysRegClass(Dst)->getSize() / 2;
245 unsigned VR0 =
MRI.createVirtualRegister(RC);
246 unsigned VR1 =
MRI.createVirtualRegister(RC);
248 unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
249 unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
252 BuildMI(MBB, I, DL,
TII.get(MFLoOpc), VR0).addReg(Src);
253 BuildMI(MBB, I, DL,
TII.get(TargetOpcode::COPY), DstLo)
255 BuildMI(MBB, I, DL,
TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
256 BuildMI(MBB, I, DL,
TII.get(TargetOpcode::COPY), DstHi)
281 if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) ||
282 (FP64 && !Subtarget.useOddSPReg())) {
283 unsigned DstReg = I->getOperand(0).getReg();
284 unsigned LoReg = I->getOperand(1).getReg();
285 unsigned HiReg = I->getOperand(2).getReg();
290 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
291 !Subtarget.isFP64bit());
295 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
300 if (!Subtarget.isLittle())
302 TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC,
304 TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC,
306 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, 0);
325 unsigned DstReg = I->getOperand(0).getReg();
326 BuildMI(MBB, I, I->getDebugLoc(),
TII.get(Mips::IMPLICIT_DEF), DstReg);
343 if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) ||
344 (FP64 && !Subtarget.useOddSPReg())) {
345 unsigned DstReg = I->getOperand(0).getReg();
346 unsigned SrcReg = Op1.
getReg();
348 int64_t
Offset = 4 * (Subtarget.isLittle() ? N : (1 -
N));
353 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
354 !Subtarget.isFP64bit());
357 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
363 TII.storeRegToStack(MBB, I, SrcReg, Op1.
isKill(), FI, RC, &RegInfo, 0);
364 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, Offset);
376 assert(&MF.
front() == &MBB &&
"Shrink-wrapping not yet supported");
396 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
399 uint64_t StackSize = MFI.getStackSize();
402 if (StackSize == 0 && !MFI.adjustsStack())
return;
409 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
414 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
415 .addCFIIndex(CFIIndex);
418 emitInterruptPrologueStub(MF, MBB);
420 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
425 for (
unsigned i = 0;
i < CSI.size(); ++
i)
430 for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
431 E = CSI.end(); I !=
E; ++
I) {
432 int64_t Offset = MFI.getObjectOffset(I->getFrameIdx());
433 unsigned Reg = I->getReg();
437 if (Mips::AFGR64RegClass.
contains(Reg)) {
448 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
449 .addCFIIndex(CFIIndex);
453 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
454 .addCFIIndex(CFIIndex);
455 }
else if (Mips::FGR64RegClass.
contains(Reg)) {
464 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
465 .addCFIIndex(CFIIndex);
469 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
470 .addCFIIndex(CFIIndex);
475 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
476 .addCFIIndex(CFIIndex);
483 for (
int I = 0; I < 4; ++
I) {
486 TII.storeRegToStackSlot(MBB, MBBI, ABI.
GetEhDataReg(I),
false,
491 for (
int I = 0; I < 4; ++
I) {
496 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
497 .addCFIIndex(CFIIndex);
510 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
511 .addCFIIndex(CFIIndex);
513 if (RegInfo.needsStackRealignment(MF)) {
518 "Function's alignment size requirement is not supported.");
519 int MaxAlign = -(int)MFI.getMaxAlignment();
535 void MipsSEFrameLowering::emitInterruptPrologueStub(
549 "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
558 "static relocation model on MIPS at the present time.");
562 "O32 ABI on MIPS32R2+ at the present time.");
571 if (IntKind ==
"eic") {
575 .addReg(Mips::COP013)
589 .addReg(Mips::COP014)
600 .addReg(Mips::COP012)
610 unsigned InsPosition = 8;
611 unsigned InsSize = 0;
612 unsigned SrcReg = Mips::ZERO;
616 if (IntKind ==
"eic") {
631 assert(InsSize != 0 &&
"Unknown interrupt type!");
696 ABI.
ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
704 for (
int J = 0; J < 4; ++J) {
711 emitInterruptEpilogueStub(MF, MBB);
720 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
723 void MipsSEFrameLowering::emitInterruptEpilogueStub(
756 unsigned &FrameReg)
const {
772 const std::vector<CalleeSavedInfo> &CSI,
778 for (
unsigned i = 0, e = CSI.size();
i != e; ++
i) {
784 unsigned Reg = CSI[
i].getReg();
785 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
787 if (!IsRAAndRetAddrIsTaken)
792 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
793 Reg == Mips::HI0 || Reg == Mips::HI0_64);
803 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
811 bool IsKill = !IsRAAndRetAddrIsTaken;
814 CSI[
i].getFrameIdx(), RC, TRI);
847 unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
866 if (ExpandPseudo(MF).
expand()) {
870 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
884 ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
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.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
bool ArePtrs64bit() const
const MipsFrameLowering * createMipsSEFrameLowering(const MipsSubtarget &ST)
const MipsABIInfo & getABI() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
const MipsSubtarget & STI
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Describe properties that are true of each instruction in the target description file.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
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
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
constexpr bool isInt< 16 >(int64_t x)
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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.
return AArch64::GPR64RegClass contains(Reg)
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
DILocation * get() const
Get the underlying DILocation.
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()
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
const MachineBasicBlock & front() const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
int getOffsetAdjustment() const
Return the correction for frame offsets.
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.
bool hasBP(const MachineFunction &MF) 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)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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.
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 getAlignment() const
Return the minimum required alignment for a register of this class.
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.
MCRegAliasIterator enumerates all registers aliasing Reg.
static const unsigned End
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool useSoftFloat() const
unsigned GetGPRMoveOp() const
unsigned GetBasePtr() const
static Expected< BitVector > expand(StringRef S, StringRef Original)
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...
int getEhDataRegFI(unsigned Reg) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned GetEhDataReg(unsigned I) const
unsigned GetStackPtr() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
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
unsigned GetNullPtr() const
static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, unsigned Reg)
Mark Reg and all registers aliasing it in the bitset.
const MipsRegisterInfo * getRegisterInfo() const override
const MCContext & getContext() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
MachineOperand class - Representation of each machine instruction operand.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MCRegisterInfo * getRegisterInfo() const
Reloc::Model getRelocationModel() const
bool callsEhReturn() const
Bitwise operators - logical and, logical or, logical xor.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MipsSEFrameLowering(const MipsSubtarget &STI)
unsigned GetFramePtr() const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, const AllocaInst *Alloca=nullptr)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
unsigned getReg() const
getReg - Returns the register number.
StringRef getValueAsString() const
Return the attribute's value as a string.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
uint64_t estimateStackSize(const MachineFunction &MF) const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
MachineModuleInfo & getMMI() const
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...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
unsigned GetPtrAddiuOp() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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