28 "loongarch-disable-reloc-sched",
29 cl::desc(
"Disable scheduling of instructions with target flags"),
32#define GET_INSTRINFO_CTOR_DTOR
33#include "LoongArchGenInstrInfo.inc"
52 bool RenamableSrc)
const {
53 if (LoongArch::GPRRegClass.
contains(DstReg, SrcReg)) {
61 if (LoongArch::LSX128RegClass.
contains(DstReg, SrcReg)) {
69 if (LoongArch::LASX256RegClass.
contains(DstReg, SrcReg)) {
77 if (LoongArch::CFRRegClass.
contains(DstReg) &&
78 LoongArch::GPRRegClass.
contains(SrcReg)) {
84 if (LoongArch::GPRRegClass.
contains(DstReg) &&
85 LoongArch::CFRRegClass.
contains(SrcReg)) {
91 if (LoongArch::CFRRegClass.
contains(DstReg, SrcReg)) {
99 if (LoongArch::FPR32RegClass.
contains(DstReg, SrcReg)) {
100 Opc = LoongArch::FMOV_S;
101 }
else if (LoongArch::FPR64RegClass.
contains(DstReg, SrcReg)) {
102 Opc = LoongArch::FMOV_D;
103 }
else if (LoongArch::GPRRegClass.
contains(DstReg) &&
104 LoongArch::FPR32RegClass.
contains(SrcReg)) {
106 Opc = LoongArch::MOVFR2GR_S;
107 }
else if (LoongArch::GPRRegClass.
contains(DstReg) &&
108 LoongArch::FPR64RegClass.
contains(SrcReg)) {
110 Opc = LoongArch::MOVFR2GR_D;
129 if (LoongArch::GPRRegClass.hasSubClassEq(RC))
130 Opcode =
TRI.getRegSizeInBits(LoongArch::GPRRegClass) == 32
133 else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
134 Opcode = LoongArch::FST_S;
135 else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
136 Opcode = LoongArch::FST_D;
137 else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
138 Opcode = LoongArch::VST;
139 else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
140 Opcode = LoongArch::XVST;
141 else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
142 Opcode = LoongArch::PseudoST_CFR;
165 DL =
I->getDebugLoc();
168 if (LoongArch::GPRRegClass.hasSubClassEq(RC))
169 Opcode = RegInfo.getRegSizeInBits(LoongArch::GPRRegClass) == 32
172 else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
173 Opcode = LoongArch::FLD_S;
174 else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
175 Opcode = LoongArch::FLD_D;
176 else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
177 Opcode = LoongArch::VLD;
178 else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
179 Opcode = LoongArch::XVLD;
180 else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
181 Opcode = LoongArch::PseudoLD_CFR;
196 int &FrameIndex)
const {
204 switch (
MI.getOpcode()) {
207 case LoongArch::LD_W:
208 case LoongArch::FLD_S:
211 case LoongArch::LD_D:
212 case LoongArch::FLD_D:
218 case LoongArch::XVLD:
223 if ((
MI.getOperand(1).isFI()) &&
224 (
MI.getOperand(2).isImm()) &&
225 (
MI.getOperand(2).getImm() == 0)) {
226 FrameIndex =
MI.getOperand(1).getIndex();
227 return MI.getOperand(0).getReg();
234 int &FrameIndex)
const {
242 switch (
MI.getOpcode()) {
245 case LoongArch::ST_W:
246 case LoongArch::FST_S:
249 case LoongArch::ST_D:
250 case LoongArch::FST_D:
256 case LoongArch::XVST:
261 if ((
MI.getOperand(1).isFI()) &&
262 (
MI.getOperand(2).isImm()) &&
263 (
MI.getOperand(2).getImm() == 0)) {
264 FrameIndex =
MI.getOperand(1).getIndex();
265 return MI.getOperand(0).getReg();
283 for (
auto &Inst : Seq) {
285 case LoongArch::LU12I_W:
290 case LoongArch::ADDI_W:
292 case LoongArch::LU32I_D:
293 case LoongArch::LU52I_D:
299 case LoongArch::BSTRINS_D:
308 assert(
false &&
"Unknown insn emitted by LoongArchMatInt");
317 unsigned Opcode =
MI.getOpcode();
319 if (Opcode == TargetOpcode::INLINEASM ||
320 Opcode == TargetOpcode::INLINEASM_BR) {
323 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(), MAI);
326 unsigned NumBytes = 0;
332 switch (
Desc.getOpcode()) {
334 return Desc.getSize();
335 case TargetOpcode::STATEPOINT:
337 assert(NumBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
342 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
345 if (
F.hasFnAttribute(
"patchable-function-entry")) {
347 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
352 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
353 case TargetOpcode::PATCHABLE_TAIL_CALL:
356 case TargetOpcode::BUNDLE:
357 return getInstBundleSize(
MI);
363 const unsigned Opcode =
MI.getOpcode();
367 case LoongArch::ADDI_D:
369 case LoongArch::XORI:
370 return (
MI.getOperand(1).isReg() &&
371 MI.getOperand(1).getReg() == LoongArch::R0) ||
372 (
MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0);
374 return MI.isAsCheapAsAMove();
379 const PseudoSourceValue *PSV = MMO->getPseudoValue();
380 return PSV && PSV->isJumpTable();
388 if (!
Reg.isVirtual())
395 switch (
MI->getOpcode()) {
396 case LoongArch::ADDI_D:
397 case LoongArch::ADDI_W:
398 case LoongArch::PseudoLA_PCREL:
401 return MO.getIndex();
403 case LoongArch::LDX_D:
404 case LoongArch::LDX_W:
424 if (!
Reg.isVirtual())
431 switch (
MI->getOpcode()) {
432 case LoongArch::ADD_W:
440 case LoongArch::ALSL_W:
459 if (
MI.getOpcode() != LoongArch::PseudoBRIND)
463 if (!Reg.isVirtual())
472 switch (Def->getOpcode()) {
473 case LoongArch::LD_W:
481 case LoongArch::ADD_D:
482 case LoongArch::ADD_W:
499 Opc = *InverseOpcode;
505 case LoongArch::FADD_S:
506 case LoongArch::FADD_D:
507 case LoongArch::FMUL_S:
508 case LoongArch::FMUL_D:
509 case LoongArch::VFADD_S:
510 case LoongArch::VFADD_D:
511 case LoongArch::VFMUL_S:
512 case LoongArch::VFMUL_D:
513 case LoongArch::XVFADD_S:
514 case LoongArch::XVFADD_D:
515 case LoongArch::XVFMUL_S:
516 case LoongArch::XVFMUL_D:
523 case LoongArch::FMIN_S:
524 case LoongArch::FMIN_D:
525 case LoongArch::FMAX_S:
526 case LoongArch::FMAX_D:
527 case LoongArch::VFMIN_S:
528 case LoongArch::VFMIN_D:
529 case LoongArch::VFMAX_S:
530 case LoongArch::VFMAX_D:
531 case LoongArch::XVFMIN_S:
532 case LoongArch::XVFMIN_D:
533 case LoongArch::XVFMAX_S:
534 case LoongArch::XVFMAX_D:
536 case LoongArch::ADD_D:
537 case LoongArch::ADD_W:
541 case LoongArch::MUL_D:
542 case LoongArch::MUL_W:
543 case LoongArch::VADD_B:
544 case LoongArch::VADD_H:
545 case LoongArch::VADD_W:
546 case LoongArch::VADD_D:
547 case LoongArch::VMUL_B:
548 case LoongArch::VMUL_H:
549 case LoongArch::VMUL_W:
550 case LoongArch::VMUL_D:
551 case LoongArch::VAND_V:
552 case LoongArch::VOR_V:
553 case LoongArch::VXOR_V:
554 case LoongArch::VMIN_B:
555 case LoongArch::VMIN_H:
556 case LoongArch::VMIN_W:
557 case LoongArch::VMIN_D:
558 case LoongArch::VMIN_BU:
559 case LoongArch::VMIN_HU:
560 case LoongArch::VMIN_WU:
561 case LoongArch::VMIN_DU:
562 case LoongArch::VMAX_B:
563 case LoongArch::VMAX_H:
564 case LoongArch::VMAX_W:
565 case LoongArch::VMAX_D:
566 case LoongArch::VMAX_BU:
567 case LoongArch::VMAX_HU:
568 case LoongArch::VMAX_WU:
569 case LoongArch::VMAX_DU:
570 case LoongArch::XVADD_B:
571 case LoongArch::XVADD_H:
572 case LoongArch::XVADD_W:
573 case LoongArch::XVADD_D:
574 case LoongArch::XVMUL_B:
575 case LoongArch::XVMUL_H:
576 case LoongArch::XVMUL_W:
577 case LoongArch::XVMUL_D:
578 case LoongArch::XVAND_V:
579 case LoongArch::XVOR_V:
580 case LoongArch::XVXOR_V:
581 case LoongArch::XVMIN_B:
582 case LoongArch::XVMIN_H:
583 case LoongArch::XVMIN_W:
584 case LoongArch::XVMIN_D:
585 case LoongArch::XVMIN_BU:
586 case LoongArch::XVMIN_HU:
587 case LoongArch::XVMIN_WU:
588 case LoongArch::XVMIN_DU:
589 case LoongArch::XVMAX_B:
590 case LoongArch::XVMAX_H:
591 case LoongArch::XVMAX_W:
592 case LoongArch::XVMAX_D:
593 case LoongArch::XVMAX_BU:
594 case LoongArch::XVMAX_HU:
595 case LoongArch::XVMAX_WU:
596 case LoongArch::XVMAX_DU:
603std::optional<unsigned>
608 case LoongArch::ADD_W:
609 return LoongArch::SUB_W;
610 case LoongArch::ADD_D:
611 return LoongArch::SUB_D;
612 case LoongArch::SUB_W:
613 return LoongArch::ADD_W;
614 case LoongArch::SUB_D:
615 return LoongArch::ADD_D;
616 case LoongArch::FADD_S:
617 return LoongArch::FSUB_S;
618 case LoongArch::FADD_D:
619 return LoongArch::FSUB_D;
620 case LoongArch::FSUB_S:
621 return LoongArch::FADD_S;
622 case LoongArch::FSUB_D:
623 return LoongArch::FADD_D;
624 case LoongArch::VADD_B:
625 return LoongArch::VSUB_B;
626 case LoongArch::VADD_H:
627 return LoongArch::VSUB_H;
628 case LoongArch::VADD_W:
629 return LoongArch::VSUB_W;
630 case LoongArch::VADD_D:
631 return LoongArch::VSUB_D;
632 case LoongArch::VSUB_B:
633 return LoongArch::VADD_B;
634 case LoongArch::VSUB_H:
635 return LoongArch::VADD_H;
636 case LoongArch::VSUB_W:
637 return LoongArch::VADD_W;
638 case LoongArch::VSUB_D:
639 return LoongArch::VADD_D;
640 case LoongArch::VFADD_S:
641 return LoongArch::VFSUB_S;
642 case LoongArch::VFADD_D:
643 return LoongArch::VFSUB_D;
644 case LoongArch::VFSUB_S:
645 return LoongArch::VFADD_S;
646 case LoongArch::VFSUB_D:
647 return LoongArch::VFADD_D;
648 case LoongArch::XVADD_B:
649 return LoongArch::XVSUB_B;
650 case LoongArch::XVADD_H:
651 return LoongArch::XVSUB_H;
652 case LoongArch::XVADD_W:
653 return LoongArch::XVSUB_W;
654 case LoongArch::XVADD_D:
655 return LoongArch::XVSUB_D;
656 case LoongArch::XVSUB_B:
657 return LoongArch::XVADD_B;
658 case LoongArch::XVSUB_H:
659 return LoongArch::XVADD_H;
660 case LoongArch::XVSUB_W:
661 return LoongArch::XVADD_W;
662 case LoongArch::XVSUB_D:
663 return LoongArch::XVADD_D;
664 case LoongArch::XVFADD_S:
665 return LoongArch::XVFSUB_S;
666 case LoongArch::XVFADD_D:
667 return LoongArch::XVFSUB_D;
668 case LoongArch::XVFSUB_S:
669 return LoongArch::XVFADD_S;
670 case LoongArch::XVFSUB_D:
671 return LoongArch::XVFADD_D;
677 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
679 return MI.getOperand(
MI.getNumExplicitOperands() - 1).getMBB();
686 "Unknown conditional branch");
691 for (
int i = 0; i < NumOp - 1; i++)
699 bool AllowModify)
const {
705 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
711 int NumTerminators = 0;
712 for (
auto J =
I.getReverse(); J !=
MBB.rend() && isUnpredicatedTerminator(*J);
715 if (J->getDesc().isUnconditionalBranch() ||
716 J->getDesc().isIndirectBranch()) {
723 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.end()) {
724 while (std::next(FirstUncondOrIndirectBr) !=
MBB.end()) {
725 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
728 I = FirstUncondOrIndirectBr;
732 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
738 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
744 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
745 I->getDesc().isUnconditionalBranch()) {
756 int64_t BrOffset)
const {
764 case LoongArch::BLTU:
765 case LoongArch::BGEU:
767 case LoongArch::BEQZ:
768 case LoongArch::BNEZ:
769 case LoongArch::BCEQZ:
770 case LoongArch::BCNEZ:
773 case LoongArch::PseudoBR:
783 if (MO.getTargetFlags())
787 auto MII =
MI.getIterator();
788 auto MIE =
MBB->end();
819 switch (
MI.getOpcode()) {
820 case LoongArch::PCALAU12I: {
821 auto AddI = std::next(MII);
822 if (AddI == MIE || AddI->getOpcode() != LoongArch::ADDI_D)
824 auto Lu32I = std::next(AddI);
825 if (Lu32I == MIE || Lu32I->getOpcode() != LoongArch::LU32I_D)
827 auto MO0 =
MI.getOperand(1).getTargetFlags();
828 auto MO1 = AddI->getOperand(2).getTargetFlags();
829 auto MO2 = Lu32I->getOperand(2).getTargetFlags();
846 case LoongArch::LU52I_D: {
847 auto MO =
MI.getOperand(2).getTargetFlags();
858 if (
STI.hasFeature(LoongArch::FeatureRelax)) {
875 unsigned AddiOp =
STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
876 unsigned LdOp =
STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
877 switch (
MI.getOpcode()) {
878 case LoongArch::PCALAU12I: {
880 auto SecondOp = std::next(MII);
882 if (SecondOp == MIE || SecondOp->getOpcode() != AddiOp)
884 auto Ld = std::next(SecondOp);
885 if (Ld == MIE || Ld->getOpcode() != LdOp)
893 if (SecondOp == MIE ||
894 (SecondOp->getOpcode() != AddiOp && SecondOp->getOpcode() != LdOp))
909 case LoongArch::ADDI_W:
910 case LoongArch::ADDI_D: {
916 case LoongArch::LD_W:
917 case LoongArch::LD_D: {
923 case LoongArch::PseudoDESC_CALL: {
950 int *BytesRemoved)
const {
957 if (!
I->getDesc().isBranch())
963 I->eraseFromParent();
967 if (
I ==
MBB.begin())
970 if (!
I->getDesc().isConditionalBranch())
976 I->eraseFromParent();
989 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
991 "LoongArch branch conditions have at most two components!");
1003 for (
unsigned i = 1; i <
Cond.size(); ++i)
1026 assert(RS &&
"RegScavenger required for long branching");
1028 "new block should be inserted for expanding unconditional branch");
1036 bool Has32S =
STI.hasFeature(LoongArch::Feature32S);
1040 "Branch offsets outside of the signed 32-bit range not supported");
1045 auto II =
MBB.end();
1046 unsigned ADDIOp =
STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
1067 RS->enterBasicBlockEnd(
MBB);
1068 Register Scav = RS->scavengeRegisterBackwards(
1069 LoongArch::GPRRegClass, PCAI->
getIterator(),
false,
1071 if (Scav != LoongArch::NoRegister)
1072 RS->setRegUsed(Scav);
1076 Scav = LoongArch::R20;
1078 if (FrameIndex == -1)
1081 &LoongArch::GPRRegClass,
Register());
1088 &LoongArch::GPRRegClass,
Register());
1089 TRI->eliminateFrameIndex(RestoreBB.
back(),
1100 case LoongArch::BEQ:
1101 return LoongArch::BNE;
1102 case LoongArch::BNE:
1103 return LoongArch::BEQ;
1104 case LoongArch::BEQZ:
1105 return LoongArch::BNEZ;
1106 case LoongArch::BNEZ:
1107 return LoongArch::BEQZ;
1108 case LoongArch::BCEQZ:
1109 return LoongArch::BCNEZ;
1110 case LoongArch::BCNEZ:
1111 return LoongArch::BCEQZ;
1112 case LoongArch::BLT:
1113 return LoongArch::BGE;
1114 case LoongArch::BGE:
1115 return LoongArch::BLT;
1116 case LoongArch::BLTU:
1117 return LoongArch::BGEU;
1118 case LoongArch::BGEU:
1119 return LoongArch::BLTU;
1125 assert((
Cond.size() &&
Cond.size() <= 3) &&
"Invalid branch condition!");
1130std::pair<unsigned, unsigned>
1133 return std::make_pair(TF & Mask, TF & ~Mask);
1140 static const std::pair<unsigned, const char *> TargetFlags[] = {
1141 {MO_CALL,
"loongarch-call"},
1142 {MO_CALL_PLT,
"loongarch-call-plt"},
1143 {MO_PCREL_HI,
"loongarch-pcrel-hi"},
1144 {MO_PCREL_LO,
"loongarch-pcrel-lo"},
1145 {MO_PCREL64_LO,
"loongarch-pcrel64-lo"},
1146 {MO_PCREL64_HI,
"loongarch-pcrel64-hi"},
1147 {MO_GOT_PC_HI,
"loongarch-got-pc-hi"},
1148 {MO_GOT_PC_LO,
"loongarch-got-pc-lo"},
1149 {MO_GOT_PC64_LO,
"loongarch-got-pc64-lo"},
1150 {MO_GOT_PC64_HI,
"loongarch-got-pc64-hi"},
1151 {MO_LE_HI,
"loongarch-le-hi"},
1152 {MO_LE_LO,
"loongarch-le-lo"},
1153 {MO_LE64_LO,
"loongarch-le64-lo"},
1154 {MO_LE64_HI,
"loongarch-le64-hi"},
1155 {MO_IE_PC_HI,
"loongarch-ie-pc-hi"},
1156 {MO_IE_PC_LO,
"loongarch-ie-pc-lo"},
1157 {MO_IE_PC64_LO,
"loongarch-ie-pc64-lo"},
1158 {MO_IE_PC64_HI,
"loongarch-ie-pc64-hi"},
1159 {MO_LD_PC_HI,
"loongarch-ld-pc-hi"},
1160 {MO_GD_PC_HI,
"loongarch-gd-pc-hi"},
1161 {MO_CALL30,
"loongarch-call30"},
1162 {MO_CALL36,
"loongarch-call36"},
1163 {MO_DESC_PC_HI,
"loongarch-desc-pc-hi"},
1164 {MO_DESC_PC_LO,
"loongarch-desc-pc-lo"},
1165 {MO_DESC64_PC_LO,
"loongarch-desc64-pc-lo"},
1166 {MO_DESC64_PC_HI,
"loongarch-desc64-pc-hi"},
1167 {MO_DESC_LD,
"loongarch-desc-ld"},
1168 {MO_DESC_CALL,
"loongarch-desc-call"},
1169 {MO_LE_HI_R,
"loongarch-le-hi-r"},
1170 {MO_LE_ADD_R,
"loongarch-le-add-r"},
1171 {MO_LE_LO_R,
"loongarch-le-lo-r"},
1172 {MO_PCADD_HI,
"loongarch-pcadd-hi"},
1173 {MO_PCADD_LO,
"loongarch-pcadd-lo"},
1174 {MO_GOT_PCADD_HI,
"loongarch-got-pcadd-hi"},
1175 {MO_GOT_PCADD_LO,
"loongarch-got-pcadd-lo"},
1176 {MO_IE_PCADD_HI,
"loongarch-ie-pcadd-hi"},
1177 {MO_IE_PCADD_LO,
"loongarch-ie-pcadd-lo"},
1178 {MO_LD_PCADD_HI,
"loongarch-ld-pcadd-hi"},
1179 {MO_LD_PCADD_LO,
"loongarch-ld-pcadd-lo"},
1180 {MO_GD_PCADD_HI,
"loongarch-gd-pcadd-hi"},
1181 {MO_GD_PCADD_LO,
"loongarch-gd-pcadd-lo"},
1182 {MO_DESC_PCADD_HI,
"loongarch-pcadd-desc-hi"},
1183 {MO_DESC_PCADD_LO,
"loongarch-pcadd-desc-lo"}};
1190 static const std::pair<unsigned, const char *> TargetFlags[] = {
1191 {MO_RELAX,
"loongarch-relax"}};
1199 enum MemIOffsetType {
1215 case LoongArch::LDPTR_W:
1216 case LoongArch::LDPTR_D:
1217 case LoongArch::STPTR_W:
1218 case LoongArch::STPTR_D:
1221 case LoongArch::LD_B:
1222 case LoongArch::LD_H:
1223 case LoongArch::LD_W:
1224 case LoongArch::LD_D:
1225 case LoongArch::LD_BU:
1226 case LoongArch::LD_HU:
1227 case LoongArch::LD_WU:
1228 case LoongArch::ST_B:
1229 case LoongArch::ST_H:
1230 case LoongArch::ST_W:
1231 case LoongArch::ST_D:
1232 case LoongArch::FLD_S:
1233 case LoongArch::FLD_D:
1234 case LoongArch::FST_S:
1235 case LoongArch::FST_D:
1236 case LoongArch::VLD:
1237 case LoongArch::VST:
1238 case LoongArch::XVLD:
1239 case LoongArch::XVST:
1240 case LoongArch::VLDREPL_B:
1241 case LoongArch::XVLDREPL_B:
1244 case LoongArch::VLDREPL_H:
1245 case LoongArch::XVLDREPL_H:
1248 case LoongArch::VLDREPL_W:
1249 case LoongArch::XVLDREPL_W:
1252 case LoongArch::VLDREPL_D:
1253 case LoongArch::XVLDREPL_D:
1256 case LoongArch::VSTELM_B:
1257 case LoongArch::XVSTELM_B:
1260 case LoongArch::VSTELM_H:
1261 case LoongArch::XVSTELM_H:
1264 case LoongArch::VSTELM_W:
1265 case LoongArch::XVSTELM_W:
1268 case LoongArch::VSTELM_D:
1269 case LoongArch::XVSTELM_D:
1277 if ((AddrI.
getOpcode() != LoongArch::ADDI_W &&
1278 AddrI.
getOpcode() != LoongArch::ADDI_D) ||
1284 int64_t NewOffset = OldOffset + Disp;
1289 !(OT == Imm12 &&
isInt<12>(NewOffset)) &&
1293 !(OT == Imm8 &&
isInt<8>(NewOffset)) &&
1314 "Addressing mode not supported for folding");
1325 case LoongArch::VSTELM_B:
1326 case LoongArch::VSTELM_H:
1327 case LoongArch::VSTELM_W:
1328 case LoongArch::VSTELM_D:
1329 case LoongArch::XVSTELM_B:
1330 case LoongArch::XVSTELM_H:
1331 case LoongArch::XVSTELM_W:
1332 case LoongArch::XVSTELM_D:
1345 return MI.getOpcode() == LoongArch::ADDI_W &&
MI.getOperand(1).isReg() &&
1346 MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0;
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 unsigned getOppositeBranchOpc(unsigned Opcode)
static cl::opt< bool > DisableRelocSched("loongarch-disable-reloc-sched", cl::desc("Disable scheduling of instructions with target flags"), cl::init(false), cl::Hidden)
static int getJumpTableIndexFromReg(const MachineRegisterInfo &MRI, Register Reg)
static int getJumpTableIndexFromLoadAddr(const MachineRegisterInfo &MRI, Register Reg)
static bool isJumpTableLoad(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
const LoongArchSubtarget & STI
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
int getJumpTableIndex(const MachineInstr &MI) const override
bool isSafeToMove(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
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
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
MCInst getNop() const override
LoongArchInstrInfo(const LoongArchSubtarget &STI)
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) 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 insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) 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...
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
MCInstBuilder & addReg(MCRegister 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.
Describe properties that are true of each instruction in the target description file.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
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.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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 & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) 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.
const MachineBasicBlock * getParent() const
LLVM_ABI void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
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.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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...
MI-level Statepoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
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 =0
Return the target's register information.
Target - Wrapper for Target specific information.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static constexpr TypeSize getZero()
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getDirectFlags(const MachineOperand &MO)
InstSeq generateInstSeq(int64_t Val)
bool isSEXT_W(const MachineInstr &MI)
initializer< Ty > init(const Ty &Val)
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr RegState getDefRegState(bool B)
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
MCRegisterClass TargetRegisterClass
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.