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