40#include "llvm/IR/IntrinsicsX86.h"
50#define DEBUG_TYPE "X86-isel"
56#define GET_GLOBALISEL_PREDICATE_BITSET
57#include "X86GenGlobalISel.inc"
58#undef GET_GLOBALISEL_PREDICATE_BITSET
75 Align Alignment)
const;
144#define GET_GLOBALISEL_PREDICATES_DECL
145#include "X86GenGlobalISel.inc"
146#undef GET_GLOBALISEL_PREDICATES_DECL
148#define GET_GLOBALISEL_TEMPORARIES_DECL
149#include "X86GenGlobalISel.inc"
150#undef GET_GLOBALISEL_TEMPORARIES_DECL
155#define GET_GLOBALISEL_IMPL
156#include "X86GenGlobalISel.inc"
157#undef GET_GLOBALISEL_IMPL
162 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
165#include
"X86GenGlobalISel.inc"
168#include
"X86GenGlobalISel.inc"
176X86InstructionSelector::getRegClass(
LLT Ty,
const RegisterBank &RB)
const {
177 if (RB.
getID() == X86::GPRRegBankID) {
179 return &X86::GR8RegClass;
181 return &X86::GR16RegClass;
183 return &X86::GR32RegClass;
185 return &X86::GR64RegClass;
187 if (RB.
getID() == X86::VECRRegBankID) {
189 return STI.
hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
191 return STI.
hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
193 return STI.
hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
195 return STI.
hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
197 return STI.
hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
199 return &X86::VR512RegClass;
202 if (RB.
getID() == X86::PSRRegBankID) {
204 return &X86::RFP80RegClass;
206 return &X86::RFP64RegClass;
208 return &X86::RFP32RegClass;
214const TargetRegisterClass *
215X86InstructionSelector::getRegClass(LLT Ty,
Register Reg,
216 MachineRegisterInfo &
MRI)
const {
221static unsigned getSubRegIndex(
const TargetRegisterClass *RC) {
222 unsigned SubIdx = X86::NoSubRegister;
223 if (RC == &X86::GR32RegClass) {
224 SubIdx = X86::sub_32bit;
225 }
else if (RC == &X86::GR16RegClass) {
226 SubIdx = X86::sub_16bit;
227 }
else if (RC == &X86::GR8RegClass) {
228 SubIdx = X86::sub_8bit;
237 return &X86::GR64RegClass;
239 return &X86::GR32RegClass;
241 return &X86::GR16RegClass;
243 return &X86::GR8RegClass;
251bool X86InstructionSelector::selectDebugInstr(MachineInstr &
I,
252 MachineRegisterInfo &
MRI)
const {
253 for (MachineOperand &MO :
I.operands()) {
261 LLT Ty =
MRI.getType(
Reg);
263 const TargetRegisterClass *RC =
270 dbgs() <<
"Warning: DBG_VALUE operand has unexpected size/bank\n");
281bool X86InstructionSelector::selectCopy(MachineInstr &
I,
282 MachineRegisterInfo &
MRI)
const {
283 Register DstReg =
I.getOperand(0).getReg();
287 Register SrcReg =
I.getOperand(1).getReg();
292 assert(
I.isCopy() &&
"Generic operators do not allow physical registers");
294 if (DstSize > SrcSize && SrcRegBank.
getID() == X86::GPRRegBankID &&
295 DstRegBank.
getID() == X86::GPRRegBankID) {
297 const TargetRegisterClass *SrcRC =
301 if (SrcRC != DstRC) {
303 Register ExtSrc =
MRI.createVirtualRegister(DstRC);
305 TII.get(TargetOpcode::SUBREG_TO_REG))
309 .
addImm(getSubRegIndex(SrcRC));
311 I.getOperand(1).setReg(ExtSrc);
316 if (SrcSize == 16 && SrcRegBank.
getID() == X86::GPRRegBankID &&
317 (DstRegBank.
getID() == X86::VECRRegBankID)) {
322 Register ExtReg =
MRI.createVirtualRegister(&X86::GR32RegClass);
323 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::SUBREG_TO_REG),
330 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
337 if (DstSize == 16 && DstRegBank.
getID() == X86::GPRRegBankID &&
338 (SrcRegBank.
getID() == X86::VECRRegBankID)) {
343 Register Temp32 =
MRI.createVirtualRegister(&X86::GR32RegClass);
344 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Temp32)
348 if (
Register Dst32 =
TRI.getMatchingSuperReg(DstReg, X86::sub_16bit,
349 &X86::GR32RegClass)) {
351 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Dst32)
355 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
356 .
addReg(Temp32, 0, X86::sub_16bit);
366 "No phys reg on generic operators");
367 assert((DstSize == SrcSize ||
372 "Copy with different width?!");
374 const TargetRegisterClass *DstRC =
377 if (SrcRegBank.
getID() == X86::GPRRegBankID &&
378 DstRegBank.
getID() == X86::GPRRegBankID && SrcSize > DstSize &&
384 if (DstRC != SrcRC) {
385 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
386 I.getOperand(1).substPhysReg(SrcReg,
TRI);
393 const TargetRegisterClass *OldRC =
MRI.getRegClassOrNull(DstReg);
401 I.setDesc(
TII.get(X86::COPY));
405bool X86InstructionSelector::select(MachineInstr &
I) {
406 assert(
I.getParent() &&
"Instruction should be in a basic block!");
407 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
413 unsigned Opcode =
I.getOpcode();
417 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
423 if (
I.isDebugInstr())
429 assert(
I.getNumOperands() ==
I.getNumExplicitOperands() &&
430 "Generic instruction has unexpected implicit operands\n");
432 if (selectImpl(
I, *CoverageInfo))
438 switch (
I.getOpcode()) {
441 case TargetOpcode::G_STORE:
442 case TargetOpcode::G_LOAD:
444 case TargetOpcode::G_PTR_ADD:
445 case TargetOpcode::G_FRAME_INDEX:
446 return selectFrameIndexOrGep(
I,
MRI, MF);
447 case TargetOpcode::G_GLOBAL_VALUE:
448 return selectGlobalValue(
I,
MRI, MF);
449 case TargetOpcode::G_CONSTANT:
450 return selectConstant(
I,
MRI, MF);
451 case TargetOpcode::G_FCONSTANT:
452 return materializeFP(
I,
MRI, MF);
453 case TargetOpcode::G_PTRTOINT:
454 case TargetOpcode::G_TRUNC:
455 return selectTruncOrPtrToInt(
I,
MRI, MF);
456 case TargetOpcode::G_INTTOPTR:
457 case TargetOpcode::G_FREEZE:
459 case TargetOpcode::G_ZEXT:
460 return selectZext(
I,
MRI, MF);
461 case TargetOpcode::G_ANYEXT:
462 return selectAnyext(
I,
MRI, MF);
463 case TargetOpcode::G_ICMP:
464 return selectCmp(
I,
MRI, MF);
465 case TargetOpcode::G_FCMP:
466 return selectFCmp(
I,
MRI, MF);
467 case TargetOpcode::G_UADDE:
468 case TargetOpcode::G_UADDO:
469 case TargetOpcode::G_USUBE:
470 case TargetOpcode::G_USUBO:
471 return selectUAddSub(
I,
MRI, MF);
472 case TargetOpcode::G_UNMERGE_VALUES:
474 case TargetOpcode::G_MERGE_VALUES:
475 case TargetOpcode::G_CONCAT_VECTORS:
477 case TargetOpcode::G_EXTRACT:
478 return selectExtract(
I,
MRI, MF);
479 case TargetOpcode::G_INSERT:
480 return selectInsert(
I,
MRI, MF);
481 case TargetOpcode::G_BRCOND:
482 return selectCondBranch(
I,
MRI, MF);
483 case TargetOpcode::G_IMPLICIT_DEF:
484 case TargetOpcode::G_PHI:
485 return selectImplicitDefOrPHI(
I,
MRI);
486 case TargetOpcode::G_MUL:
487 case TargetOpcode::G_SMULH:
488 case TargetOpcode::G_UMULH:
489 case TargetOpcode::G_SDIV:
490 case TargetOpcode::G_UDIV:
491 case TargetOpcode::G_SREM:
492 case TargetOpcode::G_UREM:
493 return selectMulDivRem(
I,
MRI, MF);
494 case TargetOpcode::G_SELECT:
495 return selectSelect(
I,
MRI, MF);
501unsigned X86InstructionSelector::getPtrLoadStoreOp(
const LLT &Ty,
502 const RegisterBank &RB,
503 unsigned Opc)
const {
504 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
505 "Only G_STORE and G_LOAD are expected for selection");
507 bool IsLoad = (
Opc == TargetOpcode::G_LOAD);
512 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
514 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
520unsigned X86InstructionSelector::getLoadStoreOp(
const LLT &Ty,
521 const RegisterBank &RB,
523 Align Alignment)
const {
524 bool Isload = (
Opc == TargetOpcode::G_LOAD);
525 bool HasAVX = STI.
hasAVX();
527 bool HasVLX = STI.hasVLX();
530 if (X86::GPRRegBankID == RB.
getID())
531 return Isload ? X86::MOV8rm : X86::MOV8mr;
533 if (X86::GPRRegBankID == RB.
getID())
534 return Isload ? X86::MOV16rm : X86::MOV16mr;
536 if (X86::GPRRegBankID == RB.
getID())
537 return Isload ? X86::MOV32rm : X86::MOV32mr;
538 if (X86::VECRRegBankID == RB.
getID())
539 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
540 HasAVX ? X86::VMOVSSrm_alt :
542 : (HasAVX512 ?
X86::VMOVSSZmr :
543 HasAVX ?
X86::VMOVSSmr :
545 if (X86::PSRRegBankID == RB.
getID())
546 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
548 if (X86::GPRRegBankID == RB.
getID())
549 return Isload ? X86::MOV64rm : X86::MOV64mr;
550 if (X86::VECRRegBankID == RB.
getID())
551 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
552 HasAVX ? X86::VMOVSDrm_alt :
554 : (HasAVX512 ?
X86::VMOVSDZmr :
555 HasAVX ?
X86::VMOVSDmr :
557 if (X86::PSRRegBankID == RB.
getID())
558 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
560 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
562 if (Alignment >=
Align(16))
563 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
565 ? X86::VMOVAPSZ128rm_NOVLX
566 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
567 : (HasVLX ?
X86::VMOVAPSZ128mr
569 ?
X86::VMOVAPSZ128mr_NOVLX
570 : HasAVX ?
X86::VMOVAPSmr :
X86::MOVAPSmr);
572 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
574 ? X86::VMOVUPSZ128rm_NOVLX
575 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
576 : (HasVLX ? X86::VMOVUPSZ128mr
578 ? X86::VMOVUPSZ128mr_NOVLX
579 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
581 if (Alignment >=
Align(32))
582 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
583 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
585 : (HasVLX ?
X86::VMOVAPSZ256mr
586 : HasAVX512 ?
X86::VMOVAPSZ256mr_NOVLX
589 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
590 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
592 : (HasVLX ? X86::VMOVUPSZ256mr
593 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
596 if (Alignment >=
Align(64))
597 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
599 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
608 assert(
I.getOperand(0).isReg() &&
"unsupported operand.");
609 assert(
MRI.getType(
I.getOperand(0).getReg()).isPointer() &&
610 "unsupported type.");
612 switch (
I.getOpcode()) {
615 case TargetOpcode::G_FRAME_INDEX:
619 case TargetOpcode::G_PTR_ADD: {
623 AM.
Disp =
static_cast<int32_t
>(Imm);
624 AM.
Base.
Reg =
I.getOperand(1).getReg();
630 case TargetOpcode::G_GLOBAL_VALUE: {
631 auto GV =
I.getOperand(1).getGlobal();
632 if (GV->isThreadLocal()) {
652 "RIP-relative addresses can't have additional register operands");
657 case TargetOpcode::G_CONSTANT_POOL: {
665 else if (STI.is64Bit())
668 AM.
Disp =
I.getOperand(1).getIndex();
673 AM.
Base.
Reg =
I.getOperand(0).getReg();
677bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &
I,
678 MachineRegisterInfo &
MRI,
679 MachineFunction &MF)
const {
680 unsigned Opc =
I.getOpcode();
682 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
683 "Only G_STORE and G_LOAD are expected for selection");
685 const Register DefReg =
I.getOperand(0).getReg();
686 LLT Ty =
MRI.getType(DefReg);
690 auto &MemOp = **
I.memoperands_begin();
691 if (MemOp.isAtomic()) {
697 if (!MemOp.isUnordered()) {
707 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB,
Opc);
711 I.setDesc(
TII.get(NewOpc));
712 MachineInstrBuilder MIB(MF,
I);
713 MachineInstr *Ptr =
MRI.getVRegDef(
I.getOperand(1).getReg());
719 if (
Opc == TargetOpcode::G_LOAD) {
729 I.addImplicitDefUseOperands(MF);
742bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &
I,
743 MachineRegisterInfo &
MRI,
744 MachineFunction &MF)
const {
745 unsigned Opc =
I.getOpcode();
747 assert((
Opc == TargetOpcode::G_FRAME_INDEX ||
Opc == TargetOpcode::G_PTR_ADD) &&
748 "unexpected instruction");
750 const Register DefReg =
I.getOperand(0).getReg();
751 LLT Ty =
MRI.getType(DefReg);
754 unsigned NewOpc =
getLeaOP(Ty, STI);
755 I.setDesc(
TII.get(NewOpc));
756 MachineInstrBuilder MIB(MF,
I);
758 if (
Opc == TargetOpcode::G_FRAME_INDEX) {
761 MachineOperand &InxOp =
I.getOperand(2);
764 MIB.addImm(0).addReg(0);
770bool X86InstructionSelector::selectGlobalValue(MachineInstr &
I,
771 MachineRegisterInfo &
MRI,
772 MachineFunction &MF)
const {
773 assert((
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
774 "unexpected instruction");
780 const Register DefReg =
I.getOperand(0).getReg();
781 LLT Ty =
MRI.getType(DefReg);
782 unsigned NewOpc =
getLeaOP(Ty, STI);
784 I.setDesc(
TII.get(NewOpc));
785 MachineInstrBuilder MIB(MF,
I);
793bool X86InstructionSelector::selectConstant(MachineInstr &
I,
794 MachineRegisterInfo &
MRI,
795 MachineFunction &MF)
const {
796 assert((
I.getOpcode() == TargetOpcode::G_CONSTANT) &&
797 "unexpected instruction");
799 const Register DefReg =
I.getOperand(0).getReg();
800 LLT Ty =
MRI.getType(DefReg);
806 if (
I.getOperand(1).isCImm()) {
807 Val =
I.getOperand(1).getCImm()->getZExtValue();
808 I.getOperand(1).ChangeToImmediate(Val);
809 }
else if (
I.getOperand(1).isImm()) {
810 Val =
I.getOperand(1).getImm();
817 NewOpc = X86::MOV8ri;
820 NewOpc = X86::MOV16ri;
823 NewOpc = X86::MOV32ri;
828 NewOpc = X86::MOV64ri32;
830 NewOpc = X86::MOV64ri;
836 I.setDesc(
TII.get(NewOpc));
845 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
846 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
847 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
850bool X86InstructionSelector::selectTurnIntoCOPY(
851 MachineInstr &
I, MachineRegisterInfo &
MRI,
const Register DstReg,
852 const TargetRegisterClass *DstRC,
const Register SrcReg,
853 const TargetRegisterClass *SrcRC)
const {
861 I.setDesc(
TII.get(X86::COPY));
865bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &
I,
866 MachineRegisterInfo &
MRI,
867 MachineFunction &MF)
const {
868 assert((
I.getOpcode() == TargetOpcode::G_TRUNC ||
869 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
870 "unexpected instruction");
872 const Register DstReg =
I.getOperand(0).getReg();
873 const Register SrcReg =
I.getOperand(1).getReg();
875 const LLT DstTy =
MRI.getType(DstReg);
876 const LLT SrcTy =
MRI.getType(SrcReg);
883 <<
" input/output on different banks\n");
887 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
888 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
890 if (!DstRC || !SrcRC)
897 return selectTurnIntoCOPY(
I,
MRI, DstReg, DstRC, SrcReg, SrcRC);
899 if (DstRB.
getID() != X86::GPRRegBankID)
903 if (DstRC == SrcRC) {
905 SubIdx = X86::NoSubRegister;
906 }
else if (DstRC == &X86::GR32RegClass) {
907 SubIdx = X86::sub_32bit;
908 }
else if (DstRC == &X86::GR16RegClass) {
909 SubIdx = X86::sub_16bit;
910 }
else if (DstRC == &X86::GR8RegClass) {
911 SubIdx = X86::sub_8bit;
916 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
925 I.getOperand(1).setSubReg(SubIdx);
927 I.setDesc(
TII.get(X86::COPY));
931bool X86InstructionSelector::selectZext(MachineInstr &
I,
932 MachineRegisterInfo &
MRI,
933 MachineFunction &MF)
const {
934 assert((
I.getOpcode() == TargetOpcode::G_ZEXT) &&
"unexpected instruction");
936 const Register DstReg =
I.getOperand(0).getReg();
937 const Register SrcReg =
I.getOperand(1).getReg();
939 const LLT DstTy =
MRI.getType(DstReg);
940 const LLT SrcTy =
MRI.getType(SrcReg);
943 "8=>16 Zext is handled by tablegen");
945 "8=>32 Zext is handled by tablegen");
947 "16=>32 Zext is handled by tablegen");
949 "8=>64 Zext is handled by tablegen");
951 "16=>64 Zext is handled by tablegen");
953 "32=>64 Zext is handled by tablegen");
960 AndOpc = X86::AND8ri;
962 AndOpc = X86::AND16ri;
964 AndOpc = X86::AND32ri;
966 AndOpc = X86::AND64ri32;
975 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
979 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
985 MachineInstr &AndInst =
986 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(AndOpc), DstReg)
996bool X86InstructionSelector::selectAnyext(MachineInstr &
I,
997 MachineRegisterInfo &
MRI,
998 MachineFunction &MF)
const {
999 assert((
I.getOpcode() == TargetOpcode::G_ANYEXT) &&
"unexpected instruction");
1001 const Register DstReg =
I.getOperand(0).getReg();
1002 const Register SrcReg =
I.getOperand(1).getReg();
1004 const LLT DstTy =
MRI.getType(DstReg);
1005 const LLT SrcTy =
MRI.getType(SrcReg);
1011 "G_ANYEXT input/output on different banks\n");
1014 "G_ANYEXT incorrect operand size");
1016 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
1017 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
1023 return selectTurnIntoCOPY(
I,
MRI, SrcReg, SrcRC, DstReg, DstRC);
1025 if (DstRB.
getID() != X86::GPRRegBankID)
1035 if (SrcRC == DstRC) {
1036 I.setDesc(
TII.get(X86::COPY));
1041 TII.get(TargetOpcode::SUBREG_TO_REG))
1045 .
addImm(getSubRegIndex(SrcRC));
1047 I.eraseFromParent();
1051bool X86InstructionSelector::selectCmp(MachineInstr &
I,
1052 MachineRegisterInfo &
MRI,
1053 MachineFunction &MF)
const {
1054 assert((
I.getOpcode() == TargetOpcode::G_ICMP) &&
"unexpected instruction");
1068 LLT Ty =
MRI.getType(
LHS);
1074 OpCmp = X86::CMP8rr;
1077 OpCmp = X86::CMP16rr;
1080 OpCmp = X86::CMP32rr;
1083 OpCmp = X86::CMP64rr;
1087 MachineInstr &CmpInst =
1088 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1092 MachineInstr &SetInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1093 TII.get(X86::SETCCr),
I.getOperand(0).getReg()).
addImm(CC);
1098 I.eraseFromParent();
1102bool X86InstructionSelector::selectFCmp(MachineInstr &
I,
1103 MachineRegisterInfo &
MRI,
1104 MachineFunction &MF)
const {
1105 assert((
I.getOpcode() == TargetOpcode::G_FCMP) &&
"unexpected instruction");
1107 Register LhsReg =
I.getOperand(2).getReg();
1108 Register RhsReg =
I.getOperand(3).getReg();
1113 static const uint16_t SETFOpcTable[2][3] = {
1116 const uint16_t *SETFOpc =
nullptr;
1117 switch (Predicate) {
1121 SETFOpc = &SETFOpcTable[0][0];
1124 SETFOpc = &SETFOpcTable[1][0];
1129 "Both arguments of FCMP need to be virtual!");
1132 assert((LhsBank == RhsBank) &&
1133 "Both banks assigned to FCMP arguments need to be same!");
1137 LLT Ty =
MRI.getType(LhsReg);
1142 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr32
1146 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr64
1150 OpCmp = X86::UCOM_FpIr80;
1154 Register ResultReg =
I.getOperand(0).getReg();
1159 MachineInstr &CmpInst =
1160 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1164 Register FlagReg1 =
MRI.createVirtualRegister(&X86::GR8RegClass);
1165 Register FlagReg2 =
MRI.createVirtualRegister(&X86::GR8RegClass);
1166 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1167 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1168 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1169 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1170 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1171 TII.get(SETFOpc[2]), ResultReg)
1179 I.eraseFromParent();
1192 MachineInstr &CmpInst =
1193 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1201 I.eraseFromParent();
1205bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1206 MachineRegisterInfo &
MRI,
1207 MachineFunction &MF)
const {
1208 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1209 I.getOpcode() == TargetOpcode::G_UADDO ||
1210 I.getOpcode() == TargetOpcode::G_USUBE ||
1211 I.getOpcode() == TargetOpcode::G_USUBO) &&
1212 "unexpected instruction");
1216 const Register DstReg = CarryMI.getDstReg();
1217 const Register CarryOutReg = CarryMI.getCarryOutReg();
1218 const Register Op0Reg = CarryMI.getLHSReg();
1219 const Register Op1Reg = CarryMI.getRHSReg();
1220 bool IsSub = CarryMI.isSub();
1222 const LLT DstTy =
MRI.getType(DstReg);
1223 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1226 unsigned OpADC, OpADD, OpSBB, OpSUB;
1229 OpADC = X86::ADC8rr;
1230 OpADD = X86::ADD8rr;
1231 OpSBB = X86::SBB8rr;
1232 OpSUB = X86::SUB8rr;
1235 OpADC = X86::ADC16rr;
1236 OpADD = X86::ADD16rr;
1237 OpSBB = X86::SBB16rr;
1238 OpSUB = X86::SUB16rr;
1241 OpADC = X86::ADC32rr;
1242 OpADD = X86::ADD32rr;
1243 OpSBB = X86::SBB32rr;
1244 OpSUB = X86::SUB32rr;
1247 OpADC = X86::ADC64rr;
1248 OpADD = X86::ADD64rr;
1249 OpSBB = X86::SBB64rr;
1250 OpSUB = X86::SUB64rr;
1257 const TargetRegisterClass *CarryRC =
1260 unsigned Opcode = IsSub ? OpSUB : OpADD;
1264 Register CarryInReg = CarryInMI->getCarryInReg();
1265 MachineInstr *
Def =
MRI.getVRegDef(CarryInReg);
1266 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1267 CarryInReg =
Def->getOperand(1).getReg();
1268 Def =
MRI.getVRegDef(CarryInReg);
1272 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1273 Def->getOpcode() == TargetOpcode::G_UADDO ||
1274 Def->getOpcode() == TargetOpcode::G_USUBE ||
1275 Def->getOpcode() == TargetOpcode::G_USUBO) {
1278 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::CMP8ri))
1285 Opcode = IsSub ? OpSBB : OpADC;
1291 Opcode = IsSub ? OpSUB : OpADD;
1296 MachineInstr &Inst =
1297 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1301 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1308 I.eraseFromParent();
1312bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1313 MachineRegisterInfo &
MRI,
1314 MachineFunction &MF)
const {
1315 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1316 "unexpected instruction");
1318 const Register DstReg =
I.getOperand(0).getReg();
1319 const Register SrcReg =
I.getOperand(1).getReg();
1320 int64_t
Index =
I.getOperand(2).getImm();
1322 const LLT DstTy =
MRI.getType(DstReg);
1323 const LLT SrcTy =
MRI.getType(SrcReg);
1334 if (!emitExtractSubreg(DstReg, SrcReg,
I,
MRI, MF))
1337 I.eraseFromParent();
1341 bool HasAVX = STI.
hasAVX();
1343 bool HasVLX = STI.hasVLX();
1347 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1349 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1354 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1356 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1364 I.getOperand(2).setImm(Index);
1369bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1371 MachineRegisterInfo &
MRI,
1372 MachineFunction &MF)
const {
1373 const LLT DstTy =
MRI.getType(DstReg);
1374 const LLT SrcTy =
MRI.getType(SrcReg);
1375 unsigned SubIdx = X86::NoSubRegister;
1381 "Incorrect Src/Dst register size");
1384 SubIdx = X86::sub_xmm;
1386 SubIdx = X86::sub_ymm;
1390 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg,
MRI);
1391 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg,
MRI);
1393 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1401 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1402 .
addReg(SrcReg, 0, SubIdx);
1407bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1409 MachineRegisterInfo &
MRI,
1410 MachineFunction &MF)
const {
1411 const LLT DstTy =
MRI.getType(DstReg);
1412 const LLT SrcTy =
MRI.getType(SrcReg);
1413 unsigned SubIdx = X86::NoSubRegister;
1420 "Incorrect Src/Dst register size");
1423 SubIdx = X86::sub_xmm;
1425 SubIdx = X86::sub_ymm;
1429 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg,
MRI);
1430 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg,
MRI);
1438 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY))
1445bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1446 MachineRegisterInfo &
MRI,
1447 MachineFunction &MF)
const {
1448 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1450 const Register DstReg =
I.getOperand(0).getReg();
1451 const Register SrcReg =
I.getOperand(1).getReg();
1452 const Register InsertReg =
I.getOperand(2).getReg();
1453 int64_t
Index =
I.getOperand(3).getImm();
1455 const LLT DstTy =
MRI.getType(DstReg);
1456 const LLT InsertRegTy =
MRI.getType(InsertReg);
1465 if (Index == 0 &&
MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1467 if (!emitInsertSubreg(DstReg, InsertReg,
I,
MRI, MF))
1470 I.eraseFromParent();
1474 bool HasAVX = STI.
hasAVX();
1476 bool HasVLX = STI.hasVLX();
1480 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1482 I.setDesc(
TII.get(X86::VINSERTF128rri));
1487 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1489 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1498 I.getOperand(3).setImm(Index);
1503bool X86InstructionSelector::selectUnmergeValues(
1504 MachineInstr &
I, MachineRegisterInfo &
MRI, MachineFunction &MF) {
1505 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1506 "unexpected instruction");
1509 unsigned NumDefs =
I.getNumOperands() - 1;
1510 Register SrcReg =
I.getOperand(NumDefs).getReg();
1511 unsigned DefSize =
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits();
1513 for (
unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1514 MachineInstr &ExtrInst =
1516 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1520 if (!select(ExtrInst))
1524 I.eraseFromParent();
1528bool X86InstructionSelector::selectMergeValues(
1529 MachineInstr &
I, MachineRegisterInfo &
MRI, MachineFunction &MF) {
1530 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1531 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1532 "unexpected instruction");
1535 Register DstReg =
I.getOperand(0).getReg();
1536 Register SrcReg0 =
I.getOperand(1).getReg();
1538 const LLT DstTy =
MRI.getType(DstReg);
1539 const LLT SrcTy =
MRI.getType(SrcReg0);
1545 Register DefReg =
MRI.createGenericVirtualRegister(DstTy);
1546 MRI.setRegBank(DefReg, RegBank);
1547 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I,
MRI, MF))
1550 for (
unsigned Idx = 2; Idx <
I.getNumOperands(); ++Idx) {
1551 Register Tmp =
MRI.createGenericVirtualRegister(DstTy);
1552 MRI.setRegBank(Tmp, RegBank);
1554 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1555 TII.get(TargetOpcode::G_INSERT), Tmp)
1557 .
addReg(
I.getOperand(Idx).getReg())
1558 .
addImm((Idx - 1) * SrcSize);
1562 if (!select(InsertInst))
1566 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1567 TII.get(TargetOpcode::COPY), DstReg)
1570 if (!select(CopyInst))
1573 I.eraseFromParent();
1577bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1578 MachineRegisterInfo &
MRI,
1579 MachineFunction &MF)
const {
1580 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1582 const Register CondReg =
I.getOperand(0).getReg();
1583 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1585 MachineInstr &TestInst =
1586 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1589 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1594 I.eraseFromParent();
1598bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1599 MachineRegisterInfo &
MRI,
1600 MachineFunction &MF)
const {
1601 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1602 "unexpected instruction");
1609 const Register DstReg =
I.getOperand(0).getReg();
1610 const LLT DstTy =
MRI.getType(DstReg);
1613 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1616 const DebugLoc &DbgLoc =
I.getDebugLoc();
1619 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1622 MachineInstr *LoadInst =
nullptr;
1629 Register AddrReg =
MRI.createVirtualRegister(&X86::GR64RegClass);
1630 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1647 unsigned PICBase = 0;
1656 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1662 I.eraseFromParent();
1666bool X86InstructionSelector::selectImplicitDefOrPHI(
1667 MachineInstr &
I, MachineRegisterInfo &
MRI)
const {
1668 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1669 I.getOpcode() == TargetOpcode::G_PHI) &&
1670 "unexpected instruction");
1672 Register DstReg =
I.getOperand(0).getReg();
1674 if (!
MRI.getRegClassOrNull(DstReg)) {
1675 const LLT DstTy =
MRI.getType(DstReg);
1685 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1686 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1688 I.setDesc(
TII.get(X86::PHI));
1693bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1694 MachineRegisterInfo &
MRI,
1695 MachineFunction &MF)
const {
1697 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1698 I.getOpcode() == TargetOpcode::G_SMULH ||
1699 I.getOpcode() == TargetOpcode::G_UMULH ||
1700 I.getOpcode() == TargetOpcode::G_SDIV ||
1701 I.getOpcode() == TargetOpcode::G_SREM ||
1702 I.getOpcode() == TargetOpcode::G_UDIV ||
1703 I.getOpcode() == TargetOpcode::G_UREM) &&
1704 "unexpected instruction");
1706 const Register DstReg =
I.getOperand(0).getReg();
1707 const Register Op1Reg =
I.getOperand(1).getReg();
1708 const Register Op2Reg =
I.getOperand(2).getReg();
1710 const LLT RegTy =
MRI.getType(DstReg);
1711 assert(RegTy ==
MRI.getType(Op1Reg) && RegTy ==
MRI.getType(Op2Reg) &&
1712 "Arguments and return value types must match");
1715 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1718 const static unsigned NumTypes = 4;
1719 const static unsigned NumOps = 7;
1720 const static bool S =
true;
1721 const static bool U =
false;
1722 const static unsigned Copy = TargetOpcode::COPY;
1732 const static struct MulDivRemEntry {
1734 unsigned SizeInBits;
1738 struct MulDivRemResult {
1739 unsigned OpMulDivRem;
1740 unsigned OpSignExtend;
1747 } OpTable[NumTypes] = {
1752 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1753 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1754 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1755 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1756 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1757 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1758 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1764 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1765 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1766 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1767 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1768 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1769 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1770 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1776 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1777 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1778 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1779 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1780 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1781 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1782 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1788 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1789 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1790 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1791 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1792 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1793 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1794 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1798 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1801 if (OpEntryIt == std::end(OpTable))
1805 switch (
I.getOpcode()) {
1808 case TargetOpcode::G_SDIV:
1811 case TargetOpcode::G_SREM:
1814 case TargetOpcode::G_UDIV:
1817 case TargetOpcode::G_UREM:
1820 case TargetOpcode::G_MUL:
1823 case TargetOpcode::G_SMULH:
1826 case TargetOpcode::G_UMULH:
1831 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1832 const MulDivRemEntry::MulDivRemResult &OpEntry =
1835 const TargetRegisterClass *RegRC =
getRegClass(RegTy, *RegRB);
1845 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1850 if (OpEntry.OpSignExtend) {
1851 if (OpEntry.IsOpSigned)
1853 TII.get(OpEntry.OpSignExtend));
1855 Register Zero32 =
MRI.createVirtualRegister(&X86::GR32RegClass);
1856 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0),
1865 .
addReg(Zero32, 0, X86::sub_16bit);
1872 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1881 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1892 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1893 Register SourceSuperReg =
MRI.createVirtualRegister(&X86::GR16RegClass);
1894 Register ResultSuperReg =
MRI.createVirtualRegister(&X86::GR16RegClass);
1895 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1899 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1905 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1907 .
addReg(ResultSuperReg, 0, X86::sub_8bit);
1909 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1911 .
addReg(OpEntry.ResultReg);
1913 I.eraseFromParent();
1918bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1919 MachineRegisterInfo &
MRI,
1920 MachineFunction &MF)
const {
1928 LLT Ty =
MRI.getType(DstReg);
1939 OpCmp = X86::CMOV_GR8;
1942 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1945 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1949 OpCmp = X86::CMOV64rr;
1967InstructionSelector::ComplexRendererFns
1968X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1970 MachineIRBuilder MIRBuilder(*
MI);
1972 MachineRegisterInfo &
MRI =
MI->getMF()->getRegInfo();
1973 MachineInstr *Ptr =
MRI.getVRegDef(Root.
getReg());
1978 return std::nullopt;
1981 {[=](MachineInstrBuilder &MIB) {
1986 "Unknown type of address base");
1991 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
1993 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
1995 [=](MachineInstrBuilder &MIB) {
2001 MIB.addImm(AM.
Disp);
2004 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
2007InstructionSelector *
2011 return new X86InstructionSelector(TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM, const MachineRegisterInfo &MRI, const X86Subtarget &STI, X86AddressMode &AM)
static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC, const TargetRegisterClass *SrcRC)
static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI)
static const TargetRegisterClass * getRegClassFromGRPhysReg(Register Reg)
This file declares the targeting of the RegisterBankInfo class for X86.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Register getCondReg() const
Register getFalseReg() const
Register getTrueReg() const
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) 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
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
@ MOLoad
The memory access reads data.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
CodeModel::Model getCodeModel() const
Returns the code model.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Type * getType() const
All values are typed, get the type of this value.
Register getGlobalBaseReg(MachineFunction *MF) const
getGlobalBaseReg - Return a virtual register initialized with the the global base register value.
This class provides the information for the target register banks.
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
const X86InstrInfo * getInstrInfo() const override
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
bool isPICStyleRIPRel() const
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
std::pair< CondCode, bool > getX86ConditionCode(CmpInst::Predicate Predicate)
Return a pair of condition code for the given predicate and whether the instruction operands should b...
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, Register GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static const MachineInstrBuilder & addOffset(const MachineInstrBuilder &MIB, int Offset)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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 const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, Register Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
InstructionSelector * createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
X86AddressMode - This struct holds a generalized full x86 address mode.
union llvm::X86AddressMode::BaseUnion Base
enum llvm::X86AddressMode::@202116273335065351270200035056227005202106004277 BaseType