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