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) {}
52 switch (
MI.getOpcode()) {
71 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
72 MI.getOperand(2).getImm() == 0) {
73 FrameIndex =
MI.getOperand(1).getIndex();
74 return MI.getOperand(0).getReg();
87 switch (
MI.getOpcode()) {
106 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
107 MI.getOperand(1).getImm() == 0) {
108 FrameIndex =
MI.getOperand(0).getIndex();
109 return MI.getOperand(2).getReg();
194 return Opc == SP::BCOND ||
Opc == SP::BPICC ||
Opc == SP::BPICCA ||
195 Opc == SP::BPICCNT ||
Opc == SP::BPICCANT;
199 return Opc == SP::BPXCC ||
Opc == SP::BPXCCA ||
Opc == SP::BPXCCNT ||
204 return Opc == SP::BPR ||
Opc == SP::BPRA ||
Opc == SP::BPRNT ||
209 return Opc == SP::FBCOND ||
Opc == SP::FBCONDA ||
Opc == SP::FBCOND_V9 ||
210 Opc == SP::FBCONDA_V9;
219 return Opc == SP::BINDrr ||
Opc == SP::BINDri;
244 switch (
MI.getOpcode()) {
270 return MI.getOperand(0).getMBB();
278 bool AllowModify)
const {
283 if (!isUnpredicatedTerminator(*
I))
288 unsigned LastOpc = LastInst->
getOpcode();
291 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
306 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
313 LastInst = SecondLastInst;
315 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
320 SecondLastInst = &*
I;
321 SecondLastOpc = SecondLastInst->
getOpcode();
327 if (SecondLastInst &&
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
349 I->eraseFromParent();
362 int *BytesAdded)
const {
363 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
365 "Sparc branch conditions should have at most three components!");
368 assert(!FBB &&
"Unconditional branch with multiple successors!");
376 unsigned Opc =
Cond[0].getImm();
377 unsigned CC =
Cond[1].getImm();
398 int *BytesRemoved)
const {
402 while (
I !=
MBB.begin()) {
405 if (
I->isDebugInstr())
413 I->eraseFromParent();
419 *BytesRemoved = Removed;
433 assert((
Offset & 0b11) == 0 &&
"Malformed branch offset");
472 bool RenamableDest,
bool RenamableSrc)
const {
473 unsigned numSubRegs = 0;
475 const unsigned *subRegIdx =
nullptr;
476 bool ExtraG0 =
false;
478 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
479 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
480 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
481 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
482 SP::sub_odd64_then_sub_even,
483 SP::sub_odd64_then_sub_odd };
485 if (SP::IntRegsRegClass.
contains(DestReg, SrcReg))
488 else if (SP::IntPairRegClass.
contains(DestReg, SrcReg)) {
489 subRegIdx = DW_SubRegsIdx;
493 }
else if (SP::FPRegsRegClass.
contains(DestReg, SrcReg))
496 else if (SP::DFPRegsRegClass.
contains(DestReg, SrcReg)) {
497 if (Subtarget.isV9()) {
502 subRegIdx = DFP_FP_SubRegsIdx;
506 }
else if (SP::QFPRegsRegClass.
contains(DestReg, SrcReg)) {
507 if (Subtarget.isV9()) {
508 if (Subtarget.hasHardQuad()) {
513 subRegIdx = QFP_DFP_SubRegsIdx;
519 subRegIdx = QFP_FP_SubRegsIdx;
523 }
else if (SP::ASRRegsRegClass.
contains(DestReg) &&
524 SP::IntRegsRegClass.
contains(SrcReg)) {
528 }
else if (SP::IntRegsRegClass.
contains(DestReg) &&
529 SP::ASRRegsRegClass.
contains(SrcReg)) {
535 if (numSubRegs == 0 || subRegIdx ==
nullptr || movOpc == 0)
541 for (
unsigned i = 0; i != numSubRegs; ++i) {
542 Register Dst =
TRI->getSubReg(DestReg, subRegIdx[i]);
543 Register Src =
TRI->getSubReg(SrcReg, subRegIdx[i]);
544 assert(Dst && Src &&
"Bad sub-register");
560 Register SrcReg,
bool isKill,
int FI,
565 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
574 if (RC == &SP::I64RegsRegClass)
577 else if (RC == &SP::IntRegsRegClass)
580 else if (RC == &SP::IntPairRegClass)
583 else if (RC == &SP::FPRegsRegClass)
586 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
589 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
605 if (
I !=
MBB.end())
DL =
I->getDebugLoc();
613 if (RC == &SP::I64RegsRegClass)
616 else if (RC == &SP::IntRegsRegClass)
619 else if (RC == &SP::IntPairRegClass)
622 else if (RC == &SP::FPRegsRegClass)
625 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
628 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
641 return GlobalBaseReg;
649 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
650 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
656 return GlobalBaseReg;
660 unsigned Opcode =
MI.getOpcode();
662 if (
MI.isInlineAsm()) {
664 const char *AsmStr =
MI.getOperand(0).getSymbolName();
671 if (
MI.hasDelaySlot())
672 return get(Opcode).getSize() * 2;
673 return get(Opcode).getSize();
677 Register &SrcReg2, int64_t &CmpMask,
678 int64_t &CmpValue)
const {
680 switch (
MI.getOpcode()) {
684 DstReg =
MI.getOperand(0).getReg();
685 SrcReg =
MI.getOperand(1).getReg();
688 CmpValue =
MI.getOperand(2).getImm();
689 return DstReg == SP::G0 && CmpValue == 0;
691 DstReg =
MI.getOperand(0).getReg();
692 SrcReg =
MI.getOperand(1).getReg();
693 SrcReg2 =
MI.getOperand(2).getReg();
696 return DstReg == SP::G0 && SrcReg2 == SP::G0;
716 switch (
MI->getOpcode()) {
718 NewOpcode = SP::ANDNCCrr;
721 NewOpcode = SP::ANDNCCri;
724 NewOpcode = SP::ANDCCrr;
727 NewOpcode = SP::ANDCCri;
730 NewOpcode = SP::ORCCrr;
733 NewOpcode = SP::ORCCri;
736 NewOpcode = SP::ORNCCrr;
739 NewOpcode = SP::ORNCCri;
742 NewOpcode = SP::XORCCrr;
745 NewOpcode = SP::XNORCCri;
748 NewOpcode = SP::XNORCCrr;
751 NewOpcode = SP::ADDCCrr;
754 NewOpcode = SP::ADDCCri;
757 NewOpcode = SP::SUBCCrr;
760 NewOpcode = SP::SUBCCri;
766 bool IsICCModified =
false;
774 if (
I->modifiesRegister(SP::ICC,
TRI) ||
I->readsRegister(SP::ICC,
TRI))
780 if (
I->readsRegister(SP::ICC,
TRI)) {
781 bool IsICCBranch =
I->getOpcode() == SP::BCOND ||
782 I->getOpcode() == SP::BPICC ||
783 I->getOpcode() == SP::BPXCC;
785 I->getOpcode() == SP::MOVICCrr ||
I->getOpcode() == SP::MOVICCri ||
786 I->getOpcode() == SP::MOVXCCrr ||
I->getOpcode() == SP::MOVXCCri;
787 bool IsICCConditional = IsICCBranch || IsICCMove;
788 if (!IsICCConditional ||
789 (
I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_E &&
790 I->getOperand(IsICCBranch ? 1 : 3).getImm() !=
SPCC::ICC_NE))
792 }
else if (
I->modifiesRegister(SP::ICC,
TRI)) {
793 IsICCModified =
true;
798 if (!IsICCModified) {
805 if (
MRI->hasOneNonDBGUse(SrcReg))
806 MI->getOperand(0).setReg(SP::G0);
808 MI->setDesc(
get(NewOpcode));
809 MI->addRegisterDefined(SP::ICC);
816 switch (
MI.getOpcode()) {
817 case TargetOpcode::LOAD_STACK_GUARD: {
818 assert(Subtarget.getTargetTriple().isOSLinux() &&
819 "Only Linux target is expected to contain LOAD_STACK_GUARD");
821 const int64_t
Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
822 MI.setDesc(
get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
829 assert(!Subtarget.isV9() &&
830 "V8BAR should not be emitted on V9 processors!");
unsigned const MachineRegisterInfo * MRI
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
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)
ArrayRef - 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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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
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 void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineBasicBlock * getMBB() const
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
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)
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
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.
@ C
The default llvm calling convention, compatible with C.
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)
FunctionAddr 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.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.