27#define DEBUG_TYPE "ve-instr-info"
31#define GET_INSTRINFO_CTOR_DTOR
32#include "VEGenInstrInfo.inc"
35void VEInstrInfo::anchor() {}
38 :
VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI() {}
99#define BRKIND(NAME) (Opc == NAME##a || Opc == NAME##a_nt || Opc == NAME##a_t)
103 "Branch relative word/double/float always instructions should not be "
114#define BRKIND(NAME) \
115 (Opc == NAME##rr || Opc == NAME##rr_nt || Opc == NAME##rr_t || \
116 Opc == NAME##ir || Opc == NAME##ir_nt || Opc == NAME##ir_t)
126#define BRKIND(NAME) \
127 (Opc == NAME##ari || Opc == NAME##ari_nt || Opc == NAME##ari_t)
131 "Branch word/double/float always instructions should not be used!");
147 bool AllowModify)
const {
152 if (!isUnpredicatedTerminator(*
I))
157 unsigned LastOpc = LastInst->
getOpcode();
160 if (
I ==
MBB.
begin() || !isUnpredicatedTerminator(*--
I)) {
175 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
182 LastInst = SecondLastInst;
184 if (
I ==
MBB.
begin() || !isUnpredicatedTerminator(*--
I)) {
189 SecondLastInst = &*
I;
190 SecondLastOpc = SecondLastInst->
getOpcode();
195 if (SecondLastInst &&
I !=
MBB.
begin() && isUnpredicatedTerminator(*--
I))
217 I->eraseFromParent();
230 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
232 "VE branch conditions should have three component!");
233 assert(!BytesAdded &&
"code size not handled");
236 assert(!FBB &&
"Unconditional branch with multiple successors!");
252 if (
TRI->getRegSizeInBits(Reg,
MRI) == 32) {
253 opc[0] = VE::BRCFWir;
254 opc[1] = VE::BRCFWrr;
256 opc[0] = VE::BRCFLir;
257 opc[1] = VE::BRCFLrr;
260 if (
TRI->getRegSizeInBits(Reg,
MRI) == 32) {
261 opc[0] = VE::BRCFSir;
262 opc[1] = VE::BRCFSrr;
264 opc[0] = VE::BRCFDir;
265 opc[1] = VE::BRCFDrr;
268 if (
Cond[1].isImm()) {
291 int *BytesRemoved)
const {
292 assert(!BytesRemoved &&
"code size not handled");
299 if (
I->isDebugValue())
306 I->eraseFromParent();
321 return VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) ||
322 VE::F32RegClass.contains(Reg);
329 const unsigned *SubRegIdx,
333 for (
unsigned Idx = 0;
Idx != NumSubRegs; ++
Idx) {
336 assert(SubDest && SubSrc &&
"Bad sub-register");
343 }
else if (MCID.
getOpcode() == VE::ANDMmm) {
361 bool RenamableDest,
bool RenamableSrc)
const {
367 }
else if (VE::V64RegClass.
contains(DestReg, SrcReg)) {
376 Register SubTmp =
TRI->getSubReg(TmpReg, VE::sub_i32);
386 }
else if (VE::VMRegClass.
contains(DestReg, SrcReg)) {
390 }
else if (VE::VM512RegClass.
contains(DestReg, SrcReg)) {
392 const unsigned SubRegIdx[] = {VE::sub_vm_even, VE::sub_vm_odd};
393 unsigned int NumSubRegs = 2;
396 }
else if (VE::F128RegClass.
contains(DestReg, SrcReg)) {
398 const unsigned SubRegIdx[] = {VE::sub_even, VE::sub_odd};
399 unsigned int NumSubRegs = 2;
416 int &FrameIndex)
const {
417 if (
MI.getOpcode() == VE::LDrii ||
418 MI.getOpcode() == VE::LDLSXrii ||
419 MI.getOpcode() == VE::LDUrii ||
420 MI.getOpcode() == VE::LDQrii ||
421 MI.getOpcode() == VE::LDVMrii ||
422 MI.getOpcode() == VE::LDVM512rii
424 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
425 MI.getOperand(2).getImm() == 0 &&
MI.getOperand(3).isImm() &&
426 MI.getOperand(3).getImm() == 0) {
427 FrameIndex =
MI.getOperand(1).getIndex();
428 return MI.getOperand(0).getReg();
440 int &FrameIndex)
const {
441 if (
MI.getOpcode() == VE::STrii ||
442 MI.getOpcode() == VE::STLrii ||
443 MI.getOpcode() == VE::STUrii ||
444 MI.getOpcode() == VE::STQrii ||
445 MI.getOpcode() == VE::STVMrii ||
446 MI.getOpcode() == VE::STVM512rii
448 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
449 MI.getOperand(1).getImm() == 0 &&
MI.getOperand(2).isImm() &&
450 MI.getOperand(2).getImm() == 0) {
451 FrameIndex =
MI.getOperand(0).getIndex();
452 return MI.getOperand(3).getReg();
460 Register SrcReg,
bool isKill,
int FI,
467 DL =
I->getDebugLoc();
476 if (RC == &VE::I64RegClass) {
483 }
else if (RC == &VE::I32RegClass) {
490 }
else if (RC == &VE::F32RegClass) {
497 }
else if (VE::F128RegClass.hasSubClassEq(RC)) {
504 }
else if (RC == &VE::VMRegClass) {
511 }
else if (VE::VM512RegClass.hasSubClassEq(RC)) {
528 DL =
I->getDebugLoc();
536 if (RC == &VE::I64RegClass) {
542 }
else if (RC == &VE::I32RegClass) {
548 }
else if (RC == &VE::F32RegClass) {
554 }
else if (VE::F128RegClass.hasSubClassEq(RC)) {
560 }
else if (RC == &VE::VMRegClass) {
566 }
else if (VE::VM512RegClass.hasSubClassEq(RC)) {
582 switch (
DefMI.getOpcode()) {
602 if (!
DefMI.getOperand(3).isImm())
605 ImmVal =
DefMI.getOperand(2).getImm() +
DefMI.getOperand(3).getImm();
638 unsigned NewUseOpcSImm7;
639 unsigned NewUseOpcMImm;
646#define INSTRKIND(NAME) \
648 NewUseOpcSImm7 = NAME##ri; \
649 NewUseOpcMImm = NAME##rm; \
650 InstType = rr2ri_rm; \
652#define NCINSTRKIND(NAME) \
654 NewUseOpcSImm7 = NAME##ir; \
655 NewUseOpcMImm = NAME##rm; \
656 InstType = rr2ir_rm; \
659 switch (
UseMI.getOpcode()) {
701 bool Commute =
false;
711 if (isInt<7>(ImmVal)) {
714 NewUseOpc = NewUseOpcSImm7;
717 NewUseOpc = NewUseOpcMImm;
725 if (!isInt<7>(ImmVal))
727 NewUseOpc = NewUseOpcSImm7;
734 NewUseOpc = NewUseOpcMImm;
742 bool DeleteDef =
MRI->hasOneNonDBGUse(Reg);
747 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
749 DefMI.eraseFromParent();
757 if (GlobalBaseReg != 0)
758 return GlobalBaseReg;
761 GlobalBaseReg = VE::SX15;
770 return GlobalBaseReg;
774 return (reg - VE::VMP0) * 2 + VE::VM0;
789 switch (
MI.getOpcode()) {
802 MI.eraseFromParent();
811 switch (
MI.getNumExplicitOperands()) {
816 MIB.
addReg(
MI.getOperand(1).getReg());
820 MIB.
addImm(
MI.getOperand(1).getImm());
822 MIB.
addReg(
MI.getOperand(2).getReg());
824 MIB.
addReg(
MI.getOperand(3).getReg());
828 MIB.
addImm(
MI.getOperand(1).getImm());
830 MIB.
addReg(
MI.getOperand(2).getReg());
835 MIB.
addReg(
MI.getOperand(4).getReg());
844 static const std::pair<unsigned, std::pair<unsigned, unsigned>> VFMKMap[] = {
845 {VE::VFMKyal, {VE::VFMKLal, VE::VFMKLal}},
846 {VE::VFMKynal, {VE::VFMKLnal, VE::VFMKLnal}},
847 {VE::VFMKWyvl, {VE::PVFMKWUPvl, VE::PVFMKWLOvl}},
848 {VE::VFMKWyvyl, {VE::PVFMKWUPvml, VE::PVFMKWLOvml}},
849 {VE::VFMKSyvl, {VE::PVFMKSUPvl, VE::PVFMKSLOvl}},
850 {VE::VFMKSyvyl, {VE::PVFMKSUPvml, VE::PVFMKSLOvml}},
853 unsigned Opcode =
MI.getOpcode();
857 if (Found == std::end(VFMKMap))
860 unsigned OpcodeUpper = (*Found).second.first;
861 unsigned OpcodeLower = (*Found).second.second;
871 MI.eraseFromParent();
875 switch (
MI.getOpcode()) {
876 case VE::EXTEND_STACK: {
879 case VE::EXTEND_STACK_GUARD: {
880 MI.eraseFromParent();
883 case VE::GETSTACKTOP: {
912 int64_t Imm =
MI.getOperand(1).getImm();
914 MI.getOpcode() == VE::LVMyir ||
MI.getOpcode() == VE::LVMyir_y;
915 Register Src = IsSrcReg ?
MI.getOperand(2).getReg() : VE::NoRegister;
916 int64_t MImm = IsSrcReg ? 0 :
MI.getOperand(2).getImm();
917 bool KillSrc = IsSrcReg ?
MI.getOperand(2).isKill() :
false;
925 switch (
MI.getOpcode()) {
939 assert(
MI.getOperand(0).getReg() ==
MI.getOperand(3).getReg() &&
940 "LVMyir_y has different register in 3rd operand");
948 assert(
MI.getOperand(0).getReg() ==
MI.getOperand(3).getReg() &&
949 "LVMyim_y has different register in 3rd operand");
957 MI.eraseFromParent();
964 bool KillSrc =
MI.getOperand(1).isKill();
965 int64_t Imm =
MI.getOperand(2).getImm();
980 MI.eraseFromParent();
1023 MF.
insert(It, syscallMBB);
1046 BuildMI(BB, dl,
TII.get(VE::LDrii), VE::SX61)
1053 BuildMI(BB, dl,
TII.get(VE::LEAzii), VE::SX63)
1075 MI.eraseFromParent();
1107 MI.eraseFromParent();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
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
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
static bool isReg(const MCInst &MI, unsigned OpNo)
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 SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static bool IsIntegerCC(unsigned CC)
static void expandPseudoVFMK(const TargetInstrInfo &TI, MachineInstr &MI)
#define NCINSTRKIND(NAME)
static Register getVM512Lower(Register reg)
static void copyPhysSubRegs(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, const MCInstrDesc &MCID, unsigned int NumSubRegs, const unsigned *SubRegIdx, const TargetRegisterInfo *TRI)
static bool IsAliasOfSX(Register Reg)
static Register getVM512Upper(Register reg)
static void expandPseudoLogM(MachineInstr &MI, const MCInstrDesc &MCID)
static void addOperandsForVFMK(MachineInstrBuilder &MIB, MachineInstr &MI, bool Upper)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
Describe properties that are true of each instruction in the target description file.
unsigned getOpcode() const
Return the opcode number for this descriptor.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
LLVM_ABI 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.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
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 & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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)
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...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
} Stack Spill & Reload
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
} Branch Analysis & Modification
bool expandPostRAPseudo(MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register getGlobalBaseReg(MachineFunction *MF) const
} Optimization
const VERegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
VEInstrInfo(VESubtarget &ST)
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Stack Spill & Reload {.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Branch Analysis & Modification {.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool expandExtendStackPseudo(MachineInstr &MI) const
bool expandGetStackTopPseudo(MachineInstr &MI) const
void setGlobalBaseReg(Register Reg)
Register getGlobalBaseReg() const
uint64_t getAdjustedFrameSize(uint64_t FrameSize) const
Given a actual stack size as determined by FrameInfo, this function returns adjusted framesize which ...
const VEInstrInfo * getInstrInfo() const override
const VEFrameLowering * getFrameLowering() const override
self_iterator getIterator()
#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.
static bool isIndirectBranchOpcode(int Opc)
unsigned M1(unsigned Val)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
static uint64_t val2MImm(uint64_t Val)
val2MImm - Convert an integer immediate value to target MImm immediate.
unsigned getKillRegState(bool B)
static uint64_t mimm2Val(uint64_t Val)
mimm2Val - Convert a target MImm immediate to an integer immediate value.
static bool isUncondBranchOpcode(int Opc)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static bool isMImmVal(uint64_t Val)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.