24#define GET_INSTRINFO_CTOR_DTOR
25#include "LoongArchGenInstrInfo.inc"
29 LoongArch::ADJCALLSTACKUP),
43 if (LoongArch::GPRRegClass.
contains(DstReg, SrcReg)) {
51 if (LoongArch::LSX128RegClass.
contains(DstReg, SrcReg)) {
59 if (LoongArch::LASX256RegClass.
contains(DstReg, SrcReg)) {
67 if (LoongArch::CFRRegClass.
contains(DstReg) &&
68 LoongArch::GPRRegClass.
contains(SrcReg)) {
74 if (LoongArch::GPRRegClass.
contains(DstReg) &&
75 LoongArch::CFRRegClass.
contains(SrcReg)) {
83 if (LoongArch::FPR32RegClass.
contains(DstReg, SrcReg)) {
84 Opc = LoongArch::FMOV_S;
85 }
else if (LoongArch::FPR64RegClass.
contains(DstReg, SrcReg)) {
86 Opc = LoongArch::FMOV_D;
104 if (LoongArch::GPRRegClass.hasSubClassEq(RC))
105 Opcode =
TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
108 else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
109 Opcode = LoongArch::FST_S;
110 else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
111 Opcode = LoongArch::FST_D;
112 else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
113 Opcode = LoongArch::VST;
114 else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
115 Opcode = LoongArch::XVST;
116 else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
117 Opcode = LoongArch::PseudoST_CFR;
142 if (LoongArch::GPRRegClass.hasSubClassEq(RC))
143 Opcode =
TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
146 else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
147 Opcode = LoongArch::FLD_S;
148 else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
149 Opcode = LoongArch::FLD_D;
150 else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
151 Opcode = LoongArch::VLD;
152 else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
153 Opcode = LoongArch::XVLD;
154 else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
155 Opcode = LoongArch::PseudoLD_CFR;
181 for (
auto &Inst : Seq) {
183 case LoongArch::LU12I_W:
188 case LoongArch::ADDI_W:
190 case LoongArch::LU32I_D:
191 case LoongArch::LU52I_D:
198 assert(
false &&
"Unknown insn emitted by LoongArchMatInt");
207 unsigned Opcode =
MI.getOpcode();
209 if (Opcode == TargetOpcode::INLINEASM ||
210 Opcode == TargetOpcode::INLINEASM_BR) {
213 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(), *MAI);
215 return MI.getDesc().getSize();
220 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
222 return MI.getOperand(
MI.getNumExplicitOperands() - 1).getMBB();
229 "Unknown conditional branch");
234 for (
int i = 0; i < NumOp - 1; i++)
242 bool AllowModify)
const {
248 if (
I ==
MBB.
end() || !isUnpredicatedTerminator(*
I))
254 int NumTerminators = 0;
255 for (
auto J =
I.getReverse(); J !=
MBB.
rend() && isUnpredicatedTerminator(*J);
258 if (J->getDesc().isUnconditionalBranch() ||
259 J->getDesc().isIndirectBranch()) {
266 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.
end()) {
267 while (std::next(FirstUncondOrIndirectBr) !=
MBB.
end()) {
268 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
271 I = FirstUncondOrIndirectBr;
275 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
281 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
287 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
288 I->getDesc().isUnconditionalBranch()) {
299 int64_t BrOffset)
const {
307 case LoongArch::BLTU:
308 case LoongArch::BGEU:
309 return isInt<18>(BrOffset);
310 case LoongArch::BEQZ:
311 case LoongArch::BNEZ:
312 case LoongArch::BCEQZ:
313 case LoongArch::BCNEZ:
314 return isInt<23>(BrOffset);
316 case LoongArch::PseudoBR:
317 return isInt<28>(BrOffset);
322 int *BytesRemoved)
const {
329 if (!
I->getDesc().isBranch())
335 I->eraseFromParent();
342 if (!
I->getDesc().isConditionalBranch())
348 I->eraseFromParent();
361 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
363 "LoongArch branch conditions have at most two components!");
375 for (
unsigned i = 1; i <
Cond.size(); ++i)
398 assert(RS &&
"RegScavenger required for long branching");
400 "new block should be inserted for expanding unconditional branch");
409 if (!isInt<32>(BrOffset))
411 "Branch offsets outside of the signed 32-bit range not supported");
413 Register ScratchReg =
MRI.createVirtualRegister(&LoongArch::GPRRegClass);
431 LoongArch::GPRRegClass, PCALAU12I.
getIterator(),
false,
433 if (Scav != LoongArch::NoRegister)
438 Scav = LoongArch::R20;
440 if (FrameIndex == -1)
450 TRI->eliminateFrameIndex(RestoreBB.
back(),
453 MRI.replaceRegWith(ScratchReg, Scav);
462 return LoongArch::BNE;
464 return LoongArch::BEQ;
465 case LoongArch::BEQZ:
466 return LoongArch::BNEZ;
467 case LoongArch::BNEZ:
468 return LoongArch::BEQZ;
469 case LoongArch::BCEQZ:
470 return LoongArch::BCNEZ;
471 case LoongArch::BCNEZ:
472 return LoongArch::BCEQZ;
474 return LoongArch::BGE;
476 return LoongArch::BLT;
477 case LoongArch::BLTU:
478 return LoongArch::BGEU;
479 case LoongArch::BGEU:
480 return LoongArch::BLTU;
486 assert((
Cond.size() &&
Cond.size() <= 3) &&
"Invalid branch condition!");
491std::pair<unsigned, unsigned>
493 return std::make_pair(TF, 0u);
498 using namespace LoongArchII;
500 static const std::pair<unsigned, const char *> TargetFlags[] = {
501 {MO_CALL,
"loongarch-call"},
502 {MO_CALL_PLT,
"loongarch-call-plt"},
503 {MO_PCREL_HI,
"loongarch-pcrel-hi"},
504 {MO_PCREL_LO,
"loongarch-pcrel-lo"},
505 {MO_PCREL64_LO,
"loongarch-pcrel64-lo"},
506 {MO_PCREL64_HI,
"loongarch-pcrel64-hi"},
507 {MO_GOT_PC_HI,
"loongarch-got-pc-hi"},
508 {MO_GOT_PC_LO,
"loongarch-got-pc-lo"},
509 {MO_GOT_PC64_LO,
"loongarch-got-pc64-lo"},
510 {MO_GOT_PC64_HI,
"loongarch-got-pc64-hi"},
511 {MO_LE_HI,
"loongarch-le-hi"},
512 {MO_LE_LO,
"loongarch-le-lo"},
513 {MO_LE64_LO,
"loongarch-le64-lo"},
514 {MO_LE64_HI,
"loongarch-le64-hi"},
515 {MO_IE_PC_HI,
"loongarch-ie-pc-hi"},
516 {MO_IE_PC_LO,
"loongarch-ie-pc-lo"},
517 {MO_IE_PC64_LO,
"loongarch-ie-pc64-lo"},
518 {MO_IE_PC64_HI,
"loongarch-ie-pc64-hi"},
519 {MO_LD_PC_HI,
"loongarch-ld-pc-hi"},
520 {MO_GD_PC_HI,
"loongarch-gd-pc-hi"}};
unsigned const MachineRegisterInfo * MRI
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static unsigned getOppositeBranchOpc(unsigned Opcode)
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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),...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
const LoongArchSubtarget & STI
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
LoongArchInstrInfo(LoongArchSubtarget &STI)
MCInst getNop() const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
LoongArchMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private Lo...
int getBranchRelaxationSpillFrameIndex()
This class is intended to be used as a base class for asm properties and features specific to the tar...
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
Wrapper class representing physical registers. Should be passed by value.
unsigned pred_size() const
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, uint64_t s, 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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
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 & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
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
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateImm(int64_t Val)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Target - Wrapper for Target specific information.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
InstSeq generateInstSeq(int64_t Val)
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getKillRegState(bool B)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.