67 const TargetMachine &TM;
69 X86AsmPrinter &AsmPrinter;
74 MCOperand LowerMachineOperand(
const MachineInstr *
MI,
75 const MachineOperand &MO)
const;
76 void Lower(
const MachineInstr *
MI, MCInst &OutMI)
const;
82 MachineModuleInfoMachO &getMachOMMI()
const;
98 if (b ==
OS.getAllowAutoPadding())
100 OS.setAllowAutoPadding(b);
102 OS.emitRawComment(
"autopadding");
104 OS.emitRawComment(
"noautopadding");
112void X86AsmPrinter::StackMapShadowTracker::count(
const MCInst &Inst,
116 SmallString<256>
Code;
119 CurrentShadowSize +=
Code.size();
120 if (CurrentShadowSize >= RequiredShadowSize)
125void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
126 MCStreamer &
OutStreamer,
const MCSubtargetInfo &STI) {
127 if (InShadow && CurrentShadowSize < RequiredShadowSize) {
130 &
MF->getSubtarget<X86Subtarget>());
134void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
150MCSymbol *X86MCInstLower::GetSymbolFromOperand(
const MachineOperand &MO)
const {
157 "Isn't a symbol reference");
160 SmallString<128>
Name;
173 Suffix =
"$non_lazy_ptr";
178 Name +=
DL.getInternalSymbolPrefix();
185 }
else if (MO.
isMBB()) {
200 MachineModuleInfoCOFF &MMICOFF =
203 if (!StubSym.getPointer()) {
213 getMachOMMI().getGVStubEntry(Sym);
227MCOperand X86MCInstLower::LowerSymbolOperand(
const MachineOperand &MO,
228 MCSymbol *Sym)
const {
231 const MCExpr *Expr =
nullptr;
314 AsmPrinter.
OutStreamer->emitAssignment(Label, Expr);
330 return Subtarget.is64Bit() ? X86::RET64 : X86::RET32;
333MCOperand X86MCInstLower::LowerMachineOperand(
const MachineInstr *
MI,
334 const MachineOperand &MO)
const {
370 Opcode = X86::JMP32r;
373 Opcode = X86::JMP32m;
375 case X86::TAILJMPr64:
376 Opcode = X86::JMP64r;
378 case X86::TAILJMPm64:
379 Opcode = X86::JMP64m;
381 case X86::TAILJMPr64_REX:
382 Opcode = X86::JMP64r_REX;
384 case X86::TAILJMPm64_REX:
385 Opcode = X86::JMP64m_REX;
388 case X86::TAILJMPd64:
389 Opcode = IsLarge ? X86::JMPABS64i : X86::JMP_1;
391 case X86::TAILJMPd_CC:
392 case X86::TAILJMPd64_CC:
400void X86MCInstLower::Lower(
const MachineInstr *
MI, MCInst &OutMI)
const {
403 for (
const MachineOperand &MO :
MI->operands())
404 if (
auto Op = LowerMachineOperand(
MI, MO);
Op.isValid())
424 "Unexpected # of LEA operands");
426 "LEA has segment specified!");
431 case X86::MULX64Hrm: {
436 case X86::MULX32Hrr: NewOpc = X86::MULX32rr;
break;
437 case X86::MULX32Hrm: NewOpc = X86::MULX32rm;
break;
438 case X86::MULX64Hrr: NewOpc = X86::MULX64rr;
break;
439 case X86::MULX64Hrm: NewOpc = X86::MULX64rm;
break;
452 case X86::CALL64pcrel32:
456 case X86::EH_RETURN64: {
461 case X86::CLEANUPRET: {
467 case X86::CATCHRET: {
469 const X86Subtarget &Subtarget = AsmPrinter.
getSubtarget();
470 unsigned ReturnReg = In64BitMode ? X86::RAX : X86::EAX;
479 case X86::TAILJMPr64:
480 case X86::TAILJMPr64_REX:
485 case X86::TAILJMPd64: {
489 "Unexpected TAILJMPd64 in large code model without JMPABS");
493 case X86::TAILJMPd_CC:
494 case X86::TAILJMPd64_CC:
499 case X86::TAILJMPm64:
500 case X86::TAILJMPm64_REX:
502 "Unexpected number of operands!");
505 case X86::MASKMOVDQU:
506 case X86::VMASKMOVDQU:
520 const MachineOperand *FlagDef =
521 MI->findRegisterDefOperand(X86::EFLAGS,
nullptr);
531void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
532 const MachineInstr &
MI) {
533 NoAutoPaddingScope NoPadScope(*OutStreamer);
534 bool Is64Bits = getSubtarget().is64Bit();
535 bool Is64BitsLP64 = getSubtarget().isTarget64BitLP64();
539 switch (
MI.getOpcode()) {
540 case X86::TLS_addr32:
541 case X86::TLS_addr64:
542 case X86::TLS_addrX32:
545 case X86::TLS_base_addr32:
548 case X86::TLS_base_addr64:
549 case X86::TLS_base_addrX32:
552 case X86::TLS_desc32:
553 case X86::TLS_desc64:
561 MCInstLowering.GetSymbolFromOperand(
MI.getOperand(3)), Specifier, Ctx);
568 bool UseGot = MMI->getModule()->getRtLibUseGOT() &&
575 EmitAndCountInstruction(
576 MCInstBuilder(Is64BitsLP64 ? X86::LEA64r : X86::LEA32r)
577 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
578 .addReg(Is64Bits ? X86::RIP : X86::EBX)
583 EmitAndCountInstruction(
584 MCInstBuilder(Is64Bits ? X86::CALL64m : X86::CALL32m)
585 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
590 }
else if (Is64Bits) {
592 if (NeedsPadding && Is64BitsLP64)
593 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
594 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
604 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
605 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
606 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
611 EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)
618 EmitAndCountInstruction(
619 MCInstBuilder(X86::CALL64pcrel32)
624 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
632 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
644 EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)
651 EmitAndCountInstruction(
652 MCInstBuilder(X86::CALLpcrel32)
665 unsigned MaxNopLength = 1;
666 unsigned BaseReg = X86::RAX;
667 if (Subtarget->is64Bit()) {
668 if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))
670 else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))
672 else if (Subtarget->hasFeature(X86::TuningFast11ByteNOP))
676 }
else if (Subtarget->is32Bit() && Subtarget->hasFeature(X86::FeatureNOPL)) {
679 }
else if (Subtarget->is32Bit())
683 NumBytes = std::min(NumBytes, MaxNopLength);
686 unsigned Opc, ScaleVal, IndexReg, Displacement, SegmentReg;
687 IndexReg = Displacement = SegmentReg = 0;
744 SegmentReg = X86::CS;
748 unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);
749 NopSize += NumPrefixes;
750 for (
unsigned i = 0; i != NumPrefixes; ++i)
768 .addImm(Displacement)
773 assert(NopSize <= NumBytes &&
"We overemitted?");
780 unsigned NopsToEmit = NumBytes;
783 NumBytes -=
emitNop(OS, NumBytes, Subtarget);
784 assert(NopsToEmit >= NumBytes &&
"Emitted more than I asked for!");
788void X86AsmPrinter::LowerSTATEPOINT(
const MachineInstr &
MI,
789 X86MCInstLower &MCIL) {
790 assert(Subtarget->is64Bit() &&
"Statepoint currently only supports X86-64");
792 NoAutoPaddingScope NoPadScope(*OutStreamer);
794 StatepointOpers SOpers(&
MI);
795 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
799 const MachineOperand &CallTarget = SOpers.getCallTarget();
800 MCOperand CallTargetMCOp;
802 switch (CallTarget.
getType()) {
805 CallTargetMCOp = MCIL.LowerSymbolOperand(
806 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
807 CallOpcode = X86::CALL64pcrel32;
815 CallOpcode = X86::CALL64pcrel32;
827 CallOpcode = X86::CALL64r;
839 maybeEmitNopAfterCallForWindowsEH(&
MI);
847 SM.recordStatepoint(*MILabel,
MI);
850void X86AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI,
851 X86MCInstLower &MCIL) {
855 NoAutoPaddingScope NoPadScope(*OutStreamer);
862 unsigned OperandsBeginIdx = 4;
869 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
872 MI.setOpcode(Opcode);
874 if (DefRegister != X86::NoRegister)
877 for (
const MachineOperand &MO :
879 if (
auto Op = MCIL.LowerMachineOperand(&FaultingMI, MO);
Op.isValid())
886void X86AsmPrinter::LowerFENTRY_CALL(
const MachineInstr &
MI,
887 X86MCInstLower &MCIL) {
888 bool Is64Bits = Subtarget->is64Bit();
891 if (MF->getFunction().hasFnAttribute(
"mrecord-mcount")) {
892 MCSymbol *DotSym = OutContext.createTempSymbol();
901 if (MF->getFunction().hasFnAttribute(
"mnop-mcount")) {
911 EmitAndCountInstruction(
912 MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
916void X86AsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
917 assert(std::next(
MI.getIterator())->isCall() &&
918 "KCFI_CHECK not followed by a call instruction");
926 "patchable-function-prefix");
933 const Register AddrReg =
MI.getOperand(0).getReg();
934 const uint32_t
Type =
MI.getOperand(1).getImm();
937 unsigned TempReg = AddrReg == X86::R10 ? X86::R11D : X86::R10D;
938 EmitAndCountInstruction(
939 MCInstBuilder(X86::MOV32ri).addReg(TempReg).addImm(-MaskKCFIType(
Type)));
940 EmitAndCountInstruction(MCInstBuilder(X86::ADD32rm)
941 .addReg(X86::NoRegister)
945 .addReg(X86::NoRegister)
946 .addImm(-(PrefixNops + 4))
947 .addReg(X86::NoRegister));
950 EmitAndCountInstruction(
951 MCInstBuilder(X86::JCC_1)
957 EmitAndCountInstruction(MCInstBuilder(X86::TRAP));
958 emitKCFITrapEntry(MF,
Trap);
962void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
964 if (!TM.getTargetTriple().isOSBinFormatELF()) {
969 const auto &
Reg =
MI.getOperand(0).getReg();
970 ASanAccessInfo AccessInfo(
MI.getOperand(1).getImm());
976 TM.getTargetTriple(), 64, AccessInfo.CompileKernel,
977 &ShadowBase, &MappingScale, &OrShadowOffset);
979 StringRef
Name = AccessInfo.IsWrite ?
"store" :
"load";
980 StringRef
Op = OrShadowOffset ?
"or" :
"add";
981 std::string SymName = (
"__asan_check_" +
Name +
"_" +
Op +
"_" +
982 Twine(1ULL << AccessInfo.AccessSizeIndex) +
"_" +
983 TM.getMCRegisterInfo().getName(
Reg.
asMCReg()))
987 "OrShadowOffset is not supported with optimized callbacks");
989 EmitAndCountInstruction(
990 MCInstBuilder(X86::CALL64pcrel32)
992 OutContext.getOrCreateSymbol(SymName), OutContext)));
995void X86AsmPrinter::LowerPATCHABLE_OP(
const MachineInstr &
MI,
996 X86MCInstLower &MCIL) {
999 NoAutoPaddingScope NoPadScope(*OutStreamer);
1001 auto NextMI = std::find_if(std::next(
MI.getIterator()),
1002 MI.getParent()->end().getInstrIterator(),
1003 [](
auto &
II) { return !II.isMetaInstruction(); });
1005 SmallString<256>
Code;
1006 unsigned MinSize =
MI.getOperand(0).getImm();
1008 if (NextMI !=
MI.getParent()->end() && !NextMI->isInlineAsm()) {
1013 MCIL.Lower(&*NextMI, MCI);
1019 if (
Code.size() < MinSize) {
1020 if (MinSize == 2 && Subtarget->is32Bit() &&
1022 (Subtarget->getCPU().empty() || Subtarget->getCPU() ==
"pentium3")) {
1028 MCInstBuilder(X86::MOV32rr_REV).addReg(X86::EDI).addReg(X86::EDI),
1031 unsigned NopSize =
emitNop(*OutStreamer, MinSize, Subtarget);
1032 assert(NopSize == MinSize &&
"Could not implement MinSize!");
1040void X86AsmPrinter::LowerSTACKMAP(
const MachineInstr &
MI) {
1041 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1047 SM.recordStackMap(*MILabel,
MI);
1048 unsigned NumShadowBytes =
MI.getOperand(1).getImm();
1049 SMShadowTracker.reset(NumShadowBytes);
1054void X86AsmPrinter::LowerPATCHPOINT(
const MachineInstr &
MI,
1055 X86MCInstLower &MCIL) {
1056 assert(Subtarget->is64Bit() &&
"Patchpoint currently only supports X86-64");
1058 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1060 NoAutoPaddingScope NoPadScope(*OutStreamer);
1065 SM.recordPatchPoint(*MILabel,
MI);
1067 PatchPointOpers opers(&
MI);
1068 unsigned ScratchIdx = opers.getNextScratchIdx();
1069 unsigned EncodedBytes = 0;
1070 const MachineOperand &CalleeMO = opers.getCallTarget();
1075 MCOperand CalleeMCOp;
1086 CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,
1087 MCIL.GetSymbolFromOperand(CalleeMO));
1093 Register ScratchReg =
MI.getOperand(ScratchIdx).getReg();
1099 EmitAndCountInstruction(
1100 MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).
addOperand(CalleeMCOp));
1104 "Lowering patchpoint with thunks not yet implemented.");
1105 EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
1109 unsigned NumBytes = opers.getNumPatchBytes();
1110 assert(NumBytes >= EncodedBytes &&
1111 "Patchpoint can't request size less than the length of a call.");
1113 emitX86Nops(*OutStreamer, NumBytes - EncodedBytes, Subtarget);
1116void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
1117 X86MCInstLower &MCIL) {
1118 assert(Subtarget->is64Bit() &&
"XRay custom events only supports X86-64");
1120 NoAutoPaddingScope NoPadScope(*OutStreamer);
1142 auto CurSled = OutContext.createTempSymbol(
"xray_event_sled_",
true);
1143 OutStreamer->
AddComment(
"# XRay Custom Event Log");
1154 const Register DestRegs[] = {X86::RDI, X86::RSI};
1155 bool UsedMask[] = {
false,
false};
1164 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1165 if (
auto Op = MCIL.LowerMachineOperand(&
MI,
MI.getOperand(
I));
1167 assert(
Op.isReg() &&
"Only support arguments in registers");
1170 if (SrcRegs[
I] != DestRegs[
I]) {
1172 EmitAndCountInstruction(
1173 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[
I]));
1183 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1184 if (SrcRegs[
I] != DestRegs[
I])
1185 EmitAndCountInstruction(
1186 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[
I]).addReg(SrcRegs[
I]));
1190 auto TSym = OutContext.getOrCreateSymbol(
"__xray_CustomEvent");
1192 if (isPositionIndependent())
1196 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1197 .
addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1200 for (
unsigned I =
sizeof UsedMask;
I-- > 0;)
1202 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[
I]));
1206 OutStreamer->
AddComment(
"xray custom event end.");
1211 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
1214void X86AsmPrinter::LowerPATCHABLE_TYPED_EVENT_CALL(
const MachineInstr &
MI,
1215 X86MCInstLower &MCIL) {
1216 assert(Subtarget->is64Bit() &&
"XRay typed events only supports X86-64");
1218 NoAutoPaddingScope NoPadScope(*OutStreamer);
1240 auto CurSled = OutContext.createTempSymbol(
"xray_typed_event_sled_",
true);
1241 OutStreamer->
AddComment(
"# XRay Typed Event Log");
1253 const Register DestRegs[] = {X86::RDI, X86::RSI, X86::RDX};
1254 bool UsedMask[] = {
false,
false,
false};
1263 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1264 if (
auto Op = MCIL.LowerMachineOperand(&
MI,
MI.getOperand(
I));
1267 assert(
Op.isReg() &&
"Only supports arguments in registers");
1270 if (SrcRegs[
I] != DestRegs[
I]) {
1272 EmitAndCountInstruction(
1273 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[
I]));
1288 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1290 EmitAndCountInstruction(
1291 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[
I]).addReg(SrcRegs[
I]));
1295 auto TSym = OutContext.getOrCreateSymbol(
"__xray_TypedEvent");
1297 if (isPositionIndependent())
1301 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1302 .
addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1305 for (
unsigned I =
sizeof UsedMask;
I-- > 0;)
1307 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[
I]));
1311 OutStreamer->
AddComment(
"xray typed event end.");
1314 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
1317void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI,
1318 X86MCInstLower &MCIL) {
1320 NoAutoPaddingScope NoPadScope(*OutStreamer);
1323 if (
F.hasFnAttribute(
"patchable-function-entry")) {
1324 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
1341 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1350 recordSled(CurSled,
MI, SledKind::FUNCTION_ENTER, 2);
1353void X86AsmPrinter::LowerPATCHABLE_RET(
const MachineInstr &
MI,
1354 X86MCInstLower &MCIL) {
1355 NoAutoPaddingScope NoPadScope(*OutStreamer);
1371 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1374 unsigned OpCode =
MI.getOperand(0).getImm();
1378 if (
auto Op = MCIL.LowerMachineOperand(&
MI, MO);
Op.isValid())
1382 recordSled(CurSled,
MI, SledKind::FUNCTION_EXIT, 2);
1385void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI,
1386 X86MCInstLower &MCIL) {
1391 bool IsConditional = TC.
getOpcode() == X86::JCC_1;
1393 if (IsConditional) {
1404 FallthroughLabel = OutContext.createTempSymbol();
1407 MCInstBuilder(X86::JCC_1)
1416 NoAutoPaddingScope NoPadScope(*OutStreamer);
1424 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1427 auto Target = OutContext.createTempSymbol();
1435 recordSled(CurSled,
MI, SledKind::TAIL_CALL, 2);
1440 for (
auto &MO : TCOperands)
1441 if (
auto Op = MCIL.LowerMachineOperand(&
MI, MO);
Op.isValid())
1446 OutStreamer->
emitLabel(FallthroughLabel);
1462 unsigned SrcOpIdx) {
1472 CS <<
" {%" << Mask <<
"}";
1483 if (Src1Name == Src2Name)
1484 for (
int i = 0, e = ShuffleMask.size(); i != e; ++i)
1485 if (ShuffleMask[i] >= e)
1486 ShuffleMask[i] -= e;
1488 for (
int i = 0, e = ShuffleMask.size(); i != e; ++i) {
1498 bool isSrc1 = ShuffleMask[i] < (int)e;
1499 CS << (isSrc1 ? Src1Name : Src2Name) <<
'[';
1501 bool IsFirst =
true;
1503 (ShuffleMask[i] < (
int)e) == isSrc1) {
1511 CS << ShuffleMask[i] % (int)e;
1521 std::string Comment;
1541 bool PrintZero =
false) {
1550 CS << (PrintZero ? 0ULL : Val.
getRawData()[i]);
1557 bool PrintZero =
false) {
1573 for (
unsigned I = 0,
E = VTy->getNumElements();
I !=
E; ++
I) {
1582 unsigned EltBits = VTy->getScalarSizeInBits();
1583 unsigned E = std::min(
BitWidth / EltBits, VTy->getNumElements());
1585 for (
unsigned I = 0;
I !=
E; ++
I) {
1596 Type *EltTy = CDS->getElementType();
1600 unsigned E = std::min(
BitWidth / EltBits, (
unsigned)CDS->getNumElements());
1602 for (
unsigned I = 0;
I !=
E; ++
I) {
1616 unsigned EltBits = CV->getType()->getScalarSizeInBits();
1617 unsigned E = std::min(
BitWidth / EltBits, CV->getNumOperands());
1619 for (
unsigned I = 0;
I !=
E; ++
I) {
1633 int SclWidth,
int VecWidth,
1634 const char *ShuffleComment) {
1637 std::string Comment;
1645 for (
int I = 1,
E = VecWidth / SclWidth;
I <
E; ++
I) {
1655 CS << ShuffleComment;
1663 std::string Comment;
1667 for (
int l = 0; l != Repeats; ++l) {
1678 unsigned OpNo,
int BitWidth,
int Repeats = 1) {
1680 std::string Comment;
1683 for (
int I = 0;
I != Repeats; ++
I) {
1694 int SrcEltBits,
int DstEltBits,
bool IsSext) {
1697 if (
C &&
C->getType()->getScalarSizeInBits() ==
unsigned(SrcEltBits)) {
1699 int NumElts = CDS->getNumElements();
1700 std::string Comment;
1704 for (
int i = 0; i != NumElts; ++i) {
1707 if (CDS->getElementType()->isIntegerTy()) {
1708 APInt Elt = CDS->getElementAsAPInt(i);
1709 Elt = IsSext ? Elt.
sext(DstEltBits) : Elt.
zext(DstEltBits);
1723 int SrcEltBits,
int DstEltBits) {
1727 int SrcEltBits,
int DstEltBits) {
1728 if (
printExtend(
MI, OutStreamer, SrcEltBits, DstEltBits,
false))
1732 std::string Comment;
1739 assert((Width % DstEltBits) == 0 && (DstEltBits % SrcEltBits) == 0 &&
1740 "Illegal extension ratio");
1747void X86AsmPrinter::EmitSEHInstruction(
const MachineInstr *
MI) {
1748 assert(MF->
hasWinCFI() &&
"SEH_ instruction in function without WinCFI?");
1749 assert(getSubtarget().isOSWindowsOrUEFI() &&
1750 "SEH_ instruction Windows and UEFI only");
1754 X86TargetStreamer *XTS =
1756 switch (
MI->getOpcode()) {
1757 case X86::SEH_PushReg:
1760 case X86::SEH_StackAlloc:
1763 case X86::SEH_StackAlign:
1766 case X86::SEH_SetFrame:
1767 assert(
MI->getOperand(1).getImm() == 0 &&
1768 ".cv_fpo_setframe takes no offset");
1771 case X86::SEH_EndPrologue:
1774 case X86::SEH_SaveReg:
1775 case X86::SEH_SaveXMM:
1776 case X86::SEH_PushFrame:
1777 case X86::SEH_Push2Regs:
1787 switch (
MI->getOpcode()) {
1788 case X86::SEH_PushReg:
1792 case X86::SEH_Push2Regs:
1794 MI->getOperand(1).getImm());
1797 case X86::SEH_SaveReg:
1799 MI->getOperand(1).getImm());
1802 case X86::SEH_SaveXMM:
1804 MI->getOperand(1).getImm());
1807 case X86::SEH_StackAlloc:
1811 case X86::SEH_SetFrame:
1813 MI->getOperand(1).getImm());
1816 case X86::SEH_PushFrame:
1820 case X86::SEH_EndPrologue:
1824 case X86::SEH_BeginEpilogue:
1828 case X86::SEH_EndEpilogue:
1832 case X86::SEH_UnwindV2Start:
1836 case X86::SEH_UnwindVersion:
1847 switch (
MI->getOpcode()) {
1852 case X86::VPSHUFBrm:
1853 case X86::VPSHUFBYrm:
1854 case X86::VPSHUFBZ128rm:
1855 case X86::VPSHUFBZ128rmk:
1856 case X86::VPSHUFBZ128rmkz:
1857 case X86::VPSHUFBZ256rm:
1858 case X86::VPSHUFBZ256rmk:
1859 case X86::VPSHUFBZ256rmkz:
1860 case X86::VPSHUFBZrm:
1861 case X86::VPSHUFBZrmk:
1862 case X86::VPSHUFBZrmkz: {
1874 case X86::VPERMILPSrm:
1875 case X86::VPERMILPSYrm:
1876 case X86::VPERMILPSZ128rm:
1877 case X86::VPERMILPSZ128rmk:
1878 case X86::VPERMILPSZ128rmkz:
1879 case X86::VPERMILPSZ256rm:
1880 case X86::VPERMILPSZ256rmk:
1881 case X86::VPERMILPSZ256rmkz:
1882 case X86::VPERMILPSZrm:
1883 case X86::VPERMILPSZrmk:
1884 case X86::VPERMILPSZrmkz: {
1895 case X86::VPERMILPDrm:
1896 case X86::VPERMILPDYrm:
1897 case X86::VPERMILPDZ128rm:
1898 case X86::VPERMILPDZ128rmk:
1899 case X86::VPERMILPDZ128rmkz:
1900 case X86::VPERMILPDZ256rm:
1901 case X86::VPERMILPDZ256rmk:
1902 case X86::VPERMILPDZ256rmkz:
1903 case X86::VPERMILPDZrm:
1904 case X86::VPERMILPDZrmk:
1905 case X86::VPERMILPDZrmkz: {
1917 case X86::VPERMIL2PDrm:
1918 case X86::VPERMIL2PSrm:
1919 case X86::VPERMIL2PDYrm:
1920 case X86::VPERMIL2PSYrm: {
1922 "Unexpected number of operands!");
1925 if (!CtrlOp.
isImm())
1929 switch (
MI->getOpcode()) {
1931 case X86::VPERMIL2PSrm:
case X86::VPERMIL2PSYrm: ElSize = 32;
break;
1932 case X86::VPERMIL2PDrm:
case X86::VPERMIL2PDYrm: ElSize = 64;
break;
1945 case X86::VPPERMrrm: {
1956 case X86::MMX_MOVQ64rm: {
1958 std::string Comment;
1963 CS <<
"0x" <<
toString(CF->getValueAPF().bitcastToAPInt(), 16,
false);
1970 case X86::GF2P8AFFINEQBrmi:
1971 case X86::VGF2P8AFFINEQBrmi:
1972 case X86::VGF2P8AFFINEQBYrmi:
1973 case X86::VGF2P8AFFINEQBZrmi:
1974 case X86::VGF2P8AFFINEQBZ128rmi:
1975 case X86::VGF2P8AFFINEQBZ256rmi: {
1983 case X86::VGF2P8AFFINEQBZ128rmbi:
1984 case X86::VGF2P8AFFINEQBZ256rmbi:
1985 case X86::VGF2P8AFFINEQBZrmbi: {
1992#define INSTR_CASE(Prefix, Instr, Suffix, Postfix) \
1993 case X86::Prefix##Instr##Suffix##rm##Postfix:
1995#define CASE_AVX512_ARITH_RM(Instr) \
1996 INSTR_CASE(V, Instr, Z128, ) \
1997 INSTR_CASE(V, Instr, Z128, k) \
1998 INSTR_CASE(V, Instr, Z128, kz) \
1999 INSTR_CASE(V, Instr, Z256, ) \
2000 INSTR_CASE(V, Instr, Z256, k) \
2001 INSTR_CASE(V, Instr, Z256, kz) \
2002 INSTR_CASE(V, Instr, Z, ) \
2003 INSTR_CASE(V, Instr, Z, k) \
2004 INSTR_CASE(V, Instr, Z, kz)
2006#define CASE_ARITH_RM(Instr) \
2007 INSTR_CASE(, Instr, , ) \
2008 INSTR_CASE(V, Instr, , ) \
2009 INSTR_CASE(V, Instr, Y, ) \
2010 INSTR_CASE(V, Instr, Z128, ) \
2011 INSTR_CASE(V, Instr, Z128, k) \
2012 INSTR_CASE(V, Instr, Z128, kz) \
2013 INSTR_CASE(V, Instr, Z256, ) \
2014 INSTR_CASE(V, Instr, Z256, k) \
2015 INSTR_CASE(V, Instr, Z256, kz) \
2016 INSTR_CASE(V, Instr, Z, ) \
2017 INSTR_CASE(V, Instr, Z, k) \
2018 INSTR_CASE(V, Instr, Z, kz)
2036 unsigned VectorWidth =
2042#define MASK_AVX512_CASE(Instr) \
2050 case X86::MOVSDrm_alt:
2051 case X86::VMOVSDrm_alt:
2052 case X86::VMOVSDZrm_alt:
2053 case X86::MOVQI2PQIrm:
2054 case X86::VMOVQI2PQIrm:
2055 case X86::VMOVQI2PQIZrm:
2060 case X86::VMOVSHZrm_alt:
2062 "mem[0],zero,zero,zero,zero,zero,zero,zero");
2068 case X86::MOVSSrm_alt:
2069 case X86::VMOVSSrm_alt:
2070 case X86::VMOVSSZrm_alt:
2071 case X86::MOVDI2PDIrm:
2072 case X86::VMOVDI2PDIrm:
2073 case X86::VMOVDI2PDIZrm:
2077#define MOV_CASE(Prefix, Suffix) \
2078 case X86::Prefix##MOVAPD##Suffix##rm: \
2079 case X86::Prefix##MOVAPS##Suffix##rm: \
2080 case X86::Prefix##MOVUPD##Suffix##rm: \
2081 case X86::Prefix##MOVUPS##Suffix##rm: \
2082 case X86::Prefix##MOVDQA##Suffix##rm: \
2083 case X86::Prefix##MOVDQU##Suffix##rm:
2085#define MOV_AVX512_CASE(Suffix, Postfix) \
2086 case X86::VMOVDQA64##Suffix##rm##Postfix: \
2087 case X86::VMOVDQA32##Suffix##rm##Postfix: \
2088 case X86::VMOVDQU64##Suffix##rm##Postfix: \
2089 case X86::VMOVDQU32##Suffix##rm##Postfix: \
2090 case X86::VMOVDQU16##Suffix##rm##Postfix: \
2091 case X86::VMOVDQU8##Suffix##rm##Postfix: \
2092 case X86::VMOVAPS##Suffix##rm##Postfix: \
2093 case X86::VMOVAPD##Suffix##rm##Postfix: \
2094 case X86::VMOVUPS##Suffix##rm##Postfix: \
2095 case X86::VMOVUPD##Suffix##rm##Postfix:
2097#define CASE_128_MOV_RM() \
2100 MOV_AVX512_CASE(Z128, ) \
2101 MOV_AVX512_CASE(Z128, k) \
2102 MOV_AVX512_CASE(Z128, kz)
2104#define CASE_256_MOV_RM() \
2106 MOV_AVX512_CASE(Z256, ) \
2107 MOV_AVX512_CASE(Z256, k) \
2108 MOV_AVX512_CASE(Z256, kz) \
2110#define CASE_512_MOV_RM() \
2111 MOV_AVX512_CASE(Z, ) \
2112 MOV_AVX512_CASE(Z, k) \
2113 MOV_AVX512_CASE(Z, kz) \
2126 case X86::VBROADCASTF128rm:
2127 case X86::VBROADCASTI128rm:
2149 case X86::MOVDDUPrm:
2150 case X86::VMOVDDUPrm:
2152 case X86::VPBROADCASTQrm:
2156 case X86::VBROADCASTSDYrm:
2158 case X86::VPBROADCASTQYrm:
2166 case X86::VBROADCASTSSrm:
2168 case X86::VPBROADCASTDrm:
2172 case X86::VBROADCASTSSYrm:
2174 case X86::VPBROADCASTDYrm:
2182 case X86::VPBROADCASTWrm:
2186 case X86::VPBROADCASTWYrm:
2193 case X86::VPBROADCASTBrm:
2197 case X86::VPBROADCASTBYrm:
2205#define MOVX_CASE(Prefix, Ext, Type, Suffix, Postfix) \
2206 case X86::Prefix##PMOV##Ext##Type##Suffix##rm##Postfix:
2208#define CASE_MOVX_RM(Ext, Type) \
2209 MOVX_CASE(, Ext, Type, , ) \
2210 MOVX_CASE(V, Ext, Type, , ) \
2211 MOVX_CASE(V, Ext, Type, Y, ) \
2212 MOVX_CASE(V, Ext, Type, Z128, ) \
2213 MOVX_CASE(V, Ext, Type, Z128, k ) \
2214 MOVX_CASE(V, Ext, Type, Z128, kz ) \
2215 MOVX_CASE(V, Ext, Type, Z256, ) \
2216 MOVX_CASE(V, Ext, Type, Z256, k ) \
2217 MOVX_CASE(V, Ext, Type, Z256, kz ) \
2218 MOVX_CASE(V, Ext, Type, Z, ) \
2219 MOVX_CASE(V, Ext, Type, Z, k ) \
2220 MOVX_CASE(V, Ext, Type, Z, kz )
2269 assert(
MI->getOpcode() == X86::TAILJMPm64_REX ||
2270 MI->getOpcode() == X86::CALL64m);
2280 for (
auto I =
MBB.instr_rbegin(),
E =
MBB.instr_rend();
I !=
E; ++
I)
2281 if (
I->isJumpTableDebugInfo())
2292 X86MCInstLower MCInstLowering(*
MF, *
this);
2296 if (
MI->getOpcode() == X86::OR64rm) {
2297 for (
auto &Opd :
MI->operands()) {
2298 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
2299 "swift_async_extendedFramePointerFlags") {
2300 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
2310 if (
TM.Options.MCOptions.ShowMCEncoding) {
2312 OutStreamer->AddComment(
"EVEX TO LEGACY Compression ",
false);
2314 OutStreamer->AddComment(
"EVEX TO VEX Compression ",
false);
2316 OutStreamer->AddComment(
"EVEX TO EVEX Compression ",
false);
2320 bool IsTailJump =
false;
2322 switch (
MI->getOpcode()) {
2323 case TargetOpcode::DBG_VALUE:
2326 case X86::EH_RETURN:
2327 case X86::EH_RETURN64: {
2334 case X86::CLEANUPRET: {
2340 case X86::CATCHRET: {
2347 case X86::ENDBR64: {
2354 MI == &
MF->front().front()) {
2356 MCInstLowering.Lower(
MI, Inst);
2357 EmitAndCountInstruction(Inst);
2365 case X86::TAILJMPd64:
2366 if (IndCSPrefix &&
MI->hasRegisterImplicitUseOperand(X86::R11))
2370 emitLabelAndRecordForImportCallOptimization(
2371 IMAGE_RETPOLINE_AMD64_IMPORT_BR);
2382 case X86::TAILJMPd_CC:
2383 case X86::TAILJMPr64:
2384 case X86::TAILJMPm64:
2385 case X86::TAILJMPd64_CC:
2386 if (EnableImportCallOptimization)
2388 "import call optimization was enabled");
2395 case X86::TAILJMPm64_REX:
2397 emitLabelAndRecordForImportCallOptimization(
2398 IMAGE_RETPOLINE_AMD64_CFG_BR_REX);
2405 case X86::TAILJMPr64_REX: {
2406 if (EnableImportCallOptimization) {
2407 assert(
MI->getOperand(0).getReg() == X86::RAX &&
2408 "Indirect tail calls with impcall enabled must go through RAX (as "
2409 "enforced by TCRETURNImpCallri64)");
2410 emitLabelAndRecordForImportCallOptimization(
2411 IMAGE_RETPOLINE_AMD64_INDIR_BR);
2421 uint16_t EncodedReg =
2422 this->
getSubtarget().getRegisterInfo()->getEncodingValue(
2423 MI->getOperand(0).getReg().asMCReg());
2424 emitLabelAndRecordForImportCallOptimization(
2425 (ImportCallKind)(IMAGE_RETPOLINE_AMD64_SWITCHTABLE_FIRST +
2437 "Unexpected JMP instruction was emitted for a jump-table when import "
2438 "call optimization was enabled");
2441 case X86::TLS_addr32:
2442 case X86::TLS_addr64:
2443 case X86::TLS_addrX32:
2444 case X86::TLS_base_addr32:
2445 case X86::TLS_base_addr64:
2446 case X86::TLS_base_addrX32:
2447 case X86::TLS_desc32:
2448 case X86::TLS_desc64:
2449 return LowerTlsAddr(MCInstLowering, *
MI);
2451 case X86::MOVPC32r: {
2462 EmitAndCountInstruction(
2468 bool hasFP = FrameLowering->
hasFP(*
MF);
2471 bool HasActiveDwarfFrame =
OutStreamer->getNumFrameInfos() &&
2476 if (HasActiveDwarfFrame && !hasFP) {
2477 OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);
2485 EmitAndCountInstruction(
2488 if (HasActiveDwarfFrame && !hasFP) {
2494 case X86::ADD32ri: {
2510 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(
MI->getOperand(2));
2521 .addReg(
MI->getOperand(0).getReg())
2522 .
addReg(
MI->getOperand(1).getReg())
2526 case TargetOpcode::STATEPOINT:
2527 return LowerSTATEPOINT(*
MI, MCInstLowering);
2529 case TargetOpcode::FAULTING_OP:
2530 return LowerFAULTING_OP(*
MI, MCInstLowering);
2532 case TargetOpcode::FENTRY_CALL:
2533 return LowerFENTRY_CALL(*
MI, MCInstLowering);
2535 case TargetOpcode::PATCHABLE_OP:
2536 return LowerPATCHABLE_OP(*
MI, MCInstLowering);
2538 case TargetOpcode::STACKMAP:
2539 return LowerSTACKMAP(*
MI);
2541 case TargetOpcode::PATCHPOINT:
2542 return LowerPATCHPOINT(*
MI, MCInstLowering);
2544 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2545 return LowerPATCHABLE_FUNCTION_ENTER(*
MI, MCInstLowering);
2547 case TargetOpcode::PATCHABLE_RET:
2548 return LowerPATCHABLE_RET(*
MI, MCInstLowering);
2550 case TargetOpcode::PATCHABLE_TAIL_CALL:
2551 return LowerPATCHABLE_TAIL_CALL(*
MI, MCInstLowering);
2553 case TargetOpcode::PATCHABLE_EVENT_CALL:
2554 return LowerPATCHABLE_EVENT_CALL(*
MI, MCInstLowering);
2556 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
2557 return LowerPATCHABLE_TYPED_EVENT_CALL(*
MI, MCInstLowering);
2559 case X86::MORESTACK_RET:
2563 case X86::KCFI_CHECK:
2564 return LowerKCFI_CHECK(*
MI);
2566 case X86::ASAN_CHECK_MEMACCESS:
2567 return LowerASAN_CHECK_MEMACCESS(*
MI);
2569 case X86::MORESTACK_RET_RESTORE_R10:
2572 EmitAndCountInstruction(
2573 MCInstBuilder(X86::MOV64rr).addReg(X86::R10).addReg(X86::RAX));
2576 case X86::SEH_PushReg:
2577 case X86::SEH_Push2Regs:
2578 case X86::SEH_SaveReg:
2579 case X86::SEH_SaveXMM:
2580 case X86::SEH_StackAlloc:
2581 case X86::SEH_StackAlign:
2582 case X86::SEH_SetFrame:
2583 case X86::SEH_PushFrame:
2584 case X86::SEH_EndPrologue:
2585 case X86::SEH_EndEpilogue:
2586 case X86::SEH_UnwindV2Start:
2587 case X86::SEH_UnwindVersion:
2588 EmitSEHInstruction(
MI);
2591 case X86::SEH_SplitChainedAtEndOfBlock:
2592 assert(!SplitChainedAtEndOfBlock &&
2593 "Duplicate SEH_SplitChainedAtEndOfBlock in a current block");
2594 SplitChainedAtEndOfBlock =
true;
2597 case X86::SEH_SplitChained:
2598 assert(
MF->hasWinCFI() &&
"SEH_ instruction in function without WinCFI?");
2602 case X86::SEH_BeginEpilogue: {
2603 assert(
MF->hasWinCFI() &&
"SEH_ instruction in function without WinCFI?");
2604 EmitSEHInstruction(
MI);
2607 case X86::UBSAN_UD1:
2612 .addReg(X86::NoRegister)
2613 .addImm(
MI->getOperand(0).getImm())
2614 .
addReg(X86::NoRegister));
2616 case X86::CALL64pcrel32:
2617 if (IndCSPrefix &&
MI->hasRegisterImplicitUseOperand(X86::R11))
2621 emitLabelAndRecordForImportCallOptimization(
2622 IMAGE_RETPOLINE_AMD64_IMPORT_CALL);
2625 MCInstLowering.Lower(
MI, TmpInst);
2630 emitCallInstruction(TmpInst);
2632 maybeEmitNopAfterCallForWindowsEH(
MI);
2639 if (EnableImportCallOptimization) {
2640 assert(
MI->getOperand(0).getReg() == X86::RAX &&
2641 "Indirect calls with impcall enabled must go through RAX (as "
2642 "enforced by CALL64r_ImpCall)");
2644 emitLabelAndRecordForImportCallOptimization(
2645 IMAGE_RETPOLINE_AMD64_INDIR_CALL);
2647 MCInstLowering.Lower(
MI, TmpInst);
2648 emitCallInstruction(TmpInst);
2653 maybeEmitNopAfterCallForWindowsEH(
MI);
2660 emitLabelAndRecordForImportCallOptimization(
2661 IMAGE_RETPOLINE_AMD64_CFG_CALL);
2676 getSubtarget().getCLOpts().branch_hint_probability_threshold, 100);
2677 if (EdgeProb > Threshold)
2685 EmitAndCountInstruction(
2688 .addImm(
MI->getOperand(0).getImm()));
2693 MCInstLowering.Lower(
MI, TmpInst);
2696 emitCallInstruction(TmpInst);
2700 maybeEmitNopAfterCallForWindowsEH(
MI);
2704 EmitAndCountInstruction(TmpInst);
2715 maybeEmitNopAfterCallForWindowsEH(
MI);
2719void X86AsmPrinter::emitCallInstruction(
const llvm::MCInst &MCI) {
2726 SMShadowTracker.count(MCI, getSubtargetInfo(), CodeEmitter.get());
2729 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
2793void X86AsmPrinter::maybeEmitNopAfterCallForWindowsEH(
const MachineInstr *
MI) {
2818 const MachineInstr &NextMI = *
MBBI;
2824 if (HasEHPersonality) {
2825 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2844 if (NextMI.
getOpcode() == X86::SEH_BeginEpilogue) {
2845 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2871 if (HasEHPersonality) {
2877 if (
MI->getParent()->succ_empty())
2878 EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2880 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2886 const MachineBasicBlock *NextMBB = &*MFI;
2892void X86AsmPrinter::emitLabelAndRecordForImportCallOptimization(
2893 ImportCallKind Kind) {
2894 assert(EnableImportCallOptimization);
2896 MCSymbol *CallSiteSymbol = MMI->getContext().createNamedTempSymbol(
"impcall");
2900 .push_back({CallSiteSymbol,
Kind});
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static void printShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef< int > Mask)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
print mir2vec MIR2Vec Vocabulary Printer Pass
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Promote Memory to Register
uint64_t IntrinsicInst * II
static MCSymbol * GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallString class.
static MCOperand LowerSymbolOperand(const MachineInstr *MI, const MachineOperand &MO, const MCSymbol *Symbol, AsmPrinter &AP)
static void emitX86Nops(MCStreamer &OS, unsigned NumBytes, const X86Subtarget *Subtarget)
Emit the optimal amount of multi-byte nops on X86.
static unsigned getRetOpcode(const X86Subtarget &Subtarget)
static void printSignExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits)
static unsigned getSrcIdx(const MachineInstr *MI, unsigned SrcIdx)
static void printBroadcast(const MachineInstr *MI, MCStreamer &OutStreamer, int Repeats, int BitWidth)
static bool printExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits, bool IsSext)
static void printZeroUpperMove(const MachineInstr *MI, MCStreamer &OutStreamer, int SclWidth, int VecWidth, const char *ShuffleComment)
static void addConstantComment(const MachineInstr *MI, MCStreamer &OutStreamer, unsigned OpNo, int BitWidth, int Repeats=1)
static unsigned convertTailJumpOpcode(unsigned Opcode, bool IsLarge=false)
#define MASK_AVX512_CASE(Instr)
#define CASE_ARITH_RM(Instr)
static void addConstantComments(const MachineInstr *MI, MCStreamer &OutStreamer)
#define CASE_256_MOV_RM()
#define CASE_AVX512_ARITH_RM(Instr)
bool hasJumpTableInfoInBlock(const llvm::MachineInstr *MI)
static unsigned emitNop(MCStreamer &OS, unsigned NumBytes, const X86Subtarget *Subtarget)
Emit the largest nop instruction smaller than or equal to NumBytes bytes.
static void printDstRegisterName(raw_ostream &CS, const MachineInstr *MI, unsigned SrcOpIdx)
#define CASE_MOVX_RM(Ext, Type)
bool isImportedFunction(const MachineOperand &MO)
static void printConstant(const APInt &Val, raw_ostream &CS, bool PrintZero=false)
static void printZeroExtend(const MachineInstr *MI, MCStreamer &OutStreamer, int SrcEltBits, int DstEltBits)
static std::string getShuffleComment(const MachineInstr *MI, unsigned SrcOp1Idx, unsigned SrcOp2Idx, ArrayRef< int > Mask)
bool isCallToCFGuardFunction(const MachineInstr *MI)
#define CASE_512_MOV_RM()
#define CASE_128_MOV_RM()
void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const
const fltSemantics & getSemantics() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned getNumWords() const
Get the number of words.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
MCSymbol * getSymbol(const GlobalValue *GV) const
MCSymbol * CurrentFnBegin
TargetMachine & TM
Target machine description.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
MachineFunction * MF
The current machine function.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
MCSymbol * CurrentPatchableFunctionEntrySym
The symbol for the entry in __patchable_function_entires.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCAsmInfo & MAI
Target Asm Printer information.
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
std::function< MachineBranchProbabilityInfo *(MachineFunction &)> GetMBPI
This is an important base class in LLVM.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasInternalLinkage() const
bool doesSetDirectiveSuppressReloc() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MCCodeEmitter - Generic instruction encoding interface.
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
LLVM_ABI const MCTargetOptions & getTargetOptions() const
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
Streaming machine code generation interface.
virtual void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc=SMLoc())
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual bool popSection()
Restore the current and previous section from the section stack.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo &STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitWinCFIUnwindV2Start(SMLoc Loc=SMLoc())
virtual void emitWinCFIEndEpilogue(SMLoc Loc=SMLoc())
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
void pushSection()
Save the current and previous section on the section stack.
virtual void emitWinCFIPush2Regs(MCRegister Reg1, MCRegister Reg2, SMLoc Loc=SMLoc())
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
MCSection * getCurrentSectionOnly() const
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
instr_iterator instr_begin()
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
instr_iterator instr_end()
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::const_iterator const_iterator
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
const MachineOperand & getOperand(unsigned i) const
bool isMetaInstruction(QueryType Type=IgnoreBundle) const
Return true if this instruction doesn't produce any output in the form of executable instructions.
StubValueTy & getGVStubEntry(MCSymbol *Sym)
PointerIntPair< MCSymbol *, 1, bool > StubValueTy
MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
const GlobalValue * getGlobal() const
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.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static const char * getRegisterName(MCRegister Reg)
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
const X86Subtarget & getSubtarget() const
X86AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo, const MachineInstr *MI) override
Let the target do anything it needs to do after emitting inlineasm.
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
unsigned getSlotSize() const
bool isTargetWindowsMSVC() const
bool useIndirectThunkCalls() const
virtual bool emitFPOPushReg(MCRegister Reg, SMLoc L={})
virtual bool emitFPOEndPrologue(SMLoc L={})
virtual bool emitFPOStackAlign(unsigned Align, SMLoc L={})
virtual bool emitFPOSetFrame(MCRegister Reg, SMLoc L={})
virtual bool emitFPOStackAlloc(unsigned StackAlloc, SMLoc L={})
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ Itanium
Windows CE ARM, PowerPC, SH3, SH4.
bool isKMergeMasked(uint64_t TSFlags)
@ MO_TLSLD
MO_TLSLD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_DARWIN_NONLAZY_PIC_BASE
MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...
@ MO_GOT_ABSOLUTE_ADDRESS
MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a relocation of: SYMBOL_LABEL + [.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
@ MO_NTPOFF
MO_NTPOFF - On a symbol operand this indicates that the immediate is the negative thread-pointer offs...
@ MO_DARWIN_NONLAZY
MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...
@ MO_INDNTPOFF
MO_INDNTPOFF - On a symbol operand this indicates that the immediate is the absolute address of the G...
@ MO_GOTNTPOFF
MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry w...
@ MO_TPOFF
MO_TPOFF - On a symbol operand this indicates that the immediate is the thread-pointer offset for the...
@ MO_TLVP_PIC_BASE
MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate is some TLS offset from the ...
@ MO_GOT
MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...
@ MO_ABS8
MO_ABS8 - On a symbol operand this indicates that the symbol is known to be an absolute symbol in ran...
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
@ MO_TLSGD
MO_TLSGD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ MO_TLVP
MO_TLVP - On a symbol operand this indicates that the immediate is some TLS offset.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
@ MO_GOTTPOFF
MO_GOTTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry wi...
@ MO_SECREL
MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...
@ MO_DTPOFF
MO_DTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
@ MO_TLSLDM
MO_TLSLDM - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
bool isKMasked(uint64_t TSFlags)
bool isX86_64ExtendedReg(MCRegister Reg)
bool optimizeToFixedRegisterOrShortImmediateForm(MCInst &MI)
bool optimizeMOV(MCInst &MI, bool In64BitMode)
Simplify things like MOV32rm to MOV32o32a.
CondCode GetOppositeBranchCondition(CondCode CC)
GetOppositeBranchCondition - Return the inverse of the specified cond, e.g.
bool optimizeMOVSX(MCInst &MI)
bool optimizeVPCMPWithImmediateOneOrSix(MCInst &MI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
const Constant * getConstantFromPool(const MachineInstr &MI, unsigned OpNo)
Find any constant pool entry associated with a specific instruction operand.
bool optimizeINCDEC(MCInst &MI, bool In64BitMode)
unsigned getVectorRegisterWidth(const MCOperandInfo &Info)
Get the width of the vector register operand.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
void DecodeZeroExtendMask(unsigned SrcScalarBits, unsigned DstScalarBits, unsigned NumDstElts, bool IsAnyExtend, SmallVectorImpl< int > &ShuffleMask)
Decode a zero extension instruction as a shuffle mask.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void DecodeVPERMILPMask(unsigned NumElts, unsigned ScalarBits, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMILPD/VPERMILPS variable mask from a raw array of constants.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
LLVM_ABI bool isCFGuardFunction(const GlobalValue *GV)
void DecodeVPERMIL2PMask(unsigned NumElts, unsigned ScalarBits, unsigned M2Z, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMIL2PD/VPERMIL2PS variable mask from a raw array of constants.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
LLVM_ABI void getAddressSanitizerParams(const LLVMContext &Ctx, const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
void DecodeVPPERMMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPPERM mask from a raw array of constants such as from BUILD_VECTOR.
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr unsigned BitWidth
@ WinEH
Windows Exception Handling.
void DecodePSHUFBMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a PSHUFB mask from a raw array of constants such as from BUILD_VECTOR.
void changeAndComment(bool b)
NoAutoPaddingScope(MCStreamer &OS)
const bool OldAllowAutoPadding