LLVM 23.0.0git
X86MCInstLower.cpp
Go to the documentation of this file.
1//===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains code to lower X86 MachineInstrs to their corresponding
10// MCInst records.
11//
12//===----------------------------------------------------------------------===//
13
21#include "X86AsmPrinter.h"
23#include "X86RegisterInfo.h"
25#include "X86Subtarget.h"
26#include "llvm/ADT/STLExtras.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/GlobalValue.h"
38#include "llvm/IR/Mangler.h"
39#include "llvm/MC/MCAsmInfo.h"
41#include "llvm/MC/MCContext.h"
42#include "llvm/MC/MCExpr.h"
43#include "llvm/MC/MCFixup.h"
44#include "llvm/MC/MCInst.h"
46#include "llvm/MC/MCSection.h"
47#include "llvm/MC/MCStreamer.h"
48#include "llvm/MC/MCSymbol.h"
55#include <string>
56
57using namespace llvm;
58
59static cl::opt<bool> EnableBranchHint("enable-branch-hint",
60 cl::desc("Enable branch hint."),
61 cl::init(false), cl::Hidden);
63 "branch-hint-probability-threshold",
64 cl::desc("The probability threshold of enabling branch hint."),
65 cl::init(50), cl::Hidden);
66
67namespace {
68
69/// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
70class X86MCInstLower {
71 MCContext &Ctx;
72 const MachineFunction &MF;
73 const TargetMachine &TM;
74 const MCAsmInfo &MAI;
76
77public:
78 X86MCInstLower(const MachineFunction &MF, X86AsmPrinter &asmprinter);
79
80 MCOperand LowerMachineOperand(const MachineInstr *MI,
81 const MachineOperand &MO) const;
82 void Lower(const MachineInstr *MI, MCInst &OutMI) const;
83
86
87private:
88 MachineModuleInfoMachO &getMachOMMI() const;
89};
90
91} // end anonymous namespace
92
93/// A RAII helper which defines a region of instructions which can't have
94/// padding added between them for correctness.
99 : OS(OS), OldAllowAutoPadding(OS.getAllowAutoPadding()) {
100 changeAndComment(false);
101 }
103 void changeAndComment(bool b) {
104 if (b == OS.getAllowAutoPadding())
105 return;
106 OS.setAllowAutoPadding(b);
107 if (b)
108 OS.emitRawComment("autopadding");
109 else
110 OS.emitRawComment("noautopadding");
111 }
112};
113
114// Emit a minimal sequence of nops spanning NumBytes bytes.
115static void emitX86Nops(MCStreamer &OS, unsigned NumBytes,
116 const X86Subtarget *Subtarget);
117
118void X86AsmPrinter::StackMapShadowTracker::count(const MCInst &Inst,
119 const MCSubtargetInfo &STI,
120 MCCodeEmitter *CodeEmitter) {
121 if (InShadow) {
122 SmallString<256> Code;
124 CodeEmitter->encodeInstruction(Inst, Code, Fixups, STI);
125 CurrentShadowSize += Code.size();
126 if (CurrentShadowSize >= RequiredShadowSize)
127 InShadow = false; // The shadow is big enough. Stop counting.
128 }
129}
130
131void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
132 MCStreamer &OutStreamer, const MCSubtargetInfo &STI) {
133 if (InShadow && CurrentShadowSize < RequiredShadowSize) {
134 InShadow = false;
135 emitX86Nops(OutStreamer, RequiredShadowSize - CurrentShadowSize,
136 &MF->getSubtarget<X86Subtarget>());
137 }
138}
139
140void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
141 OutStreamer->emitInstruction(Inst, getSubtargetInfo());
142 SMShadowTracker.count(Inst, getSubtargetInfo(), CodeEmitter.get());
143}
144
145X86MCInstLower::X86MCInstLower(const MachineFunction &mf,
146 X86AsmPrinter &asmprinter)
147 : Ctx(asmprinter.OutContext), MF(mf), TM(mf.getTarget()),
148 MAI(*TM.getMCAsmInfo()), AsmPrinter(asmprinter) {}
149
150MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
151 return AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoMachO>();
152}
153
154/// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
155/// operand to an MCSymbol.
156MCSymbol *X86MCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
157 const Triple &TT = TM.getTargetTriple();
158 if (MO.isGlobal() && TT.isOSBinFormatELF())
159 return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());
160
161 const DataLayout &DL = MF.getDataLayout();
162 assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
163 "Isn't a symbol reference");
164
165 MCSymbol *Sym = nullptr;
166 SmallString<128> Name;
167 StringRef Suffix;
168
169 switch (MO.getTargetFlags()) {
171 // Handle dllimport linkage.
172 Name += "__imp_";
173 break;
175 Name += ".refptr.";
176 break;
179 Suffix = "$non_lazy_ptr";
180 break;
181 }
182
183 if (!Suffix.empty())
184 Name += DL.getInternalSymbolPrefix();
185
186 if (MO.isGlobal()) {
187 const GlobalValue *GV = MO.getGlobal();
188 AsmPrinter.getNameWithPrefix(Name, GV);
189 } else if (MO.isSymbol()) {
191 } else if (MO.isMBB()) {
192 assert(Suffix.empty());
193 Sym = MO.getMBB()->getSymbol();
194 }
195
196 Name += Suffix;
197 if (!Sym)
198 Sym = Ctx.getOrCreateSymbol(Name);
199
200 // If the target flags on the operand changes the name of the symbol, do that
201 // before we return the symbol.
202 switch (MO.getTargetFlags()) {
203 default:
204 break;
205 case X86II::MO_COFFSTUB: {
206 MachineModuleInfoCOFF &MMICOFF =
207 AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoCOFF>();
209 if (!StubSym.getPointer()) {
210 assert(MO.isGlobal() && "Extern symbol not handled yet");
212 AsmPrinter.getSymbol(MO.getGlobal()), true);
213 }
214 break;
215 }
219 getMachOMMI().getGVStubEntry(Sym);
220 if (!StubSym.getPointer()) {
221 assert(MO.isGlobal() && "Extern symbol not handled yet");
223 AsmPrinter.getSymbol(MO.getGlobal()),
225 }
226 break;
227 }
228 }
229
230 return Sym;
231}
232
233MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
234 MCSymbol *Sym) const {
235 // FIXME: We would like an efficient form for this, so we don't have to do a
236 // lot of extra uniquing.
237 const MCExpr *Expr = nullptr;
238 uint16_t Specifier = X86::S_None;
239
240 switch (MO.getTargetFlags()) {
241 default:
242 llvm_unreachable("Unknown target flag on GV operand");
243 case X86II::MO_NO_FLAG: // No flag.
244 // These affect the name of the symbol, not any suffix.
248 break;
249
250 case X86II::MO_TLVP:
252 break;
254 Expr = MCSymbolRefExpr::create(Sym, X86::S_TLVP, Ctx);
255 // Subtract the pic base.
257 Expr, MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx), Ctx);
258 break;
259 case X86II::MO_SECREL:
260 Specifier = uint16_t(X86::S_COFF_SECREL);
261 break;
262 case X86II::MO_TLSGD:
264 break;
265 case X86II::MO_TLSLD:
267 break;
268 case X86II::MO_TLSLDM:
270 break;
273 break;
276 break;
277 case X86II::MO_TPOFF:
279 break;
280 case X86II::MO_DTPOFF:
282 break;
283 case X86II::MO_NTPOFF:
285 break;
288 break;
291 break;
294 break;
295 case X86II::MO_GOT:
297 break;
298 case X86II::MO_GOTOFF:
300 break;
301 case X86II::MO_PLT:
303 break;
304 case X86II::MO_ABS8:
306 break;
309 Expr = MCSymbolRefExpr::create(Sym, Ctx);
310 // Subtract the pic base.
312 Expr, MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx), Ctx);
313 if (MO.isJTI()) {
315 // If .set directive is supported, use it to reduce the number of
316 // relocations the assembler will generate for differences between
317 // local labels. This is only safe when the symbols are in the same
318 // section so we are restricting it to jumptable references.
320 AsmPrinter.OutStreamer->emitAssignment(Label, Expr);
321 Expr = MCSymbolRefExpr::create(Label, Ctx);
322 }
323 break;
324 }
325
326 if (!Expr)
327 Expr = MCSymbolRefExpr::create(Sym, Specifier, Ctx);
328
329 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
331 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
332 return MCOperand::createExpr(Expr);
333}
334
335static unsigned getRetOpcode(const X86Subtarget &Subtarget) {
336 return Subtarget.is64Bit() ? X86::RET64 : X86::RET32;
337}
338
339MCOperand X86MCInstLower::LowerMachineOperand(const MachineInstr *MI,
340 const MachineOperand &MO) const {
341 switch (MO.getType()) {
342 default:
343 MI->print(errs());
344 llvm_unreachable("unknown operand type");
346 // Ignore all implicit register operands.
347 if (MO.isImplicit())
348 return MCOperand();
349 return MCOperand::createReg(MO.getReg());
351 return MCOperand::createImm(MO.getImm());
357 return LowerSymbolOperand(MO, MO.getMCSymbol());
359 return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
361 return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
363 return LowerSymbolOperand(
364 MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
366 // Ignore call clobbers.
367 return MCOperand();
368 }
369}
370
371// Replace TAILJMP opcodes with their equivalent opcodes that have encoding
372// information.
373static unsigned convertTailJumpOpcode(unsigned Opcode, bool IsLarge = false) {
374 switch (Opcode) {
375 case X86::TAILJMPr:
376 Opcode = X86::JMP32r;
377 break;
378 case X86::TAILJMPm:
379 Opcode = X86::JMP32m;
380 break;
381 case X86::TAILJMPr64:
382 Opcode = X86::JMP64r;
383 break;
384 case X86::TAILJMPm64:
385 Opcode = X86::JMP64m;
386 break;
387 case X86::TAILJMPr64_REX:
388 Opcode = X86::JMP64r_REX;
389 break;
390 case X86::TAILJMPm64_REX:
391 Opcode = X86::JMP64m_REX;
392 break;
393 case X86::TAILJMPd:
394 case X86::TAILJMPd64:
395 Opcode = IsLarge ? X86::JMPABS64i : X86::JMP_1;
396 break;
397 case X86::TAILJMPd_CC:
398 case X86::TAILJMPd64_CC:
399 Opcode = X86::JCC_1;
400 break;
401 }
402
403 return Opcode;
404}
405
406void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
407 OutMI.setOpcode(MI->getOpcode());
408
409 for (const MachineOperand &MO : MI->operands())
410 if (auto Op = LowerMachineOperand(MI, MO); Op.isValid())
411 OutMI.addOperand(Op);
412
413 bool In64BitMode = AsmPrinter.getSubtarget().is64Bit();
414 if (X86::optimizeInstFromVEX3ToVEX2(OutMI, MI->getDesc()) ||
417 X86::optimizeMOVSX(OutMI) || X86::optimizeINCDEC(OutMI, In64BitMode) ||
418 X86::optimizeMOV(OutMI, In64BitMode) ||
420 return;
421
422 // Handle a few special cases to eliminate operand modifiers.
423 switch (OutMI.getOpcode()) {
424 case X86::LEA64_32r:
425 case X86::LEA64r:
426 case X86::LEA16r:
427 case X86::LEA32r:
428 // LEA should have a segment register, but it must be empty.
430 "Unexpected # of LEA operands");
431 assert(OutMI.getOperand(1 + X86::AddrSegmentReg).getReg() == 0 &&
432 "LEA has segment specified!");
433 break;
434 case X86::MULX32Hrr:
435 case X86::MULX32Hrm:
436 case X86::MULX64Hrr:
437 case X86::MULX64Hrm: {
438 // Turn into regular MULX by duplicating the destination.
439 unsigned NewOpc;
440 switch (OutMI.getOpcode()) {
441 default: llvm_unreachable("Invalid opcode");
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;
446 }
447 OutMI.setOpcode(NewOpc);
448 // Duplicate the destination.
449 MCRegister DestReg = OutMI.getOperand(0).getReg();
450 OutMI.insert(OutMI.begin(), MCOperand::createReg(DestReg));
451 break;
452 }
453 // CALL64r, CALL64pcrel32 - These instructions used to have
454 // register inputs modeled as normal uses instead of implicit uses. As such,
455 // they we used to truncate off all but the first operand (the callee). This
456 // issue seems to have been fixed at some point. This assert verifies that.
457 case X86::CALL64r:
458 case X86::CALL64pcrel32:
459 assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
460 break;
461 case X86::EH_RETURN:
462 case X86::EH_RETURN64: {
463 OutMI = MCInst();
464 OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
465 break;
466 }
467 case X86::CLEANUPRET: {
468 // Replace CLEANUPRET with the appropriate RET.
469 OutMI = MCInst();
470 OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
471 break;
472 }
473 case X86::CATCHRET: {
474 // Replace CATCHRET with the appropriate RET.
475 const X86Subtarget &Subtarget = AsmPrinter.getSubtarget();
476 unsigned ReturnReg = In64BitMode ? X86::RAX : X86::EAX;
477 OutMI = MCInst();
478 OutMI.setOpcode(getRetOpcode(Subtarget));
479 OutMI.addOperand(MCOperand::createReg(ReturnReg));
480 break;
481 }
482 // TAILJMPd, TAILJMPd64, TailJMPd_cc - Lower to the correct jump
483 // instruction.
484 case X86::TAILJMPr:
485 case X86::TAILJMPr64:
486 case X86::TAILJMPr64_REX:
487 case X86::TAILJMPd:
488 assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
490 break;
491 case X86::TAILJMPd64: {
492 assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
493 bool IsLarge = TM.getCodeModel() == CodeModel::Large;
494 assert((!IsLarge || AsmPrinter.getSubtarget().hasJMPABS()) &&
495 "Unexpected TAILJMPd64 in large code model without JMPABS");
496 OutMI.setOpcode(convertTailJumpOpcode(OutMI.getOpcode(), IsLarge));
497 break;
498 }
499 case X86::TAILJMPd_CC:
500 case X86::TAILJMPd64_CC:
501 assert(OutMI.getNumOperands() == 2 && "Unexpected number of operands!");
503 break;
504 case X86::TAILJMPm:
505 case X86::TAILJMPm64:
506 case X86::TAILJMPm64_REX:
508 "Unexpected number of operands!");
510 break;
511 case X86::MASKMOVDQU:
512 case X86::VMASKMOVDQU:
513 if (In64BitMode)
515 break;
516 case X86::BSF16rm:
517 case X86::BSF16rr:
518 case X86::BSF32rm:
519 case X86::BSF32rr:
520 case X86::BSF64rm:
521 case X86::BSF64rr: {
522 // Add an REP prefix to BSF instructions so that new processors can
523 // recognize as TZCNT, which has better performance than BSF.
524 // BSF and TZCNT have different interpretations on ZF bit. So make sure
525 // it won't be used later.
526 const MachineOperand *FlagDef =
527 MI->findRegisterDefOperand(X86::EFLAGS, /*TRI=*/nullptr);
528 if (!MF.getFunction().hasOptSize() && FlagDef && FlagDef->isDead())
530 break;
531 }
532 default:
533 break;
534 }
535}
536
537void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
538 const MachineInstr &MI) {
539 NoAutoPaddingScope NoPadScope(*OutStreamer);
540 bool Is64Bits = getSubtarget().is64Bit();
541 bool Is64BitsLP64 = getSubtarget().isTarget64BitLP64();
542 MCContext &Ctx = OutStreamer->getContext();
543
545 switch (MI.getOpcode()) {
546 case X86::TLS_addr32:
547 case X86::TLS_addr64:
548 case X86::TLS_addrX32:
550 break;
551 case X86::TLS_base_addr32:
553 break;
554 case X86::TLS_base_addr64:
555 case X86::TLS_base_addrX32:
557 break;
558 case X86::TLS_desc32:
559 case X86::TLS_desc64:
561 break;
562 default:
563 llvm_unreachable("unexpected opcode");
564 }
565
566 const MCSymbolRefExpr *Sym = MCSymbolRefExpr::create(
567 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), Specifier, Ctx);
568
569 // Before binutils 2.41, ld has a bogus TLS relaxation error when the GD/LD
570 // code sequence using R_X86_64_GOTPCREL (instead of R_X86_64_GOTPCRELX) is
571 // attempted to be relaxed to IE/LE (binutils PR24784). Work around the bug by
572 // only using GOT when GOTPCRELX is enabled.
573 // TODO Delete the workaround when rustc no longer relies on the hack
574 bool UseGot = MMI->getModule()->getRtLibUseGOT() &&
576
577 if (Specifier == X86::S_TLSDESC) {
578 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(
579 MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), X86::S_TLSCALL,
580 Ctx);
581 EmitAndCountInstruction(
582 MCInstBuilder(Is64BitsLP64 ? X86::LEA64r : X86::LEA32r)
583 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
584 .addReg(Is64Bits ? X86::RIP : X86::EBX)
585 .addImm(1)
586 .addReg(0)
587 .addExpr(Sym)
588 .addReg(0));
589 EmitAndCountInstruction(
590 MCInstBuilder(Is64Bits ? X86::CALL64m : X86::CALL32m)
591 .addReg(Is64BitsLP64 ? X86::RAX : X86::EAX)
592 .addImm(1)
593 .addReg(0)
594 .addExpr(Expr)
595 .addReg(0));
596 } else if (Is64Bits) {
597 bool NeedsPadding = Specifier == X86::S_TLSGD;
598 if (NeedsPadding && Is64BitsLP64)
599 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
600 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
601 .addReg(X86::RDI)
602 .addReg(X86::RIP)
603 .addImm(1)
604 .addReg(0)
605 .addExpr(Sym)
606 .addReg(0));
607 const MCSymbol *TlsGetAddr = Ctx.getOrCreateSymbol("__tls_get_addr");
608 if (NeedsPadding) {
609 if (!UseGot)
610 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
611 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
612 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
613 }
614 if (UseGot) {
615 const MCExpr *Expr =
617 EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)
618 .addReg(X86::RIP)
619 .addImm(1)
620 .addReg(0)
621 .addExpr(Expr)
622 .addReg(0));
623 } else {
624 EmitAndCountInstruction(
625 MCInstBuilder(X86::CALL64pcrel32)
626 .addExpr(MCSymbolRefExpr::create(TlsGetAddr, X86::S_PLT, Ctx)));
627 }
628 } else {
629 if (Specifier == X86::S_TLSGD && !UseGot) {
630 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
631 .addReg(X86::EAX)
632 .addReg(0)
633 .addImm(1)
634 .addReg(X86::EBX)
635 .addExpr(Sym)
636 .addReg(0));
637 } else {
638 EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
639 .addReg(X86::EAX)
640 .addReg(X86::EBX)
641 .addImm(1)
642 .addReg(0)
643 .addExpr(Sym)
644 .addReg(0));
645 }
646
647 const MCSymbol *TlsGetAddr = Ctx.getOrCreateSymbol("___tls_get_addr");
648 if (UseGot) {
649 const MCExpr *Expr = MCSymbolRefExpr::create(TlsGetAddr, X86::S_GOT, Ctx);
650 EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)
651 .addReg(X86::EBX)
652 .addImm(1)
653 .addReg(0)
654 .addExpr(Expr)
655 .addReg(0));
656 } else {
657 EmitAndCountInstruction(
658 MCInstBuilder(X86::CALLpcrel32)
659 .addExpr(MCSymbolRefExpr::create(TlsGetAddr, X86::S_PLT, Ctx)));
660 }
661 }
662}
663
664/// Emit the largest nop instruction smaller than or equal to \p NumBytes
665/// bytes. Return the size of nop emitted.
666static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
667 const X86Subtarget *Subtarget) {
668 // Determine the longest nop which can be efficiently decoded for the given
669 // target cpu. 15-bytes is the longest single NOP instruction, but some
670 // platforms can't decode the longest forms efficiently.
671 unsigned MaxNopLength = 1;
672 if (Subtarget->is64Bit()) {
673 // FIXME: We can use NOOPL on 32-bit targets with FeatureNOPL, but the
674 // IndexReg/BaseReg below need to be updated.
675 if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))
676 MaxNopLength = 7;
677 else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))
678 MaxNopLength = 15;
679 else if (Subtarget->hasFeature(X86::TuningFast11ByteNOP))
680 MaxNopLength = 11;
681 else
682 MaxNopLength = 10;
683 } if (Subtarget->is32Bit())
684 MaxNopLength = 2;
685
686 // Cap a single nop emission at the profitable value for the target
687 NumBytes = std::min(NumBytes, MaxNopLength);
688
689 unsigned NopSize;
690 unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
691 IndexReg = Displacement = SegmentReg = 0;
692 BaseReg = X86::RAX;
693 ScaleVal = 1;
694 switch (NumBytes) {
695 case 0:
696 llvm_unreachable("Zero nops?");
697 break;
698 case 1:
699 NopSize = 1;
700 Opc = X86::NOOP;
701 break;
702 case 2:
703 NopSize = 2;
704 Opc = X86::XCHG16ar;
705 break;
706 case 3:
707 NopSize = 3;
708 Opc = X86::NOOPL;
709 break;
710 case 4:
711 NopSize = 4;
712 Opc = X86::NOOPL;
713 Displacement = 8;
714 break;
715 case 5:
716 NopSize = 5;
717 Opc = X86::NOOPL;
718 Displacement = 8;
719 IndexReg = X86::RAX;
720 break;
721 case 6:
722 NopSize = 6;
723 Opc = X86::NOOPW;
724 Displacement = 8;
725 IndexReg = X86::RAX;
726 break;
727 case 7:
728 NopSize = 7;
729 Opc = X86::NOOPL;
730 Displacement = 512;
731 break;
732 case 8:
733 NopSize = 8;
734 Opc = X86::NOOPL;
735 Displacement = 512;
736 IndexReg = X86::RAX;
737 break;
738 case 9:
739 NopSize = 9;
740 Opc = X86::NOOPW;
741 Displacement = 512;
742 IndexReg = X86::RAX;
743 break;
744 default:
745 NopSize = 10;
746 Opc = X86::NOOPW;
747 Displacement = 512;
748 IndexReg = X86::RAX;
749 SegmentReg = X86::CS;
750 break;
751 }
752
753 unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);
754 NopSize += NumPrefixes;
755 for (unsigned i = 0; i != NumPrefixes; ++i)
756 OS.emitBytes("\x66");
757
758 switch (Opc) {
759 default: llvm_unreachable("Unexpected opcode");
760 case X86::NOOP:
761 OS.emitInstruction(MCInstBuilder(Opc), *Subtarget);
762 break;
763 case X86::XCHG16ar:
764 OS.emitInstruction(MCInstBuilder(Opc).addReg(X86::AX).addReg(X86::AX),
765 *Subtarget);
766 break;
767 case X86::NOOPL:
768 case X86::NOOPW:
770 .addReg(BaseReg)
771 .addImm(ScaleVal)
772 .addReg(IndexReg)
773 .addImm(Displacement)
774 .addReg(SegmentReg),
775 *Subtarget);
776 break;
777 }
778 assert(NopSize <= NumBytes && "We overemitted?");
779 return NopSize;
780}
781
782/// Emit the optimal amount of multi-byte nops on X86.
783static void emitX86Nops(MCStreamer &OS, unsigned NumBytes,
784 const X86Subtarget *Subtarget) {
785 unsigned NopsToEmit = NumBytes;
786 (void)NopsToEmit;
787 while (NumBytes) {
788 NumBytes -= emitNop(OS, NumBytes, Subtarget);
789 assert(NopsToEmit >= NumBytes && "Emitted more than I asked for!");
790 }
791}
792
793void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
794 X86MCInstLower &MCIL) {
795 assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
796
797 NoAutoPaddingScope NoPadScope(*OutStreamer);
798
799 StatepointOpers SOpers(&MI);
800 if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
801 emitX86Nops(*OutStreamer, PatchBytes, Subtarget);
802 } else {
803 // Lower call target and choose correct opcode
804 const MachineOperand &CallTarget = SOpers.getCallTarget();
805 MCOperand CallTargetMCOp;
806 unsigned CallOpcode;
807 switch (CallTarget.getType()) {
810 CallTargetMCOp = MCIL.LowerSymbolOperand(
811 CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
812 CallOpcode = X86::CALL64pcrel32;
813 // Currently, we only support relative addressing with statepoints.
814 // Otherwise, we'll need a scratch register to hold the target
815 // address. You'll fail asserts during load & relocation if this
816 // symbol is to far away. (TODO: support non-relative addressing)
817 break;
819 CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
820 CallOpcode = X86::CALL64pcrel32;
821 // Currently, we only support relative addressing with statepoints.
822 // Otherwise, we'll need a scratch register to hold the target
823 // immediate. You'll fail asserts during load & relocation if this
824 // address is to far away. (TODO: support non-relative addressing)
825 break;
827 // FIXME: Add retpoline support and remove this.
828 if (Subtarget->useIndirectThunkCalls())
829 report_fatal_error("Lowering register statepoints with thunks not "
830 "yet implemented.");
831 CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
832 CallOpcode = X86::CALL64r;
833 break;
834 default:
835 llvm_unreachable("Unsupported operand type in statepoint call target");
836 break;
837 }
838
839 // Emit call
840 MCInst CallInst;
841 CallInst.setOpcode(CallOpcode);
842 CallInst.addOperand(CallTargetMCOp);
843 OutStreamer->emitInstruction(CallInst, getSubtargetInfo());
844 maybeEmitNopAfterCallForWindowsEH(&MI);
845 }
846
847 // Record our statepoint node in the same section used by STACKMAP
848 // and PATCHPOINT
849 auto &Ctx = OutStreamer->getContext();
850 MCSymbol *MILabel = Ctx.createTempSymbol();
851 OutStreamer->emitLabel(MILabel);
852 SM.recordStatepoint(*MILabel, MI);
853}
854
855void X86AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI,
856 X86MCInstLower &MCIL) {
857 // FAULTING_LOAD_OP <def>, <faltinf type>, <MBB handler>,
858 // <opcode>, <operands>
859
860 NoAutoPaddingScope NoPadScope(*OutStreamer);
861
862 Register DefRegister = FaultingMI.getOperand(0).getReg();
864 static_cast<FaultMaps::FaultKind>(FaultingMI.getOperand(1).getImm());
865 MCSymbol *HandlerLabel = FaultingMI.getOperand(2).getMBB()->getSymbol();
866 unsigned Opcode = FaultingMI.getOperand(3).getImm();
867 unsigned OperandsBeginIdx = 4;
868
869 auto &Ctx = OutStreamer->getContext();
870 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
871 OutStreamer->emitLabel(FaultingLabel);
872
873 assert(FK < FaultMaps::FaultKindMax && "Invalid Faulting Kind!");
874 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
875
876 MCInst MI;
877 MI.setOpcode(Opcode);
878
879 if (DefRegister != X86::NoRegister)
880 MI.addOperand(MCOperand::createReg(DefRegister));
881
882 for (const MachineOperand &MO :
883 llvm::drop_begin(FaultingMI.operands(), OperandsBeginIdx))
884 if (auto Op = MCIL.LowerMachineOperand(&FaultingMI, MO); Op.isValid())
885 MI.addOperand(Op);
886
887 OutStreamer->AddComment("on-fault: " + HandlerLabel->getName());
888 OutStreamer->emitInstruction(MI, getSubtargetInfo());
889}
890
891void X86AsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
892 X86MCInstLower &MCIL) {
893 bool Is64Bits = Subtarget->is64Bit();
894 MCContext &Ctx = OutStreamer->getContext();
895 MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
896 const MCSymbolRefExpr *Op = MCSymbolRefExpr::create(fentry, Ctx);
897
898 EmitAndCountInstruction(
899 MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
900 .addExpr(Op));
901}
902
903void X86AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
904 assert(std::next(MI.getIterator())->isCall() &&
905 "KCFI_CHECK not followed by a call instruction");
906
907 // Adjust the offset for patchable-function-prefix. X86InstrInfo::getNop()
908 // returns a 1-byte X86::NOOP, which means the offset is the same in
909 // bytes. This assumes that patchable-function-prefix is the same for all
910 // functions.
911 const MachineFunction &MF = *MI.getMF();
912 int64_t PrefixNops = 0;
913 (void)MF.getFunction()
914 .getFnAttribute("patchable-function-prefix")
916 .getAsInteger(10, PrefixNops);
917
918 // KCFI allows indirect calls to any location that's preceded by a valid
919 // type identifier. To avoid encoding the full constant into an instruction,
920 // and thus emitting potential call target gadgets at each indirect call
921 // site, load a negated constant to a register and compare that to the
922 // expected value at the call target.
923 const Register AddrReg = MI.getOperand(0).getReg();
924 const uint32_t Type = MI.getOperand(1).getImm();
925 // The check is immediately before the call. If the call target is in R10,
926 // we can clobber R11 for the check instead.
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)
932 .addReg(TempReg)
933 .addReg(AddrReg)
934 .addImm(1)
935 .addReg(X86::NoRegister)
936 .addImm(-(PrefixNops + 4))
937 .addReg(X86::NoRegister));
938
939 MCSymbol *Pass = OutContext.createTempSymbol();
940 EmitAndCountInstruction(
941 MCInstBuilder(X86::JCC_1)
942 .addExpr(MCSymbolRefExpr::create(Pass, OutContext))
943 .addImm(X86::COND_E));
944
945 MCSymbol *Trap = OutContext.createTempSymbol();
946 OutStreamer->emitLabel(Trap);
947 EmitAndCountInstruction(MCInstBuilder(X86::TRAP));
948 emitKCFITrapEntry(MF, Trap);
949 OutStreamer->emitLabel(Pass);
950}
951
952void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
953 // FIXME: Make this work on non-ELF.
954 if (!TM.getTargetTriple().isOSBinFormatELF()) {
955 report_fatal_error("llvm.asan.check.memaccess only supported on ELF");
956 return;
957 }
958
959 const auto &Reg = MI.getOperand(0).getReg();
960 ASanAccessInfo AccessInfo(MI.getOperand(1).getImm());
961
962 uint64_t ShadowBase;
963 int MappingScale;
964 bool OrShadowOffset;
965 getAddressSanitizerParams(TM.getTargetTriple(), 64, AccessInfo.CompileKernel,
966 &ShadowBase, &MappingScale, &OrShadowOffset);
967
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()))
973 .str();
974 if (OrShadowOffset)
976 "OrShadowOffset is not supported with optimized callbacks");
977
978 EmitAndCountInstruction(
979 MCInstBuilder(X86::CALL64pcrel32)
981 OutContext.getOrCreateSymbol(SymName), OutContext)));
982}
983
984void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
985 X86MCInstLower &MCIL) {
986 // PATCHABLE_OP minsize
987
988 NoAutoPaddingScope NoPadScope(*OutStreamer);
989
990 auto NextMI = std::find_if(std::next(MI.getIterator()),
991 MI.getParent()->end().getInstrIterator(),
992 [](auto &II) { return !II.isMetaInstruction(); });
993
994 SmallString<256> Code;
995 unsigned MinSize = MI.getOperand(0).getImm();
996
997 if (NextMI != MI.getParent()->end() && !NextMI->isInlineAsm()) {
998 // Lower the next MachineInstr to find its byte size.
999 // If the next instruction is inline assembly, we skip lowering it for now,
1000 // and assume we should always generate NOPs.
1001 MCInst MCI;
1002 MCIL.Lower(&*NextMI, MCI);
1003
1005 CodeEmitter->encodeInstruction(MCI, Code, Fixups, getSubtargetInfo());
1006 }
1007
1008 if (Code.size() < MinSize) {
1009 if (MinSize == 2 && Subtarget->is32Bit() &&
1010 Subtarget->isTargetWindowsMSVC() &&
1011 (Subtarget->getCPU().empty() || Subtarget->getCPU() == "pentium3")) {
1012 // For compatibility reasons, when targetting MSVC, it is important to
1013 // generate a 'legacy' NOP in the form of a 8B FF MOV EDI, EDI. Some tools
1014 // rely specifically on this pattern to be able to patch a function.
1015 // This is only for 32-bit targets, when using /arch:IA32 or /arch:SSE.
1016 OutStreamer->emitInstruction(
1017 MCInstBuilder(X86::MOV32rr_REV).addReg(X86::EDI).addReg(X86::EDI),
1018 *Subtarget);
1019 } else {
1020 unsigned NopSize = emitNop(*OutStreamer, MinSize, Subtarget);
1021 assert(NopSize == MinSize && "Could not implement MinSize!");
1022 (void)NopSize;
1023 }
1024 }
1025}
1026
1027// Lower a stackmap of the form:
1028// <id>, <shadowBytes>, ...
1029void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
1030 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1031
1032 auto &Ctx = OutStreamer->getContext();
1033 MCSymbol *MILabel = Ctx.createTempSymbol();
1034 OutStreamer->emitLabel(MILabel);
1035
1036 SM.recordStackMap(*MILabel, MI);
1037 unsigned NumShadowBytes = MI.getOperand(1).getImm();
1038 SMShadowTracker.reset(NumShadowBytes);
1039}
1040
1041// Lower a patchpoint of the form:
1042// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
1043void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
1044 X86MCInstLower &MCIL) {
1045 assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");
1046
1047 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1048
1049 NoAutoPaddingScope NoPadScope(*OutStreamer);
1050
1051 auto &Ctx = OutStreamer->getContext();
1052 MCSymbol *MILabel = Ctx.createTempSymbol();
1053 OutStreamer->emitLabel(MILabel);
1054 SM.recordPatchPoint(*MILabel, MI);
1055
1056 PatchPointOpers opers(&MI);
1057 unsigned ScratchIdx = opers.getNextScratchIdx();
1058 unsigned EncodedBytes = 0;
1059 const MachineOperand &CalleeMO = opers.getCallTarget();
1060
1061 // Check for null target. If target is non-null (i.e. is non-zero or is
1062 // symbolic) then emit a call.
1063 if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {
1064 MCOperand CalleeMCOp;
1065 switch (CalleeMO.getType()) {
1066 default:
1067 /// FIXME: Add a verifier check for bad callee types.
1068 llvm_unreachable("Unrecognized callee operand type.");
1070 if (CalleeMO.getImm())
1071 CalleeMCOp = MCOperand::createImm(CalleeMO.getImm());
1072 break;
1075 CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,
1076 MCIL.GetSymbolFromOperand(CalleeMO));
1077 break;
1078 }
1079
1080 // Emit MOV to materialize the target address and the CALL to target.
1081 // This is encoded with 12-13 bytes, depending on which register is used.
1082 Register ScratchReg = MI.getOperand(ScratchIdx).getReg();
1083 if (X86II::isX86_64ExtendedReg(ScratchReg))
1084 EncodedBytes = 13;
1085 else
1086 EncodedBytes = 12;
1087
1088 EmitAndCountInstruction(
1089 MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));
1090 // FIXME: Add retpoline support and remove this.
1091 if (Subtarget->useIndirectThunkCalls())
1093 "Lowering patchpoint with thunks not yet implemented.");
1094 EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
1095 }
1096
1097 // Emit padding.
1098 unsigned NumBytes = opers.getNumPatchBytes();
1099 assert(NumBytes >= EncodedBytes &&
1100 "Patchpoint can't request size less than the length of a call.");
1101
1102 emitX86Nops(*OutStreamer, NumBytes - EncodedBytes, Subtarget);
1103}
1104
1105void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
1106 X86MCInstLower &MCIL) {
1107 assert(Subtarget->is64Bit() && "XRay custom events only supports X86-64");
1108
1109 NoAutoPaddingScope NoPadScope(*OutStreamer);
1110
1111 // We want to emit the following pattern, which follows the x86 calling
1112 // convention to prepare for the trampoline call to be patched in.
1113 //
1114 // .p2align 1, ...
1115 // .Lxray_event_sled_N:
1116 // jmp +N // jump across the instrumentation sled
1117 // ... // set up arguments in register
1118 // callq __xray_CustomEvent@plt // force dependency to symbol
1119 // ...
1120 // <jump here>
1121 //
1122 // After patching, it would look something like:
1123 //
1124 // nopw (2-byte nop)
1125 // ...
1126 // callq __xrayCustomEvent // already lowered
1127 // ...
1128 //
1129 // ---
1130 // First we emit the label and the jump.
1131 auto CurSled = OutContext.createTempSymbol("xray_event_sled_", true);
1132 OutStreamer->AddComment("# XRay Custom Event Log");
1133 OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1134 OutStreamer->emitLabel(CurSled);
1135
1136 // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
1137 // an operand (computed as an offset from the jmp instruction).
1138 // FIXME: Find another less hacky way do force the relative jump.
1139 OutStreamer->emitBinaryData("\xeb\x0f");
1140
1141 // The default C calling convention will place two arguments into %rcx and
1142 // %rdx -- so we only work with those.
1143 const Register DestRegs[] = {X86::RDI, X86::RSI};
1144 bool UsedMask[] = {false, false};
1145 // Filled out in loop.
1146 Register SrcRegs[] = {0, 0};
1147
1148 // Then we put the operands in the %rdi and %rsi registers. We spill the
1149 // values in the register before we clobber them, and mark them as used in
1150 // UsedMask. In case the arguments are already in the correct register, we use
1151 // emit nops appropriately sized to keep the sled the same size in every
1152 // situation.
1153 for (unsigned I = 0; I < MI.getNumOperands(); ++I)
1154 if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I));
1155 Op.isValid()) {
1156 assert(Op.isReg() && "Only support arguments in registers");
1157 SrcRegs[I] = getX86SubSuperRegister(Op.getReg(), 64);
1158 assert(SrcRegs[I].isValid() && "Invalid operand");
1159 if (SrcRegs[I] != DestRegs[I]) {
1160 UsedMask[I] = true;
1161 EmitAndCountInstruction(
1162 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));
1163 } else {
1164 emitX86Nops(*OutStreamer, 4, Subtarget);
1165 }
1166 }
1167
1168 // Now that the register values are stashed, mov arguments into place.
1169 // FIXME: This doesn't work if one of the later SrcRegs is equal to an
1170 // earlier DestReg. We will have already overwritten over the register before
1171 // we can copy from it.
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]));
1176
1177 // We emit a hard dependency on the __xray_CustomEvent symbol, which is the
1178 // name of the trampoline to be implemented by the XRay runtime.
1179 auto TSym = OutContext.getOrCreateSymbol("__xray_CustomEvent");
1180 MachineOperand TOp = MachineOperand::CreateMCSymbol(TSym);
1181 if (isPositionIndependent())
1183
1184 // Emit the call instruction.
1185 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1186 .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1187
1188 // Restore caller-saved and used registers.
1189 for (unsigned I = sizeof UsedMask; I-- > 0;)
1190 if (UsedMask[I])
1191 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));
1192 else
1193 emitX86Nops(*OutStreamer, 1, Subtarget);
1194
1195 OutStreamer->AddComment("xray custom event end.");
1196
1197 // Record the sled version. Version 0 of this sled was spelled differently, so
1198 // we let the runtime handle the different offsets we're using. Version 2
1199 // changed the absolute address to a PC-relative address.
1200 recordSled(CurSled, MI, SledKind::CUSTOM_EVENT, 2);
1201}
1202
1203void X86AsmPrinter::LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,
1204 X86MCInstLower &MCIL) {
1205 assert(Subtarget->is64Bit() && "XRay typed events only supports X86-64");
1206
1207 NoAutoPaddingScope NoPadScope(*OutStreamer);
1208
1209 // We want to emit the following pattern, which follows the x86 calling
1210 // convention to prepare for the trampoline call to be patched in.
1211 //
1212 // .p2align 1, ...
1213 // .Lxray_event_sled_N:
1214 // jmp +N // jump across the instrumentation sled
1215 // ... // set up arguments in register
1216 // callq __xray_TypedEvent@plt // force dependency to symbol
1217 // ...
1218 // <jump here>
1219 //
1220 // After patching, it would look something like:
1221 //
1222 // nopw (2-byte nop)
1223 // ...
1224 // callq __xrayTypedEvent // already lowered
1225 // ...
1226 //
1227 // ---
1228 // First we emit the label and the jump.
1229 auto CurSled = OutContext.createTempSymbol("xray_typed_event_sled_", true);
1230 OutStreamer->AddComment("# XRay Typed Event Log");
1231 OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1232 OutStreamer->emitLabel(CurSled);
1233
1234 // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
1235 // an operand (computed as an offset from the jmp instruction).
1236 // FIXME: Find another less hacky way do force the relative jump.
1237 OutStreamer->emitBinaryData("\xeb\x14");
1238
1239 // An x86-64 convention may place three arguments into %rcx, %rdx, and R8,
1240 // so we'll work with those. Or we may be called via SystemV, in which case
1241 // we don't have to do any translation.
1242 const Register DestRegs[] = {X86::RDI, X86::RSI, X86::RDX};
1243 bool UsedMask[] = {false, false, false};
1244
1245 // Will fill out src regs in the loop.
1246 Register SrcRegs[] = {0, 0, 0};
1247
1248 // Then we put the operands in the SystemV registers. We spill the values in
1249 // the registers before we clobber them, and mark them as used in UsedMask.
1250 // In case the arguments are already in the correct register, we emit nops
1251 // appropriately sized to keep the sled the same size in every situation.
1252 for (unsigned I = 0; I < MI.getNumOperands(); ++I)
1253 if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I));
1254 Op.isValid()) {
1255 // TODO: Is register only support adequate?
1256 assert(Op.isReg() && "Only supports arguments in registers");
1257 SrcRegs[I] = getX86SubSuperRegister(Op.getReg(), 64);
1258 assert(SrcRegs[I].isValid() && "Invalid operand");
1259 if (SrcRegs[I] != DestRegs[I]) {
1260 UsedMask[I] = true;
1261 EmitAndCountInstruction(
1262 MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));
1263 } else {
1264 emitX86Nops(*OutStreamer, 4, Subtarget);
1265 }
1266 }
1267
1268 // In the above loop we only stash all of the destination registers or emit
1269 // nops if the arguments are already in the right place. Doing the actually
1270 // moving is postponed until after all the registers are stashed so nothing
1271 // is clobbers. We've already added nops to account for the size of mov and
1272 // push if the register is in the right place, so we only have to worry about
1273 // emitting movs.
1274 // FIXME: This doesn't work if one of the later SrcRegs is equal to an
1275 // earlier DestReg. We will have already overwritten over the register before
1276 // we can copy from it.
1277 for (unsigned I = 0; I < MI.getNumOperands(); ++I)
1278 if (UsedMask[I])
1279 EmitAndCountInstruction(
1280 MCInstBuilder(X86::MOV64rr).addReg(DestRegs[I]).addReg(SrcRegs[I]));
1281
1282 // We emit a hard dependency on the __xray_TypedEvent symbol, which is the
1283 // name of the trampoline to be implemented by the XRay runtime.
1284 auto TSym = OutContext.getOrCreateSymbol("__xray_TypedEvent");
1285 MachineOperand TOp = MachineOperand::CreateMCSymbol(TSym);
1286 if (isPositionIndependent())
1288
1289 // Emit the call instruction.
1290 EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
1291 .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
1292
1293 // Restore caller-saved and used registers.
1294 for (unsigned I = sizeof UsedMask; I-- > 0;)
1295 if (UsedMask[I])
1296 EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));
1297 else
1298 emitX86Nops(*OutStreamer, 1, Subtarget);
1299
1300 OutStreamer->AddComment("xray typed event end.");
1301
1302 // Record the sled version.
1303 recordSled(CurSled, MI, SledKind::TYPED_EVENT, 2);
1304}
1305
1306void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
1307 X86MCInstLower &MCIL) {
1308
1309 NoAutoPaddingScope NoPadScope(*OutStreamer);
1310
1311 const Function &F = MF->getFunction();
1312 if (F.hasFnAttribute("patchable-function-entry")) {
1313 unsigned Num;
1314 if (F.getFnAttribute("patchable-function-entry")
1315 .getValueAsString()
1316 .getAsInteger(10, Num))
1317 return;
1318 emitX86Nops(*OutStreamer, Num, Subtarget);
1319 return;
1320 }
1321 // We want to emit the following pattern:
1322 //
1323 // .p2align 1, ...
1324 // .Lxray_sled_N:
1325 // jmp .tmpN
1326 // # 9 bytes worth of noops
1327 //
1328 // We need the 9 bytes because at runtime, we'd be patching over the full 11
1329 // bytes with the following pattern:
1330 //
1331 // mov %r10, <function id, 32-bit> // 6 bytes
1332 // call <relative offset, 32-bits> // 5 bytes
1333 //
1334 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1335 OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1336 OutStreamer->emitLabel(CurSled);
1337
1338 // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
1339 // an operand (computed as an offset from the jmp instruction).
1340 // FIXME: Find another less hacky way do force the relative jump.
1341 OutStreamer->emitBytes("\xeb\x09");
1342 emitX86Nops(*OutStreamer, 9, Subtarget);
1343 recordSled(CurSled, MI, SledKind::FUNCTION_ENTER, 2);
1344}
1345
1346void X86AsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI,
1347 X86MCInstLower &MCIL) {
1348 NoAutoPaddingScope NoPadScope(*OutStreamer);
1349
1350 // Since PATCHABLE_RET takes the opcode of the return statement as an
1351 // argument, we use that to emit the correct form of the RET that we want.
1352 // i.e. when we see this:
1353 //
1354 // PATCHABLE_RET X86::RET ...
1355 //
1356 // We should emit the RET followed by sleds.
1357 //
1358 // .p2align 1, ...
1359 // .Lxray_sled_N:
1360 // ret # or equivalent instruction
1361 // # 10 bytes worth of noops
1362 //
1363 // This just makes sure that the alignment for the next instruction is 2.
1364 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1365 OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1366 OutStreamer->emitLabel(CurSled);
1367 unsigned OpCode = MI.getOperand(0).getImm();
1368 MCInst Ret;
1369 Ret.setOpcode(OpCode);
1370 for (auto &MO : drop_begin(MI.operands()))
1371 if (auto Op = MCIL.LowerMachineOperand(&MI, MO); Op.isValid())
1372 Ret.addOperand(Op);
1373 OutStreamer->emitInstruction(Ret, getSubtargetInfo());
1374 emitX86Nops(*OutStreamer, 10, Subtarget);
1375 recordSled(CurSled, MI, SledKind::FUNCTION_EXIT, 2);
1376}
1377
1378void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI,
1379 X86MCInstLower &MCIL) {
1380 MCInst TC;
1381 TC.setOpcode(convertTailJumpOpcode(MI.getOperand(0).getImm()));
1382 // Drop the tail jump opcode.
1383 auto TCOperands = drop_begin(MI.operands());
1384 bool IsConditional = TC.getOpcode() == X86::JCC_1;
1385 MCSymbol *FallthroughLabel;
1386 if (IsConditional) {
1387 // Rewrite:
1388 // je target
1389 //
1390 // To:
1391 // jne .fallthrough
1392 // .p2align 1, ...
1393 // .Lxray_sled_N:
1394 // SLED_CODE
1395 // jmp target
1396 // .fallthrough:
1397 FallthroughLabel = OutContext.createTempSymbol();
1398 EmitToStreamer(
1399 *OutStreamer,
1400 MCInstBuilder(X86::JCC_1)
1401 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext))
1403 static_cast<X86::CondCode>(MI.getOperand(2).getImm()))));
1404 TC.setOpcode(X86::JMP_1);
1405 // Drop the condition code.
1406 TCOperands = drop_end(TCOperands);
1407 }
1408
1409 NoAutoPaddingScope NoPadScope(*OutStreamer);
1410
1411 // Like PATCHABLE_RET, we have the actual instruction in the operands to this
1412 // instruction so we lower that particular instruction and its operands.
1413 // Unlike PATCHABLE_RET though, we put the sled before the JMP, much like how
1414 // we do it for PATCHABLE_FUNCTION_ENTER. The sled should be very similar to
1415 // the PATCHABLE_FUNCTION_ENTER case, followed by the lowering of the actual
1416 // tail call much like how we have it in PATCHABLE_RET.
1417 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1418 OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1419 OutStreamer->emitLabel(CurSled);
1420 auto Target = OutContext.createTempSymbol();
1421
1422 // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
1423 // an operand (computed as an offset from the jmp instruction).
1424 // FIXME: Find another less hacky way do force the relative jump.
1425 OutStreamer->emitBytes("\xeb\x09");
1426 emitX86Nops(*OutStreamer, 9, Subtarget);
1427 OutStreamer->emitLabel(Target);
1428 recordSled(CurSled, MI, SledKind::TAIL_CALL, 2);
1429
1430 // Before emitting the instruction, add a comment to indicate that this is
1431 // indeed a tail call.
1432 OutStreamer->AddComment("TAILCALL");
1433 for (auto &MO : TCOperands)
1434 if (auto Op = MCIL.LowerMachineOperand(&MI, MO); Op.isValid())
1435 TC.addOperand(Op);
1436 OutStreamer->emitInstruction(TC, getSubtargetInfo());
1437
1438 if (IsConditional)
1439 OutStreamer->emitLabel(FallthroughLabel);
1440}
1441
1442static unsigned getSrcIdx(const MachineInstr* MI, unsigned SrcIdx) {
1443 if (X86II::isKMasked(MI->getDesc().TSFlags)) {
1444 // Skip mask operand.
1445 ++SrcIdx;
1446 if (X86II::isKMergeMasked(MI->getDesc().TSFlags)) {
1447 // Skip passthru operand.
1448 ++SrcIdx;
1449 }
1450 }
1451 return SrcIdx;
1452}
1453
1455 unsigned SrcOpIdx) {
1456 const MachineOperand &DstOp = MI->getOperand(0);
1458
1459 // Handle AVX512 MASK/MASXZ write mask comments.
1460 // MASK: zmmX {%kY}
1461 // MASKZ: zmmX {%kY} {z}
1462 if (X86II::isKMasked(MI->getDesc().TSFlags)) {
1463 const MachineOperand &WriteMaskOp = MI->getOperand(SrcOpIdx - 1);
1465 CS << " {%" << Mask << "}";
1466 if (!X86II::isKMergeMasked(MI->getDesc().TSFlags)) {
1467 CS << " {z}";
1468 }
1469 }
1470}
1471
1472static void printShuffleMask(raw_ostream &CS, StringRef Src1Name,
1473 StringRef Src2Name, ArrayRef<int> Mask) {
1474 // One source operand, fix the mask to print all elements in one span.
1475 SmallVector<int, 8> ShuffleMask(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;
1480
1481 for (int i = 0, e = ShuffleMask.size(); i != e; ++i) {
1482 if (i != 0)
1483 CS << ",";
1484 if (ShuffleMask[i] == SM_SentinelZero) {
1485 CS << "zero";
1486 continue;
1487 }
1488
1489 // Otherwise, it must come from src1 or src2. Print the span of elements
1490 // that comes from this src.
1491 bool isSrc1 = ShuffleMask[i] < (int)e;
1492 CS << (isSrc1 ? Src1Name : Src2Name) << '[';
1493
1494 bool IsFirst = true;
1495 while (i != e && ShuffleMask[i] != SM_SentinelZero &&
1496 (ShuffleMask[i] < (int)e) == isSrc1) {
1497 if (!IsFirst)
1498 CS << ',';
1499 else
1500 IsFirst = false;
1501 if (ShuffleMask[i] == SM_SentinelUndef)
1502 CS << "u";
1503 else
1504 CS << ShuffleMask[i] % (int)e;
1505 ++i;
1506 }
1507 CS << ']';
1508 --i; // For loop increments element #.
1509 }
1510}
1511
1512static std::string getShuffleComment(const MachineInstr *MI, unsigned SrcOp1Idx,
1513 unsigned SrcOp2Idx, ArrayRef<int> Mask) {
1514 std::string Comment;
1515
1516 const MachineOperand &SrcOp1 = MI->getOperand(SrcOp1Idx);
1517 const MachineOperand &SrcOp2 = MI->getOperand(SrcOp2Idx);
1518 StringRef Src1Name = SrcOp1.isReg()
1520 : "mem";
1521 StringRef Src2Name = SrcOp2.isReg()
1523 : "mem";
1524
1525 raw_string_ostream CS(Comment);
1526 printDstRegisterName(CS, MI, SrcOp1Idx);
1527 CS << " = ";
1528 printShuffleMask(CS, Src1Name, Src2Name, Mask);
1529
1530 return Comment;
1531}
1532
1533static void printConstant(const APInt &Val, raw_ostream &CS,
1534 bool PrintZero = false) {
1535 if (Val.getBitWidth() <= 64) {
1536 CS << (PrintZero ? 0ULL : Val.getZExtValue());
1537 } else {
1538 // print multi-word constant as (w0,w1)
1539 CS << "(";
1540 for (int i = 0, N = Val.getNumWords(); i < N; ++i) {
1541 if (i > 0)
1542 CS << ",";
1543 CS << (PrintZero ? 0ULL : Val.getRawData()[i]);
1544 }
1545 CS << ")";
1546 }
1547}
1548
1549static void printConstant(const APFloat &Flt, raw_ostream &CS,
1550 bool PrintZero = false) {
1551 SmallString<32> Str;
1552 // Force scientific notation to distinguish from integers.
1553 if (PrintZero)
1554 APFloat::getZero(Flt.getSemantics()).toString(Str, 0, 0);
1555 else
1556 Flt.toString(Str, 0, 0);
1557 CS << Str;
1558}
1559
1560static void printConstant(const Constant *COp, unsigned BitWidth,
1561 raw_ostream &CS, bool PrintZero = false) {
1562 if (isa<UndefValue>(COp)) {
1563 CS << "u";
1564 } else if (auto *CI = dyn_cast<ConstantInt>(COp)) {
1565 if (auto VTy = dyn_cast<FixedVectorType>(CI->getType())) {
1566 for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
1567 if (I != 0)
1568 CS << ',';
1569 printConstant(CI->getValue(), CS, PrintZero);
1570 }
1571 } else
1572 printConstant(CI->getValue(), CS, PrintZero);
1573 } else if (auto *CF = dyn_cast<ConstantFP>(COp)) {
1574 if (auto VTy = dyn_cast<FixedVectorType>(CF->getType())) {
1575 unsigned EltBits = VTy->getScalarSizeInBits();
1576 unsigned E = std::min(BitWidth / EltBits, VTy->getNumElements());
1577 if ((BitWidth % EltBits) == 0) {
1578 for (unsigned I = 0; I != E; ++I) {
1579 if (I != 0)
1580 CS << ",";
1581 printConstant(CF->getValueAPF(), CS, PrintZero);
1582 }
1583 } else {
1584 CS << "?";
1585 }
1586 } else
1587 printConstant(CF->getValueAPF(), CS, PrintZero);
1588 } else if (auto *CDS = dyn_cast<ConstantDataSequential>(COp)) {
1589 Type *EltTy = CDS->getElementType();
1590 bool IsInteger = EltTy->isIntegerTy();
1591 bool IsFP = EltTy->isHalfTy() || EltTy->isFloatTy() || EltTy->isDoubleTy();
1592 unsigned EltBits = EltTy->getPrimitiveSizeInBits();
1593 unsigned E = std::min(BitWidth / EltBits, (unsigned)CDS->getNumElements());
1594 if ((BitWidth % EltBits) == 0) {
1595 for (unsigned I = 0; I != E; ++I) {
1596 if (I != 0)
1597 CS << ",";
1598 if (IsInteger)
1599 printConstant(CDS->getElementAsAPInt(I), CS, PrintZero);
1600 else if (IsFP)
1601 printConstant(CDS->getElementAsAPFloat(I), CS, PrintZero);
1602 else
1603 CS << "?";
1604 }
1605 } else {
1606 CS << "?";
1607 }
1608 } else if (auto *CV = dyn_cast<ConstantVector>(COp)) {
1609 unsigned EltBits = CV->getType()->getScalarSizeInBits();
1610 unsigned E = std::min(BitWidth / EltBits, CV->getNumOperands());
1611 if ((BitWidth % EltBits) == 0) {
1612 for (unsigned I = 0; I != E; ++I) {
1613 if (I != 0)
1614 CS << ",";
1615 printConstant(CV->getOperand(I), EltBits, CS, PrintZero);
1616 }
1617 } else {
1618 CS << "?";
1619 }
1620 } else {
1621 CS << "?";
1622 }
1623}
1624
1625static void printZeroUpperMove(const MachineInstr *MI, MCStreamer &OutStreamer,
1626 int SclWidth, int VecWidth,
1627 const char *ShuffleComment) {
1628 unsigned SrcIdx = getSrcIdx(MI, 1);
1629
1630 std::string Comment;
1631 raw_string_ostream CS(Comment);
1632 printDstRegisterName(CS, MI, SrcIdx);
1633 CS << " = ";
1634
1635 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx)) {
1636 CS << "[";
1637 printConstant(C, SclWidth, CS);
1638 for (int I = 1, E = VecWidth / SclWidth; I < E; ++I) {
1639 CS << ",";
1640 printConstant(C, SclWidth, CS, true);
1641 }
1642 CS << "]";
1643 OutStreamer.AddComment(CS.str());
1644 return; // early-out
1645 }
1646
1647 // We didn't find a constant load, fallback to a shuffle mask decode.
1648 CS << ShuffleComment;
1649 OutStreamer.AddComment(CS.str());
1650}
1651
1652static void printBroadcast(const MachineInstr *MI, MCStreamer &OutStreamer,
1653 int Repeats, int BitWidth) {
1654 unsigned SrcIdx = getSrcIdx(MI, 1);
1655 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx)) {
1656 std::string Comment;
1657 raw_string_ostream CS(Comment);
1658 printDstRegisterName(CS, MI, SrcIdx);
1659 CS << " = [";
1660 for (int l = 0; l != Repeats; ++l) {
1661 if (l != 0)
1662 CS << ",";
1663 printConstant(C, BitWidth, CS);
1664 }
1665 CS << "]";
1666 OutStreamer.AddComment(CS.str());
1667 }
1668}
1669
1670static bool printExtend(const MachineInstr *MI, MCStreamer &OutStreamer,
1671 int SrcEltBits, int DstEltBits, bool IsSext) {
1672 unsigned SrcIdx = getSrcIdx(MI, 1);
1673 auto *C = X86::getConstantFromPool(*MI, SrcIdx);
1674 if (C && C->getType()->getScalarSizeInBits() == unsigned(SrcEltBits)) {
1675 if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) {
1676 int NumElts = CDS->getNumElements();
1677 std::string Comment;
1678 raw_string_ostream CS(Comment);
1679 printDstRegisterName(CS, MI, SrcIdx);
1680 CS << " = [";
1681 for (int i = 0; i != NumElts; ++i) {
1682 if (i != 0)
1683 CS << ",";
1684 if (CDS->getElementType()->isIntegerTy()) {
1685 APInt Elt = CDS->getElementAsAPInt(i);
1686 Elt = IsSext ? Elt.sext(DstEltBits) : Elt.zext(DstEltBits);
1687 printConstant(Elt, CS);
1688 } else
1689 CS << "?";
1690 }
1691 CS << "]";
1692 OutStreamer.AddComment(CS.str());
1693 return true;
1694 }
1695 }
1696
1697 return false;
1698}
1699static void printSignExtend(const MachineInstr *MI, MCStreamer &OutStreamer,
1700 int SrcEltBits, int DstEltBits) {
1701 printExtend(MI, OutStreamer, SrcEltBits, DstEltBits, true);
1702}
1703static void printZeroExtend(const MachineInstr *MI, MCStreamer &OutStreamer,
1704 int SrcEltBits, int DstEltBits) {
1705 if (printExtend(MI, OutStreamer, SrcEltBits, DstEltBits, false))
1706 return;
1707
1708 // We didn't find a constant load, fallback to a shuffle mask decode.
1709 std::string Comment;
1710 raw_string_ostream CS(Comment);
1712 CS << " = ";
1713
1714 SmallVector<int> Mask;
1715 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1716 assert((Width % DstEltBits) == 0 && (DstEltBits % SrcEltBits) == 0 &&
1717 "Illegal extension ratio");
1718 DecodeZeroExtendMask(SrcEltBits, DstEltBits, Width / DstEltBits, false, Mask);
1719 printShuffleMask(CS, "mem", "", Mask);
1720
1721 OutStreamer.AddComment(CS.str());
1722}
1723
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");
1728
1729 // Use the .cv_fpo directives if we're emitting CodeView on 32-bit x86.
1730 if (EmitFPOData) {
1731 X86TargetStreamer *XTS =
1732 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
1733 switch (MI->getOpcode()) {
1734 case X86::SEH_PushReg:
1735 XTS->emitFPOPushReg(MI->getOperand(0).getImm());
1736 break;
1737 case X86::SEH_StackAlloc:
1738 XTS->emitFPOStackAlloc(MI->getOperand(0).getImm());
1739 break;
1740 case X86::SEH_StackAlign:
1741 XTS->emitFPOStackAlign(MI->getOperand(0).getImm());
1742 break;
1743 case X86::SEH_SetFrame:
1744 assert(MI->getOperand(1).getImm() == 0 &&
1745 ".cv_fpo_setframe takes no offset");
1746 XTS->emitFPOSetFrame(MI->getOperand(0).getImm());
1747 break;
1748 case X86::SEH_EndPrologue:
1749 XTS->emitFPOEndPrologue();
1750 break;
1751 case X86::SEH_SaveReg:
1752 case X86::SEH_SaveXMM:
1753 case X86::SEH_PushFrame:
1754 llvm_unreachable("SEH_ directive incompatible with FPO");
1755 break;
1756 default:
1757 llvm_unreachable("expected SEH_ instruction");
1758 }
1759 return;
1760 }
1761
1762 // Otherwise, use the .seh_ directives for all other Windows platforms.
1763 switch (MI->getOpcode()) {
1764 case X86::SEH_PushReg:
1765 OutStreamer->emitWinCFIPushReg(MI->getOperand(0).getImm());
1766 break;
1767
1768 case X86::SEH_SaveReg:
1769 OutStreamer->emitWinCFISaveReg(MI->getOperand(0).getImm(),
1770 MI->getOperand(1).getImm());
1771 break;
1772
1773 case X86::SEH_SaveXMM:
1774 OutStreamer->emitWinCFISaveXMM(MI->getOperand(0).getImm(),
1775 MI->getOperand(1).getImm());
1776 break;
1777
1778 case X86::SEH_StackAlloc:
1779 OutStreamer->emitWinCFIAllocStack(MI->getOperand(0).getImm());
1780 break;
1781
1782 case X86::SEH_SetFrame:
1783 OutStreamer->emitWinCFISetFrame(MI->getOperand(0).getImm(),
1784 MI->getOperand(1).getImm());
1785 break;
1786
1787 case X86::SEH_PushFrame:
1788 OutStreamer->emitWinCFIPushFrame(MI->getOperand(0).getImm());
1789 break;
1790
1791 case X86::SEH_EndPrologue:
1792 OutStreamer->emitWinCFIEndProlog();
1793 break;
1794
1795 case X86::SEH_BeginEpilogue:
1796 OutStreamer->emitWinCFIBeginEpilogue();
1797 break;
1798
1799 case X86::SEH_EndEpilogue:
1800 OutStreamer->emitWinCFIEndEpilogue();
1801 break;
1802
1803 case X86::SEH_UnwindV2Start:
1804 OutStreamer->emitWinCFIUnwindV2Start();
1805 break;
1806
1807 case X86::SEH_UnwindVersion:
1808 OutStreamer->emitWinCFIUnwindVersion(MI->getOperand(0).getImm());
1809 break;
1810
1811 default:
1812 llvm_unreachable("expected SEH_ instruction");
1813 }
1814}
1815
1817 MCStreamer &OutStreamer) {
1818 switch (MI->getOpcode()) {
1819 // Lower PSHUFB and VPERMILP normally but add a comment if we can find
1820 // a constant shuffle mask. We won't be able to do this at the MC layer
1821 // because the mask isn't an immediate.
1822 case X86::PSHUFBrm:
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: {
1834 unsigned SrcIdx = getSrcIdx(MI, 1);
1835 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx + 1)) {
1836 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1838 DecodePSHUFBMask(C, Width, Mask);
1839 if (!Mask.empty())
1840 OutStreamer.AddComment(getShuffleComment(MI, SrcIdx, SrcIdx, Mask));
1841 }
1842 break;
1843 }
1844
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: {
1856 unsigned SrcIdx = getSrcIdx(MI, 1);
1857 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx + 1)) {
1858 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1860 DecodeVPERMILPMask(C, 32, Width, Mask);
1861 if (!Mask.empty())
1862 OutStreamer.AddComment(getShuffleComment(MI, SrcIdx, SrcIdx, Mask));
1863 }
1864 break;
1865 }
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: {
1877 unsigned SrcIdx = getSrcIdx(MI, 1);
1878 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx + 1)) {
1879 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1881 DecodeVPERMILPMask(C, 64, Width, Mask);
1882 if (!Mask.empty())
1883 OutStreamer.AddComment(getShuffleComment(MI, SrcIdx, SrcIdx, Mask));
1884 }
1885 break;
1886 }
1887
1888 case X86::VPERMIL2PDrm:
1889 case X86::VPERMIL2PSrm:
1890 case X86::VPERMIL2PDYrm:
1891 case X86::VPERMIL2PSYrm: {
1892 assert(MI->getNumOperands() >= (3 + X86::AddrNumOperands + 1) &&
1893 "Unexpected number of operands!");
1894
1895 const MachineOperand &CtrlOp = MI->getOperand(MI->getNumOperands() - 1);
1896 if (!CtrlOp.isImm())
1897 break;
1898
1899 unsigned ElSize;
1900 switch (MI->getOpcode()) {
1901 default: llvm_unreachable("Invalid opcode");
1902 case X86::VPERMIL2PSrm: case X86::VPERMIL2PSYrm: ElSize = 32; break;
1903 case X86::VPERMIL2PDrm: case X86::VPERMIL2PDYrm: ElSize = 64; break;
1904 }
1905
1906 if (auto *C = X86::getConstantFromPool(*MI, 3)) {
1907 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1909 DecodeVPERMIL2PMask(C, (unsigned)CtrlOp.getImm(), ElSize, Width, Mask);
1910 if (!Mask.empty())
1911 OutStreamer.AddComment(getShuffleComment(MI, 1, 2, Mask));
1912 }
1913 break;
1914 }
1915
1916 case X86::VPPERMrrm: {
1917 if (auto *C = X86::getConstantFromPool(*MI, 3)) {
1918 unsigned Width = X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1920 DecodeVPPERMMask(C, Width, Mask);
1921 if (!Mask.empty())
1922 OutStreamer.AddComment(getShuffleComment(MI, 1, 2, Mask));
1923 }
1924 break;
1925 }
1926
1927 case X86::MMX_MOVQ64rm: {
1928 if (auto *C = X86::getConstantFromPool(*MI, 1)) {
1929 std::string Comment;
1930 raw_string_ostream CS(Comment);
1931 const MachineOperand &DstOp = MI->getOperand(0);
1933 if (auto *CF = dyn_cast<ConstantFP>(C)) {
1934 CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false);
1935 OutStreamer.AddComment(CS.str());
1936 }
1937 }
1938 break;
1939 }
1940
1941#define INSTR_CASE(Prefix, Instr, Suffix, Postfix) \
1942 case X86::Prefix##Instr##Suffix##rm##Postfix:
1943
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)
1954
1955#define CASE_ARITH_RM(Instr) \
1956 INSTR_CASE(, Instr, , ) /* SSE */ \
1957 INSTR_CASE(V, Instr, , ) /* AVX-128 */ \
1958 INSTR_CASE(V, Instr, Y, ) /* AVX-256 */ \
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)
1968
1969 // TODO: Add additional instructions when useful.
1970 CASE_ARITH_RM(PADDB)
1971 CASE_ARITH_RM(PADDW)
1972 CASE_ARITH_RM(PADDD)
1973 CASE_ARITH_RM(PADDQ)
1974 CASE_ARITH_RM(PMADDUBSW)
1975 CASE_ARITH_RM(PMADDWD)
1976 CASE_ARITH_RM(PMULDQ)
1977 CASE_ARITH_RM(PMULUDQ)
1978 CASE_ARITH_RM(PMULLD)
1979 CASE_AVX512_ARITH_RM(PMULLQ)
1980 CASE_ARITH_RM(PMULLW)
1981 CASE_ARITH_RM(PMULHW)
1982 CASE_ARITH_RM(PMULHUW)
1983 CASE_ARITH_RM(PMULHRSW) {
1984 unsigned SrcIdx = getSrcIdx(MI, 1);
1985 if (auto *C = X86::getConstantFromPool(*MI, SrcIdx + 1)) {
1986 std::string Comment;
1987 raw_string_ostream CS(Comment);
1988 unsigned VectorWidth =
1989 X86::getVectorRegisterWidth(MI->getDesc().operands()[0]);
1990 CS << "[";
1991 printConstant(C, VectorWidth, CS);
1992 CS << "]";
1993 OutStreamer.AddComment(CS.str());
1994 }
1995 break;
1996 }
1997
1998#define MASK_AVX512_CASE(Instr) \
1999 case Instr: \
2000 case Instr##k: \
2001 case Instr##kz:
2002
2003 case X86::MOVSDrm:
2004 case X86::VMOVSDrm:
2005 MASK_AVX512_CASE(X86::VMOVSDZrm)
2006 case X86::MOVSDrm_alt:
2007 case X86::VMOVSDrm_alt:
2008 case X86::VMOVSDZrm_alt:
2009 case X86::MOVQI2PQIrm:
2010 case X86::VMOVQI2PQIrm:
2011 case X86::VMOVQI2PQIZrm:
2012 printZeroUpperMove(MI, OutStreamer, 64, 128, "mem[0],zero");
2013 break;
2014
2015 MASK_AVX512_CASE(X86::VMOVSHZrm)
2016 case X86::VMOVSHZrm_alt:
2017 printZeroUpperMove(MI, OutStreamer, 16, 128,
2018 "mem[0],zero,zero,zero,zero,zero,zero,zero");
2019 break;
2020
2021 case X86::MOVSSrm:
2022 case X86::VMOVSSrm:
2023 MASK_AVX512_CASE(X86::VMOVSSZrm)
2024 case X86::MOVSSrm_alt:
2025 case X86::VMOVSSrm_alt:
2026 case X86::VMOVSSZrm_alt:
2027 case X86::MOVDI2PDIrm:
2028 case X86::VMOVDI2PDIrm:
2029 case X86::VMOVDI2PDIZrm:
2030 printZeroUpperMove(MI, OutStreamer, 32, 128, "mem[0],zero,zero,zero");
2031 break;
2032
2033#define MOV_CASE(Prefix, Suffix) \
2034 case X86::Prefix##MOVAPD##Suffix##rm: \
2035 case X86::Prefix##MOVAPS##Suffix##rm: \
2036 case X86::Prefix##MOVUPD##Suffix##rm: \
2037 case X86::Prefix##MOVUPS##Suffix##rm: \
2038 case X86::Prefix##MOVDQA##Suffix##rm: \
2039 case X86::Prefix##MOVDQU##Suffix##rm:
2040
2041#define MOV_AVX512_CASE(Suffix, Postfix) \
2042 case X86::VMOVDQA64##Suffix##rm##Postfix: \
2043 case X86::VMOVDQA32##Suffix##rm##Postfix: \
2044 case X86::VMOVDQU64##Suffix##rm##Postfix: \
2045 case X86::VMOVDQU32##Suffix##rm##Postfix: \
2046 case X86::VMOVDQU16##Suffix##rm##Postfix: \
2047 case X86::VMOVDQU8##Suffix##rm##Postfix: \
2048 case X86::VMOVAPS##Suffix##rm##Postfix: \
2049 case X86::VMOVAPD##Suffix##rm##Postfix: \
2050 case X86::VMOVUPS##Suffix##rm##Postfix: \
2051 case X86::VMOVUPD##Suffix##rm##Postfix:
2052
2053#define CASE_128_MOV_RM() \
2054 MOV_CASE(, ) /* SSE */ \
2055 MOV_CASE(V, ) /* AVX-128 */ \
2056 MOV_AVX512_CASE(Z128, ) \
2057 MOV_AVX512_CASE(Z128, k) \
2058 MOV_AVX512_CASE(Z128, kz)
2059
2060#define CASE_256_MOV_RM() \
2061 MOV_CASE(V, Y) /* AVX-256 */ \
2062 MOV_AVX512_CASE(Z256, ) \
2063 MOV_AVX512_CASE(Z256, k) \
2064 MOV_AVX512_CASE(Z256, kz) \
2065
2066#define CASE_512_MOV_RM() \
2067 MOV_AVX512_CASE(Z, ) \
2068 MOV_AVX512_CASE(Z, k) \
2069 MOV_AVX512_CASE(Z, kz) \
2070
2071 // For loads from a constant pool to a vector register, print the constant
2072 // loaded.
2074 printBroadcast(MI, OutStreamer, 1, 128);
2075 break;
2077 printBroadcast(MI, OutStreamer, 1, 256);
2078 break;
2080 printBroadcast(MI, OutStreamer, 1, 512);
2081 break;
2082 case X86::VBROADCASTF128rm:
2083 case X86::VBROADCASTI128rm:
2084 MASK_AVX512_CASE(X86::VBROADCASTF32X4Z256rm)
2085 MASK_AVX512_CASE(X86::VBROADCASTF64X2Z256rm)
2086 MASK_AVX512_CASE(X86::VBROADCASTI32X4Z256rm)
2087 MASK_AVX512_CASE(X86::VBROADCASTI64X2Z256rm)
2088 printBroadcast(MI, OutStreamer, 2, 128);
2089 break;
2090 MASK_AVX512_CASE(X86::VBROADCASTF32X4Zrm)
2091 MASK_AVX512_CASE(X86::VBROADCASTF64X2Zrm)
2092 MASK_AVX512_CASE(X86::VBROADCASTI32X4Zrm)
2093 MASK_AVX512_CASE(X86::VBROADCASTI64X2Zrm)
2094 printBroadcast(MI, OutStreamer, 4, 128);
2095 break;
2096 MASK_AVX512_CASE(X86::VBROADCASTF32X8Zrm)
2097 MASK_AVX512_CASE(X86::VBROADCASTF64X4Zrm)
2098 MASK_AVX512_CASE(X86::VBROADCASTI32X8Zrm)
2099 MASK_AVX512_CASE(X86::VBROADCASTI64X4Zrm)
2100 printBroadcast(MI, OutStreamer, 2, 256);
2101 break;
2102
2103 // For broadcast loads from a constant pool to a vector register, repeatedly
2104 // print the constant loaded.
2105 case X86::MOVDDUPrm:
2106 case X86::VMOVDDUPrm:
2107 MASK_AVX512_CASE(X86::VMOVDDUPZ128rm)
2108 case X86::VPBROADCASTQrm:
2109 MASK_AVX512_CASE(X86::VPBROADCASTQZ128rm)
2110 printBroadcast(MI, OutStreamer, 2, 64);
2111 break;
2112 case X86::VBROADCASTSDYrm:
2113 MASK_AVX512_CASE(X86::VBROADCASTSDZ256rm)
2114 case X86::VPBROADCASTQYrm:
2115 MASK_AVX512_CASE(X86::VPBROADCASTQZ256rm)
2116 printBroadcast(MI, OutStreamer, 4, 64);
2117 break;
2118 MASK_AVX512_CASE(X86::VBROADCASTSDZrm)
2119 MASK_AVX512_CASE(X86::VPBROADCASTQZrm)
2120 printBroadcast(MI, OutStreamer, 8, 64);
2121 break;
2122 case X86::VBROADCASTSSrm:
2123 MASK_AVX512_CASE(X86::VBROADCASTSSZ128rm)
2124 case X86::VPBROADCASTDrm:
2125 MASK_AVX512_CASE(X86::VPBROADCASTDZ128rm)
2126 printBroadcast(MI, OutStreamer, 4, 32);
2127 break;
2128 case X86::VBROADCASTSSYrm:
2129 MASK_AVX512_CASE(X86::VBROADCASTSSZ256rm)
2130 case X86::VPBROADCASTDYrm:
2131 MASK_AVX512_CASE(X86::VPBROADCASTDZ256rm)
2132 printBroadcast(MI, OutStreamer, 8, 32);
2133 break;
2134 MASK_AVX512_CASE(X86::VBROADCASTSSZrm)
2135 MASK_AVX512_CASE(X86::VPBROADCASTDZrm)
2136 printBroadcast(MI, OutStreamer, 16, 32);
2137 break;
2138 case X86::VPBROADCASTWrm:
2139 MASK_AVX512_CASE(X86::VPBROADCASTWZ128rm)
2140 printBroadcast(MI, OutStreamer, 8, 16);
2141 break;
2142 case X86::VPBROADCASTWYrm:
2143 MASK_AVX512_CASE(X86::VPBROADCASTWZ256rm)
2144 printBroadcast(MI, OutStreamer, 16, 16);
2145 break;
2146 MASK_AVX512_CASE(X86::VPBROADCASTWZrm)
2147 printBroadcast(MI, OutStreamer, 32, 16);
2148 break;
2149 case X86::VPBROADCASTBrm:
2150 MASK_AVX512_CASE(X86::VPBROADCASTBZ128rm)
2151 printBroadcast(MI, OutStreamer, 16, 8);
2152 break;
2153 case X86::VPBROADCASTBYrm:
2154 MASK_AVX512_CASE(X86::VPBROADCASTBZ256rm)
2155 printBroadcast(MI, OutStreamer, 32, 8);
2156 break;
2157 MASK_AVX512_CASE(X86::VPBROADCASTBZrm)
2158 printBroadcast(MI, OutStreamer, 64, 8);
2159 break;
2160
2161#define MOVX_CASE(Prefix, Ext, Type, Suffix, Postfix) \
2162 case X86::Prefix##PMOV##Ext##Type##Suffix##rm##Postfix:
2163
2164#define CASE_MOVX_RM(Ext, Type) \
2165 MOVX_CASE(, Ext, Type, , ) \
2166 MOVX_CASE(V, Ext, Type, , ) \
2167 MOVX_CASE(V, Ext, Type, Y, ) \
2168 MOVX_CASE(V, Ext, Type, Z128, ) \
2169 MOVX_CASE(V, Ext, Type, Z128, k ) \
2170 MOVX_CASE(V, Ext, Type, Z128, kz ) \
2171 MOVX_CASE(V, Ext, Type, Z256, ) \
2172 MOVX_CASE(V, Ext, Type, Z256, k ) \
2173 MOVX_CASE(V, Ext, Type, Z256, kz ) \
2174 MOVX_CASE(V, Ext, Type, Z, ) \
2175 MOVX_CASE(V, Ext, Type, Z, k ) \
2176 MOVX_CASE(V, Ext, Type, Z, kz )
2177
2178 CASE_MOVX_RM(SX, BD)
2179 printSignExtend(MI, OutStreamer, 8, 32);
2180 break;
2181 CASE_MOVX_RM(SX, BQ)
2182 printSignExtend(MI, OutStreamer, 8, 64);
2183 break;
2184 CASE_MOVX_RM(SX, BW)
2185 printSignExtend(MI, OutStreamer, 8, 16);
2186 break;
2187 CASE_MOVX_RM(SX, DQ)
2188 printSignExtend(MI, OutStreamer, 32, 64);
2189 break;
2190 CASE_MOVX_RM(SX, WD)
2191 printSignExtend(MI, OutStreamer, 16, 32);
2192 break;
2193 CASE_MOVX_RM(SX, WQ)
2194 printSignExtend(MI, OutStreamer, 16, 64);
2195 break;
2196
2197 CASE_MOVX_RM(ZX, BD)
2198 printZeroExtend(MI, OutStreamer, 8, 32);
2199 break;
2200 CASE_MOVX_RM(ZX, BQ)
2201 printZeroExtend(MI, OutStreamer, 8, 64);
2202 break;
2203 CASE_MOVX_RM(ZX, BW)
2204 printZeroExtend(MI, OutStreamer, 8, 16);
2205 break;
2206 CASE_MOVX_RM(ZX, DQ)
2207 printZeroExtend(MI, OutStreamer, 32, 64);
2208 break;
2209 CASE_MOVX_RM(ZX, WD)
2210 printZeroExtend(MI, OutStreamer, 16, 32);
2211 break;
2212 CASE_MOVX_RM(ZX, WQ)
2213 printZeroExtend(MI, OutStreamer, 16, 64);
2214 break;
2215 }
2216}
2217
2218// Does the given operand refer to a DLLIMPORT function?
2220 return MO.isGlobal() && (MO.getTargetFlags() == X86II::MO_DLLIMPORT);
2221}
2222
2223// Is the given instruction a call to a CFGuard function?
2225 assert(MI->getOpcode() == X86::TAILJMPm64_REX ||
2226 MI->getOpcode() == X86::CALL64m);
2227 const MachineOperand &MO = MI->getOperand(3);
2228 return MO.isGlobal() && (MO.getTargetFlags() == X86II::MO_NO_FLAG) &&
2230}
2231
2232// Does the containing block for the given instruction contain any jump table
2233// info (indicating that the block is a dispatch for a jump table)?
2235 const MachineBasicBlock &MBB = *MI->getParent();
2236 for (auto I = MBB.instr_rbegin(), E = MBB.instr_rend(); I != E; ++I)
2237 if (I->isJumpTableDebugInfo())
2238 return true;
2239
2240 return false;
2241}
2242
2244 // FIXME: Enable feature predicate checks once all the test pass.
2245 // X86_MC::verifyInstructionPredicates(MI->getOpcode(),
2246 // Subtarget->getFeatureBits());
2247
2248 X86MCInstLower MCInstLowering(*MF, *this);
2249 const X86RegisterInfo *RI =
2250 MF->getSubtarget<X86Subtarget>().getRegisterInfo();
2251
2252 if (MI->getOpcode() == X86::OR64rm) {
2253 for (auto &Opd : MI->operands()) {
2254 if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
2255 "swift_async_extendedFramePointerFlags") {
2256 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true;
2257 }
2258 }
2259 }
2260
2261 // Add comments for values loaded from constant pool.
2262 if (OutStreamer->isVerboseAsm())
2264
2265 // Add a comment about EVEX compression
2266 if (TM.Options.MCOptions.ShowMCEncoding) {
2267 if (MI->getAsmPrinterFlags() & X86::AC_EVEX_2_LEGACY)
2268 OutStreamer->AddComment("EVEX TO LEGACY Compression ", false);
2269 else if (MI->getAsmPrinterFlags() & X86::AC_EVEX_2_VEX)
2270 OutStreamer->AddComment("EVEX TO VEX Compression ", false);
2271 else if (MI->getAsmPrinterFlags() & X86::AC_EVEX_2_EVEX)
2272 OutStreamer->AddComment("EVEX TO EVEX Compression ", false);
2273 }
2274
2275 // We use this to suppress NOP padding for Windows EH.
2276 bool IsTailJump = false;
2277
2278 switch (MI->getOpcode()) {
2279 case TargetOpcode::DBG_VALUE:
2280 llvm_unreachable("Should be handled target independently");
2281
2282 case X86::EH_RETURN:
2283 case X86::EH_RETURN64: {
2284 // Lower these as normal, but add some comments.
2285 Register Reg = MI->getOperand(0).getReg();
2286 OutStreamer->AddComment(StringRef("eh_return, addr: %") +
2288 break;
2289 }
2290 case X86::CLEANUPRET: {
2291 // Lower these as normal, but add some comments.
2292 OutStreamer->AddComment("CLEANUPRET");
2293 break;
2294 }
2295
2296 case X86::CATCHRET: {
2297 // Lower these as normal, but add some comments.
2298 OutStreamer->AddComment("CATCHRET");
2299 break;
2300 }
2301
2302 case X86::ENDBR32:
2303 case X86::ENDBR64: {
2304 // CurrentPatchableFunctionEntrySym can be CurrentFnBegin only for
2305 // -fpatchable-function-entry=N,0. The entry MBB is guaranteed to be
2306 // non-empty. If MI is the initial ENDBR, place the
2307 // __patchable_function_entries label after ENDBR.
2310 MI == &MF->front().front()) {
2311 MCInst Inst;
2312 MCInstLowering.Lower(MI, Inst);
2313 EmitAndCountInstruction(Inst);
2316 return;
2317 }
2318 break;
2319 }
2320
2321 case X86::TAILJMPd64:
2322 if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))
2323 EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2324
2325 if (EnableImportCallOptimization && isImportedFunction(MI->getOperand(0))) {
2326 emitLabelAndRecordForImportCallOptimization(
2327 IMAGE_RETPOLINE_AMD64_IMPORT_BR);
2328 }
2329
2330 // Lower this as normal, but add a comment.
2331 OutStreamer->AddComment("TAILCALL");
2332 IsTailJump = true;
2333 break;
2334
2335 case X86::TAILJMPr:
2336 case X86::TAILJMPm:
2337 case X86::TAILJMPd:
2338 case X86::TAILJMPd_CC:
2339 case X86::TAILJMPr64:
2340 case X86::TAILJMPm64:
2341 case X86::TAILJMPd64_CC:
2342 if (EnableImportCallOptimization)
2343 report_fatal_error("Unexpected TAILJMP instruction was emitted when "
2344 "import call optimization was enabled");
2345
2346 // Lower these as normal, but add some comments.
2347 OutStreamer->AddComment("TAILCALL");
2348 IsTailJump = true;
2349 break;
2350
2351 case X86::TAILJMPm64_REX:
2352 if (EnableImportCallOptimization && isCallToCFGuardFunction(MI)) {
2353 emitLabelAndRecordForImportCallOptimization(
2354 IMAGE_RETPOLINE_AMD64_CFG_BR_REX);
2355 }
2356
2357 OutStreamer->AddComment("TAILCALL");
2358 IsTailJump = true;
2359 break;
2360
2361 case X86::TAILJMPr64_REX: {
2362 if (EnableImportCallOptimization) {
2363 assert(MI->getOperand(0).getReg() == X86::RAX &&
2364 "Indirect tail calls with impcall enabled must go through RAX (as "
2365 "enforced by TCRETURNImpCallri64)");
2366 emitLabelAndRecordForImportCallOptimization(
2367 IMAGE_RETPOLINE_AMD64_INDIR_BR);
2368 }
2369
2370 OutStreamer->AddComment("TAILCALL");
2371 IsTailJump = true;
2372 break;
2373 }
2374
2375 case X86::JMP64r:
2376 if (EnableImportCallOptimization && hasJumpTableInfoInBlock(MI)) {
2377 uint16_t EncodedReg =
2378 this->getSubtarget().getRegisterInfo()->getEncodingValue(
2379 MI->getOperand(0).getReg().asMCReg());
2380 emitLabelAndRecordForImportCallOptimization(
2381 (ImportCallKind)(IMAGE_RETPOLINE_AMD64_SWITCHTABLE_FIRST +
2382 EncodedReg));
2383 }
2384 break;
2385
2386 case X86::JMP16r:
2387 case X86::JMP16m:
2388 case X86::JMP32r:
2389 case X86::JMP32m:
2390 case X86::JMP64m:
2391 if (EnableImportCallOptimization && hasJumpTableInfoInBlock(MI))
2393 "Unexpected JMP instruction was emitted for a jump-table when import "
2394 "call optimization was enabled");
2395 break;
2396
2397 case X86::TLS_addr32:
2398 case X86::TLS_addr64:
2399 case X86::TLS_addrX32:
2400 case X86::TLS_base_addr32:
2401 case X86::TLS_base_addr64:
2402 case X86::TLS_base_addrX32:
2403 case X86::TLS_desc32:
2404 case X86::TLS_desc64:
2405 return LowerTlsAddr(MCInstLowering, *MI);
2406
2407 case X86::MOVPC32r: {
2408 // This is a pseudo op for a two instruction sequence with a label, which
2409 // looks like:
2410 // call "L1$pb"
2411 // "L1$pb":
2412 // popl %esi
2413
2414 // Emit the call.
2415 MCSymbol *PICBase = MF->getPICBaseSymbol();
2416 // FIXME: We would like an efficient form for this, so we don't have to do a
2417 // lot of extra uniquing.
2418 EmitAndCountInstruction(
2419 MCInstBuilder(X86::CALLpcrel32)
2420 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
2421
2422 const X86FrameLowering *FrameLowering =
2423 MF->getSubtarget<X86Subtarget>().getFrameLowering();
2424 bool hasFP = FrameLowering->hasFP(*MF);
2425
2426 // TODO: This is needed only if we require precise CFA.
2427 bool HasActiveDwarfFrame = OutStreamer->getNumFrameInfos() &&
2428 !OutStreamer->getDwarfFrameInfos().back().End;
2429
2430 int stackGrowth = -RI->getSlotSize();
2431
2432 if (HasActiveDwarfFrame && !hasFP) {
2433 OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);
2434 MF->getInfo<X86MachineFunctionInfo>()->setHasCFIAdjustCfa(true);
2435 }
2436
2437 // Emit the label.
2438 OutStreamer->emitLabel(PICBase);
2439
2440 // popl $reg
2441 EmitAndCountInstruction(
2442 MCInstBuilder(X86::POP32r).addReg(MI->getOperand(0).getReg()));
2443
2444 if (HasActiveDwarfFrame && !hasFP) {
2445 OutStreamer->emitCFIAdjustCfaOffset(stackGrowth);
2446 }
2447 return;
2448 }
2449
2450 case X86::ADD32ri: {
2451 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
2452 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
2453 break;
2454
2455 // Okay, we have something like:
2456 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
2457
2458 // For this, we want to print something like:
2459 // MYGLOBAL + (. - PICBASE)
2460 // However, we can't generate a ".", so just emit a new label here and refer
2461 // to it.
2462 MCSymbol *DotSym = OutContext.createTempSymbol();
2463 OutStreamer->emitLabel(DotSym);
2464
2465 // Now that we have emitted the label, lower the complex operand expression.
2466 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
2467
2468 const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
2469 const MCExpr *PICBase =
2470 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
2471 DotExpr = MCBinaryExpr::createSub(DotExpr, PICBase, OutContext);
2472
2473 DotExpr = MCBinaryExpr::createAdd(
2475
2476 EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)
2477 .addReg(MI->getOperand(0).getReg())
2478 .addReg(MI->getOperand(1).getReg())
2479 .addExpr(DotExpr));
2480 return;
2481 }
2482 case TargetOpcode::STATEPOINT:
2483 return LowerSTATEPOINT(*MI, MCInstLowering);
2484
2485 case TargetOpcode::FAULTING_OP:
2486 return LowerFAULTING_OP(*MI, MCInstLowering);
2487
2488 case TargetOpcode::FENTRY_CALL:
2489 return LowerFENTRY_CALL(*MI, MCInstLowering);
2490
2491 case TargetOpcode::PATCHABLE_OP:
2492 return LowerPATCHABLE_OP(*MI, MCInstLowering);
2493
2494 case TargetOpcode::STACKMAP:
2495 return LowerSTACKMAP(*MI);
2496
2497 case TargetOpcode::PATCHPOINT:
2498 return LowerPATCHPOINT(*MI, MCInstLowering);
2499
2500 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2501 return LowerPATCHABLE_FUNCTION_ENTER(*MI, MCInstLowering);
2502
2503 case TargetOpcode::PATCHABLE_RET:
2504 return LowerPATCHABLE_RET(*MI, MCInstLowering);
2505
2506 case TargetOpcode::PATCHABLE_TAIL_CALL:
2507 return LowerPATCHABLE_TAIL_CALL(*MI, MCInstLowering);
2508
2509 case TargetOpcode::PATCHABLE_EVENT_CALL:
2510 return LowerPATCHABLE_EVENT_CALL(*MI, MCInstLowering);
2511
2512 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
2513 return LowerPATCHABLE_TYPED_EVENT_CALL(*MI, MCInstLowering);
2514
2515 case X86::MORESTACK_RET:
2516 EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
2517 return;
2518
2519 case X86::KCFI_CHECK:
2520 return LowerKCFI_CHECK(*MI);
2521
2522 case X86::ASAN_CHECK_MEMACCESS:
2523 return LowerASAN_CHECK_MEMACCESS(*MI);
2524
2525 case X86::MORESTACK_RET_RESTORE_R10:
2526 // Return, then restore R10.
2527 EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
2528 EmitAndCountInstruction(
2529 MCInstBuilder(X86::MOV64rr).addReg(X86::R10).addReg(X86::RAX));
2530 return;
2531
2532 case X86::SEH_PushReg:
2533 case X86::SEH_SaveReg:
2534 case X86::SEH_SaveXMM:
2535 case X86::SEH_StackAlloc:
2536 case X86::SEH_StackAlign:
2537 case X86::SEH_SetFrame:
2538 case X86::SEH_PushFrame:
2539 case X86::SEH_EndPrologue:
2540 case X86::SEH_EndEpilogue:
2541 case X86::SEH_UnwindV2Start:
2542 case X86::SEH_UnwindVersion:
2543 EmitSEHInstruction(MI);
2544 return;
2545
2546 case X86::SEH_SplitChainedAtEndOfBlock:
2547 assert(!SplitChainedAtEndOfBlock &&
2548 "Duplicate SEH_SplitChainedAtEndOfBlock in a current block");
2549 SplitChainedAtEndOfBlock = true;
2550 return;
2551
2552 case X86::SEH_BeginEpilogue: {
2553 assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
2554 EmitSEHInstruction(MI);
2555 return;
2556 }
2557 case X86::UBSAN_UD1:
2558 EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)
2559 .addReg(X86::EAX)
2560 .addReg(X86::EAX)
2561 .addImm(1)
2562 .addReg(X86::NoRegister)
2563 .addImm(MI->getOperand(0).getImm())
2564 .addReg(X86::NoRegister));
2565 return;
2566 case X86::CALL64pcrel32:
2567 if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))
2568 EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2569
2570 if (EnableImportCallOptimization && isImportedFunction(MI->getOperand(0))) {
2571 emitLabelAndRecordForImportCallOptimization(
2572 IMAGE_RETPOLINE_AMD64_IMPORT_CALL);
2573
2574 MCInst TmpInst;
2575 MCInstLowering.Lower(MI, TmpInst);
2576
2577 // For Import Call Optimization to work, we need a the call instruction
2578 // with a rex prefix, and a 5-byte nop after the call instruction.
2579 EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
2580 emitCallInstruction(TmpInst);
2581 emitNop(*OutStreamer, 5, Subtarget);
2582 maybeEmitNopAfterCallForWindowsEH(MI);
2583 return;
2584 }
2585
2586 break;
2587
2588 case X86::CALL64r:
2589 if (EnableImportCallOptimization) {
2590 assert(MI->getOperand(0).getReg() == X86::RAX &&
2591 "Indirect calls with impcall enabled must go through RAX (as "
2592 "enforced by CALL64r_ImpCall)");
2593
2594 emitLabelAndRecordForImportCallOptimization(
2595 IMAGE_RETPOLINE_AMD64_INDIR_CALL);
2596 MCInst TmpInst;
2597 MCInstLowering.Lower(MI, TmpInst);
2598 emitCallInstruction(TmpInst);
2599
2600 // For Import Call Optimization to work, we need a 3-byte nop after the
2601 // call instruction.
2602 emitNop(*OutStreamer, 3, Subtarget);
2603 maybeEmitNopAfterCallForWindowsEH(MI);
2604 return;
2605 }
2606 break;
2607
2608 case X86::CALL64m:
2609 if (EnableImportCallOptimization && isCallToCFGuardFunction(MI)) {
2610 emitLabelAndRecordForImportCallOptimization(
2611 IMAGE_RETPOLINE_AMD64_CFG_CALL);
2612 }
2613 break;
2614
2615 case X86::JCC_1:
2616 // Two instruction prefixes (2EH for branch not-taken and 3EH for branch
2617 // taken) are used as branch hints. Here we add branch taken prefix for
2618 // jump instruction with higher probability than threshold.
2619 if (getSubtarget().hasBranchHint() && EnableBranchHint) {
2620 const MachineBranchProbabilityInfo *MBPI =
2622 MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
2623 BranchProbability EdgeProb =
2624 MBPI->getEdgeProbability(MI->getParent(), DestBB);
2626 if (EdgeProb > Threshold)
2627 EmitAndCountInstruction(MCInstBuilder(X86::DS_PREFIX));
2628 }
2629 break;
2630
2631 case X86::JCC_SELF:
2632 MCSymbol *Sym = OutContext.createTempSymbol();
2633 OutStreamer->emitLabel(Sym);
2634 EmitAndCountInstruction(
2635 MCInstBuilder(X86::JCC_1)
2636 .addExpr(MCSymbolRefExpr::create(Sym, OutContext))
2637 .addImm(MI->getOperand(0).getImm()));
2638 return;
2639 }
2640
2641 MCInst TmpInst;
2642 MCInstLowering.Lower(MI, TmpInst);
2643
2644 if (MI->isCall()) {
2645 emitCallInstruction(TmpInst);
2646 // Since tail calls transfer control without leaving a stack frame, there is
2647 // never a need for NOP padding tail calls.
2648 if (!IsTailJump)
2649 maybeEmitNopAfterCallForWindowsEH(MI);
2650 return;
2651 }
2652
2653 EmitAndCountInstruction(TmpInst);
2654}
2655
2657 const MCSubtargetInfo *EndInfo,
2658 const MachineInstr *MI) {
2659 if (MI) {
2660 // If unwinding inline asm ends on a call, wineh may require insertion of
2661 // a nop.
2662 unsigned ExtraInfo = MI->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
2663 if (ExtraInfo & InlineAsm::Extra_MayUnwind)
2664 maybeEmitNopAfterCallForWindowsEH(MI);
2665 }
2666}
2667
2668void X86AsmPrinter::emitCallInstruction(const llvm::MCInst &MCI) {
2669 // Stackmap shadows cannot include branch targets, so we can count the bytes
2670 // in a call towards the shadow, but must ensure that the no thread returns
2671 // in to the stackmap shadow. The only way to achieve this is if the call
2672 // is at the end of the shadow.
2673
2674 // Count then size of the call towards the shadow
2675 SMShadowTracker.count(MCI, getSubtargetInfo(), CodeEmitter.get());
2676 // Then flush the shadow so that we fill with nops before the call, not
2677 // after it.
2678 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
2679 // Then emit the call
2680 OutStreamer->emitInstruction(MCI, getSubtargetInfo());
2681}
2682
2683// Determines whether a NOP is required after a CALL, so that Windows EH
2684// IP2State tables have the correct information.
2685//
2686// On most Windows platforms (AMD64, ARM64, ARM32, IA64, but *not* x86-32),
2687// exception handling works by looking up instruction pointers in lookup
2688// tables. These lookup tables are stored in .xdata sections in executables.
2689// One element of the lookup tables are the "IP2State" tables (Instruction
2690// Pointer to State).
2691//
2692// If a function has any instructions that require cleanup during exception
2693// unwinding, then it will have an IP2State table. Each entry in the IP2State
2694// table describes a range of bytes in the function's instruction stream, and
2695// associates an "EH state number" with that range of instructions. A value of
2696// -1 means "the null state", which does not require any code to execute.
2697// A value other than -1 is an index into the State table.
2698//
2699// The entries in the IP2State table contain byte offsets within the instruction
2700// stream of the function. The Windows ABI requires that these offsets are
2701// aligned to instruction boundaries; they are not permitted to point to a byte
2702// that is not the first byte of an instruction.
2703//
2704// Unfortunately, CALL instructions present a problem during unwinding. CALL
2705// instructions push the address of the instruction after the CALL instruction,
2706// so that execution can resume after the CALL. If the CALL is the last
2707// instruction within an IP2State region, then the return address (on the stack)
2708// points to the *next* IP2State region. This means that the unwinder will
2709// use the wrong cleanup funclet during unwinding.
2710//
2711// To fix this problem, the Windows AMD64 ABI requires that CALL instructions
2712// are never placed at the end of an IP2State region. Stated equivalently, the
2713// end of a CALL instruction cannot be aligned to an IP2State boundary. If a
2714// CALL instruction would occur at the end of an IP2State region, then the
2715// compiler must insert a NOP instruction after the CALL. The NOP instruction
2716// is placed in the same EH region as the CALL instruction, so that the return
2717// address points to the NOP and the unwinder will locate the correct region.
2718//
2719// NOP padding is only necessary on Windows AMD64 targets. On ARM64 and ARM32,
2720// instructions have a fixed size so the unwinder knows how to "back up" by
2721// one instruction.
2722//
2723// Interaction with Import Call Optimization (ICO):
2724//
2725// Import Call Optimization (ICO) is a compiler + OS feature on Windows which
2726// improves the performance and security of DLL imports. ICO relies on using a
2727// specific CALL idiom that can be replaced by the OS DLL loader. This removes
2728// a load and indirect CALL and replaces it with a single direct CALL.
2729//
2730// To achieve this, ICO also inserts NOPs after the CALL instruction. If the
2731// end of the CALL is aligned with an EH state transition, we *also* insert
2732// a single-byte NOP. **Both forms of NOPs must be preserved.** They cannot
2733// be combined into a single larger NOP; nor can the second NOP be removed.
2734//
2735// This is necessary because, if ICO is active and the call site is modified
2736// by the loader, the loader will end up overwriting the NOPs that were inserted
2737// for ICO. That means that those NOPs cannot be used for the correct
2738// termination of the exception handling region (the IP2State transition),
2739// so we still need an additional NOP instruction. The NOPs cannot be combined
2740// into a longer NOP (which is ordinarily desirable) because then ICO would
2741// split one instruction, producing a malformed instruction after the ICO call.
2742void X86AsmPrinter::maybeEmitNopAfterCallForWindowsEH(const MachineInstr *MI) {
2743 // We only need to insert NOPs after CALLs when targeting Windows on AMD64.
2744 // (Don't let the name fool you: Itanium refers to table-based exception
2745 // handling, not the Itanium architecture.)
2746 if (MAI->getExceptionHandlingType() != ExceptionHandling::WinEH ||
2747 MAI->getWinEHEncodingType() != WinEH::EncodingType::Itanium) {
2748 return;
2749 }
2750
2751 bool HasEHPersonality = MF->getWinEHFuncInfo() != nullptr;
2752
2753 // Set up MBB iterator, initially positioned on the same MBB as MI.
2754 MachineFunction::const_iterator MFI(MI->getParent());
2756
2757 // Set up instruction iterator, positioned immediately *after* MI.
2759 MachineBasicBlock::const_iterator MBBE = MI->getParent()->end();
2760 ++MBBI; // Step over MI
2761
2762 // This loop iterates MBBs
2763 for (;;) {
2764 // This loop iterates instructions
2765 for (; MBBI != MBBE; ++MBBI) {
2766 // Check the instruction that follows this CALL.
2767 const MachineInstr &NextMI = *MBBI;
2768
2769 // If there is an EH_LABEL after this CALL, then there is an EH state
2770 // transition after this CALL. This is exactly the situation which
2771 // requires NOP padding.
2772 if (NextMI.isEHLabel()) {
2773 if (HasEHPersonality) {
2774 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2775 return;
2776 }
2777 // We actually want to continue, in case there is an SEH_BeginEpilogue
2778 // instruction after the EH_LABEL. In some situations, IR is produced
2779 // that contains EH_LABEL pseudo-instructions, even when we are not
2780 // generating IP2State tables. We still need to insert a NOP before
2781 // SEH_BeginEpilogue in that case.
2782 continue;
2783 }
2784
2785 // Somewhat similarly, if the CALL is the last instruction before the
2786 // SEH prologue, then we also need a NOP. This is necessary because the
2787 // Windows stack unwinder will not invoke a function's exception handler
2788 // if the instruction pointer is in the function prologue or epilogue.
2789 //
2790 // We always emit a NOP before SEH_BeginEpilogue, even if there is no
2791 // personality function (unwind info) for this frame. This is the same
2792 // behavior as MSVC.
2793 if (NextMI.getOpcode() == X86::SEH_BeginEpilogue) {
2794 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2795 return;
2796 }
2797
2798 if (!NextMI.isPseudo() && !NextMI.isMetaInstruction()) {
2799 // We found a real instruction. During the CALL, the return IP will
2800 // point to this instruction. Since this instruction has the same EH
2801 // state as the call itself (because there is no intervening EH_LABEL),
2802 // the IP2State table will be accurate; there is no need to insert a
2803 // NOP.
2804 return;
2805 }
2806
2807 // The next instruction is a pseudo-op. Ignore it and keep searching.
2808 // Because these instructions do not generate any machine code, they
2809 // cannot prevent the IP2State table from pointing at the wrong
2810 // instruction during a CALL.
2811 }
2812
2813 // We've reached the end of this MBB. Find the next MBB in program order.
2814 // MBB order should be finalized by this point, so falling across MBBs is
2815 // expected.
2816 ++MFI;
2817 if (MFI == MFE) {
2818 // No more blocks; we've reached the end of the function. This should
2819 // only happen with no-return functions, but double-check to be sure.
2820 if (HasEHPersonality) {
2821 // If the CALL has no successors, then it is a noreturn function.
2822 // Insert an INT3 instead of a NOP. This accomplishes the same purpose,
2823 // but is more clear to read. Also, analysis tools will understand
2824 // that they should not continue disassembling after the CALL (unless
2825 // there are other branches to that label).
2826 if (MI->getParent()->succ_empty())
2827 EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2828 else
2829 EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
2830 }
2831 return;
2832 }
2833
2834 // Set up iterator to scan the next basic block.
2835 const MachineBasicBlock *NextMBB = &*MFI;
2836 MBBI = NextMBB->instr_begin();
2837 MBBE = NextMBB->instr_end();
2838 }
2839}
2840
2841void X86AsmPrinter::emitLabelAndRecordForImportCallOptimization(
2842 ImportCallKind Kind) {
2843 assert(EnableImportCallOptimization);
2844
2845 MCSymbol *CallSiteSymbol = MMI->getContext().createNamedTempSymbol("impcall");
2846 OutStreamer->emitLabel(CallSiteSymbol);
2847
2848 SectionToImportedFunctionCalls[OutStreamer->getCurrentSectionOnly()]
2849 .push_back({CallSiteSymbol, Kind});
2850}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MachineBasicBlock & MBB
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")
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:598
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
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 contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
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
Definition APFloat.h:1545
const fltSemantics & getSemantics() const
Definition APFloat.h:1524
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Definition APFloat.h:1134
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1043
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1555
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1503
unsigned getNumWords() const
Get the number of words.
Definition APInt.h:1510
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1016
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
Definition APInt.h:576
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:91
MCSymbol * getSymbol(const GlobalValue *GV) const
MCSymbol * CurrentFnBegin
Definition AsmPrinter.h:233
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:94
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition AsmPrinter.h:97
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:109
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.
Definition AsmPrinter.h:112
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:101
MCSymbol * createTempSymbol(const Twine &Name) const
MCSymbol * CurrentPatchableFunctionEntrySym
The symbol for the entry in __patchable_function_entires.
Definition AsmPrinter.h:124
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:106
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.
Definition Constant.h:43
Register getReg() const
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition Function.h:714
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:763
bool hasInternalLinkage() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:64
bool doesSetDirectiveSuppressReloc() const
Definition MCAsmInfo.h:605
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:428
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)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI const MCTargetOptions * getTargetOptions() const
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.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
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.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
unsigned getOpcode() const
Definition MCInst.h:202
iterator insert(iterator I, const MCOperand &Op)
Definition MCInst.h:232
void setFlags(unsigned F)
Definition MCInst.h:204
void addOperand(const MCOperand Op)
Definition MCInst.h:215
iterator begin()
Definition MCInst.h:227
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
Streaming machine code generation interface.
Definition MCStreamer.h:222
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
Definition MCStreamer.h:323
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:394
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()
Definition MCStreamer.h:333
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
Definition MCStreamer.h:428
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())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
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.
mop_range operands()
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 isEHLabel() 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
int64_t getImm() 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.
Definition Mangler.cpp:121
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition Pass.cpp:140
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.
Definition Register.h:20
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:107
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
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.
Definition StringRef.h:55
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
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.
Definition Type.h:46
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:201
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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.
Definition raw_ostream.h:53
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.
Definition CallingConv.h:34
@ Itanium
Windows CE ARM, PowerPC, SH3, SH4.
Definition MCAsmInfo.h:49
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)
@ AddrNumOperands
Definition X86BaseInfo.h:36
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)
uint16_t Specifier
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.
@ S_GOTPCREL_NORELAX
initializer< Ty > init(const Ty &Val)
NodeAddr< CodeNode * > Code
Definition RDFGraph.h:388
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.
Definition STLExtras.h:316
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.
Definition Casting.h:643
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
LLVM_ABI bool isCFGuardFunction(const GlobalValue *GV)
Definition CFGuard.cpp:319
@ WinEH
Windows Exception Handling.
Definition CodeGen.h:58
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)
Definition Error.cpp:163
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...
Definition Casting.h:547
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.
Definition STLExtras.h:323
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)
@ SM_SentinelUndef
@ SM_SentinelZero
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.
#define N
void changeAndComment(bool b)
NoAutoPaddingScope(MCStreamer &OS)
const bool OldAllowAutoPadding