26#define GET_INSTRINFO_CTOR_DTOR
27#include "SparcGenInstrInfo.inc"
31 cl::desc(
"Restrict range of BPcc/FBPfcc instructions (DEBUG)"));
35 cl::desc(
"Restrict range of BPr instructions (DEBUG)"));
38void SparcInstrInfo::anchor() {}
42 RI(ST), Subtarget(ST) {}
46 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
57 switch (
MI.getOpcode()) {
76 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
77 MI.getOperand(2).getImm() == 0) {
78 FrameIndex =
MI.getOperand(1).getIndex();
79 return MI.getOperand(0).getReg();
92 switch (
MI.getOpcode()) {
111 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
112 MI.getOperand(1).getImm() == 0) {
113 FrameIndex =
MI.getOperand(0).getIndex();
114 return MI.getOperand(2).getReg();
199 return Opc == SP::BCOND ||
Opc == SP::BPICC ||
Opc == SP::BPICCA ||
200 Opc == SP::BPICCNT ||
Opc == SP::BPICCANT;
204 return Opc == SP::BPXCC ||
Opc == SP::BPXCCA ||
Opc == SP::BPXCCNT ||
209 return Opc == SP::BPR ||
Opc == SP::BPRA ||
Opc == SP::BPRNT ||
214 return Opc == SP::FBCOND ||
Opc == SP::FBCONDA ||
Opc == SP::FBCOND_V9 ||
215 Opc == SP::FBCONDA_V9;
224 return Opc == SP::BINDrr ||
Opc == SP::BINDri;
249 switch (
MI.getOpcode()) {
275 return MI.getOperand(0).getMBB();
283 bool AllowModify)
const {
288 if (!isUnpredicatedTerminator(*
I))
293 unsigned LastOpc = LastInst->
getOpcode();
296 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
311 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
318 LastInst = SecondLastInst;
320 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
325 SecondLastInst = &*
I;
326 SecondLastOpc = SecondLastInst->
getOpcode();
332 if (SecondLastInst &&
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
354 I->eraseFromParent();
367 int *BytesAdded)
const {
368 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
370 "Sparc branch conditions should have at most three components!");
373 assert(!FBB &&
"Unconditional branch with multiple successors!");
381 unsigned Opc =
Cond[0].getImm();
382 unsigned CC =
Cond[1].getImm();
403 int *BytesRemoved)
const {
407 while (
I !=
MBB.begin()) {
410 if (
I->isDebugInstr())
418 I->eraseFromParent();
424 *BytesRemoved = Removed;
438 assert((
Offset & 0b11) == 0 &&
"Malformed branch offset");
477 bool RenamableDest,
bool RenamableSrc)
const {
478 unsigned numSubRegs = 0;
480 const unsigned *subRegIdx =
nullptr;
481 bool ExtraG0 =
false;
483 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
484 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
485 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
486 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
487 SP::sub_odd64_then_sub_even,
488 SP::sub_odd64_then_sub_odd };
490 if (SP::IntRegsRegClass.
contains(DestReg, SrcReg))
493 else if (SP::IntPairRegClass.
contains(DestReg, SrcReg)) {
494 subRegIdx = DW_SubRegsIdx;
498 }
else if (SP::FPRegsRegClass.
contains(DestReg, SrcReg))
501 else if (SP::DFPRegsRegClass.
contains(DestReg, SrcReg)) {
502 if (Subtarget.isV9()) {
507 subRegIdx = DFP_FP_SubRegsIdx;
511 }
else if (SP::QFPRegsRegClass.
contains(DestReg, SrcReg)) {
512 if (Subtarget.isV9()) {
513 if (Subtarget.hasHardQuad()) {
518 subRegIdx = QFP_DFP_SubRegsIdx;
524 subRegIdx = QFP_FP_SubRegsIdx;
528 }
else if (SP::ASRRegsRegClass.
contains(DestReg) &&
529 SP::IntRegsRegClass.
contains(SrcReg)) {
533 }
else if (SP::IntRegsRegClass.
contains(DestReg) &&
534 SP::ASRRegsRegClass.
contains(SrcReg)) {
540 if (numSubRegs == 0 || subRegIdx ==
nullptr || movOpc == 0)
546 for (
unsigned i = 0; i != numSubRegs; ++i) {
547 Register Dst =
TRI->getSubReg(DestReg, subRegIdx[i]);
548 Register Src =
TRI->getSubReg(SrcReg, subRegIdx[i]);
549 assert(Dst && Src &&
"Bad sub-register");
565 Register SrcReg,
bool isKill,
int FI,
570 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
579 if (RC == &SP::I64RegsRegClass)
582 else if (RC == &SP::IntRegsRegClass)
585 else if (RC == &SP::IntPairRegClass)
588 else if (RC == &SP::FPRegsRegClass)
591 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
594 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
610 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
618 if (RC == &SP::I64RegsRegClass)
621 else if (RC == &SP::IntRegsRegClass)
624 else if (RC == &SP::IntPairRegClass)
627 else if (RC == &SP::FPRegsRegClass)
630 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
633 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
646 return GlobalBaseReg;
654 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
655 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
661 return GlobalBaseReg;
665 unsigned &StructSize)
const {
669 unsigned StructSizeOpNum = 0;
670 switch (
MI.getOpcode()) {
682 case SP::TAIL_CALLri:
695 return StructSize != 0;
699 unsigned Opcode =
MI.getOpcode();
701 if (
MI.isInlineAsm()) {
703 const char *AsmStr =
MI.getOperand(0).getSymbolName();
707 if (Opcode == TargetOpcode::BUNDLE)
708 return getInstBundleSize(
MI);
710 if (
MI.getOpcode() == SP::GETPCX) {
729 if (
MI.hasDelaySlot()) {
730 unsigned StructSize = 0;
733 return get(Opcode).getSize();
737 Register &SrcReg2, int64_t &CmpMask,
738 int64_t &CmpValue)
const {
740 switch (
MI.getOpcode()) {
744 DstReg =
MI.getOperand(0).getReg();
745 SrcReg =
MI.getOperand(1).getReg();
748 CmpValue =
MI.getOperand(2).getImm();
749 return DstReg == SP::G0 && CmpValue == 0;
751 DstReg =
MI.getOperand(0).getReg();
752 SrcReg =
MI.getOperand(1).getReg();
753 SrcReg2 =
MI.getOperand(2).getReg();
756 return DstReg == SP::G0 && SrcReg2 == SP::G0;
776 switch (
MI->getOpcode()) {
778 NewOpcode = SP::ANDNCCrr;
781 NewOpcode = SP::ANDNCCri;
784 NewOpcode = SP::ANDCCrr;
787 NewOpcode = SP::ANDCCri;
790 NewOpcode = SP::ORCCrr;
793 NewOpcode = SP::ORCCri;
796 NewOpcode = SP::ORNCCrr;
799 NewOpcode = SP::ORNCCri;
802 NewOpcode = SP::XORCCrr;
805 NewOpcode = SP::XNORCCri;
808 NewOpcode = SP::XNORCCrr;
811 NewOpcode = SP::ADDCCrr;
814 NewOpcode = SP::ADDCCri;
817 NewOpcode = SP::SUBCCrr;
820 NewOpcode = SP::SUBCCri;
826 bool IsICCModified =
false;
834 if (
I->modifiesRegister(SP::ICC,
TRI) ||
I->readsRegister(SP::ICC,
TRI))
840 if (
I->readsRegister(SP::ICC,
TRI)) {
841 bool IsICCBranch =
I->getOpcode() == SP::BCOND ||
842 I->getOpcode() == SP::BPICC ||
843 I->getOpcode() == SP::BPXCC;
845 I->getOpcode() == SP::MOVICCrr ||
I->getOpcode() == SP::MOVICCri ||
846 I->getOpcode() == SP::MOVXCCrr ||
I->getOpcode() == SP::MOVXCCri;
847 bool IsICCConditional = IsICCBranch || IsICCMove;
848 if (!IsICCConditional ||
849 (
I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_E &&
850 I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_NE))
852 }
else if (
I->modifiesRegister(SP::ICC,
TRI)) {
853 IsICCModified =
true;
858 if (!IsICCModified) {
866 MI->getOperand(0).setReg(SP::G0);
868 MI->setDesc(
get(NewOpcode));
869 MI->addRegisterDefined(SP::ICC);
876 switch (
MI.getOpcode()) {
877 case TargetOpcode::LOAD_STACK_GUARD: {
878 assert(Subtarget.getTargetTriple().isOSLinux() &&
879 "Only Linux target is expected to contain LOAD_STACK_GUARD");
881 const int64_t
Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
882 MI.setDesc(
get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
889 assert(!Subtarget.isV9() &&
890 "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
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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 cl::opt< unsigned > BPrDisplacementBits("sparc-bpr-offset-bits", cl::Hidden, cl::init(16), cl::desc("Restrict range of BPr instructions (DEBUG)"))
static bool isI32CondBranchOpcode(int Opc)
static cl::opt< unsigned > BPccDisplacementBits("sparc-bpcc-offset-bits", cl::Hidden, cl::init(19), cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)"))
static bool isI64CondBranchOpcode(int Opc)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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 & 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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Wrapper class representing virtual and physical registers.
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
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
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.
initializer< Ty > init(const Ty &Val)
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 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)
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.