27#define GET_INSTRINFO_CTOR_DTOR
28#include "SparcGenInstrInfo.inc"
31void SparcInstrInfo::anchor() {}
35 RI(ST), Subtarget(ST) {}
39 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
50 switch (
MI.getOpcode()) {
69 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
70 MI.getOperand(2).getImm() == 0) {
71 FrameIndex =
MI.getOperand(1).getIndex();
72 return MI.getOperand(0).getReg();
85 switch (
MI.getOpcode()) {
104 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
105 MI.getOperand(1).getImm() == 0) {
106 FrameIndex =
MI.getOperand(0).getIndex();
107 return MI.getOperand(2).getReg();
192 return Opc == SP::BCOND ||
Opc == SP::BPICC ||
Opc == SP::BPICCA ||
193 Opc == SP::BPICCNT ||
Opc == SP::BPICCANT;
197 return Opc == SP::BPXCC ||
Opc == SP::BPXCCA ||
Opc == SP::BPXCCNT ||
202 return Opc == SP::BPR ||
Opc == SP::BPRA ||
Opc == SP::BPRNT ||
207 return Opc == SP::FBCOND ||
Opc == SP::FBCONDA ||
Opc == SP::FBCOND_V9 ||
208 Opc == SP::FBCONDA_V9;
217 return Opc == SP::BINDrr ||
Opc == SP::BINDri;
242 switch (
MI.getOpcode()) {
268 case SP::CALL_LONGJUMP:
269 return MI.getOperand(0).getMBB();
277 bool AllowModify)
const {
282 if (!isUnpredicatedTerminator(*
I))
287 unsigned LastOpc = LastInst->
getOpcode();
290 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
305 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
312 LastInst = SecondLastInst;
314 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
319 SecondLastInst = &*
I;
320 SecondLastOpc = SecondLastInst->
getOpcode();
326 if (SecondLastInst &&
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
348 I->eraseFromParent();
361 int *BytesAdded)
const {
362 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
364 "Sparc branch conditions should have at most three components!");
367 assert(!FBB &&
"Unconditional branch with multiple successors!");
375 unsigned Opc =
Cond[0].getImm();
376 unsigned CC =
Cond[1].getImm();
401 assert(RS &&
"RegScavenger required for long branching");
403 "new block should be inserted for expanding unconditional branch");
404 assert(
MBB.pred_size() == 1 &&
"should only have a single predecessor");
406 "restore block should be inserted for restoring clobbered registers");
413 "Branch offsets outside of the signed 32-bit range not supported");
414 RS->enterBasicBlockEnd(
MBB);
423 bool IsO7Used = RS->isRegUsed(SP::O7);
424 Register ScratchReg = RS->FindUnusedReg(&SP::IntRegsRegClass);
431 RS->setRegUsed(ScratchReg);
437 Subtarget.is64Bit() ? SP::I64RegsRegClass : SP::IntRegsRegClass;
441 TRI.eliminateFrameIndex(std::prev(
I), 0, 0, RS);
446 .
addMBB(IsO7Used ? &RestoreBB : &NewDestBB);
455 Subtarget.is64Bit() ? SP::I64RegsRegClass : SP::IntRegsRegClass;
459 TRI.eliminateFrameIndex(std::prev(
I), 0, 1, RS);
465 int *BytesRemoved)
const {
469 while (
I !=
MBB.begin()) {
472 if (
I->isDebugInstr())
480 I->eraseFromParent();
486 *BytesRemoved = Removed;
500 assert((
Offset & 0b11) == 0 &&
"Malformed branch offset");
502 case SP::CALL_LONGJUMP:
526 return isIntN(Subtarget.getCLOpts().bpcc_offset_bits,
Offset >> 2);
532 return isIntN(Subtarget.getCLOpts().bpr_offset_bits,
Offset >> 2);
542 bool RenamableDest,
bool RenamableSrc)
const {
543 unsigned numSubRegs = 0;
545 const unsigned *subRegIdx =
nullptr;
546 bool ExtraG0 =
false;
548 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
549 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
550 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
551 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
552 SP::sub_odd64_then_sub_even,
553 SP::sub_odd64_then_sub_odd };
555 if (SP::IntRegsRegClass.
contains(DestReg, SrcReg))
558 else if (SP::IntPairRegClass.
contains(DestReg, SrcReg)) {
559 subRegIdx = DW_SubRegsIdx;
563 }
else if (SP::FPRegsRegClass.
contains(DestReg, SrcReg))
566 else if (SP::DFPRegsRegClass.
contains(DestReg, SrcReg)) {
567 if (Subtarget.isV9()) {
572 subRegIdx = DFP_FP_SubRegsIdx;
576 }
else if (SP::QFPRegsRegClass.
contains(DestReg, SrcReg)) {
577 if (Subtarget.isV9()) {
578 if (Subtarget.hasHardQuad()) {
583 subRegIdx = QFP_DFP_SubRegsIdx;
589 subRegIdx = QFP_FP_SubRegsIdx;
593 }
else if (SP::ASRRegsRegClass.
contains(DestReg) &&
594 SP::IntRegsRegClass.
contains(SrcReg)) {
598 }
else if (SP::IntRegsRegClass.
contains(DestReg) &&
599 SP::ASRRegsRegClass.
contains(SrcReg)) {
605 if (numSubRegs == 0 || subRegIdx ==
nullptr || movOpc == 0)
611 for (
unsigned i = 0; i != numSubRegs; ++i) {
612 Register Dst =
TRI->getSubReg(DestReg, subRegIdx[i]);
613 Register Src =
TRI->getSubReg(SrcReg, subRegIdx[i]);
614 assert(Dst && Src &&
"Bad sub-register");
630 Register SrcReg,
bool isKill,
int FI,
635 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
644 if (RC == &SP::I64RegsRegClass)
647 else if (RC == &SP::IntRegsRegClass)
650 else if (RC == &SP::IntPairRegClass)
653 else if (RC == &SP::FPRegsRegClass)
656 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
659 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
675 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
683 if (RC == &SP::I64RegsRegClass)
686 else if (RC == &SP::IntRegsRegClass)
689 else if (RC == &SP::IntPairRegClass)
692 else if (RC == &SP::FPRegsRegClass)
695 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
698 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
711 return GlobalBaseReg;
719 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
720 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
727 return GlobalBaseReg;
731 unsigned &StructSize)
const {
735 unsigned StructSizeOpNum = 0;
736 switch (
MI.getOpcode()) {
748 case SP::TAIL_CALLri:
761 return StructSize != 0;
765 unsigned Opcode =
MI.getOpcode();
767 if (
MI.isInlineAsm()) {
769 const char *AsmStr =
MI.getOperand(0).getSymbolName();
773 if (Opcode == TargetOpcode::BUNDLE)
774 return getInstBundleSize(
MI);
776 if (
MI.getOpcode() == SP::GETPCX) {
795 if (
MI.hasDelaySlot()) {
796 unsigned StructSize = 0;
799 return get(Opcode).getSize();
803 Register &SrcReg2, int64_t &CmpMask,
804 int64_t &CmpValue)
const {
806 switch (
MI.getOpcode()) {
810 DstReg =
MI.getOperand(0).getReg();
811 SrcReg =
MI.getOperand(1).getReg();
814 CmpValue =
MI.getOperand(2).getImm();
815 return DstReg == SP::G0 && CmpValue == 0;
817 DstReg =
MI.getOperand(0).getReg();
818 SrcReg =
MI.getOperand(1).getReg();
819 SrcReg2 =
MI.getOperand(2).getReg();
822 return DstReg == SP::G0 && SrcReg2 == SP::G0;
842 switch (
MI->getOpcode()) {
844 NewOpcode = SP::ANDNCCrr;
847 NewOpcode = SP::ANDNCCri;
850 NewOpcode = SP::ANDCCrr;
853 NewOpcode = SP::ANDCCri;
856 NewOpcode = SP::ORCCrr;
859 NewOpcode = SP::ORCCri;
862 NewOpcode = SP::ORNCCrr;
865 NewOpcode = SP::ORNCCri;
868 NewOpcode = SP::XORCCrr;
871 NewOpcode = SP::XNORCCri;
874 NewOpcode = SP::XNORCCrr;
877 NewOpcode = SP::ADDCCrr;
880 NewOpcode = SP::ADDCCri;
883 NewOpcode = SP::SUBCCrr;
886 NewOpcode = SP::SUBCCri;
892 bool IsICCModified =
false;
900 if (
I->modifiesRegister(SP::ICC,
TRI) ||
I->readsRegister(SP::ICC,
TRI))
906 if (
I->readsRegister(SP::ICC,
TRI)) {
907 bool IsICCBranch =
I->getOpcode() == SP::BCOND ||
908 I->getOpcode() == SP::BPICC ||
909 I->getOpcode() == SP::BPXCC;
911 I->getOpcode() == SP::MOVICCrr ||
I->getOpcode() == SP::MOVICCri ||
912 I->getOpcode() == SP::MOVXCCrr ||
I->getOpcode() == SP::MOVXCCri;
913 bool IsICCConditional = IsICCBranch || IsICCMove;
914 if (!IsICCConditional ||
915 (
I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_E &&
916 I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_NE))
918 }
else if (
I->modifiesRegister(SP::ICC,
TRI)) {
919 IsICCModified =
true;
924 if (!IsICCModified) {
931 if (
MRI->hasOneNonDBGUse(SrcReg))
932 MI->getOperand(0).setReg(SP::G0);
934 MI->setDesc(
get(NewOpcode));
935 MI->addRegisterDefined(SP::ICC);
942 switch (
MI.getOpcode()) {
943 case TargetOpcode::LOAD_STACK_GUARD: {
944 assert(Subtarget.getTargetTriple().isOSLinux() &&
945 "Only Linux target is expected to contain LOAD_STACK_GUARD");
947 const int64_t
Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
948 MI.setDesc(
get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
955 assert(!Subtarget.isV9() &&
956 "V8BAR should not be emitted on V9 processors!");
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Register const TargetRegisterInfo * TRI
Promote Memory to Register
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
static bool isFCondBranchOpcode(int Opc)
static bool isRegCondBranchOpcode(int Opc)
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static bool isI32CondBranchOpcode(int Opc)
static bool isI64CondBranchOpcode(int Opc)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
MCRegisterClass - Base class of TargetRegisterClass.
Helper class for constructing bundles of MachineInstrs.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
LLVM_ABI void addRegisterDefined(Register Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool needsUnimp(const MachineInstr &MI, unsigned &StructSize) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex, TypeSize &MemBytes) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t Offset) const override
Determine if the branch target is in range.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Register getGlobalBaseReg(MachineFunction *MF) const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex, TypeSize &MemBytes) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
SparcInstrInfo(const SparcSubtarget &ST)
const SparcRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool expandPostRAPseudo(MachineInstr &MI) const override
Register getGlobalBaseReg() const
int getBranchRelaxationSpillFrameIndex()
void setGlobalBaseReg(Register Reg)
Primary interface to the complete machine description for the target machine.
bool isPositionIndependent() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
static bool isCondBranchOpcode(int Opc)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
static bool isIndirectBranchOpcode(int Opc)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
static bool isUncondBranchOpcode(int Opc)
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
MCRegisterClass TargetRegisterClass
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.