28#define GET_INSTRINFO_CTOR_DTOR
29#include "SparcGenInstrInfo.inc"
33 cl::desc(
"Restrict range of BPcc/FBPfcc instructions (DEBUG)"));
37 cl::desc(
"Restrict range of BPr instructions (DEBUG)"));
40void SparcInstrInfo::anchor() {}
52 int &FrameIndex)
const {
53 if (
MI.getOpcode() == SP::LDri ||
MI.getOpcode() == SP::LDXri ||
54 MI.getOpcode() == SP::LDFri ||
MI.getOpcode() == SP::LDDFri ||
55 MI.getOpcode() == SP::LDQFri) {
56 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
57 MI.getOperand(2).getImm() == 0) {
58 FrameIndex =
MI.getOperand(1).getIndex();
59 return MI.getOperand(0).getReg();
71 int &FrameIndex)
const {
72 if (
MI.getOpcode() == SP::STri ||
MI.getOpcode() == SP::STXri ||
73 MI.getOpcode() == SP::STFri ||
MI.getOpcode() == SP::STDFri ||
74 MI.getOpcode() == SP::STQFri) {
75 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
76 MI.getOperand(1).getImm() == 0) {
77 FrameIndex =
MI.getOperand(0).getIndex();
78 return MI.getOperand(2).getReg();
164 return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||
165 Opc == SP::BPICCNT || Opc == SP::BPICCANT;
169 return Opc == SP::BPXCC || Opc == SP::BPXCCA || Opc == SP::BPXCCNT ||
174 return Opc == SP::BPR || Opc == SP::BPRA || Opc == SP::BPRNT ||
179 return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 ||
180 Opc == SP::FBCONDA_V9;
189 return Opc == SP::BINDrr || Opc == SP::BINDri;
214 switch (
MI.getOpcode()) {
240 return MI.getOperand(0).getMBB();
248 bool AllowModify)
const {
253 if (!isUnpredicatedTerminator(*
I))
258 unsigned LastOpc = LastInst->
getOpcode();
261 if (
I ==
MBB.
begin() || !isUnpredicatedTerminator(*--
I)) {
276 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
283 LastInst = SecondLastInst;
285 if (
I ==
MBB.
begin() || !isUnpredicatedTerminator(*--
I)) {
290 SecondLastInst = &*
I;
291 SecondLastOpc = SecondLastInst->
getOpcode();
297 if (SecondLastInst &&
I !=
MBB.
begin() && isUnpredicatedTerminator(*--
I))
319 I->eraseFromParent();
332 int *BytesAdded)
const {
333 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
335 "Sparc branch conditions should have at most three components!");
338 assert(!FBB &&
"Unconditional branch with multiple successors!");
346 unsigned Opc =
Cond[0].getImm();
347 unsigned CC =
Cond[1].getImm();
368 int *BytesRemoved)
const {
375 if (
I->isDebugInstr())
383 I->eraseFromParent();
389 *BytesRemoved = Removed;
403 assert((
Offset & 0b11) == 0 &&
"Malformed branch offset");
442 unsigned numSubRegs = 0;
444 const unsigned *subRegIdx =
nullptr;
445 bool ExtraG0 =
false;
447 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
448 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
449 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
450 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
451 SP::sub_odd64_then_sub_even,
452 SP::sub_odd64_then_sub_odd };
454 if (SP::IntRegsRegClass.
contains(DestReg, SrcReg))
457 else if (SP::IntPairRegClass.
contains(DestReg, SrcReg)) {
458 subRegIdx = DW_SubRegsIdx;
462 }
else if (SP::FPRegsRegClass.
contains(DestReg, SrcReg))
465 else if (SP::DFPRegsRegClass.
contains(DestReg, SrcReg)) {
466 if (Subtarget.isV9()) {
471 subRegIdx = DFP_FP_SubRegsIdx;
475 }
else if (SP::QFPRegsRegClass.
contains(DestReg, SrcReg)) {
476 if (Subtarget.isV9()) {
477 if (Subtarget.hasHardQuad()) {
482 subRegIdx = QFP_DFP_SubRegsIdx;
488 subRegIdx = QFP_FP_SubRegsIdx;
492 }
else if (SP::ASRRegsRegClass.
contains(DestReg) &&
493 SP::IntRegsRegClass.
contains(SrcReg)) {
497 }
else if (SP::IntRegsRegClass.
contains(DestReg) &&
498 SP::ASRRegsRegClass.
contains(SrcReg)) {
504 if (numSubRegs == 0 || subRegIdx ==
nullptr || movOpc == 0)
510 for (
unsigned i = 0; i != numSubRegs; ++i) {
511 Register Dst =
TRI->getSubReg(DestReg, subRegIdx[i]);
512 Register Src =
TRI->getSubReg(SrcReg, subRegIdx[i]);
513 assert(Dst && Src &&
"Bad sub-register");
529 Register SrcReg,
bool isKill,
int FI,
543 if (RC == &SP::I64RegsRegClass)
546 else if (RC == &SP::IntRegsRegClass)
549 else if (RC == &SP::IntPairRegClass)
552 else if (RC == &SP::FPRegsRegClass)
555 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
558 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
582 if (RC == &SP::I64RegsRegClass)
585 else if (RC == &SP::IntRegsRegClass)
588 else if (RC == &SP::IntPairRegClass)
591 else if (RC == &SP::FPRegsRegClass)
594 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
597 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
610 return GlobalBaseReg;
618 Subtarget.
is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
625 return GlobalBaseReg;
629 unsigned Opcode =
MI.getOpcode();
631 if (
MI.isInlineAsm()) {
633 const char *AsmStr =
MI.getOperand(0).getSymbolName();
640 if (
MI.hasDelaySlot())
641 return get(Opcode).getSize() * 2;
642 return get(Opcode).getSize();
646 switch (
MI.getOpcode()) {
647 case TargetOpcode::LOAD_STACK_GUARD: {
649 "Only Linux target is expected to contain LOAD_STACK_GUARD");
652 MI.setDesc(
get(Subtarget.
is64Bit() ? SP::LDXri : SP::LDri));
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Wrapper class representing physical registers. Should be passed by value.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
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,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t Offset) const override
Determine if the branch target is in range.
SparcInstrInfo(SparcSubtarget &ST)
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Register getGlobalBaseReg(MachineFunction *MF) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) 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 isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
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)
bool isTargetLinux() const
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.
#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.
static bool isIndirectBranchOpcode(int Opc)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static bool isUncondBranchOpcode(int Opc)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.