63 "branch-hint-probability-threshold",
64 cl::desc(
"The probability threshold of enabling branch hint."),
104 if (b ==
OS.getAllowAutoPadding())
106 OS.setAllowAutoPadding(b);
108 OS.emitRawComment(
"autopadding");
110 OS.emitRawComment(
"noautopadding");
118void X86AsmPrinter::StackMapShadowTracker::count(
const MCInst &Inst,
122 SmallString<256>
Code;
125 CurrentShadowSize +=
Code.size();
126 if (CurrentShadowSize >= RequiredShadowSize)
131void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
132 MCStreamer &
OutStreamer,
const MCSubtargetInfo &STI) {
133 if (InShadow && CurrentShadowSize < RequiredShadowSize) {
136 &
MF->getSubtarget<X86Subtarget>());
140void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
145X86MCInstLower::X86MCInstLower(
const MachineFunction &mf,
156MCSymbol *X86MCInstLower::GetSymbolFromOperand(
const MachineOperand &MO)
const {
163 "Isn't a symbol reference");
166 SmallString<128>
Name;
179 Suffix =
"$non_lazy_ptr";
184 Name +=
DL.getInternalSymbolPrefix();
191 }
else if (MO.
isMBB()) {
206 MachineModuleInfoCOFF &MMICOFF =
209 if (!StubSym.getPointer()) {
219 getMachOMMI().getGVStubEntry(Sym);
233MCOperand X86MCInstLower::LowerSymbolOperand(
const MachineOperand &MO,
234 MCSymbol *Sym)
const {
237 const MCExpr *Expr =
nullptr;
320 AsmPrinter.
OutStreamer->emitAssignment(Label, Expr);
336 return Subtarget.is64Bit() ? X86::RET64 : X86::RET32;
339MCOperand X86MCInstLower::LowerMachineOperand(
const MachineInstr *
MI,
340 const MachineOperand &MO)
const {
376 Opcode = X86::JMP32r;
379 Opcode = X86::JMP32m;
381 case X86::TAILJMPr64:
382 Opcode = X86::JMP64r;
384 case X86::TAILJMPm64:
385 Opcode = X86::JMP64m;
387 case X86::TAILJMPr64_REX:
388 Opcode = X86::JMP64r_REX;
390 case X86::TAILJMPm64_REX:
391 Opcode = X86::JMP64m_REX;
394 case X86::TAILJMPd64:
395 Opcode = IsLarge ? X86::JMPABS64i : X86::JMP_1;
397 case X86::TAILJMPd_CC:
398 case X86::TAILJMPd64_CC:
406void X86MCInstLower::Lower(
const MachineInstr *
MI, MCInst &OutMI)
const {
409 for (
const MachineOperand &MO :
MI->operands())
410 if (
auto Op = LowerMachineOperand(
MI, MO);
Op.isValid())
430 "Unexpected # of LEA operands");
432 "LEA has segment specified!");
437 case X86::MULX64Hrm: {
442 case X86::MULX32Hrr: NewOpc = X86::MULX32rr;
break;
443 case X86::MULX32Hrm: NewOpc = X86::MULX32rm;
break;
444 case X86::MULX64Hrr: NewOpc = X86::MULX64rr;
break;
445 case X86::MULX64Hrm: NewOpc = X86::MULX64rm;
break;
458 case X86::CALL64pcrel32:
462 case X86::EH_RETURN64: {
467 case X86::CLEANUPRET: {
473 case X86::CATCHRET: {
475 const X86Subtarget &Subtarget = AsmPrinter.
getSubtarget();
476 unsigned ReturnReg = In64BitMode ? X86::RAX : X86::EAX;
485 case X86::TAILJMPr64:
486 case X86::TAILJMPr64_REX:
491 case X86::TAILJMPd64: {
495 "Unexpected TAILJMPd64 in large code model without JMPABS");
499 case X86::TAILJMPd_CC:
500 case X86::TAILJMPd64_CC:
505 case X86::TAILJMPm64:
506 case X86::TAILJMPm64_REX:
508 "Unexpected number of operands!");
511 case X86::MASKMOVDQU:
512 case X86::VMASKMOVDQU:
526 const MachineOperand *FlagDef =
527 MI->findRegisterDefOperand(X86::EFLAGS,
nullptr);
537void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
538 const MachineInstr &
MI) {
539 NoAutoPaddingScope NoPadScope(*OutStreamer);
540 bool Is64Bits = getSubtarget().is64Bit();
541 bool Is64BitsLP64 = getSubtarget().isTarget64BitLP64();
545 switch (
MI.getOpcode()) {
546 case X86::TLS_addr32:
547 case X86::TLS_addr64:
548 case X86::TLS_addrX32:
551 case X86::TLS_base_addr32:
554 case X86::TLS_base_addr64:
555 case X86::TLS_base_addrX32:
558 case X86::TLS_desc32:
559 case X86::TLS_desc64:
567 MCInstLowering.GetSymbolFromOperand(
MI.getOperand(3)), Specifier, Ctx);
574 bool UseGot = MMI->getModule()->getRtLibUseGOT() &&
581 EmitAndCountInstruction(
582 MCInstBuilder(Is64BitsLP64 ? X86::LEA64r : X86::LEA32r)
583 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
584 .addReg(Is64Bits ? X86::RIP : X86::EBX)
589 EmitAndCountInstruction(
590 MCInstBuilder(Is64Bits ? X86::CALL64m : X86::CALL32m)
591 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
596 }
else if (Is64Bits) {
598 if (NeedsPadding && Is64BitsLP64)
599 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
600 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
610 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
611 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
612 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
617 EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)
624 EmitAndCountInstruction(
625 MCInstBuilder(X86::CALL64pcrel32)
630 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
638 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
650 EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)
657 EmitAndCountInstruction(
658 MCInstBuilder(X86::CALLpcrel32)
671 unsigned MaxNopLength = 1;
672 if (Subtarget->is64Bit()) {
675 if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))
677 else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))
679 else if (Subtarget->hasFeature(X86::TuningFast11ByteNOP))
683 }
if (Subtarget->is32Bit())
687 NumBytes = std::min(NumBytes, MaxNopLength);
690 unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
691 IndexReg = Displacement = SegmentReg = 0;
749 SegmentReg = X86::CS;
753 unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);
754 NopSize += NumPrefixes;
755 for (
unsigned i = 0; i != NumPrefixes; ++i)
773 .addImm(Displacement)
778 assert(NopSize <= NumBytes &&
"We overemitted?");
785 unsigned NopsToEmit = NumBytes;
788 NumBytes -=
emitNop(OS, NumBytes, Subtarget);
789 assert(NopsToEmit >= NumBytes &&
"Emitted more than I asked for!");
793void X86AsmPrinter::LowerSTATEPOINT(
const MachineInstr &
MI,
794 X86MCInstLower &MCIL) {
795 assert(Subtarget->is64Bit() &&
"Statepoint currently only supports X86-64");
797 NoAutoPaddingScope NoPadScope(*OutStreamer);
799 StatepointOpers SOpers(&
MI);
800 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
804 const MachineOperand &CallTarget = SOpers.getCallTarget();
805 MCOperand CallTargetMCOp;
807 switch (CallTarget.
getType()) {
810 CallTargetMCOp = MCIL.LowerSymbolOperand(
811 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
812 CallOpcode = X86::CALL64pcrel32;
820 CallOpcode = X86::CALL64pcrel32;
832 CallOpcode = X86::CALL64r;
844 maybeEmitNopAfterCallForWindowsEH(&
MI);
852 SM.recordStatepoint(*MILabel,
MI);
855void X86AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI,
856 X86MCInstLower &MCIL) {
860 NoAutoPaddingScope NoPadScope(*OutStreamer);
867 unsigned OperandsBeginIdx = 4;
874 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
877 MI.setOpcode(Opcode);
879 if (DefRegister != X86::NoRegister)
882 for (
const MachineOperand &MO :
884 if (
auto Op = MCIL.LowerMachineOperand(&FaultingMI, MO);
Op.isValid())
891void X86AsmPrinter::LowerFENTRY_CALL(
const MachineInstr &
MI,
892 X86MCInstLower &MCIL) {
893 bool Is64Bits = Subtarget->is64Bit();
898 EmitAndCountInstruction(
899 MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
903void X86AsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
904 assert(std::next(
MI.getIterator())->isCall() &&
905 "KCFI_CHECK not followed by a call instruction");
911 const MachineFunction &MF = *
MI.getMF();
912 int64_t PrefixNops = 0;
923 const Register AddrReg =
MI.getOperand(0).getReg();
924 const uint32_t
Type =
MI.getOperand(1).getImm();
927 unsigned TempReg = AddrReg == X86::R10 ? X86::R11D : X86::R10D;
928 EmitAndCountInstruction(
929 MCInstBuilder(X86::MOV32ri).addReg(TempReg).addImm(-MaskKCFIType(
Type)));
930 EmitAndCountInstruction(MCInstBuilder(X86::ADD32rm)
931 .addReg(X86::NoRegister)
935 .addReg(X86::NoRegister)
936 .addImm(-(PrefixNops + 4))
937 .addReg(X86::NoRegister));
940 EmitAndCountInstruction(
941 MCInstBuilder(X86::JCC_1)
947 EmitAndCountInstruction(MCInstBuilder(X86::TRAP));
948 emitKCFITrapEntry(MF,
Trap);
952void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
954 if (!TM.getTargetTriple().isOSBinFormatELF()) {
959 const auto &
Reg =
MI.getOperand(0).getReg();
960 ASanAccessInfo AccessInfo(
MI.getOperand(1).getImm());
966 &ShadowBase, &MappingScale, &OrShadowOffset);
968 StringRef
Name = AccessInfo.IsWrite ?
"store" :
"load";
969 StringRef
Op = OrShadowOffset ?
"or" :
"add";
970 std::string SymName = (
"__asan_check_" +
Name +
"_" +
Op +
"_" +
971 Twine(1ULL << AccessInfo.AccessSizeIndex) +
"_" +
972 TM.getMCRegisterInfo()->getName(
Reg.
asMCReg()))
976 "OrShadowOffset is not supported with optimized callbacks");
978 EmitAndCountInstruction(
979 MCInstBuilder(X86::CALL64pcrel32)
981 OutContext.getOrCreateSymbol(SymName), OutContext)));
984void X86AsmPrinter::LowerPATCHABLE_OP(
const MachineInstr &
MI,
985 X86MCInstLower &MCIL) {
988 NoAutoPaddingScope NoPadScope(*OutStreamer);
990 auto NextMI = std::find_if(std::next(
MI.getIterator()),
991 MI.getParent()->end().getInstrIterator(),
992 [](
auto &
II) { return !II.isMetaInstruction(); });
994 SmallString<256>
Code;
995 unsigned MinSize =
MI.getOperand(0).getImm();
997 if (NextMI !=
MI.getParent()->end() && !NextMI->isInlineAsm()) {
1002 MCIL.Lower(&*NextMI, MCI);
1008 if (
Code.size() < MinSize) {
1009 if (MinSize == 2 && Subtarget->is32Bit() &&
1011 (Subtarget->getCPU().empty() || Subtarget->getCPU() ==
"pentium3")) {
1017 MCInstBuilder(X86::MOV32rr_REV).addReg(X86::EDI).addReg(X86::EDI),
1020 unsigned NopSize =
emitNop(*OutStreamer, MinSize, Subtarget);
1021 assert(NopSize == MinSize &&
"Could not implement MinSize!");
1029void X86AsmPrinter::LowerSTACKMAP(
const MachineInstr &
MI) {
1030 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1036 SM.recordStackMap(*MILabel,
MI);
1037 unsigned NumShadowBytes =
MI.getOperand(1).getImm();
1038 SMShadowTracker.reset(NumShadowBytes);
1043void X86AsmPrinter::LowerPATCHPOINT(
const MachineInstr &
MI,
1044 X86MCInstLower &MCIL) {
1045 assert(Subtarget->is64Bit() &&
"Patchpoint currently only supports X86-64");
1047 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1049 NoAutoPaddingScope NoPadScope(*OutStreamer);
1054 SM.recordPatchPoint(*MILabel,
MI);
1056 PatchPointOpers opers(&
MI);
1057 unsigned ScratchIdx = opers.getNextScratchIdx();
1058 unsigned EncodedBytes = 0;
1059 const MachineOperand &CalleeMO = opers.getCallTarget();
1064 MCOperand CalleeMCOp;
1075 CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,
1076 MCIL.GetSymbolFromOperand(CalleeMO));
1082 Register ScratchReg =
MI.getOperand(ScratchIdx).getReg();
1088 EmitAndCountInstruction(
1089 MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).
addOperand(CalleeMCOp));
1093 "Lowering patchpoint with thunks not yet implemented.");
1094 EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
1098 unsigned NumBytes = opers.getNumPatchBytes();
1099 assert(NumBytes >= EncodedBytes &&
1100 "Patchpoint can't request size less than the length of a call.");
1102 emitX86Nops(*OutStreamer, NumBytes - EncodedBytes, Subtarget);
1105void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
1106 X86MCInstLower &MCIL) {
1107 assert(Subtarget->is64Bit() &&
"XRay custom events only supports X86-64");
1109 NoAutoPaddingScope NoPadScope(*OutStreamer);
1131 auto CurSled = OutContext.createTempSymbol(
"xray_event_sled_",
true);
1132 OutStreamer->
AddComment(
"# XRay Custom Event Log");
1143 const Register DestRegs[] = {X86::RDI, X86::RSI};
1144 bool UsedMask[] = {
false,
false};
1153 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1154 if (
auto Op = MCIL.LowerMachineOperand(&
MI,
MI.getOperand(
I));
1156 assert(
Op.isReg() &&
"Only support arguments in registers");
1159 if (SrcRegs[
I] != DestRegs[
I]) {
1161 EmitAndCountInstruction(
1162 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[
I]));
1172 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1173 if (SrcRegs[
I] != DestRegs[
I])
1174 EmitAndCountInstruction(
1175 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[
I]).addReg(SrcRegs[
I]));
1179 auto TSym = OutContext.getOrCreateSymbol(
"__xray_CustomEvent");
1181 if (isPositionIndependent())
1185 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1186 .
addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1189 for (
unsigned I =
sizeof UsedMask;
I-- > 0;)
1191 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[
I]));
1195 OutStreamer->
AddComment(
"xray custom event end.");
1200 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
1203void X86AsmPrinter::LowerPATCHABLE_TYPED_EVENT_CALL(
const MachineInstr &
MI,
1204 X86MCInstLower &MCIL) {
1205 assert(Subtarget->is64Bit() &&
"XRay typed events only supports X86-64");
1207 NoAutoPaddingScope NoPadScope(*OutStreamer);
1229 auto CurSled = OutContext.createTempSymbol(
"xray_typed_event_sled_",
true);
1230 OutStreamer->
AddComment(
"# XRay Typed Event Log");
1242 const Register DestRegs[] = {X86::RDI, X86::RSI, X86::RDX};
1243 bool UsedMask[] = {
false,
false,
false};
1252 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1253 if (
auto Op = MCIL.LowerMachineOperand(&
MI,
MI.getOperand(
I));
1256 assert(
Op.isReg() &&
"Only supports arguments in registers");
1259 if (SrcRegs[
I] != DestRegs[
I]) {
1261 EmitAndCountInstruction(
1262 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[
I]));
1277 for (
unsigned I = 0;
I <
MI.getNumOperands(); ++
I)
1279 EmitAndCountInstruction(
1280 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[
I]).addReg(SrcRegs[
I]));
1284 auto TSym = OutContext.getOrCreateSymbol(
"__xray_TypedEvent");
1286 if (isPositionIndependent())
1290 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1291 .
addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1294 for (
unsigned I =
sizeof UsedMask;
I-- > 0;)
1296 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[
I]));
1300 OutStreamer->
AddComment(
"xray typed event end.");
1303 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
1306void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI,
1307 X86MCInstLower &MCIL) {
1309 NoAutoPaddingScope NoPadScope(*OutStreamer);
1312 if (
F.hasFnAttribute(
"patchable-function-entry")) {
1314 if (
F.getFnAttribute(
"patchable-function-entry")
1316 .getAsInteger(10, Num))
1334 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1343 recordSled(CurSled,
MI, SledKind::FUNCTION_ENTER, 2);
1346void X86AsmPrinter::LowerPATCHABLE_RET(
const MachineInstr &
MI,
1347 X86MCInstLower &MCIL) {
1348 NoAutoPaddingScope NoPadScope(*OutStreamer);
1364 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1367 unsigned OpCode =
MI.getOperand(0).getImm();
1371 if (
auto Op = MCIL.LowerMachineOperand(&
MI, MO);
Op.isValid())
1375 recordSled(CurSled,
MI, SledKind::FUNCTION_EXIT, 2);
1378void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI,
1379 X86MCInstLower &MCIL) {
1384 bool IsConditional = TC.
getOpcode() == X86::JCC_1;
1386 if (IsConditional) {
1397 FallthroughLabel = OutContext.createTempSymbol();
1400 MCInstBuilder(X86::JCC_1)
1409 NoAutoPaddingScope NoPadScope(*OutStreamer);
1417 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
1420 auto Target = OutContext.createTempSymbol();
1428 recordSled(CurSled,
MI, SledKind::TAIL_CALL, 2);
1433 for (
auto &MO : TCOperands)
1434 if (
auto Op = MCIL.LowerMachineOperand(&
MI, MO);
Op.isValid())
1439 OutStreamer->
emitLabel(FallthroughLabel);
1455 unsigned SrcOpIdx) {
1465 CS <<
" {%" << Mask <<
"}";
1476 if (Src1Name == Src2Name)
1477 for (
int i = 0, e = ShuffleMask.size(); i != e; ++i)
1478 if (ShuffleMask[i] >= e)
1479 ShuffleMask[i] -= e;
1481 for (
int i = 0, e = ShuffleMask.size(); i != e; ++i) {
1491 bool isSrc1 = ShuffleMask[i] < (int)e;
1492 CS << (isSrc1 ? Src1Name : Src2Name) <<
'[';
1494 bool IsFirst =
true;
1496 (ShuffleMask[i] < (
int)e) == isSrc1) {
1504 CS << ShuffleMask[i] % (int)e;
1514 std::string Comment;
1534 bool PrintZero =
false) {
1543 CS << (PrintZero ? 0ULL : Val.
getRawData()[i]);
1550 bool PrintZero =
false) {
1566 for (
unsigned I = 0,
E = VTy->getNumElements();
I !=
E; ++
I) {
1575 unsigned EltBits = VTy->getScalarSizeInBits();
1576 unsigned E = std::min(
BitWidth / EltBits, VTy->getNumElements());
1578 for (
unsigned I = 0;
I !=
E; ++
I) {
1589 Type *EltTy = CDS->getElementType();
1593 unsigned E = std::min(
BitWidth / EltBits, (
unsigned)CDS->getNumElements());
1595 for (
unsigned I = 0;
I !=
E; ++
I) {
1609 unsigned EltBits = CV->getType()->getScalarSizeInBits();
1610 unsigned E = std::min(
BitWidth / EltBits, CV->getNumOperands());
1612 for (
unsigned I = 0;
I !=
E; ++
I) {
1626 int SclWidth,
int VecWidth,
1627 const char *ShuffleComment) {
1630 std::string Comment;
1638 for (
int I = 1,
E = VecWidth / SclWidth;
I <
E; ++
I) {
1648 CS << ShuffleComment;
1656 std::string Comment;
1660 for (
int l = 0; l != Repeats; ++l) {
1671 int SrcEltBits,
int DstEltBits,
bool IsSext) {
1674 if (
C &&
C->getType()->getScalarSizeInBits() ==
unsigned(SrcEltBits)) {
1676 int NumElts = CDS->getNumElements();
1677 std::string Comment;
1681 for (
int i = 0; i != NumElts; ++i) {
1684 if (CDS->getElementType()->isIntegerTy()) {
1685 APInt Elt = CDS->getElementAsAPInt(i);
1686 Elt = IsSext ? Elt.
sext(DstEltBits) : Elt.
zext(DstEltBits);
1700 int SrcEltBits,
int DstEltBits) {
1704 int SrcEltBits,
int DstEltBits) {
1705 if (
printExtend(
MI, OutStreamer, SrcEltBits, DstEltBits,
false))
1709 std::string Comment;
1716 assert((Width % DstEltBits) == 0 && (DstEltBits % SrcEltBits) == 0 &&
1717 "Illegal extension ratio");
1724void X86AsmPrinter::EmitSEHInstruction(
const MachineInstr *
MI) {
1725 assert(MF->
hasWinCFI() &&
"SEH_ instruction in function without WinCFI?");
1726 assert((getSubtarget().isOSWindows() || getSubtarget().isUEFI()) &&
1727 "SEH_ instruction Windows and UEFI only");
1731 X86TargetStreamer *XTS =
1733 switch (
MI->getOpcode()) {
1734 case X86::SEH_PushReg:
1737 case X86::SEH_StackAlloc:
1740 case X86::SEH_StackAlign:
1743 case X86::SEH_SetFrame:
1744 assert(
MI->getOperand(1).getImm() == 0 &&
1745 ".cv_fpo_setframe takes no offset");
1748 case X86::SEH_EndPrologue:
1751 case X86::SEH_SaveReg:
1752 case X86::SEH_SaveXMM:
1753 case X86::SEH_PushFrame:
1763 switch (
MI->getOpcode()) {
1764 case X86::SEH_PushReg:
1768 case X86::SEH_SaveReg:
1770 MI->getOperand(1).getImm());
1773 case X86::SEH_SaveXMM:
1775 MI->getOperand(1).getImm());
1778 case X86::SEH_StackAlloc:
1782 case X86::SEH_SetFrame:
1784 MI->getOperand(1).getImm());
1787 case X86::SEH_PushFrame:
1791 case X86::SEH_EndPrologue:
1795 case X86::SEH_BeginEpilogue:
1799 case X86::SEH_EndEpilogue:
1803 case X86::SEH_UnwindV2Start:
1807 case X86::SEH_UnwindVersion:
1818 switch (
MI->getOpcode()) {
1823 case X86::VPSHUFBrm:
1824 case X86::VPSHUFBYrm:
1825 case X86::VPSHUFBZ128rm:
1826 case X86::VPSHUFBZ128rmk:
1827 case X86::VPSHUFBZ128rmkz:
1828 case X86::VPSHUFBZ256rm:
1829 case X86::VPSHUFBZ256rmk:
1830 case X86::VPSHUFBZ256rmkz:
1831 case X86::VPSHUFBZrm:
1832 case X86::VPSHUFBZrmk:
1833 case X86::VPSHUFBZrmkz: {
1845 case X86::VPERMILPSrm:
1846 case X86::VPERMILPSYrm:
1847 case X86::VPERMILPSZ128rm:
1848 case X86::VPERMILPSZ128rmk:
1849 case X86::VPERMILPSZ128rmkz:
1850 case X86::VPERMILPSZ256rm:
1851 case X86::VPERMILPSZ256rmk:
1852 case X86::VPERMILPSZ256rmkz:
1853 case X86::VPERMILPSZrm:
1854 case X86::VPERMILPSZrmk:
1855 case X86::VPERMILPSZrmkz: {
1866 case X86::VPERMILPDrm:
1867 case X86::VPERMILPDYrm:
1868 case X86::VPERMILPDZ128rm:
1869 case X86::VPERMILPDZ128rmk:
1870 case X86::VPERMILPDZ128rmkz:
1871 case X86::VPERMILPDZ256rm:
1872 case X86::VPERMILPDZ256rmk:
1873 case X86::VPERMILPDZ256rmkz:
1874 case X86::VPERMILPDZrm:
1875 case X86::VPERMILPDZrmk:
1876 case X86::VPERMILPDZrmkz: {
1888 case X86::VPERMIL2PDrm:
1889 case X86::VPERMIL2PSrm:
1890 case X86::VPERMIL2PDYrm:
1891 case X86::VPERMIL2PSYrm: {
1893 "Unexpected number of operands!");
1896 if (!CtrlOp.
isImm())
1900 switch (
MI->getOpcode()) {
1902 case X86::VPERMIL2PSrm:
case X86::VPERMIL2PSYrm: ElSize = 32;
break;
1903 case X86::VPERMIL2PDrm:
case X86::VPERMIL2PDYrm: ElSize = 64;
break;
1916 case X86::VPPERMrrm: {
1927 case X86::MMX_MOVQ64rm: {
1929 std::string Comment;
1934 CS <<
"0x" <<
toString(CF->getValueAPF().bitcastToAPInt(), 16,
false);
1941#define INSTR_CASE(Prefix, Instr, Suffix, Postfix) \
1942 case X86::Prefix##Instr##Suffix##rm##Postfix:
1944#define CASE_AVX512_ARITH_RM(Instr) \
1945 INSTR_CASE(V, Instr, Z128, ) \
1946 INSTR_CASE(V, Instr, Z128, k) \
1947 INSTR_CASE(V, Instr, Z128, kz) \
1948 INSTR_CASE(V, Instr, Z256, ) \
1949 INSTR_CASE(V, Instr, Z256, k) \
1950 INSTR_CASE(V, Instr, Z256, kz) \
1951 INSTR_CASE(V, Instr, Z, ) \
1952 INSTR_CASE(V, Instr, Z, k) \
1953 INSTR_CASE(V, Instr, Z, kz)
1955#define CASE_ARITH_RM(Instr) \
1956 INSTR_CASE(, Instr, , ) \
1957 INSTR_CASE(V, Instr, , ) \
1958 INSTR_CASE(V, Instr, Y, ) \
1959 INSTR_CASE(V, Instr, Z128, ) \
1960 INSTR_CASE(V, Instr, Z128, k) \
1961 INSTR_CASE(V, Instr, Z128, kz) \
1962 INSTR_CASE(V, Instr, Z256, ) \
1963 INSTR_CASE(V, Instr, Z256, k) \
1964 INSTR_CASE(V, Instr, Z256, kz) \
1965 INSTR_CASE(V, Instr, Z, ) \
1966 INSTR_CASE(V, Instr, Z, k) \
1967 INSTR_CASE(V, Instr, Z, kz)
1982 std::string Comment;
1984 unsigned VectorWidth =
1994#define MASK_AVX512_CASE(Instr) \
2002 case X86::MOVSDrm_alt:
2003 case X86::VMOVSDrm_alt:
2004 case X86::VMOVSDZrm_alt:
2005 case X86::MOVQI2PQIrm:
2006 case X86::VMOVQI2PQIrm:
2007 case X86::VMOVQI2PQIZrm:
2012 case X86::VMOVSHZrm_alt:
2014 "mem[0],zero,zero,zero,zero,zero,zero,zero");
2020 case X86::MOVSSrm_alt:
2021 case X86::VMOVSSrm_alt:
2022 case X86::VMOVSSZrm_alt:
2023 case X86::MOVDI2PDIrm:
2024 case X86::VMOVDI2PDIrm:
2025 case X86::VMOVDI2PDIZrm:
2029#define MOV_CASE(Prefix, Suffix) \
2030 case X86::Prefix##MOVAPD##Suffix##rm: \
2031 case X86::Prefix##MOVAPS##Suffix##rm: \
2032 case X86::Prefix##MOVUPD##Suffix##rm: \
2033 case X86::Prefix##MOVUPS##Suffix##rm: \
2034 case X86::Prefix##MOVDQA##Suffix##rm: \
2035 case X86::Prefix##MOVDQU##Suffix##rm:
2037#define MOV_AVX512_CASE(Suffix, Postfix) \
2038 case X86::VMOVDQA64##Suffix##rm##Postfix: \
2039 case X86::VMOVDQA32##Suffix##rm##Postfix: \
2040 case X86::VMOVDQU64##Suffix##rm##Postfix: \
2041 case X86::VMOVDQU32##Suffix##rm##Postfix: \
2042 case X86::VMOVDQU16##Suffix##rm##Postfix: \
2043 case X86::VMOVDQU8##Suffix##rm##Postfix: \
2044 case X86::VMOVAPS##Suffix##rm##Postfix: \
2045 case X86::VMOVAPD##Suffix##rm##Postfix: \
2046 case X86::VMOVUPS##Suffix##rm##Postfix: \
2047 case X86::VMOVUPD##Suffix##rm##Postfix:
2049#define CASE_128_MOV_RM() \
2052 MOV_AVX512_CASE(Z128, ) \
2053 MOV_AVX512_CASE(Z128, k) \
2054 MOV_AVX512_CASE(Z128, kz)
2056#define CASE_256_MOV_RM() \
2058 MOV_AVX512_CASE(Z256, ) \
2059 MOV_AVX512_CASE(Z256, k) \
2060 MOV_AVX512_CASE(Z256, kz) \
2062#define CASE_512_MOV_RM() \
2063 MOV_AVX512_CASE(Z, ) \
2064 MOV_AVX512_CASE(Z, k) \
2065 MOV_AVX512_CASE(Z, kz) \
2078 case X86::VBROADCASTF128rm:
2079 case X86::VBROADCASTI128rm:
2101 case X86::MOVDDUPrm:
2102 case X86::VMOVDDUPrm:
2104 case X86::VPBROADCASTQrm:
2108 case X86::VBROADCASTSDYrm:
2110 case X86::VPBROADCASTQYrm:
2118 case X86::VBROADCASTSSrm:
2120 case X86::VPBROADCASTDrm:
2124 case X86::VBROADCASTSSYrm:
2126 case X86::VPBROADCASTDYrm:
2134 case X86::VPBROADCASTWrm:
2138 case X86::VPBROADCASTWYrm:
2145 case X86::VPBROADCASTBrm:
2149 case X86::VPBROADCASTBYrm:
2157#define MOVX_CASE(Prefix, Ext, Type, Suffix, Postfix) \
2158 case X86::Prefix##PMOV##Ext##Type##Suffix##rm##Postfix:
2160#define CASE_MOVX_RM(Ext, Type) \
2161 MOVX_CASE(, Ext, Type, , ) \
2162 MOVX_CASE(V, Ext, Type, , ) \
2163 MOVX_CASE(V, Ext, Type, Y, ) \
2164 MOVX_CASE(V, Ext, Type, Z128, ) \
2165 MOVX_CASE(V, Ext, Type, Z128, k ) \
2166 MOVX_CASE(V, Ext, Type, Z128, kz ) \
2167 MOVX_CASE(V, Ext, Type, Z256, ) \
2168 MOVX_CASE(V, Ext, Type, Z256, k ) \
2169 MOVX_CASE(V, Ext, Type, Z256, kz ) \
2170 MOVX_CASE(V, Ext, Type, Z, ) \
2171 MOVX_CASE(V, Ext, Type, Z, k ) \
2172 MOVX_CASE(V, Ext, Type, Z, kz )
2221 assert(
MI->getOpcode() == X86::TAILJMPm64_REX ||
2222 MI->getOpcode() == X86::CALL64m);
2232 for (
auto I =
MBB.instr_rbegin(),
E =
MBB.instr_rend();
I !=
E; ++
I)
2233 if (
I->isJumpTableDebugInfo())
2244 X86MCInstLower MCInstLowering(*
MF, *
this);
2248 if (
MI->getOpcode() == X86::OR64rm) {
2249 for (
auto &Opd :
MI->operands()) {
2250 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
2251 "swift_async_extendedFramePointerFlags") {
2252 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
2262 if (
TM.Options.MCOptions.ShowMCEncoding) {
2264 OutStreamer->AddComment(
"EVEX TO LEGACY Compression ",
false);
2266 OutStreamer->AddComment(
"EVEX TO VEX Compression ",
false);
2268 OutStreamer->AddComment(
"EVEX TO EVEX Compression ",
false);
2272 bool IsTailJump =
false;
2274 switch (
MI->getOpcode()) {
2275 case TargetOpcode::DBG_VALUE:
2278 case X86::EH_RETURN:
2279 case X86::EH_RETURN64: {
2286 case X86::CLEANUPRET: {
2292 case X86::CATCHRET: {
2299 case X86::ENDBR64: {
2306 MI == &
MF->front().front()) {
2308 MCInstLowering.Lower(
MI, Inst);
2309 EmitAndCountInstruction(Inst);
2317 case X86::TAILJMPd64:
2318 if (IndCSPrefix &&
MI->hasRegisterImplicitUseOperand(X86::R11))
2322 emitLabelAndRecordForImportCallOptimization(
2323 IMAGE_RETPOLINE_AMD64_IMPORT_BR);
2334 case X86::TAILJMPd_CC:
2335 case X86::TAILJMPr64:
2336 case X86::TAILJMPm64:
2337 case X86::TAILJMPd64_CC:
2338 if (EnableImportCallOptimization)
2340 "import call optimization was enabled");
2347 case X86::TAILJMPm64_REX:
2349 emitLabelAndRecordForImportCallOptimization(
2350 IMAGE_RETPOLINE_AMD64_CFG_BR_REX);
2357 case X86::TAILJMPr64_REX: {
2358 if (EnableImportCallOptimization) {
2359 assert(
MI->getOperand(0).getReg() == X86::RAX &&
2360 "Indirect tail calls with impcall enabled must go through RAX (as "
2361 "enforced by TCRETURNImpCallri64)");
2362 emitLabelAndRecordForImportCallOptimization(
2363 IMAGE_RETPOLINE_AMD64_INDIR_BR);
2374 this->
getSubtarget().getRegisterInfo()->getEncodingValue(
2375 MI->getOperand(0).getReg().asMCReg());
2376 emitLabelAndRecordForImportCallOptimization(
2377 (ImportCallKind)(IMAGE_RETPOLINE_AMD64_SWITCHTABLE_FIRST +
2389 "Unexpected JMP instruction was emitted for a jump-table when import "
2390 "call optimization was enabled");
2393 case X86::TLS_addr32:
2394 case X86::TLS_addr64:
2395 case X86::TLS_addrX32:
2396 case X86::TLS_base_addr32:
2397 case X86::TLS_base_addr64:
2398 case X86::TLS_base_addrX32:
2399 case X86::TLS_desc32:
2400 case X86::TLS_desc64:
2401 return LowerTlsAddr(MCInstLowering, *
MI);
2403 case X86::MOVPC32r: {
2414 EmitAndCountInstruction(
2420 bool hasFP = FrameLowering->
hasFP(*
MF);
2423 bool HasActiveDwarfFrame =
OutStreamer->getNumFrameInfos() &&
2428 if (HasActiveDwarfFrame && !hasFP) {
2429 OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);
2437 EmitAndCountInstruction(
2440 if (HasActiveDwarfFrame && !hasFP) {
2446 case X86::ADD32ri: {
2462 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(
MI->getOperand(2));
2473 .addReg(
MI->getOperand(0).getReg())
2474 .
addReg(
MI->getOperand(1).getReg())
2478 case TargetOpcode::STATEPOINT:
2479 return LowerSTATEPOINT(*
MI, MCInstLowering);
2481 case TargetOpcode::FAULTING_OP:
2482 return LowerFAULTING_OP(*
MI, MCInstLowering);
2484 case TargetOpcode::FENTRY_CALL:
2485 return LowerFENTRY_CALL(*
MI, MCInstLowering);
2487 case TargetOpcode::PATCHABLE_OP:
2488 return LowerPATCHABLE_OP(*
MI, MCInstLowering);
2490 case TargetOpcode::STACKMAP:
2491 return LowerSTACKMAP(*
MI);
2493 case TargetOpcode::PATCHPOINT:
2494 return LowerPATCHPOINT(*
MI, MCInstLowering);
2496 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2497 return LowerPATCHABLE_FUNCTION_ENTER(*
MI, MCInstLowering);
2499 case TargetOpcode::PATCHABLE_RET:
2500 return LowerPATCHABLE_RET(*
MI, MCInstLowering);
2502 case TargetOpcode::PATCHABLE_TAIL_CALL:
2503 return LowerPATCHABLE_TAIL_CALL(*
MI, MCInstLowering);
2505 case TargetOpcode::PATCHABLE_EVENT_CALL:
2506 return LowerPATCHABLE_EVENT_CALL(*
MI, MCInstLowering);
2508 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
2509 return LowerPATCHABLE_TYPED_EVENT_CALL(*
MI, MCInstLowering);
2511 case X86::MORESTACK_RET:
2515 case X86::KCFI_CHECK:
2516 return LowerKCFI_CHECK(*
MI);
2518 case X86::ASAN_CHECK_MEMACCESS:
2519 return LowerASAN_CHECK_MEMACCESS(*
MI);
2521 case X86::MORESTACK_RET_RESTORE_R10:
2524 EmitAndCountInstruction(
2525 MCInstBuilder(X86::MOV64rr).addReg(X86::R10).addReg(X86::RAX));
2528 case X86::SEH_PushReg:
2529 case X86::SEH_SaveReg:
2530 case X86::SEH_SaveXMM:
2531 case X86::SEH_StackAlloc:
2532 case X86::SEH_StackAlign:
2533 case X86::SEH_SetFrame:
2534 case X86::SEH_PushFrame:
2535 case X86::SEH_EndPrologue:
2536 case X86::SEH_EndEpilogue:
2537 case X86::SEH_UnwindV2Start:
2538 case X86::SEH_UnwindVersion:
2539 EmitSEHInstruction(
MI);
2542 case X86::SEH_SplitChainedAtEndOfBlock:
2543 assert(!SplitChainedAtEndOfBlock &&
2544 "Duplicate SEH_SplitChainedAtEndOfBlock in a current block");
2545 SplitChainedAtEndOfBlock =
true;
2548 case X86::SEH_BeginEpilogue: {
2549 assert(
MF->hasWinCFI() &&
"SEH_ instruction in function without WinCFI?");
2550 EmitSEHInstruction(
MI);
2553 case X86::UBSAN_UD1:
2558 .addReg(X86::NoRegister)
2559 .addImm(
MI->getOperand(0).getImm())
2560 .
addReg(X86::NoRegister));
2562 case X86::CALL64pcrel32:
2563 if (IndCSPrefix &&
MI->hasRegisterImplicitUseOperand(X86::R11))
2567 emitLabelAndRecordForImportCallOptimization(
2568 IMAGE_RETPOLINE_AMD64_IMPORT_CALL);
2571 MCInstLowering.Lower(
MI, TmpInst);
2576 emitCallInstruction(TmpInst);
2578 maybeEmitNopAfterCallForWindowsEH(
MI);
2585 if (EnableImportCallOptimization) {
2586 assert(
MI->getOperand(0).getReg() == X86::RAX &&
2587 "Indirect calls with impcall enabled must go through RAX (as "
2588 "enforced by CALL64r_ImpCall)");
2590 emitLabelAndRecordForImportCallOptimization(
2591 IMAGE_RETPOLINE_AMD64_INDIR_CALL);
2593 MCInstLowering.Lower(
MI, TmpInst);
2594 emitCallInstruction(TmpInst);
2599 maybeEmitNopAfterCallForWindowsEH(
MI);
2606 emitLabelAndRecordForImportCallOptimization(
2607 IMAGE_RETPOLINE_AMD64_CFG_CALL);
2622 if (EdgeProb > Threshold)
2630 EmitAndCountInstruction(
2633 .addImm(
MI->getOperand(0).getImm()));
2638 MCInstLowering.Lower(
MI, TmpInst);
2641 emitCallInstruction(TmpInst);
2645 maybeEmitNopAfterCallForWindowsEH(
MI);
2649 EmitAndCountInstruction(TmpInst);
2660 maybeEmitNopAfterCallForWindowsEH(
MI);
2664void X86AsmPrinter::emitCallInstruction(
const llvm::MCInst &MCI) {
2671 SMShadowTracker.count(MCI, getSubtargetInfo(), CodeEmitter.get());
2674 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
2738void X86AsmPrinter::maybeEmitNopAfterCallForWindowsEH(
const MachineInstr *
MI) {
2763 const MachineInstr &NextMI = *
MBBI;
2769 if (HasEHPersonality) {
2770 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2789 if (NextMI.
getOpcode() == X86::SEH_BeginEpilogue) {
2790 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2816 if (HasEHPersonality) {
2822 if (
MI->getParent()->succ_empty())
2823 EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2825 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2831 const MachineBasicBlock *NextMBB = &*MFI;
2837void X86AsmPrinter::emitLabelAndRecordForImportCallOptimization(
2838 ImportCallKind Kind) {
2839 assert(EnableImportCallOptimization);
2841 MCSymbol *CallSiteSymbol = MMI->getContext().createNamedTempSymbol(
"impcall");
2845 .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< 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
static constexpr unsigned SM(unsigned Version)
uint64_t IntrinsicInst * II
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
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 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 cl::opt< bool > EnableBranchHint("enable-branch-hint", cl::desc("Enable branch hint."), cl::init(false), cl::Hidden)
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()
static cl::opt< unsigned > BranchHintProbabilityThreshold("branch-hint-probability-threshold", cl::desc("The probability threshold of enabling branch hint."), cl::init(50), cl::Hidden)
#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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is intended to be used as a driving class for all asm writers.
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.
const MCAsmInfo * MAI
Target Asm Printer information.
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.
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.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
This is an important base class in LLVM.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasInternalLinkage() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
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)
Context object for machine code objects.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
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
Instances of this class represent operands of the MCInst class.
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 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
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())
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())
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
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()
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.
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
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.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr bool empty() const
empty - 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.
Primary interface to the complete machine description for the target machine.
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.
@ C
The default llvm calling convention, compatible with C.
@ 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.
initializer< Ty > init(const Ty &Val)
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)
@ WinEH
Windows Exception Handling.
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.
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
void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
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