26#define GET_INSTRINFO_CTOR_DTOR
27#include "SparcGenInstrInfo.inc"
30void SparcInstrInfo::anchor() {}
34 RI(ST), Subtarget(ST) {}
38 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
49 switch (
MI.getOpcode()) {
68 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
69 MI.getOperand(2).getImm() == 0) {
70 FrameIndex =
MI.getOperand(1).getIndex();
71 return MI.getOperand(0).getReg();
84 switch (
MI.getOpcode()) {
103 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
104 MI.getOperand(1).getImm() == 0) {
105 FrameIndex =
MI.getOperand(0).getIndex();
106 return MI.getOperand(2).getReg();
191 return Opc == SP::BCOND ||
Opc == SP::BPICC ||
Opc == SP::BPICCA ||
192 Opc == SP::BPICCNT ||
Opc == SP::BPICCANT;
196 return Opc == SP::BPXCC ||
Opc == SP::BPXCCA ||
Opc == SP::BPXCCNT ||
201 return Opc == SP::BPR ||
Opc == SP::BPRA ||
Opc == SP::BPRNT ||
206 return Opc == SP::FBCOND ||
Opc == SP::FBCONDA ||
Opc == SP::FBCOND_V9 ||
207 Opc == SP::FBCONDA_V9;
216 return Opc == SP::BINDrr ||
Opc == SP::BINDri;
241 switch (
MI.getOpcode()) {
267 return MI.getOperand(0).getMBB();
275 bool AllowModify)
const {
280 if (!isUnpredicatedTerminator(*
I))
285 unsigned LastOpc = LastInst->
getOpcode();
288 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
303 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
310 LastInst = SecondLastInst;
312 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
317 SecondLastInst = &*
I;
318 SecondLastOpc = SecondLastInst->
getOpcode();
324 if (SecondLastInst &&
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
346 I->eraseFromParent();
359 int *BytesAdded)
const {
360 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
362 "Sparc branch conditions should have at most three components!");
365 assert(!FBB &&
"Unconditional branch with multiple successors!");
373 unsigned Opc =
Cond[0].getImm();
374 unsigned CC =
Cond[1].getImm();
395 int *BytesRemoved)
const {
399 while (
I !=
MBB.begin()) {
402 if (
I->isDebugInstr())
410 I->eraseFromParent();
416 *BytesRemoved = Removed;
430 assert((
Offset & 0b11) == 0 &&
"Malformed branch offset");
453 return isIntN(Subtarget.getCLOpts().bpcc_offset_bits,
Offset >> 2);
459 return isIntN(Subtarget.getCLOpts().bpr_offset_bits,
Offset >> 2);
469 bool RenamableDest,
bool RenamableSrc)
const {
470 unsigned numSubRegs = 0;
472 const unsigned *subRegIdx =
nullptr;
473 bool ExtraG0 =
false;
475 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
476 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
477 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
478 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
479 SP::sub_odd64_then_sub_even,
480 SP::sub_odd64_then_sub_odd };
482 if (SP::IntRegsRegClass.
contains(DestReg, SrcReg))
485 else if (SP::IntPairRegClass.
contains(DestReg, SrcReg)) {
486 subRegIdx = DW_SubRegsIdx;
490 }
else if (SP::FPRegsRegClass.
contains(DestReg, SrcReg))
493 else if (SP::DFPRegsRegClass.
contains(DestReg, SrcReg)) {
494 if (Subtarget.isV9()) {
499 subRegIdx = DFP_FP_SubRegsIdx;
503 }
else if (SP::QFPRegsRegClass.
contains(DestReg, SrcReg)) {
504 if (Subtarget.isV9()) {
505 if (Subtarget.hasHardQuad()) {
510 subRegIdx = QFP_DFP_SubRegsIdx;
516 subRegIdx = QFP_FP_SubRegsIdx;
520 }
else if (SP::ASRRegsRegClass.
contains(DestReg) &&
521 SP::IntRegsRegClass.
contains(SrcReg)) {
525 }
else if (SP::IntRegsRegClass.
contains(DestReg) &&
526 SP::ASRRegsRegClass.
contains(SrcReg)) {
532 if (numSubRegs == 0 || subRegIdx ==
nullptr || movOpc == 0)
538 for (
unsigned i = 0; i != numSubRegs; ++i) {
539 Register Dst =
TRI->getSubReg(DestReg, subRegIdx[i]);
540 Register Src =
TRI->getSubReg(SrcReg, subRegIdx[i]);
541 assert(Dst && Src &&
"Bad sub-register");
557 Register SrcReg,
bool isKill,
int FI,
562 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
571 if (RC == &SP::I64RegsRegClass)
574 else if (RC == &SP::IntRegsRegClass)
577 else if (RC == &SP::IntPairRegClass)
580 else if (RC == &SP::FPRegsRegClass)
583 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
586 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
602 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
610 if (RC == &SP::I64RegsRegClass)
613 else if (RC == &SP::IntRegsRegClass)
616 else if (RC == &SP::IntPairRegClass)
619 else if (RC == &SP::FPRegsRegClass)
622 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
625 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
638 return GlobalBaseReg;
646 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
647 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
654 return GlobalBaseReg;
658 unsigned &StructSize)
const {
662 unsigned StructSizeOpNum = 0;
663 switch (
MI.getOpcode()) {
675 case SP::TAIL_CALLri:
688 return StructSize != 0;
692 unsigned Opcode =
MI.getOpcode();
694 if (
MI.isInlineAsm()) {
696 const char *AsmStr =
MI.getOperand(0).getSymbolName();
700 if (Opcode == TargetOpcode::BUNDLE)
701 return getInstBundleSize(
MI);
703 if (
MI.getOpcode() == SP::GETPCX) {
722 if (
MI.hasDelaySlot()) {
723 unsigned StructSize = 0;
726 return get(Opcode).getSize();
730 Register &SrcReg2, int64_t &CmpMask,
731 int64_t &CmpValue)
const {
733 switch (
MI.getOpcode()) {
737 DstReg =
MI.getOperand(0).getReg();
738 SrcReg =
MI.getOperand(1).getReg();
741 CmpValue =
MI.getOperand(2).getImm();
742 return DstReg == SP::G0 && CmpValue == 0;
744 DstReg =
MI.getOperand(0).getReg();
745 SrcReg =
MI.getOperand(1).getReg();
746 SrcReg2 =
MI.getOperand(2).getReg();
749 return DstReg == SP::G0 && SrcReg2 == SP::G0;
769 switch (
MI->getOpcode()) {
771 NewOpcode = SP::ANDNCCrr;
774 NewOpcode = SP::ANDNCCri;
777 NewOpcode = SP::ANDCCrr;
780 NewOpcode = SP::ANDCCri;
783 NewOpcode = SP::ORCCrr;
786 NewOpcode = SP::ORCCri;
789 NewOpcode = SP::ORNCCrr;
792 NewOpcode = SP::ORNCCri;
795 NewOpcode = SP::XORCCrr;
798 NewOpcode = SP::XNORCCri;
801 NewOpcode = SP::XNORCCrr;
804 NewOpcode = SP::ADDCCrr;
807 NewOpcode = SP::ADDCCri;
810 NewOpcode = SP::SUBCCrr;
813 NewOpcode = SP::SUBCCri;
819 bool IsICCModified =
false;
827 if (
I->modifiesRegister(SP::ICC,
TRI) ||
I->readsRegister(SP::ICC,
TRI))
833 if (
I->readsRegister(SP::ICC,
TRI)) {
834 bool IsICCBranch =
I->getOpcode() == SP::BCOND ||
835 I->getOpcode() == SP::BPICC ||
836 I->getOpcode() == SP::BPXCC;
838 I->getOpcode() == SP::MOVICCrr ||
I->getOpcode() == SP::MOVICCri ||
839 I->getOpcode() == SP::MOVXCCrr ||
I->getOpcode() == SP::MOVXCCri;
840 bool IsICCConditional = IsICCBranch || IsICCMove;
841 if (!IsICCConditional ||
842 (
I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_E &&
843 I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_NE))
845 }
else if (
I->modifiesRegister(SP::ICC,
TRI)) {
846 IsICCModified =
true;
851 if (!IsICCModified) {
859 MI->getOperand(0).setReg(SP::G0);
861 MI->setDesc(
get(NewOpcode));
862 MI->addRegisterDefined(SP::ICC);
869 switch (
MI.getOpcode()) {
870 case TargetOpcode::LOAD_STACK_GUARD: {
871 assert(Subtarget.getTargetTriple().isOSLinux() &&
872 "Only Linux target is expected to contain LOAD_STACK_GUARD");
874 const int64_t
Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
875 MI.setDesc(
get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
882 assert(!Subtarget.isV9() &&
883 "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 bool isI32CondBranchOpcode(int Opc)
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 & 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,...
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.
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.