109467b48Spatrick //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains code to lower X86 MachineInstrs to their corresponding
1009467b48Spatrick // MCInst records.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "MCTargetDesc/X86ATTInstPrinter.h"
1509467b48Spatrick #include "MCTargetDesc/X86BaseInfo.h"
1609467b48Spatrick #include "MCTargetDesc/X86InstComments.h"
17097a140dSpatrick #include "MCTargetDesc/X86ShuffleDecode.h"
1809467b48Spatrick #include "MCTargetDesc/X86TargetStreamer.h"
1909467b48Spatrick #include "X86AsmPrinter.h"
2009467b48Spatrick #include "X86RegisterInfo.h"
2109467b48Spatrick #include "X86ShuffleDecodeConstantPool.h"
22097a140dSpatrick #include "X86Subtarget.h"
2309467b48Spatrick #include "llvm/ADT/SmallString.h"
2409467b48Spatrick #include "llvm/ADT/iterator_range.h"
2509467b48Spatrick #include "llvm/CodeGen/MachineConstantPool.h"
2609467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2709467b48Spatrick #include "llvm/CodeGen/MachineModuleInfoImpls.h"
2809467b48Spatrick #include "llvm/CodeGen/MachineOperand.h"
2909467b48Spatrick #include "llvm/CodeGen/StackMaps.h"
3009467b48Spatrick #include "llvm/IR/DataLayout.h"
3109467b48Spatrick #include "llvm/IR/GlobalValue.h"
3209467b48Spatrick #include "llvm/IR/Mangler.h"
3309467b48Spatrick #include "llvm/MC/MCAsmInfo.h"
3409467b48Spatrick #include "llvm/MC/MCCodeEmitter.h"
3509467b48Spatrick #include "llvm/MC/MCContext.h"
3609467b48Spatrick #include "llvm/MC/MCExpr.h"
3709467b48Spatrick #include "llvm/MC/MCFixup.h"
3809467b48Spatrick #include "llvm/MC/MCInst.h"
3909467b48Spatrick #include "llvm/MC/MCInstBuilder.h"
4009467b48Spatrick #include "llvm/MC/MCSection.h"
4109467b48Spatrick #include "llvm/MC/MCSectionELF.h"
4209467b48Spatrick #include "llvm/MC/MCStreamer.h"
4309467b48Spatrick #include "llvm/MC/MCSymbol.h"
4409467b48Spatrick #include "llvm/MC/MCSymbolELF.h"
45*a96b3639Srobert #include "llvm/MC/TargetRegistry.h"
4609467b48Spatrick #include "llvm/Target/TargetLoweringObjectFile.h"
47097a140dSpatrick #include "llvm/Target/TargetMachine.h"
48*a96b3639Srobert #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
49*a96b3639Srobert #include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
50*a96b3639Srobert #include <string>
5109467b48Spatrick 
5209467b48Spatrick using namespace llvm;
5309467b48Spatrick 
5409467b48Spatrick namespace {
5509467b48Spatrick 
5609467b48Spatrick /// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
5709467b48Spatrick class X86MCInstLower {
5809467b48Spatrick   MCContext &Ctx;
5909467b48Spatrick   const MachineFunction &MF;
6009467b48Spatrick   const TargetMachine &TM;
6109467b48Spatrick   const MCAsmInfo &MAI;
6209467b48Spatrick   X86AsmPrinter &AsmPrinter;
6309467b48Spatrick 
6409467b48Spatrick public:
6509467b48Spatrick   X86MCInstLower(const MachineFunction &MF, X86AsmPrinter &asmprinter);
6609467b48Spatrick 
67*a96b3639Srobert   std::optional<MCOperand> LowerMachineOperand(const MachineInstr *MI,
6809467b48Spatrick                                                const MachineOperand &MO) const;
6909467b48Spatrick   void Lower(const MachineInstr *MI, MCInst &OutMI) const;
7009467b48Spatrick 
7109467b48Spatrick   MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const;
7209467b48Spatrick   MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
7309467b48Spatrick 
7409467b48Spatrick private:
7509467b48Spatrick   MachineModuleInfoMachO &getMachOMMI() const;
7609467b48Spatrick };
7709467b48Spatrick 
7809467b48Spatrick } // end anonymous namespace
7909467b48Spatrick 
80097a140dSpatrick /// A RAII helper which defines a region of instructions which can't have
81097a140dSpatrick /// padding added between them for correctness.
82097a140dSpatrick struct NoAutoPaddingScope {
83097a140dSpatrick   MCStreamer &OS;
84097a140dSpatrick   const bool OldAllowAutoPadding;
NoAutoPaddingScopeNoAutoPaddingScope85097a140dSpatrick   NoAutoPaddingScope(MCStreamer &OS)
86097a140dSpatrick       : OS(OS), OldAllowAutoPadding(OS.getAllowAutoPadding()) {
87097a140dSpatrick     changeAndComment(false);
88097a140dSpatrick   }
~NoAutoPaddingScopeNoAutoPaddingScope89097a140dSpatrick   ~NoAutoPaddingScope() { changeAndComment(OldAllowAutoPadding); }
changeAndCommentNoAutoPaddingScope90097a140dSpatrick   void changeAndComment(bool b) {
91097a140dSpatrick     if (b == OS.getAllowAutoPadding())
92097a140dSpatrick       return;
93097a140dSpatrick     OS.setAllowAutoPadding(b);
94097a140dSpatrick     if (b)
95097a140dSpatrick       OS.emitRawComment("autopadding");
96097a140dSpatrick     else
97097a140dSpatrick       OS.emitRawComment("noautopadding");
98097a140dSpatrick   }
99097a140dSpatrick };
100097a140dSpatrick 
10109467b48Spatrick // Emit a minimal sequence of nops spanning NumBytes bytes.
102097a140dSpatrick static void emitX86Nops(MCStreamer &OS, unsigned NumBytes,
103097a140dSpatrick                         const X86Subtarget *Subtarget);
10409467b48Spatrick 
count(MCInst & Inst,const MCSubtargetInfo & STI,MCCodeEmitter * CodeEmitter)10509467b48Spatrick void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,
10609467b48Spatrick                                                  const MCSubtargetInfo &STI,
10709467b48Spatrick                                                  MCCodeEmitter *CodeEmitter) {
10809467b48Spatrick   if (InShadow) {
10909467b48Spatrick     SmallString<256> Code;
11009467b48Spatrick     SmallVector<MCFixup, 4> Fixups;
11109467b48Spatrick     raw_svector_ostream VecOS(Code);
11209467b48Spatrick     CodeEmitter->encodeInstruction(Inst, VecOS, Fixups, STI);
11309467b48Spatrick     CurrentShadowSize += Code.size();
11409467b48Spatrick     if (CurrentShadowSize >= RequiredShadowSize)
11509467b48Spatrick       InShadow = false; // The shadow is big enough. Stop counting.
11609467b48Spatrick   }
11709467b48Spatrick }
11809467b48Spatrick 
emitShadowPadding(MCStreamer & OutStreamer,const MCSubtargetInfo & STI)11909467b48Spatrick void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
12009467b48Spatrick     MCStreamer &OutStreamer, const MCSubtargetInfo &STI) {
12109467b48Spatrick   if (InShadow && CurrentShadowSize < RequiredShadowSize) {
12209467b48Spatrick     InShadow = false;
123097a140dSpatrick     emitX86Nops(OutStreamer, RequiredShadowSize - CurrentShadowSize,
124097a140dSpatrick                 &MF->getSubtarget<X86Subtarget>());
12509467b48Spatrick   }
12609467b48Spatrick }
12709467b48Spatrick 
EmitAndCountInstruction(MCInst & Inst)12809467b48Spatrick void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
129097a140dSpatrick   OutStreamer->emitInstruction(Inst, getSubtargetInfo());
13009467b48Spatrick   SMShadowTracker.count(Inst, getSubtargetInfo(), CodeEmitter.get());
13109467b48Spatrick }
13209467b48Spatrick 
X86MCInstLower(const MachineFunction & mf,X86AsmPrinter & asmprinter)13309467b48Spatrick X86MCInstLower::X86MCInstLower(const MachineFunction &mf,
13409467b48Spatrick                                X86AsmPrinter &asmprinter)
13509467b48Spatrick     : Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()), MAI(*TM.getMCAsmInfo()),
13609467b48Spatrick       AsmPrinter(asmprinter) {}
13709467b48Spatrick 
getMachOMMI() const13809467b48Spatrick MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
13909467b48Spatrick   return MF.getMMI().getObjFileInfo<MachineModuleInfoMachO>();
14009467b48Spatrick }
14109467b48Spatrick 
14209467b48Spatrick /// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
14309467b48Spatrick /// operand to an MCSymbol.
GetSymbolFromOperand(const MachineOperand & MO) const14409467b48Spatrick MCSymbol *X86MCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
145097a140dSpatrick   const Triple &TT = TM.getTargetTriple();
146097a140dSpatrick   if (MO.isGlobal() && TT.isOSBinFormatELF())
147097a140dSpatrick     return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());
148097a140dSpatrick 
14909467b48Spatrick   const DataLayout &DL = MF.getDataLayout();
15009467b48Spatrick   assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
15109467b48Spatrick          "Isn't a symbol reference");
15209467b48Spatrick 
15309467b48Spatrick   MCSymbol *Sym = nullptr;
15409467b48Spatrick   SmallString<128> Name;
15509467b48Spatrick   StringRef Suffix;
15609467b48Spatrick 
15709467b48Spatrick   switch (MO.getTargetFlags()) {
15809467b48Spatrick   case X86II::MO_DLLIMPORT:
15909467b48Spatrick     // Handle dllimport linkage.
16009467b48Spatrick     Name += "__imp_";
16109467b48Spatrick     break;
16209467b48Spatrick   case X86II::MO_COFFSTUB:
16309467b48Spatrick     Name += ".refptr.";
16409467b48Spatrick     break;
16509467b48Spatrick   case X86II::MO_DARWIN_NONLAZY:
16609467b48Spatrick   case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
16709467b48Spatrick     Suffix = "$non_lazy_ptr";
16809467b48Spatrick     break;
16909467b48Spatrick   }
17009467b48Spatrick 
17109467b48Spatrick   if (!Suffix.empty())
17209467b48Spatrick     Name += DL.getPrivateGlobalPrefix();
17309467b48Spatrick 
17409467b48Spatrick   if (MO.isGlobal()) {
17509467b48Spatrick     const GlobalValue *GV = MO.getGlobal();
17609467b48Spatrick     AsmPrinter.getNameWithPrefix(Name, GV);
17709467b48Spatrick   } else if (MO.isSymbol()) {
17809467b48Spatrick     Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
17909467b48Spatrick   } else if (MO.isMBB()) {
18009467b48Spatrick     assert(Suffix.empty());
18109467b48Spatrick     Sym = MO.getMBB()->getSymbol();
18209467b48Spatrick   }
18309467b48Spatrick 
18409467b48Spatrick   Name += Suffix;
18509467b48Spatrick   if (!Sym)
18609467b48Spatrick     Sym = Ctx.getOrCreateSymbol(Name);
18709467b48Spatrick 
18809467b48Spatrick   // If the target flags on the operand changes the name of the symbol, do that
18909467b48Spatrick   // before we return the symbol.
19009467b48Spatrick   switch (MO.getTargetFlags()) {
19109467b48Spatrick   default:
19209467b48Spatrick     break;
19309467b48Spatrick   case X86II::MO_COFFSTUB: {
19409467b48Spatrick     MachineModuleInfoCOFF &MMICOFF =
19509467b48Spatrick         MF.getMMI().getObjFileInfo<MachineModuleInfoCOFF>();
19609467b48Spatrick     MachineModuleInfoImpl::StubValueTy &StubSym = MMICOFF.getGVStubEntry(Sym);
19709467b48Spatrick     if (!StubSym.getPointer()) {
19809467b48Spatrick       assert(MO.isGlobal() && "Extern symbol not handled yet");
19909467b48Spatrick       StubSym = MachineModuleInfoImpl::StubValueTy(
20009467b48Spatrick           AsmPrinter.getSymbol(MO.getGlobal()), true);
20109467b48Spatrick     }
20209467b48Spatrick     break;
20309467b48Spatrick   }
20409467b48Spatrick   case X86II::MO_DARWIN_NONLAZY:
20509467b48Spatrick   case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
20609467b48Spatrick     MachineModuleInfoImpl::StubValueTy &StubSym =
20709467b48Spatrick         getMachOMMI().getGVStubEntry(Sym);
20809467b48Spatrick     if (!StubSym.getPointer()) {
20909467b48Spatrick       assert(MO.isGlobal() && "Extern symbol not handled yet");
21009467b48Spatrick       StubSym = MachineModuleInfoImpl::StubValueTy(
21109467b48Spatrick           AsmPrinter.getSymbol(MO.getGlobal()),
21209467b48Spatrick           !MO.getGlobal()->hasInternalLinkage());
21309467b48Spatrick     }
21409467b48Spatrick     break;
21509467b48Spatrick   }
21609467b48Spatrick   }
21709467b48Spatrick 
21809467b48Spatrick   return Sym;
21909467b48Spatrick }
22009467b48Spatrick 
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const22109467b48Spatrick MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
22209467b48Spatrick                                              MCSymbol *Sym) const {
22309467b48Spatrick   // FIXME: We would like an efficient form for this, so we don't have to do a
22409467b48Spatrick   // lot of extra uniquing.
22509467b48Spatrick   const MCExpr *Expr = nullptr;
22609467b48Spatrick   MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
22709467b48Spatrick 
22809467b48Spatrick   switch (MO.getTargetFlags()) {
22909467b48Spatrick   default:
23009467b48Spatrick     llvm_unreachable("Unknown target flag on GV operand");
23109467b48Spatrick   case X86II::MO_NO_FLAG: // No flag.
23209467b48Spatrick   // These affect the name of the symbol, not any suffix.
23309467b48Spatrick   case X86II::MO_DARWIN_NONLAZY:
23409467b48Spatrick   case X86II::MO_DLLIMPORT:
23509467b48Spatrick   case X86II::MO_COFFSTUB:
23609467b48Spatrick     break;
23709467b48Spatrick 
23809467b48Spatrick   case X86II::MO_TLVP:
23909467b48Spatrick     RefKind = MCSymbolRefExpr::VK_TLVP;
24009467b48Spatrick     break;
24109467b48Spatrick   case X86II::MO_TLVP_PIC_BASE:
24209467b48Spatrick     Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
24309467b48Spatrick     // Subtract the pic base.
24409467b48Spatrick     Expr = MCBinaryExpr::createSub(
24509467b48Spatrick         Expr, MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx), Ctx);
24609467b48Spatrick     break;
24709467b48Spatrick   case X86II::MO_SECREL:
24809467b48Spatrick     RefKind = MCSymbolRefExpr::VK_SECREL;
24909467b48Spatrick     break;
25009467b48Spatrick   case X86II::MO_TLSGD:
25109467b48Spatrick     RefKind = MCSymbolRefExpr::VK_TLSGD;
25209467b48Spatrick     break;
25309467b48Spatrick   case X86II::MO_TLSLD:
25409467b48Spatrick     RefKind = MCSymbolRefExpr::VK_TLSLD;
25509467b48Spatrick     break;
25609467b48Spatrick   case X86II::MO_TLSLDM:
25709467b48Spatrick     RefKind = MCSymbolRefExpr::VK_TLSLDM;
25809467b48Spatrick     break;
25909467b48Spatrick   case X86II::MO_GOTTPOFF:
26009467b48Spatrick     RefKind = MCSymbolRefExpr::VK_GOTTPOFF;
26109467b48Spatrick     break;
26209467b48Spatrick   case X86II::MO_INDNTPOFF:
26309467b48Spatrick     RefKind = MCSymbolRefExpr::VK_INDNTPOFF;
26409467b48Spatrick     break;
26509467b48Spatrick   case X86II::MO_TPOFF:
26609467b48Spatrick     RefKind = MCSymbolRefExpr::VK_TPOFF;
26709467b48Spatrick     break;
26809467b48Spatrick   case X86II::MO_DTPOFF:
26909467b48Spatrick     RefKind = MCSymbolRefExpr::VK_DTPOFF;
27009467b48Spatrick     break;
27109467b48Spatrick   case X86II::MO_NTPOFF:
27209467b48Spatrick     RefKind = MCSymbolRefExpr::VK_NTPOFF;
27309467b48Spatrick     break;
27409467b48Spatrick   case X86II::MO_GOTNTPOFF:
27509467b48Spatrick     RefKind = MCSymbolRefExpr::VK_GOTNTPOFF;
27609467b48Spatrick     break;
27709467b48Spatrick   case X86II::MO_GOTPCREL:
27809467b48Spatrick     RefKind = MCSymbolRefExpr::VK_GOTPCREL;
27909467b48Spatrick     break;
280*a96b3639Srobert   case X86II::MO_GOTPCREL_NORELAX:
281*a96b3639Srobert     RefKind = MCSymbolRefExpr::VK_GOTPCREL_NORELAX;
282*a96b3639Srobert     break;
28309467b48Spatrick   case X86II::MO_GOT:
28409467b48Spatrick     RefKind = MCSymbolRefExpr::VK_GOT;
28509467b48Spatrick     break;
28609467b48Spatrick   case X86II::MO_GOTOFF:
28709467b48Spatrick     RefKind = MCSymbolRefExpr::VK_GOTOFF;
28809467b48Spatrick     break;
28909467b48Spatrick   case X86II::MO_PLT:
29009467b48Spatrick     RefKind = MCSymbolRefExpr::VK_PLT;
29109467b48Spatrick     break;
29209467b48Spatrick   case X86II::MO_ABS8:
29309467b48Spatrick     RefKind = MCSymbolRefExpr::VK_X86_ABS8;
29409467b48Spatrick     break;
29509467b48Spatrick   case X86II::MO_PIC_BASE_OFFSET:
29609467b48Spatrick   case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
29709467b48Spatrick     Expr = MCSymbolRefExpr::create(Sym, Ctx);
29809467b48Spatrick     // Subtract the pic base.
29909467b48Spatrick     Expr = MCBinaryExpr::createSub(
30009467b48Spatrick         Expr, MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx), Ctx);
30109467b48Spatrick     if (MO.isJTI()) {
30209467b48Spatrick       assert(MAI.doesSetDirectiveSuppressReloc());
30309467b48Spatrick       // If .set directive is supported, use it to reduce the number of
30409467b48Spatrick       // relocations the assembler will generate for differences between
30509467b48Spatrick       // local labels. This is only safe when the symbols are in the same
30609467b48Spatrick       // section so we are restricting it to jumptable references.
30709467b48Spatrick       MCSymbol *Label = Ctx.createTempSymbol();
308097a140dSpatrick       AsmPrinter.OutStreamer->emitAssignment(Label, Expr);
30909467b48Spatrick       Expr = MCSymbolRefExpr::create(Label, Ctx);
31009467b48Spatrick     }
31109467b48Spatrick     break;
31209467b48Spatrick   }
31309467b48Spatrick 
31409467b48Spatrick   if (!Expr)
31509467b48Spatrick     Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
31609467b48Spatrick 
31709467b48Spatrick   if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
31809467b48Spatrick     Expr = MCBinaryExpr::createAdd(
31909467b48Spatrick         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
32009467b48Spatrick   return MCOperand::createExpr(Expr);
32109467b48Spatrick }
32209467b48Spatrick 
32309467b48Spatrick /// Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
32409467b48Spatrick /// a short fixed-register form.
SimplifyShortImmForm(MCInst & Inst,unsigned Opcode)32509467b48Spatrick static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
32609467b48Spatrick   unsigned ImmOp = Inst.getNumOperands() - 1;
32709467b48Spatrick   assert(Inst.getOperand(0).isReg() &&
32809467b48Spatrick          (Inst.getOperand(ImmOp).isImm() || Inst.getOperand(ImmOp).isExpr()) &&
32909467b48Spatrick          ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() &&
33009467b48Spatrick            Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) ||
33109467b48Spatrick           Inst.getNumOperands() == 2) &&
33209467b48Spatrick          "Unexpected instruction!");
33309467b48Spatrick 
33409467b48Spatrick   // Check whether the destination register can be fixed.
33509467b48Spatrick   unsigned Reg = Inst.getOperand(0).getReg();
33609467b48Spatrick   if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
33709467b48Spatrick     return;
33809467b48Spatrick 
33909467b48Spatrick   // If so, rewrite the instruction.
34009467b48Spatrick   MCOperand Saved = Inst.getOperand(ImmOp);
34109467b48Spatrick   Inst = MCInst();
34209467b48Spatrick   Inst.setOpcode(Opcode);
34309467b48Spatrick   Inst.addOperand(Saved);
34409467b48Spatrick }
34509467b48Spatrick 
34609467b48Spatrick /// If a movsx instruction has a shorter encoding for the used register
34709467b48Spatrick /// simplify the instruction to use it instead.
SimplifyMOVSX(MCInst & Inst)34809467b48Spatrick static void SimplifyMOVSX(MCInst &Inst) {
34909467b48Spatrick   unsigned NewOpcode = 0;
35009467b48Spatrick   unsigned Op0 = Inst.getOperand(0).getReg(), Op1 = Inst.getOperand(1).getReg();
35109467b48Spatrick   switch (Inst.getOpcode()) {
35209467b48Spatrick   default:
35309467b48Spatrick     llvm_unreachable("Unexpected instruction!");
35409467b48Spatrick   case X86::MOVSX16rr8: // movsbw %al, %ax   --> cbtw
35509467b48Spatrick     if (Op0 == X86::AX && Op1 == X86::AL)
35609467b48Spatrick       NewOpcode = X86::CBW;
35709467b48Spatrick     break;
35809467b48Spatrick   case X86::MOVSX32rr16: // movswl %ax, %eax  --> cwtl
35909467b48Spatrick     if (Op0 == X86::EAX && Op1 == X86::AX)
36009467b48Spatrick       NewOpcode = X86::CWDE;
36109467b48Spatrick     break;
36209467b48Spatrick   case X86::MOVSX64rr32: // movslq %eax, %rax --> cltq
36309467b48Spatrick     if (Op0 == X86::RAX && Op1 == X86::EAX)
36409467b48Spatrick       NewOpcode = X86::CDQE;
36509467b48Spatrick     break;
36609467b48Spatrick   }
36709467b48Spatrick 
36809467b48Spatrick   if (NewOpcode != 0) {
36909467b48Spatrick     Inst = MCInst();
37009467b48Spatrick     Inst.setOpcode(NewOpcode);
37109467b48Spatrick   }
37209467b48Spatrick }
37309467b48Spatrick 
37409467b48Spatrick /// Simplify things like MOV32rm to MOV32o32a.
SimplifyShortMoveForm(X86AsmPrinter & Printer,MCInst & Inst,unsigned Opcode)37509467b48Spatrick static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst,
37609467b48Spatrick                                   unsigned Opcode) {
37709467b48Spatrick   // Don't make these simplifications in 64-bit mode; other assemblers don't
37809467b48Spatrick   // perform them because they make the code larger.
37909467b48Spatrick   if (Printer.getSubtarget().is64Bit())
38009467b48Spatrick     return;
38109467b48Spatrick 
38209467b48Spatrick   bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
38309467b48Spatrick   unsigned AddrBase = IsStore;
38409467b48Spatrick   unsigned RegOp = IsStore ? 0 : 5;
38509467b48Spatrick   unsigned AddrOp = AddrBase + 3;
38609467b48Spatrick   assert(
38709467b48Spatrick       Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
38809467b48Spatrick       Inst.getOperand(AddrBase + X86::AddrBaseReg).isReg() &&
38909467b48Spatrick       Inst.getOperand(AddrBase + X86::AddrScaleAmt).isImm() &&
39009467b48Spatrick       Inst.getOperand(AddrBase + X86::AddrIndexReg).isReg() &&
39109467b48Spatrick       Inst.getOperand(AddrBase + X86::AddrSegmentReg).isReg() &&
39209467b48Spatrick       (Inst.getOperand(AddrOp).isExpr() || Inst.getOperand(AddrOp).isImm()) &&
39309467b48Spatrick       "Unexpected instruction!");
39409467b48Spatrick 
39509467b48Spatrick   // Check whether the destination register can be fixed.
39609467b48Spatrick   unsigned Reg = Inst.getOperand(RegOp).getReg();
39709467b48Spatrick   if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
39809467b48Spatrick     return;
39909467b48Spatrick 
40009467b48Spatrick   // Check whether this is an absolute address.
40109467b48Spatrick   // FIXME: We know TLVP symbol refs aren't, but there should be a better way
40209467b48Spatrick   // to do this here.
40309467b48Spatrick   bool Absolute = true;
40409467b48Spatrick   if (Inst.getOperand(AddrOp).isExpr()) {
40509467b48Spatrick     const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
40609467b48Spatrick     if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE))
40709467b48Spatrick       if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
40809467b48Spatrick         Absolute = false;
40909467b48Spatrick   }
41009467b48Spatrick 
41109467b48Spatrick   if (Absolute &&
41209467b48Spatrick       (Inst.getOperand(AddrBase + X86::AddrBaseReg).getReg() != 0 ||
41309467b48Spatrick        Inst.getOperand(AddrBase + X86::AddrScaleAmt).getImm() != 1 ||
41409467b48Spatrick        Inst.getOperand(AddrBase + X86::AddrIndexReg).getReg() != 0))
41509467b48Spatrick     return;
41609467b48Spatrick 
41709467b48Spatrick   // If so, rewrite the instruction.
41809467b48Spatrick   MCOperand Saved = Inst.getOperand(AddrOp);
41909467b48Spatrick   MCOperand Seg = Inst.getOperand(AddrBase + X86::AddrSegmentReg);
42009467b48Spatrick   Inst = MCInst();
42109467b48Spatrick   Inst.setOpcode(Opcode);
42209467b48Spatrick   Inst.addOperand(Saved);
42309467b48Spatrick   Inst.addOperand(Seg);
42409467b48Spatrick }
42509467b48Spatrick 
getRetOpcode(const X86Subtarget & Subtarget)42609467b48Spatrick static unsigned getRetOpcode(const X86Subtarget &Subtarget) {
427*a96b3639Srobert   return Subtarget.is64Bit() ? X86::RET64 : X86::RET32;
42809467b48Spatrick }
42909467b48Spatrick 
430*a96b3639Srobert std::optional<MCOperand>
LowerMachineOperand(const MachineInstr * MI,const MachineOperand & MO) const43109467b48Spatrick X86MCInstLower::LowerMachineOperand(const MachineInstr *MI,
43209467b48Spatrick                                     const MachineOperand &MO) const {
43309467b48Spatrick   switch (MO.getType()) {
43409467b48Spatrick   default:
43509467b48Spatrick     MI->print(errs());
43609467b48Spatrick     llvm_unreachable("unknown operand type");
43709467b48Spatrick   case MachineOperand::MO_Register:
43809467b48Spatrick     // Ignore all implicit register operands.
43909467b48Spatrick     if (MO.isImplicit())
440*a96b3639Srobert       return std::nullopt;
44109467b48Spatrick     return MCOperand::createReg(MO.getReg());
44209467b48Spatrick   case MachineOperand::MO_Immediate:
44309467b48Spatrick     return MCOperand::createImm(MO.getImm());
44409467b48Spatrick   case MachineOperand::MO_MachineBasicBlock:
44509467b48Spatrick   case MachineOperand::MO_GlobalAddress:
44609467b48Spatrick   case MachineOperand::MO_ExternalSymbol:
44709467b48Spatrick     return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
44809467b48Spatrick   case MachineOperand::MO_MCSymbol:
44909467b48Spatrick     return LowerSymbolOperand(MO, MO.getMCSymbol());
45009467b48Spatrick   case MachineOperand::MO_JumpTableIndex:
45109467b48Spatrick     return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
45209467b48Spatrick   case MachineOperand::MO_ConstantPoolIndex:
45309467b48Spatrick     return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
45409467b48Spatrick   case MachineOperand::MO_BlockAddress:
45509467b48Spatrick     return LowerSymbolOperand(
45609467b48Spatrick         MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
45709467b48Spatrick   case MachineOperand::MO_RegisterMask:
45809467b48Spatrick     // Ignore call clobbers.
459*a96b3639Srobert     return std::nullopt;
46009467b48Spatrick   }
46109467b48Spatrick }
46209467b48Spatrick 
46309467b48Spatrick // Replace TAILJMP opcodes with their equivalent opcodes that have encoding
46409467b48Spatrick // information.
convertTailJumpOpcode(unsigned Opcode)46509467b48Spatrick static unsigned convertTailJumpOpcode(unsigned Opcode) {
46609467b48Spatrick   switch (Opcode) {
46709467b48Spatrick   case X86::TAILJMPr:
46809467b48Spatrick     Opcode = X86::JMP32r;
46909467b48Spatrick     break;
47009467b48Spatrick   case X86::TAILJMPm:
47109467b48Spatrick     Opcode = X86::JMP32m;
47209467b48Spatrick     break;
47309467b48Spatrick   case X86::TAILJMPr64:
47409467b48Spatrick     Opcode = X86::JMP64r;
47509467b48Spatrick     break;
47609467b48Spatrick   case X86::TAILJMPm64:
47709467b48Spatrick     Opcode = X86::JMP64m;
47809467b48Spatrick     break;
47909467b48Spatrick   case X86::TAILJMPr64_REX:
48009467b48Spatrick     Opcode = X86::JMP64r_REX;
48109467b48Spatrick     break;
48209467b48Spatrick   case X86::TAILJMPm64_REX:
48309467b48Spatrick     Opcode = X86::JMP64m_REX;
48409467b48Spatrick     break;
48509467b48Spatrick   case X86::TAILJMPd:
48609467b48Spatrick   case X86::TAILJMPd64:
48709467b48Spatrick     Opcode = X86::JMP_1;
48809467b48Spatrick     break;
48909467b48Spatrick   case X86::TAILJMPd_CC:
49009467b48Spatrick   case X86::TAILJMPd64_CC:
49109467b48Spatrick     Opcode = X86::JCC_1;
49209467b48Spatrick     break;
49309467b48Spatrick   }
49409467b48Spatrick 
49509467b48Spatrick   return Opcode;
49609467b48Spatrick }
49709467b48Spatrick 
Lower(const MachineInstr * MI,MCInst & OutMI) const49809467b48Spatrick void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
49909467b48Spatrick   OutMI.setOpcode(MI->getOpcode());
50009467b48Spatrick 
50109467b48Spatrick   for (const MachineOperand &MO : MI->operands())
50209467b48Spatrick     if (auto MaybeMCOp = LowerMachineOperand(MI, MO))
503*a96b3639Srobert       OutMI.addOperand(*MaybeMCOp);
50409467b48Spatrick 
50509467b48Spatrick   // Handle a few special cases to eliminate operand modifiers.
50609467b48Spatrick   switch (OutMI.getOpcode()) {
50709467b48Spatrick   case X86::LEA64_32r:
50809467b48Spatrick   case X86::LEA64r:
50909467b48Spatrick   case X86::LEA16r:
51009467b48Spatrick   case X86::LEA32r:
51109467b48Spatrick     // LEA should have a segment register, but it must be empty.
51209467b48Spatrick     assert(OutMI.getNumOperands() == 1 + X86::AddrNumOperands &&
51309467b48Spatrick            "Unexpected # of LEA operands");
51409467b48Spatrick     assert(OutMI.getOperand(1 + X86::AddrSegmentReg).getReg() == 0 &&
51509467b48Spatrick            "LEA has segment specified!");
51609467b48Spatrick     break;
51709467b48Spatrick 
518097a140dSpatrick   case X86::MULX32Hrr:
519097a140dSpatrick   case X86::MULX32Hrm:
520097a140dSpatrick   case X86::MULX64Hrr:
521097a140dSpatrick   case X86::MULX64Hrm: {
522097a140dSpatrick     // Turn into regular MULX by duplicating the destination.
523097a140dSpatrick     unsigned NewOpc;
524097a140dSpatrick     switch (OutMI.getOpcode()) {
525097a140dSpatrick     default: llvm_unreachable("Invalid opcode");
526097a140dSpatrick     case X86::MULX32Hrr: NewOpc = X86::MULX32rr; break;
527097a140dSpatrick     case X86::MULX32Hrm: NewOpc = X86::MULX32rm; break;
528097a140dSpatrick     case X86::MULX64Hrr: NewOpc = X86::MULX64rr; break;
529097a140dSpatrick     case X86::MULX64Hrm: NewOpc = X86::MULX64rm; break;
530097a140dSpatrick     }
531097a140dSpatrick     OutMI.setOpcode(NewOpc);
532097a140dSpatrick     // Duplicate the destination.
533097a140dSpatrick     unsigned DestReg = OutMI.getOperand(0).getReg();
534097a140dSpatrick     OutMI.insert(OutMI.begin(), MCOperand::createReg(DestReg));
535097a140dSpatrick     break;
536097a140dSpatrick   }
537097a140dSpatrick 
53809467b48Spatrick   // Commute operands to get a smaller encoding by using VEX.R instead of VEX.B
53909467b48Spatrick   // if one of the registers is extended, but other isn't.
54009467b48Spatrick   case X86::VMOVZPQILo2PQIrr:
54109467b48Spatrick   case X86::VMOVAPDrr:
54209467b48Spatrick   case X86::VMOVAPDYrr:
54309467b48Spatrick   case X86::VMOVAPSrr:
54409467b48Spatrick   case X86::VMOVAPSYrr:
54509467b48Spatrick   case X86::VMOVDQArr:
54609467b48Spatrick   case X86::VMOVDQAYrr:
54709467b48Spatrick   case X86::VMOVDQUrr:
54809467b48Spatrick   case X86::VMOVDQUYrr:
54909467b48Spatrick   case X86::VMOVUPDrr:
55009467b48Spatrick   case X86::VMOVUPDYrr:
55109467b48Spatrick   case X86::VMOVUPSrr:
55209467b48Spatrick   case X86::VMOVUPSYrr: {
55309467b48Spatrick     if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) &&
55409467b48Spatrick         X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg())) {
55509467b48Spatrick       unsigned NewOpc;
55609467b48Spatrick       switch (OutMI.getOpcode()) {
55709467b48Spatrick       default: llvm_unreachable("Invalid opcode");
55809467b48Spatrick       case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr;   break;
55909467b48Spatrick       case X86::VMOVAPDrr:        NewOpc = X86::VMOVAPDrr_REV;  break;
56009467b48Spatrick       case X86::VMOVAPDYrr:       NewOpc = X86::VMOVAPDYrr_REV; break;
56109467b48Spatrick       case X86::VMOVAPSrr:        NewOpc = X86::VMOVAPSrr_REV;  break;
56209467b48Spatrick       case X86::VMOVAPSYrr:       NewOpc = X86::VMOVAPSYrr_REV; break;
56309467b48Spatrick       case X86::VMOVDQArr:        NewOpc = X86::VMOVDQArr_REV;  break;
56409467b48Spatrick       case X86::VMOVDQAYrr:       NewOpc = X86::VMOVDQAYrr_REV; break;
56509467b48Spatrick       case X86::VMOVDQUrr:        NewOpc = X86::VMOVDQUrr_REV;  break;
56609467b48Spatrick       case X86::VMOVDQUYrr:       NewOpc = X86::VMOVDQUYrr_REV; break;
56709467b48Spatrick       case X86::VMOVUPDrr:        NewOpc = X86::VMOVUPDrr_REV;  break;
56809467b48Spatrick       case X86::VMOVUPDYrr:       NewOpc = X86::VMOVUPDYrr_REV; break;
56909467b48Spatrick       case X86::VMOVUPSrr:        NewOpc = X86::VMOVUPSrr_REV;  break;
57009467b48Spatrick       case X86::VMOVUPSYrr:       NewOpc = X86::VMOVUPSYrr_REV; break;
57109467b48Spatrick       }
57209467b48Spatrick       OutMI.setOpcode(NewOpc);
57309467b48Spatrick     }
57409467b48Spatrick     break;
57509467b48Spatrick   }
57609467b48Spatrick   case X86::VMOVSDrr:
57709467b48Spatrick   case X86::VMOVSSrr: {
57809467b48Spatrick     if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) &&
57909467b48Spatrick         X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) {
58009467b48Spatrick       unsigned NewOpc;
58109467b48Spatrick       switch (OutMI.getOpcode()) {
58209467b48Spatrick       default: llvm_unreachable("Invalid opcode");
58309467b48Spatrick       case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
58409467b48Spatrick       case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
58509467b48Spatrick       }
58609467b48Spatrick       OutMI.setOpcode(NewOpc);
58709467b48Spatrick     }
58809467b48Spatrick     break;
58909467b48Spatrick   }
59009467b48Spatrick 
59109467b48Spatrick   case X86::VPCMPBZ128rmi:  case X86::VPCMPBZ128rmik:
59209467b48Spatrick   case X86::VPCMPBZ128rri:  case X86::VPCMPBZ128rrik:
59309467b48Spatrick   case X86::VPCMPBZ256rmi:  case X86::VPCMPBZ256rmik:
59409467b48Spatrick   case X86::VPCMPBZ256rri:  case X86::VPCMPBZ256rrik:
59509467b48Spatrick   case X86::VPCMPBZrmi:     case X86::VPCMPBZrmik:
59609467b48Spatrick   case X86::VPCMPBZrri:     case X86::VPCMPBZrrik:
59709467b48Spatrick   case X86::VPCMPDZ128rmi:  case X86::VPCMPDZ128rmik:
59809467b48Spatrick   case X86::VPCMPDZ128rmib: case X86::VPCMPDZ128rmibk:
59909467b48Spatrick   case X86::VPCMPDZ128rri:  case X86::VPCMPDZ128rrik:
60009467b48Spatrick   case X86::VPCMPDZ256rmi:  case X86::VPCMPDZ256rmik:
60109467b48Spatrick   case X86::VPCMPDZ256rmib: case X86::VPCMPDZ256rmibk:
60209467b48Spatrick   case X86::VPCMPDZ256rri:  case X86::VPCMPDZ256rrik:
60309467b48Spatrick   case X86::VPCMPDZrmi:     case X86::VPCMPDZrmik:
60409467b48Spatrick   case X86::VPCMPDZrmib:    case X86::VPCMPDZrmibk:
60509467b48Spatrick   case X86::VPCMPDZrri:     case X86::VPCMPDZrrik:
60609467b48Spatrick   case X86::VPCMPQZ128rmi:  case X86::VPCMPQZ128rmik:
60709467b48Spatrick   case X86::VPCMPQZ128rmib: case X86::VPCMPQZ128rmibk:
60809467b48Spatrick   case X86::VPCMPQZ128rri:  case X86::VPCMPQZ128rrik:
60909467b48Spatrick   case X86::VPCMPQZ256rmi:  case X86::VPCMPQZ256rmik:
61009467b48Spatrick   case X86::VPCMPQZ256rmib: case X86::VPCMPQZ256rmibk:
61109467b48Spatrick   case X86::VPCMPQZ256rri:  case X86::VPCMPQZ256rrik:
61209467b48Spatrick   case X86::VPCMPQZrmi:     case X86::VPCMPQZrmik:
61309467b48Spatrick   case X86::VPCMPQZrmib:    case X86::VPCMPQZrmibk:
61409467b48Spatrick   case X86::VPCMPQZrri:     case X86::VPCMPQZrrik:
61509467b48Spatrick   case X86::VPCMPWZ128rmi:  case X86::VPCMPWZ128rmik:
61609467b48Spatrick   case X86::VPCMPWZ128rri:  case X86::VPCMPWZ128rrik:
61709467b48Spatrick   case X86::VPCMPWZ256rmi:  case X86::VPCMPWZ256rmik:
61809467b48Spatrick   case X86::VPCMPWZ256rri:  case X86::VPCMPWZ256rrik:
61909467b48Spatrick   case X86::VPCMPWZrmi:     case X86::VPCMPWZrmik:
62009467b48Spatrick   case X86::VPCMPWZrri:     case X86::VPCMPWZrrik: {
62109467b48Spatrick     // Turn immediate 0 into the VPCMPEQ instruction.
62209467b48Spatrick     if (OutMI.getOperand(OutMI.getNumOperands() - 1).getImm() == 0) {
62309467b48Spatrick       unsigned NewOpc;
62409467b48Spatrick       switch (OutMI.getOpcode()) {
62509467b48Spatrick       default: llvm_unreachable("Invalid opcode");
62609467b48Spatrick       case X86::VPCMPBZ128rmi:   NewOpc = X86::VPCMPEQBZ128rm;   break;
62709467b48Spatrick       case X86::VPCMPBZ128rmik:  NewOpc = X86::VPCMPEQBZ128rmk;  break;
62809467b48Spatrick       case X86::VPCMPBZ128rri:   NewOpc = X86::VPCMPEQBZ128rr;   break;
62909467b48Spatrick       case X86::VPCMPBZ128rrik:  NewOpc = X86::VPCMPEQBZ128rrk;  break;
63009467b48Spatrick       case X86::VPCMPBZ256rmi:   NewOpc = X86::VPCMPEQBZ256rm;   break;
63109467b48Spatrick       case X86::VPCMPBZ256rmik:  NewOpc = X86::VPCMPEQBZ256rmk;  break;
63209467b48Spatrick       case X86::VPCMPBZ256rri:   NewOpc = X86::VPCMPEQBZ256rr;   break;
63309467b48Spatrick       case X86::VPCMPBZ256rrik:  NewOpc = X86::VPCMPEQBZ256rrk;  break;
63409467b48Spatrick       case X86::VPCMPBZrmi:      NewOpc = X86::VPCMPEQBZrm;      break;
63509467b48Spatrick       case X86::VPCMPBZrmik:     NewOpc = X86::VPCMPEQBZrmk;     break;
63609467b48Spatrick       case X86::VPCMPBZrri:      NewOpc = X86::VPCMPEQBZrr;      break;
63709467b48Spatrick       case X86::VPCMPBZrrik:     NewOpc = X86::VPCMPEQBZrrk;     break;
63809467b48Spatrick       case X86::VPCMPDZ128rmi:   NewOpc = X86::VPCMPEQDZ128rm;   break;
63909467b48Spatrick       case X86::VPCMPDZ128rmib:  NewOpc = X86::VPCMPEQDZ128rmb;  break;
64009467b48Spatrick       case X86::VPCMPDZ128rmibk: NewOpc = X86::VPCMPEQDZ128rmbk; break;
64109467b48Spatrick       case X86::VPCMPDZ128rmik:  NewOpc = X86::VPCMPEQDZ128rmk;  break;
64209467b48Spatrick       case X86::VPCMPDZ128rri:   NewOpc = X86::VPCMPEQDZ128rr;   break;
64309467b48Spatrick       case X86::VPCMPDZ128rrik:  NewOpc = X86::VPCMPEQDZ128rrk;  break;
64409467b48Spatrick       case X86::VPCMPDZ256rmi:   NewOpc = X86::VPCMPEQDZ256rm;   break;
64509467b48Spatrick       case X86::VPCMPDZ256rmib:  NewOpc = X86::VPCMPEQDZ256rmb;  break;
64609467b48Spatrick       case X86::VPCMPDZ256rmibk: NewOpc = X86::VPCMPEQDZ256rmbk; break;
64709467b48Spatrick       case X86::VPCMPDZ256rmik:  NewOpc = X86::VPCMPEQDZ256rmk;  break;
64809467b48Spatrick       case X86::VPCMPDZ256rri:   NewOpc = X86::VPCMPEQDZ256rr;   break;
64909467b48Spatrick       case X86::VPCMPDZ256rrik:  NewOpc = X86::VPCMPEQDZ256rrk;  break;
65009467b48Spatrick       case X86::VPCMPDZrmi:      NewOpc = X86::VPCMPEQDZrm;      break;
65109467b48Spatrick       case X86::VPCMPDZrmib:     NewOpc = X86::VPCMPEQDZrmb;     break;
65209467b48Spatrick       case X86::VPCMPDZrmibk:    NewOpc = X86::VPCMPEQDZrmbk;    break;
65309467b48Spatrick       case X86::VPCMPDZrmik:     NewOpc = X86::VPCMPEQDZrmk;     break;
65409467b48Spatrick       case X86::VPCMPDZrri:      NewOpc = X86::VPCMPEQDZrr;      break;
65509467b48Spatrick       case X86::VPCMPDZrrik:     NewOpc = X86::VPCMPEQDZrrk;     break;
65609467b48Spatrick       case X86::VPCMPQZ128rmi:   NewOpc = X86::VPCMPEQQZ128rm;   break;
65709467b48Spatrick       case X86::VPCMPQZ128rmib:  NewOpc = X86::VPCMPEQQZ128rmb;  break;
65809467b48Spatrick       case X86::VPCMPQZ128rmibk: NewOpc = X86::VPCMPEQQZ128rmbk; break;
65909467b48Spatrick       case X86::VPCMPQZ128rmik:  NewOpc = X86::VPCMPEQQZ128rmk;  break;
66009467b48Spatrick       case X86::VPCMPQZ128rri:   NewOpc = X86::VPCMPEQQZ128rr;   break;
66109467b48Spatrick       case X86::VPCMPQZ128rrik:  NewOpc = X86::VPCMPEQQZ128rrk;  break;
66209467b48Spatrick       case X86::VPCMPQZ256rmi:   NewOpc = X86::VPCMPEQQZ256rm;   break;
66309467b48Spatrick       case X86::VPCMPQZ256rmib:  NewOpc = X86::VPCMPEQQZ256rmb;  break;
66409467b48Spatrick       case X86::VPCMPQZ256rmibk: NewOpc = X86::VPCMPEQQZ256rmbk; break;
66509467b48Spatrick       case X86::VPCMPQZ256rmik:  NewOpc = X86::VPCMPEQQZ256rmk;  break;
66609467b48Spatrick       case X86::VPCMPQZ256rri:   NewOpc = X86::VPCMPEQQZ256rr;   break;
66709467b48Spatrick       case X86::VPCMPQZ256rrik:  NewOpc = X86::VPCMPEQQZ256rrk;  break;
66809467b48Spatrick       case X86::VPCMPQZrmi:      NewOpc = X86::VPCMPEQQZrm;      break;
66909467b48Spatrick       case X86::VPCMPQZrmib:     NewOpc = X86::VPCMPEQQZrmb;     break;
67009467b48Spatrick       case X86::VPCMPQZrmibk:    NewOpc = X86::VPCMPEQQZrmbk;    break;
67109467b48Spatrick       case X86::VPCMPQZrmik:     NewOpc = X86::VPCMPEQQZrmk;     break;
67209467b48Spatrick       case X86::VPCMPQZrri:      NewOpc = X86::VPCMPEQQZrr;      break;
67309467b48Spatrick       case X86::VPCMPQZrrik:     NewOpc = X86::VPCMPEQQZrrk;     break;
67409467b48Spatrick       case X86::VPCMPWZ128rmi:   NewOpc = X86::VPCMPEQWZ128rm;   break;
67509467b48Spatrick       case X86::VPCMPWZ128rmik:  NewOpc = X86::VPCMPEQWZ128rmk;  break;
67609467b48Spatrick       case X86::VPCMPWZ128rri:   NewOpc = X86::VPCMPEQWZ128rr;   break;
67709467b48Spatrick       case X86::VPCMPWZ128rrik:  NewOpc = X86::VPCMPEQWZ128rrk;  break;
67809467b48Spatrick       case X86::VPCMPWZ256rmi:   NewOpc = X86::VPCMPEQWZ256rm;   break;
67909467b48Spatrick       case X86::VPCMPWZ256rmik:  NewOpc = X86::VPCMPEQWZ256rmk;  break;
68009467b48Spatrick       case X86::VPCMPWZ256rri:   NewOpc = X86::VPCMPEQWZ256rr;   break;
68109467b48Spatrick       case X86::VPCMPWZ256rrik:  NewOpc = X86::VPCMPEQWZ256rrk;  break;
68209467b48Spatrick       case X86::VPCMPWZrmi:      NewOpc = X86::VPCMPEQWZrm;      break;
68309467b48Spatrick       case X86::VPCMPWZrmik:     NewOpc = X86::VPCMPEQWZrmk;     break;
68409467b48Spatrick       case X86::VPCMPWZrri:      NewOpc = X86::VPCMPEQWZrr;      break;
68509467b48Spatrick       case X86::VPCMPWZrrik:     NewOpc = X86::VPCMPEQWZrrk;     break;
68609467b48Spatrick       }
68709467b48Spatrick 
68809467b48Spatrick       OutMI.setOpcode(NewOpc);
68909467b48Spatrick       OutMI.erase(&OutMI.getOperand(OutMI.getNumOperands() - 1));
69009467b48Spatrick       break;
69109467b48Spatrick     }
69209467b48Spatrick 
69309467b48Spatrick     // Turn immediate 6 into the VPCMPGT instruction.
69409467b48Spatrick     if (OutMI.getOperand(OutMI.getNumOperands() - 1).getImm() == 6) {
69509467b48Spatrick       unsigned NewOpc;
69609467b48Spatrick       switch (OutMI.getOpcode()) {
69709467b48Spatrick       default: llvm_unreachable("Invalid opcode");
69809467b48Spatrick       case X86::VPCMPBZ128rmi:   NewOpc = X86::VPCMPGTBZ128rm;   break;
69909467b48Spatrick       case X86::VPCMPBZ128rmik:  NewOpc = X86::VPCMPGTBZ128rmk;  break;
70009467b48Spatrick       case X86::VPCMPBZ128rri:   NewOpc = X86::VPCMPGTBZ128rr;   break;
70109467b48Spatrick       case X86::VPCMPBZ128rrik:  NewOpc = X86::VPCMPGTBZ128rrk;  break;
70209467b48Spatrick       case X86::VPCMPBZ256rmi:   NewOpc = X86::VPCMPGTBZ256rm;   break;
70309467b48Spatrick       case X86::VPCMPBZ256rmik:  NewOpc = X86::VPCMPGTBZ256rmk;  break;
70409467b48Spatrick       case X86::VPCMPBZ256rri:   NewOpc = X86::VPCMPGTBZ256rr;   break;
70509467b48Spatrick       case X86::VPCMPBZ256rrik:  NewOpc = X86::VPCMPGTBZ256rrk;  break;
70609467b48Spatrick       case X86::VPCMPBZrmi:      NewOpc = X86::VPCMPGTBZrm;      break;
70709467b48Spatrick       case X86::VPCMPBZrmik:     NewOpc = X86::VPCMPGTBZrmk;     break;
70809467b48Spatrick       case X86::VPCMPBZrri:      NewOpc = X86::VPCMPGTBZrr;      break;
70909467b48Spatrick       case X86::VPCMPBZrrik:     NewOpc = X86::VPCMPGTBZrrk;     break;
71009467b48Spatrick       case X86::VPCMPDZ128rmi:   NewOpc = X86::VPCMPGTDZ128rm;   break;
71109467b48Spatrick       case X86::VPCMPDZ128rmib:  NewOpc = X86::VPCMPGTDZ128rmb;  break;
71209467b48Spatrick       case X86::VPCMPDZ128rmibk: NewOpc = X86::VPCMPGTDZ128rmbk; break;
71309467b48Spatrick       case X86::VPCMPDZ128rmik:  NewOpc = X86::VPCMPGTDZ128rmk;  break;
71409467b48Spatrick       case X86::VPCMPDZ128rri:   NewOpc = X86::VPCMPGTDZ128rr;   break;
71509467b48Spatrick       case X86::VPCMPDZ128rrik:  NewOpc = X86::VPCMPGTDZ128rrk;  break;
71609467b48Spatrick       case X86::VPCMPDZ256rmi:   NewOpc = X86::VPCMPGTDZ256rm;   break;
71709467b48Spatrick       case X86::VPCMPDZ256rmib:  NewOpc = X86::VPCMPGTDZ256rmb;  break;
71809467b48Spatrick       case X86::VPCMPDZ256rmibk: NewOpc = X86::VPCMPGTDZ256rmbk; break;
71909467b48Spatrick       case X86::VPCMPDZ256rmik:  NewOpc = X86::VPCMPGTDZ256rmk;  break;
72009467b48Spatrick       case X86::VPCMPDZ256rri:   NewOpc = X86::VPCMPGTDZ256rr;   break;
72109467b48Spatrick       case X86::VPCMPDZ256rrik:  NewOpc = X86::VPCMPGTDZ256rrk;  break;
72209467b48Spatrick       case X86::VPCMPDZrmi:      NewOpc = X86::VPCMPGTDZrm;      break;
72309467b48Spatrick       case X86::VPCMPDZrmib:     NewOpc = X86::VPCMPGTDZrmb;     break;
72409467b48Spatrick       case X86::VPCMPDZrmibk:    NewOpc = X86::VPCMPGTDZrmbk;    break;
72509467b48Spatrick       case X86::VPCMPDZrmik:     NewOpc = X86::VPCMPGTDZrmk;     break;
72609467b48Spatrick       case X86::VPCMPDZrri:      NewOpc = X86::VPCMPGTDZrr;      break;
72709467b48Spatrick       case X86::VPCMPDZrrik:     NewOpc = X86::VPCMPGTDZrrk;     break;
72809467b48Spatrick       case X86::VPCMPQZ128rmi:   NewOpc = X86::VPCMPGTQZ128rm;   break;
72909467b48Spatrick       case X86::VPCMPQZ128rmib:  NewOpc = X86::VPCMPGTQZ128rmb;  break;
73009467b48Spatrick       case X86::VPCMPQZ128rmibk: NewOpc = X86::VPCMPGTQZ128rmbk; break;
73109467b48Spatrick       case X86::VPCMPQZ128rmik:  NewOpc = X86::VPCMPGTQZ128rmk;  break;
73209467b48Spatrick       case X86::VPCMPQZ128rri:   NewOpc = X86::VPCMPGTQZ128rr;   break;
73309467b48Spatrick       case X86::VPCMPQZ128rrik:  NewOpc = X86::VPCMPGTQZ128rrk;  break;
73409467b48Spatrick       case X86::VPCMPQZ256rmi:   NewOpc = X86::VPCMPGTQZ256rm;   break;
73509467b48Spatrick       case X86::VPCMPQZ256rmib:  NewOpc = X86::VPCMPGTQZ256rmb;  break;
73609467b48Spatrick       case X86::VPCMPQZ256rmibk: NewOpc = X86::VPCMPGTQZ256rmbk; break;
73709467b48Spatrick       case X86::VPCMPQZ256rmik:  NewOpc = X86::VPCMPGTQZ256rmk;  break;
73809467b48Spatrick       case X86::VPCMPQZ256rri:   NewOpc = X86::VPCMPGTQZ256rr;   break;
73909467b48Spatrick       case X86::VPCMPQZ256rrik:  NewOpc = X86::VPCMPGTQZ256rrk;  break;
74009467b48Spatrick       case X86::VPCMPQZrmi:      NewOpc = X86::VPCMPGTQZrm;      break;
74109467b48Spatrick       case X86::VPCMPQZrmib:     NewOpc = X86::VPCMPGTQZrmb;     break;
74209467b48Spatrick       case X86::VPCMPQZrmibk:    NewOpc = X86::VPCMPGTQZrmbk;    break;
74309467b48Spatrick       case X86::VPCMPQZrmik:     NewOpc = X86::VPCMPGTQZrmk;     break;
74409467b48Spatrick       case X86::VPCMPQZrri:      NewOpc = X86::VPCMPGTQZrr;      break;
74509467b48Spatrick       case X86::VPCMPQZrrik:     NewOpc = X86::VPCMPGTQZrrk;     break;
74609467b48Spatrick       case X86::VPCMPWZ128rmi:   NewOpc = X86::VPCMPGTWZ128rm;   break;
74709467b48Spatrick       case X86::VPCMPWZ128rmik:  NewOpc = X86::VPCMPGTWZ128rmk;  break;
74809467b48Spatrick       case X86::VPCMPWZ128rri:   NewOpc = X86::VPCMPGTWZ128rr;   break;
74909467b48Spatrick       case X86::VPCMPWZ128rrik:  NewOpc = X86::VPCMPGTWZ128rrk;  break;
75009467b48Spatrick       case X86::VPCMPWZ256rmi:   NewOpc = X86::VPCMPGTWZ256rm;   break;
75109467b48Spatrick       case X86::VPCMPWZ256rmik:  NewOpc = X86::VPCMPGTWZ256rmk;  break;
75209467b48Spatrick       case X86::VPCMPWZ256rri:   NewOpc = X86::VPCMPGTWZ256rr;   break;
75309467b48Spatrick       case X86::VPCMPWZ256rrik:  NewOpc = X86::VPCMPGTWZ256rrk;  break;
75409467b48Spatrick       case X86::VPCMPWZrmi:      NewOpc = X86::VPCMPGTWZrm;      break;
75509467b48Spatrick       case X86::VPCMPWZrmik:     NewOpc = X86::VPCMPGTWZrmk;     break;
75609467b48Spatrick       case X86::VPCMPWZrri:      NewOpc = X86::VPCMPGTWZrr;      break;
75709467b48Spatrick       case X86::VPCMPWZrrik:     NewOpc = X86::VPCMPGTWZrrk;     break;
75809467b48Spatrick       }
75909467b48Spatrick 
76009467b48Spatrick       OutMI.setOpcode(NewOpc);
76109467b48Spatrick       OutMI.erase(&OutMI.getOperand(OutMI.getNumOperands() - 1));
76209467b48Spatrick       break;
76309467b48Spatrick     }
76409467b48Spatrick 
76509467b48Spatrick     break;
76609467b48Spatrick   }
76709467b48Spatrick 
76809467b48Spatrick   // CALL64r, CALL64pcrel32 - These instructions used to have
76909467b48Spatrick   // register inputs modeled as normal uses instead of implicit uses.  As such,
77009467b48Spatrick   // they we used to truncate off all but the first operand (the callee). This
77109467b48Spatrick   // issue seems to have been fixed at some point. This assert verifies that.
77209467b48Spatrick   case X86::CALL64r:
77309467b48Spatrick   case X86::CALL64pcrel32:
77409467b48Spatrick     assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
77509467b48Spatrick     break;
77609467b48Spatrick 
77709467b48Spatrick   case X86::EH_RETURN:
77809467b48Spatrick   case X86::EH_RETURN64: {
77909467b48Spatrick     OutMI = MCInst();
78009467b48Spatrick     OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
78109467b48Spatrick     break;
78209467b48Spatrick   }
78309467b48Spatrick 
78409467b48Spatrick   case X86::CLEANUPRET: {
78509467b48Spatrick     // Replace CLEANUPRET with the appropriate RET.
78609467b48Spatrick     OutMI = MCInst();
78709467b48Spatrick     OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
78809467b48Spatrick     break;
78909467b48Spatrick   }
79009467b48Spatrick 
79109467b48Spatrick   case X86::CATCHRET: {
79209467b48Spatrick     // Replace CATCHRET with the appropriate RET.
79309467b48Spatrick     const X86Subtarget &Subtarget = AsmPrinter.getSubtarget();
79409467b48Spatrick     unsigned ReturnReg = Subtarget.is64Bit() ? X86::RAX : X86::EAX;
79509467b48Spatrick     OutMI = MCInst();
79609467b48Spatrick     OutMI.setOpcode(getRetOpcode(Subtarget));
79709467b48Spatrick     OutMI.addOperand(MCOperand::createReg(ReturnReg));
79809467b48Spatrick     break;
79909467b48Spatrick   }
80009467b48Spatrick 
80109467b48Spatrick   // TAILJMPd, TAILJMPd64, TailJMPd_cc - Lower to the correct jump
80209467b48Spatrick   // instruction.
80309467b48Spatrick   case X86::TAILJMPr:
80409467b48Spatrick   case X86::TAILJMPr64:
80509467b48Spatrick   case X86::TAILJMPr64_REX:
80609467b48Spatrick   case X86::TAILJMPd:
80709467b48Spatrick   case X86::TAILJMPd64:
80809467b48Spatrick     assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
80909467b48Spatrick     OutMI.setOpcode(convertTailJumpOpcode(OutMI.getOpcode()));
81009467b48Spatrick     break;
81109467b48Spatrick 
81209467b48Spatrick   case X86::TAILJMPd_CC:
81309467b48Spatrick   case X86::TAILJMPd64_CC:
81409467b48Spatrick     assert(OutMI.getNumOperands() == 2 && "Unexpected number of operands!");
81509467b48Spatrick     OutMI.setOpcode(convertTailJumpOpcode(OutMI.getOpcode()));
81609467b48Spatrick     break;
81709467b48Spatrick 
81809467b48Spatrick   case X86::TAILJMPm:
81909467b48Spatrick   case X86::TAILJMPm64:
82009467b48Spatrick   case X86::TAILJMPm64_REX:
82109467b48Spatrick     assert(OutMI.getNumOperands() == X86::AddrNumOperands &&
82209467b48Spatrick            "Unexpected number of operands!");
82309467b48Spatrick     OutMI.setOpcode(convertTailJumpOpcode(OutMI.getOpcode()));
82409467b48Spatrick     break;
82509467b48Spatrick 
82609467b48Spatrick   case X86::DEC16r:
82709467b48Spatrick   case X86::DEC32r:
82809467b48Spatrick   case X86::INC16r:
82909467b48Spatrick   case X86::INC32r:
83009467b48Spatrick     // If we aren't in 64-bit mode we can use the 1-byte inc/dec instructions.
83109467b48Spatrick     if (!AsmPrinter.getSubtarget().is64Bit()) {
83209467b48Spatrick       unsigned Opcode;
83309467b48Spatrick       switch (OutMI.getOpcode()) {
83409467b48Spatrick       default: llvm_unreachable("Invalid opcode");
83509467b48Spatrick       case X86::DEC16r: Opcode = X86::DEC16r_alt; break;
83609467b48Spatrick       case X86::DEC32r: Opcode = X86::DEC32r_alt; break;
83709467b48Spatrick       case X86::INC16r: Opcode = X86::INC16r_alt; break;
83809467b48Spatrick       case X86::INC32r: Opcode = X86::INC32r_alt; break;
83909467b48Spatrick       }
84009467b48Spatrick       OutMI.setOpcode(Opcode);
84109467b48Spatrick     }
84209467b48Spatrick     break;
84309467b48Spatrick 
84409467b48Spatrick   // We don't currently select the correct instruction form for instructions
84509467b48Spatrick   // which have a short %eax, etc. form. Handle this by custom lowering, for
84609467b48Spatrick   // now.
84709467b48Spatrick   //
84809467b48Spatrick   // Note, we are currently not handling the following instructions:
84909467b48Spatrick   // MOV64ao8, MOV64o8a
85009467b48Spatrick   // XCHG16ar, XCHG32ar, XCHG64ar
85109467b48Spatrick   case X86::MOV8mr_NOREX:
85209467b48Spatrick   case X86::MOV8mr:
85309467b48Spatrick   case X86::MOV8rm_NOREX:
85409467b48Spatrick   case X86::MOV8rm:
85509467b48Spatrick   case X86::MOV16mr:
85609467b48Spatrick   case X86::MOV16rm:
85709467b48Spatrick   case X86::MOV32mr:
85809467b48Spatrick   case X86::MOV32rm: {
85909467b48Spatrick     unsigned NewOpc;
86009467b48Spatrick     switch (OutMI.getOpcode()) {
86109467b48Spatrick     default: llvm_unreachable("Invalid opcode");
86209467b48Spatrick     case X86::MOV8mr_NOREX:
86309467b48Spatrick     case X86::MOV8mr:  NewOpc = X86::MOV8o32a; break;
86409467b48Spatrick     case X86::MOV8rm_NOREX:
86509467b48Spatrick     case X86::MOV8rm:  NewOpc = X86::MOV8ao32; break;
86609467b48Spatrick     case X86::MOV16mr: NewOpc = X86::MOV16o32a; break;
86709467b48Spatrick     case X86::MOV16rm: NewOpc = X86::MOV16ao32; break;
86809467b48Spatrick     case X86::MOV32mr: NewOpc = X86::MOV32o32a; break;
86909467b48Spatrick     case X86::MOV32rm: NewOpc = X86::MOV32ao32; break;
87009467b48Spatrick     }
87109467b48Spatrick     SimplifyShortMoveForm(AsmPrinter, OutMI, NewOpc);
87209467b48Spatrick     break;
87309467b48Spatrick   }
87409467b48Spatrick 
87509467b48Spatrick   case X86::ADC8ri: case X86::ADC16ri: case X86::ADC32ri: case X86::ADC64ri32:
87609467b48Spatrick   case X86::ADD8ri: case X86::ADD16ri: case X86::ADD32ri: case X86::ADD64ri32:
87709467b48Spatrick   case X86::AND8ri: case X86::AND16ri: case X86::AND32ri: case X86::AND64ri32:
87809467b48Spatrick   case X86::CMP8ri: case X86::CMP16ri: case X86::CMP32ri: case X86::CMP64ri32:
87909467b48Spatrick   case X86::OR8ri:  case X86::OR16ri:  case X86::OR32ri:  case X86::OR64ri32:
88009467b48Spatrick   case X86::SBB8ri: case X86::SBB16ri: case X86::SBB32ri: case X86::SBB64ri32:
88109467b48Spatrick   case X86::SUB8ri: case X86::SUB16ri: case X86::SUB32ri: case X86::SUB64ri32:
88209467b48Spatrick   case X86::TEST8ri:case X86::TEST16ri:case X86::TEST32ri:case X86::TEST64ri32:
88309467b48Spatrick   case X86::XOR8ri: case X86::XOR16ri: case X86::XOR32ri: case X86::XOR64ri32: {
88409467b48Spatrick     unsigned NewOpc;
88509467b48Spatrick     switch (OutMI.getOpcode()) {
88609467b48Spatrick     default: llvm_unreachable("Invalid opcode");
88709467b48Spatrick     case X86::ADC8ri:     NewOpc = X86::ADC8i8;    break;
88809467b48Spatrick     case X86::ADC16ri:    NewOpc = X86::ADC16i16;  break;
88909467b48Spatrick     case X86::ADC32ri:    NewOpc = X86::ADC32i32;  break;
89009467b48Spatrick     case X86::ADC64ri32:  NewOpc = X86::ADC64i32;  break;
89109467b48Spatrick     case X86::ADD8ri:     NewOpc = X86::ADD8i8;    break;
89209467b48Spatrick     case X86::ADD16ri:    NewOpc = X86::ADD16i16;  break;
89309467b48Spatrick     case X86::ADD32ri:    NewOpc = X86::ADD32i32;  break;
89409467b48Spatrick     case X86::ADD64ri32:  NewOpc = X86::ADD64i32;  break;
89509467b48Spatrick     case X86::AND8ri:     NewOpc = X86::AND8i8;    break;
89609467b48Spatrick     case X86::AND16ri:    NewOpc = X86::AND16i16;  break;
89709467b48Spatrick     case X86::AND32ri:    NewOpc = X86::AND32i32;  break;
89809467b48Spatrick     case X86::AND64ri32:  NewOpc = X86::AND64i32;  break;
89909467b48Spatrick     case X86::CMP8ri:     NewOpc = X86::CMP8i8;    break;
90009467b48Spatrick     case X86::CMP16ri:    NewOpc = X86::CMP16i16;  break;
90109467b48Spatrick     case X86::CMP32ri:    NewOpc = X86::CMP32i32;  break;
90209467b48Spatrick     case X86::CMP64ri32:  NewOpc = X86::CMP64i32;  break;
90309467b48Spatrick     case X86::OR8ri:      NewOpc = X86::OR8i8;     break;
90409467b48Spatrick     case X86::OR16ri:     NewOpc = X86::OR16i16;   break;
90509467b48Spatrick     case X86::OR32ri:     NewOpc = X86::OR32i32;   break;
90609467b48Spatrick     case X86::OR64ri32:   NewOpc = X86::OR64i32;   break;
90709467b48Spatrick     case X86::SBB8ri:     NewOpc = X86::SBB8i8;    break;
90809467b48Spatrick     case X86::SBB16ri:    NewOpc = X86::SBB16i16;  break;
90909467b48Spatrick     case X86::SBB32ri:    NewOpc = X86::SBB32i32;  break;
91009467b48Spatrick     case X86::SBB64ri32:  NewOpc = X86::SBB64i32;  break;
91109467b48Spatrick     case X86::SUB8ri:     NewOpc = X86::SUB8i8;    break;
91209467b48Spatrick     case X86::SUB16ri:    NewOpc = X86::SUB16i16;  break;
91309467b48Spatrick     case X86::SUB32ri:    NewOpc = X86::SUB32i32;  break;
91409467b48Spatrick     case X86::SUB64ri32:  NewOpc = X86::SUB64i32;  break;
91509467b48Spatrick     case X86::TEST8ri:    NewOpc = X86::TEST8i8;   break;
91609467b48Spatrick     case X86::TEST16ri:   NewOpc = X86::TEST16i16; break;
91709467b48Spatrick     case X86::TEST32ri:   NewOpc = X86::TEST32i32; break;
91809467b48Spatrick     case X86::TEST64ri32: NewOpc = X86::TEST64i32; break;
91909467b48Spatrick     case X86::XOR8ri:     NewOpc = X86::XOR8i8;    break;
92009467b48Spatrick     case X86::XOR16ri:    NewOpc = X86::XOR16i16;  break;
92109467b48Spatrick     case X86::XOR32ri:    NewOpc = X86::XOR32i32;  break;
92209467b48Spatrick     case X86::XOR64ri32:  NewOpc = X86::XOR64i32;  break;
92309467b48Spatrick     }
92409467b48Spatrick     SimplifyShortImmForm(OutMI, NewOpc);
92509467b48Spatrick     break;
92609467b48Spatrick   }
92709467b48Spatrick 
92809467b48Spatrick   // Try to shrink some forms of movsx.
92909467b48Spatrick   case X86::MOVSX16rr8:
93009467b48Spatrick   case X86::MOVSX32rr16:
93109467b48Spatrick   case X86::MOVSX64rr32:
93209467b48Spatrick     SimplifyMOVSX(OutMI);
93309467b48Spatrick     break;
93409467b48Spatrick 
93509467b48Spatrick   case X86::VCMPPDrri:
93609467b48Spatrick   case X86::VCMPPDYrri:
93709467b48Spatrick   case X86::VCMPPSrri:
93809467b48Spatrick   case X86::VCMPPSYrri:
93909467b48Spatrick   case X86::VCMPSDrr:
94009467b48Spatrick   case X86::VCMPSSrr: {
94109467b48Spatrick     // Swap the operands if it will enable a 2 byte VEX encoding.
94209467b48Spatrick     // FIXME: Change the immediate to improve opportunities?
94309467b48Spatrick     if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg()) &&
94409467b48Spatrick         X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) {
94509467b48Spatrick       unsigned Imm = MI->getOperand(3).getImm() & 0x7;
94609467b48Spatrick       switch (Imm) {
94709467b48Spatrick       default: break;
94809467b48Spatrick       case 0x00: // EQUAL
94909467b48Spatrick       case 0x03: // UNORDERED
95009467b48Spatrick       case 0x04: // NOT EQUAL
95109467b48Spatrick       case 0x07: // ORDERED
95209467b48Spatrick         std::swap(OutMI.getOperand(1), OutMI.getOperand(2));
95309467b48Spatrick         break;
95409467b48Spatrick       }
95509467b48Spatrick     }
95609467b48Spatrick     break;
95709467b48Spatrick   }
95809467b48Spatrick 
95909467b48Spatrick   case X86::VMOVHLPSrr:
96009467b48Spatrick   case X86::VUNPCKHPDrr:
96109467b48Spatrick     // These are not truly commutable so hide them from the default case.
96209467b48Spatrick     break;
96309467b48Spatrick 
964*a96b3639Srobert   case X86::MASKMOVDQU:
965*a96b3639Srobert   case X86::VMASKMOVDQU:
966*a96b3639Srobert     if (AsmPrinter.getSubtarget().is64Bit())
967*a96b3639Srobert       OutMI.setFlags(X86::IP_HAS_AD_SIZE);
968*a96b3639Srobert     break;
969*a96b3639Srobert 
97009467b48Spatrick   default: {
97109467b48Spatrick     // If the instruction is a commutable arithmetic instruction we might be
97209467b48Spatrick     // able to commute the operands to get a 2 byte VEX prefix.
97309467b48Spatrick     uint64_t TSFlags = MI->getDesc().TSFlags;
97409467b48Spatrick     if (MI->getDesc().isCommutable() &&
97509467b48Spatrick         (TSFlags & X86II::EncodingMask) == X86II::VEX &&
97609467b48Spatrick         (TSFlags & X86II::OpMapMask) == X86II::TB &&
97709467b48Spatrick         (TSFlags & X86II::FormMask) == X86II::MRMSrcReg &&
97809467b48Spatrick         !(TSFlags & X86II::VEX_W) && (TSFlags & X86II::VEX_4V) &&
97909467b48Spatrick         OutMI.getNumOperands() == 3) {
98009467b48Spatrick       if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg()) &&
98109467b48Spatrick           X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg()))
98209467b48Spatrick         std::swap(OutMI.getOperand(1), OutMI.getOperand(2));
98309467b48Spatrick     }
984*a96b3639Srobert     // Add an REP prefix to BSF instructions so that new processors can
985*a96b3639Srobert     // recognize as TZCNT, which has better performance than BSF.
986*a96b3639Srobert     if (X86::isBSF(OutMI.getOpcode()) && !MF.getFunction().hasOptSize()) {
987*a96b3639Srobert       // BSF and TZCNT have different interpretations on ZF bit. So make sure
988*a96b3639Srobert       // it won't be used later.
989*a96b3639Srobert       const MachineOperand *FlagDef = MI->findRegisterDefOperand(X86::EFLAGS);
990*a96b3639Srobert       if (FlagDef && FlagDef->isDead())
991*a96b3639Srobert         OutMI.setFlags(X86::IP_HAS_REPEAT);
992*a96b3639Srobert     }
99309467b48Spatrick     break;
99409467b48Spatrick   }
99509467b48Spatrick   }
99609467b48Spatrick }
99709467b48Spatrick 
LowerTlsAddr(X86MCInstLower & MCInstLowering,const MachineInstr & MI)99809467b48Spatrick void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
99909467b48Spatrick                                  const MachineInstr &MI) {
1000097a140dSpatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
1001a0747c9fSpatrick   bool Is64Bits = MI.getOpcode() != X86::TLS_addr32 &&
1002a0747c9fSpatrick                   MI.getOpcode() != X86::TLS_base_addr32;
1003a0747c9fSpatrick   bool Is64BitsLP64 = MI.getOpcode() == X86::TLS_addr64 ||
100409467b48Spatrick                       MI.getOpcode() == X86::TLS_base_addr64;
100509467b48Spatrick   MCContext &Ctx = OutStreamer->getContext();
100609467b48Spatrick 
100709467b48Spatrick   MCSymbolRefExpr::VariantKind SRVK;
100809467b48Spatrick   switch (MI.getOpcode()) {
100909467b48Spatrick   case X86::TLS_addr32:
101009467b48Spatrick   case X86::TLS_addr64:
1011a0747c9fSpatrick   case X86::TLS_addrX32:
101209467b48Spatrick     SRVK = MCSymbolRefExpr::VK_TLSGD;
101309467b48Spatrick     break;
101409467b48Spatrick   case X86::TLS_base_addr32:
101509467b48Spatrick     SRVK = MCSymbolRefExpr::VK_TLSLDM;
101609467b48Spatrick     break;
101709467b48Spatrick   case X86::TLS_base_addr64:
1018a0747c9fSpatrick   case X86::TLS_base_addrX32:
101909467b48Spatrick     SRVK = MCSymbolRefExpr::VK_TLSLD;
102009467b48Spatrick     break;
102109467b48Spatrick   default:
102209467b48Spatrick     llvm_unreachable("unexpected opcode");
102309467b48Spatrick   }
102409467b48Spatrick 
102509467b48Spatrick   const MCSymbolRefExpr *Sym = MCSymbolRefExpr::create(
102609467b48Spatrick       MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)), SRVK, Ctx);
102709467b48Spatrick 
102809467b48Spatrick   // As of binutils 2.32, ld has a bogus TLS relaxation error when the GD/LD
102909467b48Spatrick   // code sequence using R_X86_64_GOTPCREL (instead of R_X86_64_GOTPCRELX) is
103009467b48Spatrick   // attempted to be relaxed to IE/LE (binutils PR24784). Work around the bug by
103109467b48Spatrick   // only using GOT when GOTPCRELX is enabled.
103209467b48Spatrick   // TODO Delete the workaround when GOTPCRELX becomes commonplace.
103309467b48Spatrick   bool UseGot = MMI->getModule()->getRtLibUseGOT() &&
103409467b48Spatrick                 Ctx.getAsmInfo()->canRelaxRelocations();
103509467b48Spatrick 
103609467b48Spatrick   if (Is64Bits) {
103709467b48Spatrick     bool NeedsPadding = SRVK == MCSymbolRefExpr::VK_TLSGD;
1038a0747c9fSpatrick     if (NeedsPadding && Is64BitsLP64)
103909467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
104009467b48Spatrick     EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
104109467b48Spatrick                                 .addReg(X86::RDI)
104209467b48Spatrick                                 .addReg(X86::RIP)
104309467b48Spatrick                                 .addImm(1)
104409467b48Spatrick                                 .addReg(0)
104509467b48Spatrick                                 .addExpr(Sym)
104609467b48Spatrick                                 .addReg(0));
104709467b48Spatrick     const MCSymbol *TlsGetAddr = Ctx.getOrCreateSymbol("__tls_get_addr");
104809467b48Spatrick     if (NeedsPadding) {
104909467b48Spatrick       if (!UseGot)
105009467b48Spatrick         EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
105109467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
105209467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
105309467b48Spatrick     }
105409467b48Spatrick     if (UseGot) {
105509467b48Spatrick       const MCExpr *Expr = MCSymbolRefExpr::create(
105609467b48Spatrick           TlsGetAddr, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
105709467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::CALL64m)
105809467b48Spatrick                                   .addReg(X86::RIP)
105909467b48Spatrick                                   .addImm(1)
106009467b48Spatrick                                   .addReg(0)
106109467b48Spatrick                                   .addExpr(Expr)
106209467b48Spatrick                                   .addReg(0));
106309467b48Spatrick     } else {
106409467b48Spatrick       EmitAndCountInstruction(
106509467b48Spatrick           MCInstBuilder(X86::CALL64pcrel32)
106609467b48Spatrick               .addExpr(MCSymbolRefExpr::create(TlsGetAddr,
106709467b48Spatrick                                                MCSymbolRefExpr::VK_PLT, Ctx)));
106809467b48Spatrick     }
106909467b48Spatrick   } else {
107009467b48Spatrick     if (SRVK == MCSymbolRefExpr::VK_TLSGD && !UseGot) {
107109467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
107209467b48Spatrick                                   .addReg(X86::EAX)
107309467b48Spatrick                                   .addReg(0)
107409467b48Spatrick                                   .addImm(1)
107509467b48Spatrick                                   .addReg(X86::EBX)
107609467b48Spatrick                                   .addExpr(Sym)
107709467b48Spatrick                                   .addReg(0));
107809467b48Spatrick     } else {
107909467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::LEA32r)
108009467b48Spatrick                                   .addReg(X86::EAX)
108109467b48Spatrick                                   .addReg(X86::EBX)
108209467b48Spatrick                                   .addImm(1)
108309467b48Spatrick                                   .addReg(0)
108409467b48Spatrick                                   .addExpr(Sym)
108509467b48Spatrick                                   .addReg(0));
108609467b48Spatrick     }
108709467b48Spatrick 
108809467b48Spatrick     const MCSymbol *TlsGetAddr = Ctx.getOrCreateSymbol("___tls_get_addr");
108909467b48Spatrick     if (UseGot) {
109009467b48Spatrick       const MCExpr *Expr =
109109467b48Spatrick           MCSymbolRefExpr::create(TlsGetAddr, MCSymbolRefExpr::VK_GOT, Ctx);
109209467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::CALL32m)
109309467b48Spatrick                                   .addReg(X86::EBX)
109409467b48Spatrick                                   .addImm(1)
109509467b48Spatrick                                   .addReg(0)
109609467b48Spatrick                                   .addExpr(Expr)
109709467b48Spatrick                                   .addReg(0));
109809467b48Spatrick     } else {
109909467b48Spatrick       EmitAndCountInstruction(
110009467b48Spatrick           MCInstBuilder(X86::CALLpcrel32)
110109467b48Spatrick               .addExpr(MCSymbolRefExpr::create(TlsGetAddr,
110209467b48Spatrick                                                MCSymbolRefExpr::VK_PLT, Ctx)));
110309467b48Spatrick     }
110409467b48Spatrick   }
110509467b48Spatrick }
110609467b48Spatrick 
110709467b48Spatrick /// Emit the largest nop instruction smaller than or equal to \p NumBytes
110809467b48Spatrick /// bytes.  Return the size of nop emitted.
emitNop(MCStreamer & OS,unsigned NumBytes,const X86Subtarget * Subtarget)1109097a140dSpatrick static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
1110097a140dSpatrick                         const X86Subtarget *Subtarget) {
1111a0747c9fSpatrick   // Determine the longest nop which can be efficiently decoded for the given
1112a0747c9fSpatrick   // target cpu.  15-bytes is the longest single NOP instruction, but some
1113a0747c9fSpatrick   // platforms can't decode the longest forms efficiently.
1114a0747c9fSpatrick   unsigned MaxNopLength = 1;
1115a0747c9fSpatrick   if (Subtarget->is64Bit()) {
1116a0747c9fSpatrick     // FIXME: We can use NOOPL on 32-bit targets with FeatureNOPL, but the
1117a0747c9fSpatrick     // IndexReg/BaseReg below need to be updated.
1118*a96b3639Srobert     if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))
1119a0747c9fSpatrick       MaxNopLength = 7;
1120*a96b3639Srobert     else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))
1121a0747c9fSpatrick       MaxNopLength = 15;
1122*a96b3639Srobert     else if (Subtarget->hasFeature(X86::TuningFast11ByteNOP))
1123a0747c9fSpatrick       MaxNopLength = 11;
1124a0747c9fSpatrick     else
1125a0747c9fSpatrick       MaxNopLength = 10;
1126a0747c9fSpatrick   } if (Subtarget->is32Bit())
1127a0747c9fSpatrick     MaxNopLength = 2;
1128a0747c9fSpatrick 
112909467b48Spatrick   // Cap a single nop emission at the profitable value for the target
1130a0747c9fSpatrick   NumBytes = std::min(NumBytes, MaxNopLength);
113109467b48Spatrick 
113209467b48Spatrick   unsigned NopSize;
113309467b48Spatrick   unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
113409467b48Spatrick   IndexReg = Displacement = SegmentReg = 0;
113509467b48Spatrick   BaseReg = X86::RAX;
113609467b48Spatrick   ScaleVal = 1;
113709467b48Spatrick   switch (NumBytes) {
113809467b48Spatrick   case 0:
113909467b48Spatrick     llvm_unreachable("Zero nops?");
114009467b48Spatrick     break;
114109467b48Spatrick   case 1:
114209467b48Spatrick     NopSize = 1;
114309467b48Spatrick     Opc = X86::NOOP;
114409467b48Spatrick     break;
114509467b48Spatrick   case 2:
114609467b48Spatrick     NopSize = 2;
114709467b48Spatrick     Opc = X86::XCHG16ar;
114809467b48Spatrick     break;
114909467b48Spatrick   case 3:
115009467b48Spatrick     NopSize = 3;
115109467b48Spatrick     Opc = X86::NOOPL;
115209467b48Spatrick     break;
115309467b48Spatrick   case 4:
115409467b48Spatrick     NopSize = 4;
115509467b48Spatrick     Opc = X86::NOOPL;
115609467b48Spatrick     Displacement = 8;
115709467b48Spatrick     break;
115809467b48Spatrick   case 5:
115909467b48Spatrick     NopSize = 5;
116009467b48Spatrick     Opc = X86::NOOPL;
116109467b48Spatrick     Displacement = 8;
116209467b48Spatrick     IndexReg = X86::RAX;
116309467b48Spatrick     break;
116409467b48Spatrick   case 6:
116509467b48Spatrick     NopSize = 6;
116609467b48Spatrick     Opc = X86::NOOPW;
116709467b48Spatrick     Displacement = 8;
116809467b48Spatrick     IndexReg = X86::RAX;
116909467b48Spatrick     break;
117009467b48Spatrick   case 7:
117109467b48Spatrick     NopSize = 7;
117209467b48Spatrick     Opc = X86::NOOPL;
117309467b48Spatrick     Displacement = 512;
117409467b48Spatrick     break;
117509467b48Spatrick   case 8:
117609467b48Spatrick     NopSize = 8;
117709467b48Spatrick     Opc = X86::NOOPL;
117809467b48Spatrick     Displacement = 512;
117909467b48Spatrick     IndexReg = X86::RAX;
118009467b48Spatrick     break;
118109467b48Spatrick   case 9:
118209467b48Spatrick     NopSize = 9;
118309467b48Spatrick     Opc = X86::NOOPW;
118409467b48Spatrick     Displacement = 512;
118509467b48Spatrick     IndexReg = X86::RAX;
118609467b48Spatrick     break;
118709467b48Spatrick   default:
118809467b48Spatrick     NopSize = 10;
118909467b48Spatrick     Opc = X86::NOOPW;
119009467b48Spatrick     Displacement = 512;
119109467b48Spatrick     IndexReg = X86::RAX;
119209467b48Spatrick     SegmentReg = X86::CS;
119309467b48Spatrick     break;
119409467b48Spatrick   }
119509467b48Spatrick 
119609467b48Spatrick   unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);
119709467b48Spatrick   NopSize += NumPrefixes;
119809467b48Spatrick   for (unsigned i = 0; i != NumPrefixes; ++i)
1199097a140dSpatrick     OS.emitBytes("\x66");
120009467b48Spatrick 
120109467b48Spatrick   switch (Opc) {
120209467b48Spatrick   default: llvm_unreachable("Unexpected opcode");
120309467b48Spatrick   case X86::NOOP:
1204097a140dSpatrick     OS.emitInstruction(MCInstBuilder(Opc), *Subtarget);
120509467b48Spatrick     break;
120609467b48Spatrick   case X86::XCHG16ar:
1207097a140dSpatrick     OS.emitInstruction(MCInstBuilder(Opc).addReg(X86::AX).addReg(X86::AX),
1208097a140dSpatrick                        *Subtarget);
120909467b48Spatrick     break;
121009467b48Spatrick   case X86::NOOPL:
121109467b48Spatrick   case X86::NOOPW:
1212097a140dSpatrick     OS.emitInstruction(MCInstBuilder(Opc)
121309467b48Spatrick                            .addReg(BaseReg)
121409467b48Spatrick                            .addImm(ScaleVal)
121509467b48Spatrick                            .addReg(IndexReg)
121609467b48Spatrick                            .addImm(Displacement)
121709467b48Spatrick                            .addReg(SegmentReg),
1218097a140dSpatrick                        *Subtarget);
121909467b48Spatrick     break;
122009467b48Spatrick   }
122109467b48Spatrick   assert(NopSize <= NumBytes && "We overemitted?");
122209467b48Spatrick   return NopSize;
122309467b48Spatrick }
122409467b48Spatrick 
122509467b48Spatrick /// Emit the optimal amount of multi-byte nops on X86.
emitX86Nops(MCStreamer & OS,unsigned NumBytes,const X86Subtarget * Subtarget)1226097a140dSpatrick static void emitX86Nops(MCStreamer &OS, unsigned NumBytes,
1227097a140dSpatrick                         const X86Subtarget *Subtarget) {
122809467b48Spatrick   unsigned NopsToEmit = NumBytes;
122909467b48Spatrick   (void)NopsToEmit;
123009467b48Spatrick   while (NumBytes) {
1231097a140dSpatrick     NumBytes -= emitNop(OS, NumBytes, Subtarget);
123209467b48Spatrick     assert(NopsToEmit >= NumBytes && "Emitted more than I asked for!");
123309467b48Spatrick   }
123409467b48Spatrick }
123509467b48Spatrick 
LowerSTATEPOINT(const MachineInstr & MI,X86MCInstLower & MCIL)123609467b48Spatrick void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
123709467b48Spatrick                                     X86MCInstLower &MCIL) {
123809467b48Spatrick   assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
123909467b48Spatrick 
124009467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
124109467b48Spatrick 
124209467b48Spatrick   StatepointOpers SOpers(&MI);
124309467b48Spatrick   if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1244097a140dSpatrick     emitX86Nops(*OutStreamer, PatchBytes, Subtarget);
124509467b48Spatrick   } else {
124609467b48Spatrick     // Lower call target and choose correct opcode
124709467b48Spatrick     const MachineOperand &CallTarget = SOpers.getCallTarget();
124809467b48Spatrick     MCOperand CallTargetMCOp;
124909467b48Spatrick     unsigned CallOpcode;
125009467b48Spatrick     switch (CallTarget.getType()) {
125109467b48Spatrick     case MachineOperand::MO_GlobalAddress:
125209467b48Spatrick     case MachineOperand::MO_ExternalSymbol:
125309467b48Spatrick       CallTargetMCOp = MCIL.LowerSymbolOperand(
125409467b48Spatrick           CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
125509467b48Spatrick       CallOpcode = X86::CALL64pcrel32;
125609467b48Spatrick       // Currently, we only support relative addressing with statepoints.
125709467b48Spatrick       // Otherwise, we'll need a scratch register to hold the target
125809467b48Spatrick       // address.  You'll fail asserts during load & relocation if this
125909467b48Spatrick       // symbol is to far away. (TODO: support non-relative addressing)
126009467b48Spatrick       break;
126109467b48Spatrick     case MachineOperand::MO_Immediate:
126209467b48Spatrick       CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
126309467b48Spatrick       CallOpcode = X86::CALL64pcrel32;
126409467b48Spatrick       // Currently, we only support relative addressing with statepoints.
126509467b48Spatrick       // Otherwise, we'll need a scratch register to hold the target
126609467b48Spatrick       // immediate.  You'll fail asserts during load & relocation if this
126709467b48Spatrick       // address is to far away. (TODO: support non-relative addressing)
126809467b48Spatrick       break;
126909467b48Spatrick     case MachineOperand::MO_Register:
127009467b48Spatrick       // FIXME: Add retpoline support and remove this.
12717299aa8dSpatrick       if (Subtarget->useIndirectThunkCalls())
12727299aa8dSpatrick         report_fatal_error("Lowering register statepoints with thunks not "
127309467b48Spatrick                            "yet implemented.");
127409467b48Spatrick       CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
127509467b48Spatrick       CallOpcode = X86::CALL64r;
127609467b48Spatrick       break;
127709467b48Spatrick     default:
127809467b48Spatrick       llvm_unreachable("Unsupported operand type in statepoint call target");
127909467b48Spatrick       break;
128009467b48Spatrick     }
128109467b48Spatrick 
128209467b48Spatrick     // Emit call
128309467b48Spatrick     MCInst CallInst;
128409467b48Spatrick     CallInst.setOpcode(CallOpcode);
128509467b48Spatrick     CallInst.addOperand(CallTargetMCOp);
1286097a140dSpatrick     OutStreamer->emitInstruction(CallInst, getSubtargetInfo());
128709467b48Spatrick   }
128809467b48Spatrick 
128909467b48Spatrick   // Record our statepoint node in the same section used by STACKMAP
129009467b48Spatrick   // and PATCHPOINT
129109467b48Spatrick   auto &Ctx = OutStreamer->getContext();
129209467b48Spatrick   MCSymbol *MILabel = Ctx.createTempSymbol();
1293097a140dSpatrick   OutStreamer->emitLabel(MILabel);
129409467b48Spatrick   SM.recordStatepoint(*MILabel, MI);
129509467b48Spatrick }
129609467b48Spatrick 
LowerFAULTING_OP(const MachineInstr & FaultingMI,X86MCInstLower & MCIL)129709467b48Spatrick void X86AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI,
129809467b48Spatrick                                      X86MCInstLower &MCIL) {
129909467b48Spatrick   // FAULTING_LOAD_OP <def>, <faltinf type>, <MBB handler>,
130009467b48Spatrick   //                  <opcode>, <operands>
130109467b48Spatrick 
130209467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
130309467b48Spatrick 
130409467b48Spatrick   Register DefRegister = FaultingMI.getOperand(0).getReg();
130509467b48Spatrick   FaultMaps::FaultKind FK =
130609467b48Spatrick       static_cast<FaultMaps::FaultKind>(FaultingMI.getOperand(1).getImm());
130709467b48Spatrick   MCSymbol *HandlerLabel = FaultingMI.getOperand(2).getMBB()->getSymbol();
130809467b48Spatrick   unsigned Opcode = FaultingMI.getOperand(3).getImm();
130909467b48Spatrick   unsigned OperandsBeginIdx = 4;
131009467b48Spatrick 
131109467b48Spatrick   auto &Ctx = OutStreamer->getContext();
131209467b48Spatrick   MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1313097a140dSpatrick   OutStreamer->emitLabel(FaultingLabel);
131409467b48Spatrick 
131509467b48Spatrick   assert(FK < FaultMaps::FaultKindMax && "Invalid Faulting Kind!");
131609467b48Spatrick   FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
131709467b48Spatrick 
131809467b48Spatrick   MCInst MI;
131909467b48Spatrick   MI.setOpcode(Opcode);
132009467b48Spatrick 
132109467b48Spatrick   if (DefRegister != X86::NoRegister)
132209467b48Spatrick     MI.addOperand(MCOperand::createReg(DefRegister));
132309467b48Spatrick 
1324*a96b3639Srobert   for (const MachineOperand &MO :
1325*a96b3639Srobert        llvm::drop_begin(FaultingMI.operands(), OperandsBeginIdx))
1326*a96b3639Srobert     if (auto MaybeOperand = MCIL.LowerMachineOperand(&FaultingMI, MO))
1327*a96b3639Srobert       MI.addOperand(*MaybeOperand);
132809467b48Spatrick 
132909467b48Spatrick   OutStreamer->AddComment("on-fault: " + HandlerLabel->getName());
1330097a140dSpatrick   OutStreamer->emitInstruction(MI, getSubtargetInfo());
133109467b48Spatrick }
133209467b48Spatrick 
LowerFENTRY_CALL(const MachineInstr & MI,X86MCInstLower & MCIL)133309467b48Spatrick void X86AsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
133409467b48Spatrick                                      X86MCInstLower &MCIL) {
133509467b48Spatrick   bool Is64Bits = Subtarget->is64Bit();
133609467b48Spatrick   MCContext &Ctx = OutStreamer->getContext();
133709467b48Spatrick   MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
133809467b48Spatrick   const MCSymbolRefExpr *Op =
133909467b48Spatrick       MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_None, Ctx);
134009467b48Spatrick 
134109467b48Spatrick   EmitAndCountInstruction(
134209467b48Spatrick       MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
134309467b48Spatrick           .addExpr(Op));
134409467b48Spatrick }
134509467b48Spatrick 
LowerKCFI_CHECK(const MachineInstr & MI)1346*a96b3639Srobert void X86AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
1347*a96b3639Srobert   assert(std::next(MI.getIterator())->isCall() &&
1348*a96b3639Srobert          "KCFI_CHECK not followed by a call instruction");
1349*a96b3639Srobert 
1350*a96b3639Srobert   // Adjust the offset for patchable-function-prefix. X86InstrInfo::getNop()
1351*a96b3639Srobert   // returns a 1-byte X86::NOOP, which means the offset is the same in
1352*a96b3639Srobert   // bytes.  This assumes that patchable-function-prefix is the same for all
1353*a96b3639Srobert   // functions.
1354*a96b3639Srobert   const MachineFunction &MF = *MI.getMF();
1355*a96b3639Srobert   int64_t PrefixNops = 0;
1356*a96b3639Srobert   (void)MF.getFunction()
1357*a96b3639Srobert       .getFnAttribute("patchable-function-prefix")
1358*a96b3639Srobert       .getValueAsString()
1359*a96b3639Srobert       .getAsInteger(10, PrefixNops);
1360*a96b3639Srobert 
1361*a96b3639Srobert   // KCFI allows indirect calls to any location that's preceded by a valid
1362*a96b3639Srobert   // type identifier. To avoid encoding the full constant into an instruction,
1363*a96b3639Srobert   // and thus emitting potential call target gadgets at each indirect call
1364*a96b3639Srobert   // site, load a negated constant to a register and compare that to the
1365*a96b3639Srobert   // expected value at the call target.
1366*a96b3639Srobert   const Register AddrReg = MI.getOperand(0).getReg();
1367*a96b3639Srobert   const uint32_t Type = MI.getOperand(1).getImm();
1368*a96b3639Srobert   // The check is immediately before the call. If the call target is in R10,
1369*a96b3639Srobert   // we can clobber R11 for the check instead.
1370*a96b3639Srobert   unsigned TempReg = AddrReg == X86::R10 ? X86::R11D : X86::R10D;
1371*a96b3639Srobert   EmitAndCountInstruction(
1372*a96b3639Srobert       MCInstBuilder(X86::MOV32ri).addReg(TempReg).addImm(-MaskKCFIType(Type)));
1373*a96b3639Srobert   EmitAndCountInstruction(MCInstBuilder(X86::ADD32rm)
1374*a96b3639Srobert                               .addReg(X86::NoRegister)
1375*a96b3639Srobert                               .addReg(TempReg)
1376*a96b3639Srobert                               .addReg(AddrReg)
1377*a96b3639Srobert                               .addImm(1)
1378*a96b3639Srobert                               .addReg(X86::NoRegister)
1379*a96b3639Srobert                               .addImm(-(PrefixNops + 4))
1380*a96b3639Srobert                               .addReg(X86::NoRegister));
1381*a96b3639Srobert 
1382*a96b3639Srobert   MCSymbol *Pass = OutContext.createTempSymbol();
1383*a96b3639Srobert   EmitAndCountInstruction(
1384*a96b3639Srobert       MCInstBuilder(X86::JCC_1)
1385*a96b3639Srobert           .addExpr(MCSymbolRefExpr::create(Pass, OutContext))
1386*a96b3639Srobert           .addImm(X86::COND_E));
1387*a96b3639Srobert 
1388*a96b3639Srobert   MCSymbol *Trap = OutContext.createTempSymbol();
1389*a96b3639Srobert   OutStreamer->emitLabel(Trap);
1390*a96b3639Srobert   EmitAndCountInstruction(MCInstBuilder(X86::TRAP));
1391*a96b3639Srobert   emitKCFITrapEntry(MF, Trap);
1392*a96b3639Srobert   OutStreamer->emitLabel(Pass);
1393*a96b3639Srobert }
1394*a96b3639Srobert 
LowerASAN_CHECK_MEMACCESS(const MachineInstr & MI)1395*a96b3639Srobert void X86AsmPrinter::LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
1396*a96b3639Srobert   // FIXME: Make this work on non-ELF.
1397*a96b3639Srobert   if (!TM.getTargetTriple().isOSBinFormatELF()) {
1398*a96b3639Srobert     report_fatal_error("llvm.asan.check.memaccess only supported on ELF");
1399*a96b3639Srobert     return;
1400*a96b3639Srobert   }
1401*a96b3639Srobert 
1402*a96b3639Srobert   const auto &Reg = MI.getOperand(0).getReg();
1403*a96b3639Srobert   ASanAccessInfo AccessInfo(MI.getOperand(1).getImm());
1404*a96b3639Srobert 
1405*a96b3639Srobert   uint64_t ShadowBase;
1406*a96b3639Srobert   int MappingScale;
1407*a96b3639Srobert   bool OrShadowOffset;
1408*a96b3639Srobert   getAddressSanitizerParams(Triple(TM.getTargetTriple()), 64,
1409*a96b3639Srobert                             AccessInfo.CompileKernel, &ShadowBase,
1410*a96b3639Srobert                             &MappingScale, &OrShadowOffset);
1411*a96b3639Srobert 
1412*a96b3639Srobert   StringRef Name = AccessInfo.IsWrite ? "store" : "load";
1413*a96b3639Srobert   StringRef Op = OrShadowOffset ? "or" : "add";
1414*a96b3639Srobert   std::string SymName = ("__asan_check_" + Name + "_" + Op + "_" +
1415*a96b3639Srobert                          Twine(1ULL << AccessInfo.AccessSizeIndex) + "_" +
1416*a96b3639Srobert                          TM.getMCRegisterInfo()->getName(Reg.asMCReg()))
1417*a96b3639Srobert                             .str();
1418*a96b3639Srobert   if (OrShadowOffset)
1419*a96b3639Srobert     report_fatal_error(
1420*a96b3639Srobert         "OrShadowOffset is not supported with optimized callbacks");
1421*a96b3639Srobert 
1422*a96b3639Srobert   EmitAndCountInstruction(
1423*a96b3639Srobert       MCInstBuilder(X86::CALL64pcrel32)
1424*a96b3639Srobert           .addExpr(MCSymbolRefExpr::create(
1425*a96b3639Srobert               OutContext.getOrCreateSymbol(SymName), OutContext)));
1426*a96b3639Srobert }
1427*a96b3639Srobert 
LowerPATCHABLE_OP(const MachineInstr & MI,X86MCInstLower & MCIL)142809467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
142909467b48Spatrick                                       X86MCInstLower &MCIL) {
143009467b48Spatrick   // PATCHABLE_OP minsize, opcode, operands
143109467b48Spatrick 
143209467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
143309467b48Spatrick 
143409467b48Spatrick   unsigned MinSize = MI.getOperand(0).getImm();
143509467b48Spatrick   unsigned Opcode = MI.getOperand(1).getImm();
1436*a96b3639Srobert   // Opcode PATCHABLE_OP is a special case: there is no instruction to wrap,
1437*a96b3639Srobert   // simply emit a nop of size MinSize.
1438*a96b3639Srobert   bool EmptyInst = (Opcode == TargetOpcode::PATCHABLE_OP);
143909467b48Spatrick 
144009467b48Spatrick   MCInst MCI;
144109467b48Spatrick   MCI.setOpcode(Opcode);
1442a0747c9fSpatrick   for (auto &MO : drop_begin(MI.operands(), 2))
144309467b48Spatrick     if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
1444*a96b3639Srobert       MCI.addOperand(*MaybeOperand);
144509467b48Spatrick 
144609467b48Spatrick   SmallString<256> Code;
1447*a96b3639Srobert   if (!EmptyInst) {
144809467b48Spatrick     SmallVector<MCFixup, 4> Fixups;
144909467b48Spatrick     raw_svector_ostream VecOS(Code);
145009467b48Spatrick     CodeEmitter->encodeInstruction(MCI, VecOS, Fixups, getSubtargetInfo());
1451*a96b3639Srobert   }
145209467b48Spatrick 
145309467b48Spatrick   if (Code.size() < MinSize) {
1454097a140dSpatrick     if (MinSize == 2 && Subtarget->is32Bit() &&
1455097a140dSpatrick         Subtarget->isTargetWindowsMSVC() &&
1456097a140dSpatrick         (Subtarget->getCPU().empty() || Subtarget->getCPU() == "pentium3")) {
1457*a96b3639Srobert       // For compatibility reasons, when targetting MSVC, is is important to
1458097a140dSpatrick       // generate a 'legacy' NOP in the form of a 8B FF MOV EDI, EDI. Some tools
1459097a140dSpatrick       // rely specifically on this pattern to be able to patch a function.
1460097a140dSpatrick       // This is only for 32-bit targets, when using /arch:IA32 or /arch:SSE.
1461097a140dSpatrick       OutStreamer->emitInstruction(
1462097a140dSpatrick           MCInstBuilder(X86::MOV32rr_REV).addReg(X86::EDI).addReg(X86::EDI),
1463097a140dSpatrick           *Subtarget);
1464097a140dSpatrick     } else if (MinSize == 2 && Opcode == X86::PUSH64r) {
146509467b48Spatrick       // This is an optimization that lets us get away without emitting a nop in
146609467b48Spatrick       // many cases.
146709467b48Spatrick       //
146809467b48Spatrick       // NB! In some cases the encoding for PUSH64r (e.g. PUSH64r %r9) takes two
146909467b48Spatrick       // bytes too, so the check on MinSize is important.
147009467b48Spatrick       MCI.setOpcode(X86::PUSH64rmr);
147109467b48Spatrick     } else {
1472097a140dSpatrick       unsigned NopSize = emitNop(*OutStreamer, MinSize, Subtarget);
147309467b48Spatrick       assert(NopSize == MinSize && "Could not implement MinSize!");
147409467b48Spatrick       (void)NopSize;
147509467b48Spatrick     }
147609467b48Spatrick   }
1477*a96b3639Srobert   if (!EmptyInst)
1478097a140dSpatrick     OutStreamer->emitInstruction(MCI, getSubtargetInfo());
147909467b48Spatrick }
148009467b48Spatrick 
148109467b48Spatrick // Lower a stackmap of the form:
148209467b48Spatrick // <id>, <shadowBytes>, ...
LowerSTACKMAP(const MachineInstr & MI)148309467b48Spatrick void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
148409467b48Spatrick   SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
148509467b48Spatrick 
148609467b48Spatrick   auto &Ctx = OutStreamer->getContext();
148709467b48Spatrick   MCSymbol *MILabel = Ctx.createTempSymbol();
1488097a140dSpatrick   OutStreamer->emitLabel(MILabel);
148909467b48Spatrick 
149009467b48Spatrick   SM.recordStackMap(*MILabel, MI);
149109467b48Spatrick   unsigned NumShadowBytes = MI.getOperand(1).getImm();
149209467b48Spatrick   SMShadowTracker.reset(NumShadowBytes);
149309467b48Spatrick }
149409467b48Spatrick 
149509467b48Spatrick // Lower a patchpoint of the form:
149609467b48Spatrick // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
LowerPATCHPOINT(const MachineInstr & MI,X86MCInstLower & MCIL)149709467b48Spatrick void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
149809467b48Spatrick                                     X86MCInstLower &MCIL) {
149909467b48Spatrick   assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");
150009467b48Spatrick 
150109467b48Spatrick   SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
150209467b48Spatrick 
150309467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
150409467b48Spatrick 
150509467b48Spatrick   auto &Ctx = OutStreamer->getContext();
150609467b48Spatrick   MCSymbol *MILabel = Ctx.createTempSymbol();
1507097a140dSpatrick   OutStreamer->emitLabel(MILabel);
150809467b48Spatrick   SM.recordPatchPoint(*MILabel, MI);
150909467b48Spatrick 
151009467b48Spatrick   PatchPointOpers opers(&MI);
151109467b48Spatrick   unsigned ScratchIdx = opers.getNextScratchIdx();
151209467b48Spatrick   unsigned EncodedBytes = 0;
151309467b48Spatrick   const MachineOperand &CalleeMO = opers.getCallTarget();
151409467b48Spatrick 
151509467b48Spatrick   // Check for null target. If target is non-null (i.e. is non-zero or is
151609467b48Spatrick   // symbolic) then emit a call.
151709467b48Spatrick   if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {
151809467b48Spatrick     MCOperand CalleeMCOp;
151909467b48Spatrick     switch (CalleeMO.getType()) {
152009467b48Spatrick     default:
152109467b48Spatrick       /// FIXME: Add a verifier check for bad callee types.
152209467b48Spatrick       llvm_unreachable("Unrecognized callee operand type.");
152309467b48Spatrick     case MachineOperand::MO_Immediate:
152409467b48Spatrick       if (CalleeMO.getImm())
152509467b48Spatrick         CalleeMCOp = MCOperand::createImm(CalleeMO.getImm());
152609467b48Spatrick       break;
152709467b48Spatrick     case MachineOperand::MO_ExternalSymbol:
152809467b48Spatrick     case MachineOperand::MO_GlobalAddress:
152909467b48Spatrick       CalleeMCOp = MCIL.LowerSymbolOperand(CalleeMO,
153009467b48Spatrick                                            MCIL.GetSymbolFromOperand(CalleeMO));
153109467b48Spatrick       break;
153209467b48Spatrick     }
153309467b48Spatrick 
153409467b48Spatrick     // Emit MOV to materialize the target address and the CALL to target.
153509467b48Spatrick     // This is encoded with 12-13 bytes, depending on which register is used.
153609467b48Spatrick     Register ScratchReg = MI.getOperand(ScratchIdx).getReg();
153709467b48Spatrick     if (X86II::isX86_64ExtendedReg(ScratchReg))
153809467b48Spatrick       EncodedBytes = 13;
153909467b48Spatrick     else
154009467b48Spatrick       EncodedBytes = 12;
154109467b48Spatrick 
154209467b48Spatrick     EmitAndCountInstruction(
154309467b48Spatrick         MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));
154409467b48Spatrick     // FIXME: Add retpoline support and remove this.
15457299aa8dSpatrick     if (Subtarget->useIndirectThunkCalls())
154609467b48Spatrick       report_fatal_error(
15477299aa8dSpatrick           "Lowering patchpoint with thunks not yet implemented.");
154809467b48Spatrick     EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
154909467b48Spatrick   }
155009467b48Spatrick 
155109467b48Spatrick   // Emit padding.
155209467b48Spatrick   unsigned NumBytes = opers.getNumPatchBytes();
155309467b48Spatrick   assert(NumBytes >= EncodedBytes &&
155409467b48Spatrick          "Patchpoint can't request size less than the length of a call.");
155509467b48Spatrick 
1556097a140dSpatrick   emitX86Nops(*OutStreamer, NumBytes - EncodedBytes, Subtarget);
155709467b48Spatrick }
155809467b48Spatrick 
LowerPATCHABLE_EVENT_CALL(const MachineInstr & MI,X86MCInstLower & MCIL)155909467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
156009467b48Spatrick                                               X86MCInstLower &MCIL) {
156109467b48Spatrick   assert(Subtarget->is64Bit() && "XRay custom events only supports X86-64");
156209467b48Spatrick 
156309467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
156409467b48Spatrick 
156509467b48Spatrick   // We want to emit the following pattern, which follows the x86 calling
156609467b48Spatrick   // convention to prepare for the trampoline call to be patched in.
156709467b48Spatrick   //
156809467b48Spatrick   //   .p2align 1, ...
156909467b48Spatrick   // .Lxray_event_sled_N:
157009467b48Spatrick   //   jmp +N                        // jump across the instrumentation sled
157109467b48Spatrick   //   ...                           // set up arguments in register
157209467b48Spatrick   //   callq __xray_CustomEvent@plt  // force dependency to symbol
157309467b48Spatrick   //   ...
157409467b48Spatrick   //   <jump here>
157509467b48Spatrick   //
157609467b48Spatrick   // After patching, it would look something like:
157709467b48Spatrick   //
157809467b48Spatrick   //   nopw (2-byte nop)
157909467b48Spatrick   //   ...
158009467b48Spatrick   //   callq __xrayCustomEvent  // already lowered
158109467b48Spatrick   //   ...
158209467b48Spatrick   //
158309467b48Spatrick   // ---
158409467b48Spatrick   // First we emit the label and the jump.
158509467b48Spatrick   auto CurSled = OutContext.createTempSymbol("xray_event_sled_", true);
158609467b48Spatrick   OutStreamer->AddComment("# XRay Custom Event Log");
1587*a96b3639Srobert   OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1588097a140dSpatrick   OutStreamer->emitLabel(CurSled);
158909467b48Spatrick 
159009467b48Spatrick   // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
159109467b48Spatrick   // an operand (computed as an offset from the jmp instruction).
159209467b48Spatrick   // FIXME: Find another less hacky way do force the relative jump.
1593097a140dSpatrick   OutStreamer->emitBinaryData("\xeb\x0f");
159409467b48Spatrick 
159509467b48Spatrick   // The default C calling convention will place two arguments into %rcx and
159609467b48Spatrick   // %rdx -- so we only work with those.
159709467b48Spatrick   const Register DestRegs[] = {X86::RDI, X86::RSI};
159809467b48Spatrick   bool UsedMask[] = {false, false};
159909467b48Spatrick   // Filled out in loop.
160009467b48Spatrick   Register SrcRegs[] = {0, 0};
160109467b48Spatrick 
160209467b48Spatrick   // Then we put the operands in the %rdi and %rsi registers. We spill the
160309467b48Spatrick   // values in the register before we clobber them, and mark them as used in
160409467b48Spatrick   // UsedMask. In case the arguments are already in the correct register, we use
160509467b48Spatrick   // emit nops appropriately sized to keep the sled the same size in every
160609467b48Spatrick   // situation.
160709467b48Spatrick   for (unsigned I = 0; I < MI.getNumOperands(); ++I)
160809467b48Spatrick     if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I))) {
160909467b48Spatrick       assert(Op->isReg() && "Only support arguments in registers");
161009467b48Spatrick       SrcRegs[I] = getX86SubSuperRegister(Op->getReg(), 64);
161109467b48Spatrick       if (SrcRegs[I] != DestRegs[I]) {
161209467b48Spatrick         UsedMask[I] = true;
161309467b48Spatrick         EmitAndCountInstruction(
161409467b48Spatrick             MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));
161509467b48Spatrick       } else {
1616097a140dSpatrick         emitX86Nops(*OutStreamer, 4, Subtarget);
161709467b48Spatrick       }
161809467b48Spatrick     }
161909467b48Spatrick 
162009467b48Spatrick   // Now that the register values are stashed, mov arguments into place.
162109467b48Spatrick   // FIXME: This doesn't work if one of the later SrcRegs is equal to an
162209467b48Spatrick   // earlier DestReg. We will have already overwritten over the register before
162309467b48Spatrick   // we can copy from it.
162409467b48Spatrick   for (unsigned I = 0; I < MI.getNumOperands(); ++I)
162509467b48Spatrick     if (SrcRegs[I] != DestRegs[I])
162609467b48Spatrick       EmitAndCountInstruction(
162709467b48Spatrick           MCInstBuilder(X86::MOV64rr).addReg(DestRegs[I]).addReg(SrcRegs[I]));
162809467b48Spatrick 
162909467b48Spatrick   // We emit a hard dependency on the __xray_CustomEvent symbol, which is the
163009467b48Spatrick   // name of the trampoline to be implemented by the XRay runtime.
163109467b48Spatrick   auto TSym = OutContext.getOrCreateSymbol("__xray_CustomEvent");
163209467b48Spatrick   MachineOperand TOp = MachineOperand::CreateMCSymbol(TSym);
163309467b48Spatrick   if (isPositionIndependent())
163409467b48Spatrick     TOp.setTargetFlags(X86II::MO_PLT);
163509467b48Spatrick 
163609467b48Spatrick   // Emit the call instruction.
163709467b48Spatrick   EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
163809467b48Spatrick                               .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
163909467b48Spatrick 
164009467b48Spatrick   // Restore caller-saved and used registers.
164109467b48Spatrick   for (unsigned I = sizeof UsedMask; I-- > 0;)
164209467b48Spatrick     if (UsedMask[I])
164309467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));
164409467b48Spatrick     else
1645097a140dSpatrick       emitX86Nops(*OutStreamer, 1, Subtarget);
164609467b48Spatrick 
164709467b48Spatrick   OutStreamer->AddComment("xray custom event end.");
164809467b48Spatrick 
1649097a140dSpatrick   // Record the sled version. Version 0 of this sled was spelled differently, so
1650097a140dSpatrick   // we let the runtime handle the different offsets we're using. Version 2
1651097a140dSpatrick   // changed the absolute address to a PC-relative address.
1652097a140dSpatrick   recordSled(CurSled, MI, SledKind::CUSTOM_EVENT, 2);
165309467b48Spatrick }
165409467b48Spatrick 
LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr & MI,X86MCInstLower & MCIL)165509467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,
165609467b48Spatrick                                                     X86MCInstLower &MCIL) {
165709467b48Spatrick   assert(Subtarget->is64Bit() && "XRay typed events only supports X86-64");
165809467b48Spatrick 
165909467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
166009467b48Spatrick 
166109467b48Spatrick   // We want to emit the following pattern, which follows the x86 calling
166209467b48Spatrick   // convention to prepare for the trampoline call to be patched in.
166309467b48Spatrick   //
166409467b48Spatrick   //   .p2align 1, ...
166509467b48Spatrick   // .Lxray_event_sled_N:
166609467b48Spatrick   //   jmp +N                        // jump across the instrumentation sled
166709467b48Spatrick   //   ...                           // set up arguments in register
166809467b48Spatrick   //   callq __xray_TypedEvent@plt  // force dependency to symbol
166909467b48Spatrick   //   ...
167009467b48Spatrick   //   <jump here>
167109467b48Spatrick   //
167209467b48Spatrick   // After patching, it would look something like:
167309467b48Spatrick   //
167409467b48Spatrick   //   nopw (2-byte nop)
167509467b48Spatrick   //   ...
167609467b48Spatrick   //   callq __xrayTypedEvent  // already lowered
167709467b48Spatrick   //   ...
167809467b48Spatrick   //
167909467b48Spatrick   // ---
168009467b48Spatrick   // First we emit the label and the jump.
168109467b48Spatrick   auto CurSled = OutContext.createTempSymbol("xray_typed_event_sled_", true);
168209467b48Spatrick   OutStreamer->AddComment("# XRay Typed Event Log");
1683*a96b3639Srobert   OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1684097a140dSpatrick   OutStreamer->emitLabel(CurSled);
168509467b48Spatrick 
168609467b48Spatrick   // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
168709467b48Spatrick   // an operand (computed as an offset from the jmp instruction).
168809467b48Spatrick   // FIXME: Find another less hacky way do force the relative jump.
1689097a140dSpatrick   OutStreamer->emitBinaryData("\xeb\x14");
169009467b48Spatrick 
169109467b48Spatrick   // An x86-64 convention may place three arguments into %rcx, %rdx, and R8,
169209467b48Spatrick   // so we'll work with those. Or we may be called via SystemV, in which case
169309467b48Spatrick   // we don't have to do any translation.
169409467b48Spatrick   const Register DestRegs[] = {X86::RDI, X86::RSI, X86::RDX};
169509467b48Spatrick   bool UsedMask[] = {false, false, false};
169609467b48Spatrick 
169709467b48Spatrick   // Will fill out src regs in the loop.
169809467b48Spatrick   Register SrcRegs[] = {0, 0, 0};
169909467b48Spatrick 
170009467b48Spatrick   // Then we put the operands in the SystemV registers. We spill the values in
170109467b48Spatrick   // the registers before we clobber them, and mark them as used in UsedMask.
170209467b48Spatrick   // In case the arguments are already in the correct register, we emit nops
170309467b48Spatrick   // appropriately sized to keep the sled the same size in every situation.
170409467b48Spatrick   for (unsigned I = 0; I < MI.getNumOperands(); ++I)
170509467b48Spatrick     if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I))) {
170609467b48Spatrick       // TODO: Is register only support adequate?
170709467b48Spatrick       assert(Op->isReg() && "Only supports arguments in registers");
170809467b48Spatrick       SrcRegs[I] = getX86SubSuperRegister(Op->getReg(), 64);
170909467b48Spatrick       if (SrcRegs[I] != DestRegs[I]) {
171009467b48Spatrick         UsedMask[I] = true;
171109467b48Spatrick         EmitAndCountInstruction(
171209467b48Spatrick             MCInstBuilder(X86::PUSH64r).addReg(DestRegs[I]));
171309467b48Spatrick       } else {
1714097a140dSpatrick         emitX86Nops(*OutStreamer, 4, Subtarget);
171509467b48Spatrick       }
171609467b48Spatrick     }
171709467b48Spatrick 
171809467b48Spatrick   // In the above loop we only stash all of the destination registers or emit
171909467b48Spatrick   // nops if the arguments are already in the right place. Doing the actually
172009467b48Spatrick   // moving is postponed until after all the registers are stashed so nothing
172109467b48Spatrick   // is clobbers. We've already added nops to account for the size of mov and
172209467b48Spatrick   // push if the register is in the right place, so we only have to worry about
172309467b48Spatrick   // emitting movs.
172409467b48Spatrick   // FIXME: This doesn't work if one of the later SrcRegs is equal to an
172509467b48Spatrick   // earlier DestReg. We will have already overwritten over the register before
172609467b48Spatrick   // we can copy from it.
172709467b48Spatrick   for (unsigned I = 0; I < MI.getNumOperands(); ++I)
172809467b48Spatrick     if (UsedMask[I])
172909467b48Spatrick       EmitAndCountInstruction(
173009467b48Spatrick           MCInstBuilder(X86::MOV64rr).addReg(DestRegs[I]).addReg(SrcRegs[I]));
173109467b48Spatrick 
173209467b48Spatrick   // We emit a hard dependency on the __xray_TypedEvent symbol, which is the
173309467b48Spatrick   // name of the trampoline to be implemented by the XRay runtime.
173409467b48Spatrick   auto TSym = OutContext.getOrCreateSymbol("__xray_TypedEvent");
173509467b48Spatrick   MachineOperand TOp = MachineOperand::CreateMCSymbol(TSym);
173609467b48Spatrick   if (isPositionIndependent())
173709467b48Spatrick     TOp.setTargetFlags(X86II::MO_PLT);
173809467b48Spatrick 
173909467b48Spatrick   // Emit the call instruction.
174009467b48Spatrick   EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32)
174109467b48Spatrick                               .addOperand(MCIL.LowerSymbolOperand(TOp, TSym)));
174209467b48Spatrick 
174309467b48Spatrick   // Restore caller-saved and used registers.
174409467b48Spatrick   for (unsigned I = sizeof UsedMask; I-- > 0;)
174509467b48Spatrick     if (UsedMask[I])
174609467b48Spatrick       EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(DestRegs[I]));
174709467b48Spatrick     else
1748097a140dSpatrick       emitX86Nops(*OutStreamer, 1, Subtarget);
174909467b48Spatrick 
175009467b48Spatrick   OutStreamer->AddComment("xray typed event end.");
175109467b48Spatrick 
175209467b48Spatrick   // Record the sled version.
1753097a140dSpatrick   recordSled(CurSled, MI, SledKind::TYPED_EVENT, 2);
175409467b48Spatrick }
175509467b48Spatrick 
LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr & MI,X86MCInstLower & MCIL)175609467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
175709467b48Spatrick                                                   X86MCInstLower &MCIL) {
175809467b48Spatrick 
175909467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
176009467b48Spatrick 
176109467b48Spatrick   const Function &F = MF->getFunction();
176209467b48Spatrick   if (F.hasFnAttribute("patchable-function-entry")) {
176309467b48Spatrick     unsigned Num;
176409467b48Spatrick     if (F.getFnAttribute("patchable-function-entry")
176509467b48Spatrick             .getValueAsString()
176609467b48Spatrick             .getAsInteger(10, Num))
176709467b48Spatrick       return;
1768097a140dSpatrick     emitX86Nops(*OutStreamer, Num, Subtarget);
176909467b48Spatrick     return;
177009467b48Spatrick   }
177109467b48Spatrick   // We want to emit the following pattern:
177209467b48Spatrick   //
177309467b48Spatrick   //   .p2align 1, ...
177409467b48Spatrick   // .Lxray_sled_N:
177509467b48Spatrick   //   jmp .tmpN
177609467b48Spatrick   //   # 9 bytes worth of noops
177709467b48Spatrick   //
177809467b48Spatrick   // We need the 9 bytes because at runtime, we'd be patching over the full 11
177909467b48Spatrick   // bytes with the following pattern:
178009467b48Spatrick   //
178109467b48Spatrick   //   mov %r10, <function id, 32-bit>   // 6 bytes
178209467b48Spatrick   //   call <relative offset, 32-bits>   // 5 bytes
178309467b48Spatrick   //
178409467b48Spatrick   auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1785*a96b3639Srobert   OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1786097a140dSpatrick   OutStreamer->emitLabel(CurSled);
178709467b48Spatrick 
178809467b48Spatrick   // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
178909467b48Spatrick   // an operand (computed as an offset from the jmp instruction).
179009467b48Spatrick   // FIXME: Find another less hacky way do force the relative jump.
1791097a140dSpatrick   OutStreamer->emitBytes("\xeb\x09");
1792097a140dSpatrick   emitX86Nops(*OutStreamer, 9, Subtarget);
1793097a140dSpatrick   recordSled(CurSled, MI, SledKind::FUNCTION_ENTER, 2);
179409467b48Spatrick }
179509467b48Spatrick 
LowerPATCHABLE_RET(const MachineInstr & MI,X86MCInstLower & MCIL)179609467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI,
179709467b48Spatrick                                        X86MCInstLower &MCIL) {
179809467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
179909467b48Spatrick 
180009467b48Spatrick   // Since PATCHABLE_RET takes the opcode of the return statement as an
180109467b48Spatrick   // argument, we use that to emit the correct form of the RET that we want.
180209467b48Spatrick   // i.e. when we see this:
180309467b48Spatrick   //
180409467b48Spatrick   //   PATCHABLE_RET X86::RET ...
180509467b48Spatrick   //
180609467b48Spatrick   // We should emit the RET followed by sleds.
180709467b48Spatrick   //
180809467b48Spatrick   //   .p2align 1, ...
180909467b48Spatrick   // .Lxray_sled_N:
181009467b48Spatrick   //   ret  # or equivalent instruction
181109467b48Spatrick   //   # 10 bytes worth of noops
181209467b48Spatrick   //
181309467b48Spatrick   // This just makes sure that the alignment for the next instruction is 2.
181409467b48Spatrick   auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1815*a96b3639Srobert   OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1816097a140dSpatrick   OutStreamer->emitLabel(CurSled);
181709467b48Spatrick   unsigned OpCode = MI.getOperand(0).getImm();
181809467b48Spatrick   MCInst Ret;
181909467b48Spatrick   Ret.setOpcode(OpCode);
1820a0747c9fSpatrick   for (auto &MO : drop_begin(MI.operands()))
182109467b48Spatrick     if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
1822*a96b3639Srobert       Ret.addOperand(*MaybeOperand);
1823097a140dSpatrick   OutStreamer->emitInstruction(Ret, getSubtargetInfo());
1824097a140dSpatrick   emitX86Nops(*OutStreamer, 10, Subtarget);
1825097a140dSpatrick   recordSled(CurSled, MI, SledKind::FUNCTION_EXIT, 2);
182609467b48Spatrick }
182709467b48Spatrick 
LowerPATCHABLE_TAIL_CALL(const MachineInstr & MI,X86MCInstLower & MCIL)182809467b48Spatrick void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI,
182909467b48Spatrick                                              X86MCInstLower &MCIL) {
183009467b48Spatrick   NoAutoPaddingScope NoPadScope(*OutStreamer);
183109467b48Spatrick 
183209467b48Spatrick   // Like PATCHABLE_RET, we have the actual instruction in the operands to this
183309467b48Spatrick   // instruction so we lower that particular instruction and its operands.
183409467b48Spatrick   // Unlike PATCHABLE_RET though, we put the sled before the JMP, much like how
183509467b48Spatrick   // we do it for PATCHABLE_FUNCTION_ENTER. The sled should be very similar to
183609467b48Spatrick   // the PATCHABLE_FUNCTION_ENTER case, followed by the lowering of the actual
183709467b48Spatrick   // tail call much like how we have it in PATCHABLE_RET.
183809467b48Spatrick   auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1839*a96b3639Srobert   OutStreamer->emitCodeAlignment(Align(2), &getSubtargetInfo());
1840097a140dSpatrick   OutStreamer->emitLabel(CurSled);
184109467b48Spatrick   auto Target = OutContext.createTempSymbol();
184209467b48Spatrick 
184309467b48Spatrick   // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
184409467b48Spatrick   // an operand (computed as an offset from the jmp instruction).
184509467b48Spatrick   // FIXME: Find another less hacky way do force the relative jump.
1846097a140dSpatrick   OutStreamer->emitBytes("\xeb\x09");
1847097a140dSpatrick   emitX86Nops(*OutStreamer, 9, Subtarget);
1848097a140dSpatrick   OutStreamer->emitLabel(Target);
1849097a140dSpatrick   recordSled(CurSled, MI, SledKind::TAIL_CALL, 2);
185009467b48Spatrick 
185109467b48Spatrick   unsigned OpCode = MI.getOperand(0).getImm();
185209467b48Spatrick   OpCode = convertTailJumpOpcode(OpCode);
185309467b48Spatrick   MCInst TC;
185409467b48Spatrick   TC.setOpcode(OpCode);
185509467b48Spatrick 
185609467b48Spatrick   // Before emitting the instruction, add a comment to indicate that this is
185709467b48Spatrick   // indeed a tail call.
185809467b48Spatrick   OutStreamer->AddComment("TAILCALL");
1859a0747c9fSpatrick   for (auto &MO : drop_begin(MI.operands()))
186009467b48Spatrick     if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
1861*a96b3639Srobert       TC.addOperand(*MaybeOperand);
1862097a140dSpatrick   OutStreamer->emitInstruction(TC, getSubtargetInfo());
186309467b48Spatrick }
186409467b48Spatrick 
186509467b48Spatrick // Returns instruction preceding MBBI in MachineFunction.
186609467b48Spatrick // If MBBI is the first instruction of the first basic block, returns null.
186709467b48Spatrick static MachineBasicBlock::const_iterator
PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI)186809467b48Spatrick PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI) {
186909467b48Spatrick   const MachineBasicBlock *MBB = MBBI->getParent();
187009467b48Spatrick   while (MBBI == MBB->begin()) {
187109467b48Spatrick     if (MBB == &MBB->getParent()->front())
187209467b48Spatrick       return MachineBasicBlock::const_iterator();
187309467b48Spatrick     MBB = MBB->getPrevNode();
187409467b48Spatrick     MBBI = MBB->end();
187509467b48Spatrick   }
187609467b48Spatrick   --MBBI;
187709467b48Spatrick   return MBBI;
187809467b48Spatrick }
187909467b48Spatrick 
getConstantFromPool(const MachineInstr & MI,const MachineOperand & Op)188009467b48Spatrick static const Constant *getConstantFromPool(const MachineInstr &MI,
188109467b48Spatrick                                            const MachineOperand &Op) {
188209467b48Spatrick   if (!Op.isCPI() || Op.getOffset() != 0)
188309467b48Spatrick     return nullptr;
188409467b48Spatrick 
188509467b48Spatrick   ArrayRef<MachineConstantPoolEntry> Constants =
188609467b48Spatrick       MI.getParent()->getParent()->getConstantPool()->getConstants();
188709467b48Spatrick   const MachineConstantPoolEntry &ConstantEntry = Constants[Op.getIndex()];
188809467b48Spatrick 
188909467b48Spatrick   // Bail if this is a machine constant pool entry, we won't be able to dig out
189009467b48Spatrick   // anything useful.
189109467b48Spatrick   if (ConstantEntry.isMachineConstantPoolEntry())
189209467b48Spatrick     return nullptr;
189309467b48Spatrick 
1894a0747c9fSpatrick   return ConstantEntry.Val.ConstVal;
189509467b48Spatrick }
189609467b48Spatrick 
getShuffleComment(const MachineInstr * MI,unsigned SrcOp1Idx,unsigned SrcOp2Idx,ArrayRef<int> Mask)189709467b48Spatrick static std::string getShuffleComment(const MachineInstr *MI, unsigned SrcOp1Idx,
189809467b48Spatrick                                      unsigned SrcOp2Idx, ArrayRef<int> Mask) {
189909467b48Spatrick   std::string Comment;
190009467b48Spatrick 
190109467b48Spatrick   // Compute the name for a register. This is really goofy because we have
190209467b48Spatrick   // multiple instruction printers that could (in theory) use different
190309467b48Spatrick   // names. Fortunately most people use the ATT style (outside of Windows)
190409467b48Spatrick   // and they actually agree on register naming here. Ultimately, this is
190509467b48Spatrick   // a comment, and so its OK if it isn't perfect.
1906*a96b3639Srobert   auto GetRegisterName = [](MCRegister Reg) -> StringRef {
1907*a96b3639Srobert     return X86ATTInstPrinter::getRegisterName(Reg);
190809467b48Spatrick   };
190909467b48Spatrick 
191009467b48Spatrick   const MachineOperand &DstOp = MI->getOperand(0);
191109467b48Spatrick   const MachineOperand &SrcOp1 = MI->getOperand(SrcOp1Idx);
191209467b48Spatrick   const MachineOperand &SrcOp2 = MI->getOperand(SrcOp2Idx);
191309467b48Spatrick 
191409467b48Spatrick   StringRef DstName = DstOp.isReg() ? GetRegisterName(DstOp.getReg()) : "mem";
191509467b48Spatrick   StringRef Src1Name =
191609467b48Spatrick       SrcOp1.isReg() ? GetRegisterName(SrcOp1.getReg()) : "mem";
191709467b48Spatrick   StringRef Src2Name =
191809467b48Spatrick       SrcOp2.isReg() ? GetRegisterName(SrcOp2.getReg()) : "mem";
191909467b48Spatrick 
192009467b48Spatrick   // One source operand, fix the mask to print all elements in one span.
1921*a96b3639Srobert   SmallVector<int, 8> ShuffleMask(Mask);
192209467b48Spatrick   if (Src1Name == Src2Name)
192309467b48Spatrick     for (int i = 0, e = ShuffleMask.size(); i != e; ++i)
192409467b48Spatrick       if (ShuffleMask[i] >= e)
192509467b48Spatrick         ShuffleMask[i] -= e;
192609467b48Spatrick 
192709467b48Spatrick   raw_string_ostream CS(Comment);
192809467b48Spatrick   CS << DstName;
192909467b48Spatrick 
193009467b48Spatrick   // Handle AVX512 MASK/MASXZ write mask comments.
193109467b48Spatrick   // MASK: zmmX {%kY}
193209467b48Spatrick   // MASKZ: zmmX {%kY} {z}
193309467b48Spatrick   if (SrcOp1Idx > 1) {
193409467b48Spatrick     assert((SrcOp1Idx == 2 || SrcOp1Idx == 3) && "Unexpected writemask");
193509467b48Spatrick 
193609467b48Spatrick     const MachineOperand &WriteMaskOp = MI->getOperand(SrcOp1Idx - 1);
193709467b48Spatrick     if (WriteMaskOp.isReg()) {
193809467b48Spatrick       CS << " {%" << GetRegisterName(WriteMaskOp.getReg()) << "}";
193909467b48Spatrick 
194009467b48Spatrick       if (SrcOp1Idx == 2) {
194109467b48Spatrick         CS << " {z}";
194209467b48Spatrick       }
194309467b48Spatrick     }
194409467b48Spatrick   }
194509467b48Spatrick 
194609467b48Spatrick   CS << " = ";
194709467b48Spatrick 
194809467b48Spatrick   for (int i = 0, e = ShuffleMask.size(); i != e; ++i) {
194909467b48Spatrick     if (i != 0)
195009467b48Spatrick       CS << ",";
195109467b48Spatrick     if (ShuffleMask[i] == SM_SentinelZero) {
195209467b48Spatrick       CS << "zero";
195309467b48Spatrick       continue;
195409467b48Spatrick     }
195509467b48Spatrick 
195609467b48Spatrick     // Otherwise, it must come from src1 or src2.  Print the span of elements
195709467b48Spatrick     // that comes from this src.
195809467b48Spatrick     bool isSrc1 = ShuffleMask[i] < (int)e;
195909467b48Spatrick     CS << (isSrc1 ? Src1Name : Src2Name) << '[';
196009467b48Spatrick 
196109467b48Spatrick     bool IsFirst = true;
196209467b48Spatrick     while (i != e && ShuffleMask[i] != SM_SentinelZero &&
196309467b48Spatrick            (ShuffleMask[i] < (int)e) == isSrc1) {
196409467b48Spatrick       if (!IsFirst)
196509467b48Spatrick         CS << ',';
196609467b48Spatrick       else
196709467b48Spatrick         IsFirst = false;
196809467b48Spatrick       if (ShuffleMask[i] == SM_SentinelUndef)
196909467b48Spatrick         CS << "u";
197009467b48Spatrick       else
197109467b48Spatrick         CS << ShuffleMask[i] % (int)e;
197209467b48Spatrick       ++i;
197309467b48Spatrick     }
197409467b48Spatrick     CS << ']';
197509467b48Spatrick     --i; // For loop increments element #.
197609467b48Spatrick   }
197709467b48Spatrick   CS.flush();
197809467b48Spatrick 
197909467b48Spatrick   return Comment;
198009467b48Spatrick }
198109467b48Spatrick 
printConstant(const APInt & Val,raw_ostream & CS)198209467b48Spatrick static void printConstant(const APInt &Val, raw_ostream &CS) {
198309467b48Spatrick   if (Val.getBitWidth() <= 64) {
198409467b48Spatrick     CS << Val.getZExtValue();
198509467b48Spatrick   } else {
198609467b48Spatrick     // print multi-word constant as (w0,w1)
198709467b48Spatrick     CS << "(";
198809467b48Spatrick     for (int i = 0, N = Val.getNumWords(); i < N; ++i) {
198909467b48Spatrick       if (i > 0)
199009467b48Spatrick         CS << ",";
199109467b48Spatrick       CS << Val.getRawData()[i];
199209467b48Spatrick     }
199309467b48Spatrick     CS << ")";
199409467b48Spatrick   }
199509467b48Spatrick }
199609467b48Spatrick 
printConstant(const APFloat & Flt,raw_ostream & CS)199709467b48Spatrick static void printConstant(const APFloat &Flt, raw_ostream &CS) {
199809467b48Spatrick   SmallString<32> Str;
199909467b48Spatrick   // Force scientific notation to distinquish from integers.
200009467b48Spatrick   Flt.toString(Str, 0, 0);
200109467b48Spatrick   CS << Str;
200209467b48Spatrick }
200309467b48Spatrick 
printConstant(const Constant * COp,raw_ostream & CS)200409467b48Spatrick static void printConstant(const Constant *COp, raw_ostream &CS) {
200509467b48Spatrick   if (isa<UndefValue>(COp)) {
200609467b48Spatrick     CS << "u";
200709467b48Spatrick   } else if (auto *CI = dyn_cast<ConstantInt>(COp)) {
200809467b48Spatrick     printConstant(CI->getValue(), CS);
200909467b48Spatrick   } else if (auto *CF = dyn_cast<ConstantFP>(COp)) {
201009467b48Spatrick     printConstant(CF->getValueAPF(), CS);
201109467b48Spatrick   } else {
201209467b48Spatrick     CS << "?";
201309467b48Spatrick   }
201409467b48Spatrick }
201509467b48Spatrick 
EmitSEHInstruction(const MachineInstr * MI)201609467b48Spatrick void X86AsmPrinter::EmitSEHInstruction(const MachineInstr *MI) {
201709467b48Spatrick   assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
201809467b48Spatrick   assert(getSubtarget().isOSWindows() && "SEH_ instruction Windows only");
201909467b48Spatrick 
202009467b48Spatrick   // Use the .cv_fpo directives if we're emitting CodeView on 32-bit x86.
202109467b48Spatrick   if (EmitFPOData) {
202209467b48Spatrick     X86TargetStreamer *XTS =
202309467b48Spatrick         static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
202409467b48Spatrick     switch (MI->getOpcode()) {
202509467b48Spatrick     case X86::SEH_PushReg:
202609467b48Spatrick       XTS->emitFPOPushReg(MI->getOperand(0).getImm());
202709467b48Spatrick       break;
202809467b48Spatrick     case X86::SEH_StackAlloc:
202909467b48Spatrick       XTS->emitFPOStackAlloc(MI->getOperand(0).getImm());
203009467b48Spatrick       break;
203109467b48Spatrick     case X86::SEH_StackAlign:
203209467b48Spatrick       XTS->emitFPOStackAlign(MI->getOperand(0).getImm());
203309467b48Spatrick       break;
203409467b48Spatrick     case X86::SEH_SetFrame:
203509467b48Spatrick       assert(MI->getOperand(1).getImm() == 0 &&
203609467b48Spatrick              ".cv_fpo_setframe takes no offset");
203709467b48Spatrick       XTS->emitFPOSetFrame(MI->getOperand(0).getImm());
203809467b48Spatrick       break;
203909467b48Spatrick     case X86::SEH_EndPrologue:
204009467b48Spatrick       XTS->emitFPOEndPrologue();
204109467b48Spatrick       break;
204209467b48Spatrick     case X86::SEH_SaveReg:
204309467b48Spatrick     case X86::SEH_SaveXMM:
204409467b48Spatrick     case X86::SEH_PushFrame:
204509467b48Spatrick       llvm_unreachable("SEH_ directive incompatible with FPO");
204609467b48Spatrick       break;
204709467b48Spatrick     default:
204809467b48Spatrick       llvm_unreachable("expected SEH_ instruction");
204909467b48Spatrick     }
205009467b48Spatrick     return;
205109467b48Spatrick   }
205209467b48Spatrick 
205309467b48Spatrick   // Otherwise, use the .seh_ directives for all other Windows platforms.
205409467b48Spatrick   switch (MI->getOpcode()) {
205509467b48Spatrick   case X86::SEH_PushReg:
2056*a96b3639Srobert     OutStreamer->emitWinCFIPushReg(MI->getOperand(0).getImm());
205709467b48Spatrick     break;
205809467b48Spatrick 
205909467b48Spatrick   case X86::SEH_SaveReg:
2060*a96b3639Srobert     OutStreamer->emitWinCFISaveReg(MI->getOperand(0).getImm(),
206109467b48Spatrick                                    MI->getOperand(1).getImm());
206209467b48Spatrick     break;
206309467b48Spatrick 
206409467b48Spatrick   case X86::SEH_SaveXMM:
2065*a96b3639Srobert     OutStreamer->emitWinCFISaveXMM(MI->getOperand(0).getImm(),
206609467b48Spatrick                                    MI->getOperand(1).getImm());
206709467b48Spatrick     break;
206809467b48Spatrick 
206909467b48Spatrick   case X86::SEH_StackAlloc:
2070*a96b3639Srobert     OutStreamer->emitWinCFIAllocStack(MI->getOperand(0).getImm());
207109467b48Spatrick     break;
207209467b48Spatrick 
207309467b48Spatrick   case X86::SEH_SetFrame:
2074*a96b3639Srobert     OutStreamer->emitWinCFISetFrame(MI->getOperand(0).getImm(),
207509467b48Spatrick                                     MI->getOperand(1).getImm());
207609467b48Spatrick     break;
207709467b48Spatrick 
207809467b48Spatrick   case X86::SEH_PushFrame:
2079*a96b3639Srobert     OutStreamer->emitWinCFIPushFrame(MI->getOperand(0).getImm());
208009467b48Spatrick     break;
208109467b48Spatrick 
208209467b48Spatrick   case X86::SEH_EndPrologue:
2083*a96b3639Srobert     OutStreamer->emitWinCFIEndProlog();
208409467b48Spatrick     break;
208509467b48Spatrick 
208609467b48Spatrick   default:
208709467b48Spatrick     llvm_unreachable("expected SEH_ instruction");
208809467b48Spatrick   }
208909467b48Spatrick }
209009467b48Spatrick 
getRegisterWidth(const MCOperandInfo & Info)209109467b48Spatrick static unsigned getRegisterWidth(const MCOperandInfo &Info) {
209209467b48Spatrick   if (Info.RegClass == X86::VR128RegClassID ||
209309467b48Spatrick       Info.RegClass == X86::VR128XRegClassID)
209409467b48Spatrick     return 128;
209509467b48Spatrick   if (Info.RegClass == X86::VR256RegClassID ||
209609467b48Spatrick       Info.RegClass == X86::VR256XRegClassID)
209709467b48Spatrick     return 256;
209809467b48Spatrick   if (Info.RegClass == X86::VR512RegClassID)
209909467b48Spatrick     return 512;
210009467b48Spatrick   llvm_unreachable("Unknown register class!");
210109467b48Spatrick }
210209467b48Spatrick 
addConstantComments(const MachineInstr * MI,MCStreamer & OutStreamer)2103097a140dSpatrick static void addConstantComments(const MachineInstr *MI,
2104097a140dSpatrick                                 MCStreamer &OutStreamer) {
2105097a140dSpatrick   switch (MI->getOpcode()) {
2106097a140dSpatrick   // Lower PSHUFB and VPERMILP normally but add a comment if we can find
2107097a140dSpatrick   // a constant shuffle mask. We won't be able to do this at the MC layer
2108097a140dSpatrick   // because the mask isn't an immediate.
2109097a140dSpatrick   case X86::PSHUFBrm:
2110097a140dSpatrick   case X86::VPSHUFBrm:
2111097a140dSpatrick   case X86::VPSHUFBYrm:
2112097a140dSpatrick   case X86::VPSHUFBZ128rm:
2113097a140dSpatrick   case X86::VPSHUFBZ128rmk:
2114097a140dSpatrick   case X86::VPSHUFBZ128rmkz:
2115097a140dSpatrick   case X86::VPSHUFBZ256rm:
2116097a140dSpatrick   case X86::VPSHUFBZ256rmk:
2117097a140dSpatrick   case X86::VPSHUFBZ256rmkz:
2118097a140dSpatrick   case X86::VPSHUFBZrm:
2119097a140dSpatrick   case X86::VPSHUFBZrmk:
2120097a140dSpatrick   case X86::VPSHUFBZrmkz: {
2121097a140dSpatrick     unsigned SrcIdx = 1;
2122097a140dSpatrick     if (X86II::isKMasked(MI->getDesc().TSFlags)) {
2123097a140dSpatrick       // Skip mask operand.
2124097a140dSpatrick       ++SrcIdx;
2125097a140dSpatrick       if (X86II::isKMergeMasked(MI->getDesc().TSFlags)) {
2126097a140dSpatrick         // Skip passthru operand.
2127097a140dSpatrick         ++SrcIdx;
2128097a140dSpatrick       }
2129097a140dSpatrick     }
2130097a140dSpatrick     unsigned MaskIdx = SrcIdx + 1 + X86::AddrDisp;
2131097a140dSpatrick 
2132097a140dSpatrick     assert(MI->getNumOperands() >= (SrcIdx + 1 + X86::AddrNumOperands) &&
2133097a140dSpatrick            "Unexpected number of operands!");
2134097a140dSpatrick 
2135097a140dSpatrick     const MachineOperand &MaskOp = MI->getOperand(MaskIdx);
2136097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MaskOp)) {
2137*a96b3639Srobert       unsigned Width = getRegisterWidth(MI->getDesc().operands()[0]);
2138097a140dSpatrick       SmallVector<int, 64> Mask;
2139097a140dSpatrick       DecodePSHUFBMask(C, Width, Mask);
2140097a140dSpatrick       if (!Mask.empty())
2141097a140dSpatrick         OutStreamer.AddComment(getShuffleComment(MI, SrcIdx, SrcIdx, Mask));
2142097a140dSpatrick     }
2143097a140dSpatrick     break;
2144097a140dSpatrick   }
2145097a140dSpatrick 
2146097a140dSpatrick   case X86::VPERMILPSrm:
2147097a140dSpatrick   case X86::VPERMILPSYrm:
2148097a140dSpatrick   case X86::VPERMILPSZ128rm:
2149097a140dSpatrick   case X86::VPERMILPSZ128rmk:
2150097a140dSpatrick   case X86::VPERMILPSZ128rmkz:
2151097a140dSpatrick   case X86::VPERMILPSZ256rm:
2152097a140dSpatrick   case X86::VPERMILPSZ256rmk:
2153097a140dSpatrick   case X86::VPERMILPSZ256rmkz:
2154097a140dSpatrick   case X86::VPERMILPSZrm:
2155097a140dSpatrick   case X86::VPERMILPSZrmk:
2156097a140dSpatrick   case X86::VPERMILPSZrmkz:
2157097a140dSpatrick   case X86::VPERMILPDrm:
2158097a140dSpatrick   case X86::VPERMILPDYrm:
2159097a140dSpatrick   case X86::VPERMILPDZ128rm:
2160097a140dSpatrick   case X86::VPERMILPDZ128rmk:
2161097a140dSpatrick   case X86::VPERMILPDZ128rmkz:
2162097a140dSpatrick   case X86::VPERMILPDZ256rm:
2163097a140dSpatrick   case X86::VPERMILPDZ256rmk:
2164097a140dSpatrick   case X86::VPERMILPDZ256rmkz:
2165097a140dSpatrick   case X86::VPERMILPDZrm:
2166097a140dSpatrick   case X86::VPERMILPDZrmk:
2167097a140dSpatrick   case X86::VPERMILPDZrmkz: {
2168097a140dSpatrick     unsigned ElSize;
2169097a140dSpatrick     switch (MI->getOpcode()) {
2170097a140dSpatrick     default: llvm_unreachable("Invalid opcode");
2171097a140dSpatrick     case X86::VPERMILPSrm:
2172097a140dSpatrick     case X86::VPERMILPSYrm:
2173097a140dSpatrick     case X86::VPERMILPSZ128rm:
2174097a140dSpatrick     case X86::VPERMILPSZ256rm:
2175097a140dSpatrick     case X86::VPERMILPSZrm:
2176097a140dSpatrick     case X86::VPERMILPSZ128rmkz:
2177097a140dSpatrick     case X86::VPERMILPSZ256rmkz:
2178097a140dSpatrick     case X86::VPERMILPSZrmkz:
2179097a140dSpatrick     case X86::VPERMILPSZ128rmk:
2180097a140dSpatrick     case X86::VPERMILPSZ256rmk:
2181097a140dSpatrick     case X86::VPERMILPSZrmk:
2182097a140dSpatrick       ElSize = 32;
2183097a140dSpatrick       break;
2184097a140dSpatrick     case X86::VPERMILPDrm:
2185097a140dSpatrick     case X86::VPERMILPDYrm:
2186097a140dSpatrick     case X86::VPERMILPDZ128rm:
2187097a140dSpatrick     case X86::VPERMILPDZ256rm:
2188097a140dSpatrick     case X86::VPERMILPDZrm:
2189097a140dSpatrick     case X86::VPERMILPDZ128rmkz:
2190097a140dSpatrick     case X86::VPERMILPDZ256rmkz:
2191097a140dSpatrick     case X86::VPERMILPDZrmkz:
2192097a140dSpatrick     case X86::VPERMILPDZ128rmk:
2193097a140dSpatrick     case X86::VPERMILPDZ256rmk:
2194097a140dSpatrick     case X86::VPERMILPDZrmk:
2195097a140dSpatrick       ElSize = 64;
2196097a140dSpatrick       break;
2197097a140dSpatrick     }
2198097a140dSpatrick 
2199097a140dSpatrick     unsigned SrcIdx = 1;
2200097a140dSpatrick     if (X86II::isKMasked(MI->getDesc().TSFlags)) {
2201097a140dSpatrick       // Skip mask operand.
2202097a140dSpatrick       ++SrcIdx;
2203097a140dSpatrick       if (X86II::isKMergeMasked(MI->getDesc().TSFlags)) {
2204097a140dSpatrick         // Skip passthru operand.
2205097a140dSpatrick         ++SrcIdx;
2206097a140dSpatrick       }
2207097a140dSpatrick     }
2208097a140dSpatrick     unsigned MaskIdx = SrcIdx + 1 + X86::AddrDisp;
2209097a140dSpatrick 
2210097a140dSpatrick     assert(MI->getNumOperands() >= (SrcIdx + 1 + X86::AddrNumOperands) &&
2211097a140dSpatrick            "Unexpected number of operands!");
2212097a140dSpatrick 
2213097a140dSpatrick     const MachineOperand &MaskOp = MI->getOperand(MaskIdx);
2214097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MaskOp)) {
2215*a96b3639Srobert       unsigned Width = getRegisterWidth(MI->getDesc().operands()[0]);
2216097a140dSpatrick       SmallVector<int, 16> Mask;
2217097a140dSpatrick       DecodeVPERMILPMask(C, ElSize, Width, Mask);
2218097a140dSpatrick       if (!Mask.empty())
2219097a140dSpatrick         OutStreamer.AddComment(getShuffleComment(MI, SrcIdx, SrcIdx, Mask));
2220097a140dSpatrick     }
2221097a140dSpatrick     break;
2222097a140dSpatrick   }
2223097a140dSpatrick 
2224097a140dSpatrick   case X86::VPERMIL2PDrm:
2225097a140dSpatrick   case X86::VPERMIL2PSrm:
2226097a140dSpatrick   case X86::VPERMIL2PDYrm:
2227097a140dSpatrick   case X86::VPERMIL2PSYrm: {
2228097a140dSpatrick     assert(MI->getNumOperands() >= (3 + X86::AddrNumOperands + 1) &&
2229097a140dSpatrick            "Unexpected number of operands!");
2230097a140dSpatrick 
2231097a140dSpatrick     const MachineOperand &CtrlOp = MI->getOperand(MI->getNumOperands() - 1);
2232097a140dSpatrick     if (!CtrlOp.isImm())
2233097a140dSpatrick       break;
2234097a140dSpatrick 
2235097a140dSpatrick     unsigned ElSize;
2236097a140dSpatrick     switch (MI->getOpcode()) {
2237097a140dSpatrick     default: llvm_unreachable("Invalid opcode");
2238097a140dSpatrick     case X86::VPERMIL2PSrm: case X86::VPERMIL2PSYrm: ElSize = 32; break;
2239097a140dSpatrick     case X86::VPERMIL2PDrm: case X86::VPERMIL2PDYrm: ElSize = 64; break;
2240097a140dSpatrick     }
2241097a140dSpatrick 
2242097a140dSpatrick     const MachineOperand &MaskOp = MI->getOperand(3 + X86::AddrDisp);
2243097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MaskOp)) {
2244*a96b3639Srobert       unsigned Width = getRegisterWidth(MI->getDesc().operands()[0]);
2245097a140dSpatrick       SmallVector<int, 16> Mask;
2246097a140dSpatrick       DecodeVPERMIL2PMask(C, (unsigned)CtrlOp.getImm(), ElSize, Width, Mask);
2247097a140dSpatrick       if (!Mask.empty())
2248097a140dSpatrick         OutStreamer.AddComment(getShuffleComment(MI, 1, 2, Mask));
2249097a140dSpatrick     }
2250097a140dSpatrick     break;
2251097a140dSpatrick   }
2252097a140dSpatrick 
2253097a140dSpatrick   case X86::VPPERMrrm: {
2254097a140dSpatrick     assert(MI->getNumOperands() >= (3 + X86::AddrNumOperands) &&
2255097a140dSpatrick            "Unexpected number of operands!");
2256097a140dSpatrick 
2257097a140dSpatrick     const MachineOperand &MaskOp = MI->getOperand(3 + X86::AddrDisp);
2258097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MaskOp)) {
2259*a96b3639Srobert       unsigned Width = getRegisterWidth(MI->getDesc().operands()[0]);
2260097a140dSpatrick       SmallVector<int, 16> Mask;
2261097a140dSpatrick       DecodeVPPERMMask(C, Width, Mask);
2262097a140dSpatrick       if (!Mask.empty())
2263097a140dSpatrick         OutStreamer.AddComment(getShuffleComment(MI, 1, 2, Mask));
2264097a140dSpatrick     }
2265097a140dSpatrick     break;
2266097a140dSpatrick   }
2267097a140dSpatrick 
2268097a140dSpatrick   case X86::MMX_MOVQ64rm: {
2269097a140dSpatrick     assert(MI->getNumOperands() == (1 + X86::AddrNumOperands) &&
2270097a140dSpatrick            "Unexpected number of operands!");
2271097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MI->getOperand(1 + X86::AddrDisp))) {
2272097a140dSpatrick       std::string Comment;
2273097a140dSpatrick       raw_string_ostream CS(Comment);
2274097a140dSpatrick       const MachineOperand &DstOp = MI->getOperand(0);
2275097a140dSpatrick       CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
2276097a140dSpatrick       if (auto *CF = dyn_cast<ConstantFP>(C)) {
2277a0747c9fSpatrick         CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false);
2278097a140dSpatrick         OutStreamer.AddComment(CS.str());
2279097a140dSpatrick       }
2280097a140dSpatrick     }
2281097a140dSpatrick     break;
2282097a140dSpatrick   }
2283097a140dSpatrick 
2284097a140dSpatrick #define MOV_CASE(Prefix, Suffix)                                               \
2285097a140dSpatrick   case X86::Prefix##MOVAPD##Suffix##rm:                                        \
2286097a140dSpatrick   case X86::Prefix##MOVAPS##Suffix##rm:                                        \
2287097a140dSpatrick   case X86::Prefix##MOVUPD##Suffix##rm:                                        \
2288097a140dSpatrick   case X86::Prefix##MOVUPS##Suffix##rm:                                        \
2289097a140dSpatrick   case X86::Prefix##MOVDQA##Suffix##rm:                                        \
2290097a140dSpatrick   case X86::Prefix##MOVDQU##Suffix##rm:
2291097a140dSpatrick 
2292097a140dSpatrick #define MOV_AVX512_CASE(Suffix)                                                \
2293097a140dSpatrick   case X86::VMOVDQA64##Suffix##rm:                                             \
2294097a140dSpatrick   case X86::VMOVDQA32##Suffix##rm:                                             \
2295097a140dSpatrick   case X86::VMOVDQU64##Suffix##rm:                                             \
2296097a140dSpatrick   case X86::VMOVDQU32##Suffix##rm:                                             \
2297097a140dSpatrick   case X86::VMOVDQU16##Suffix##rm:                                             \
2298097a140dSpatrick   case X86::VMOVDQU8##Suffix##rm:                                              \
2299097a140dSpatrick   case X86::VMOVAPS##Suffix##rm:                                               \
2300097a140dSpatrick   case X86::VMOVAPD##Suffix##rm:                                               \
2301097a140dSpatrick   case X86::VMOVUPS##Suffix##rm:                                               \
2302097a140dSpatrick   case X86::VMOVUPD##Suffix##rm:
2303097a140dSpatrick 
2304097a140dSpatrick #define CASE_ALL_MOV_RM()                                                      \
2305097a140dSpatrick   MOV_CASE(, )   /* SSE */                                                     \
2306097a140dSpatrick   MOV_CASE(V, )  /* AVX-128 */                                                 \
2307097a140dSpatrick   MOV_CASE(V, Y) /* AVX-256 */                                                 \
2308097a140dSpatrick   MOV_AVX512_CASE(Z)                                                           \
2309097a140dSpatrick   MOV_AVX512_CASE(Z256)                                                        \
2310097a140dSpatrick   MOV_AVX512_CASE(Z128)
2311097a140dSpatrick 
2312097a140dSpatrick     // For loads from a constant pool to a vector register, print the constant
2313097a140dSpatrick     // loaded.
2314097a140dSpatrick     CASE_ALL_MOV_RM()
2315097a140dSpatrick   case X86::VBROADCASTF128:
2316097a140dSpatrick   case X86::VBROADCASTI128:
2317097a140dSpatrick   case X86::VBROADCASTF32X4Z256rm:
2318097a140dSpatrick   case X86::VBROADCASTF32X4rm:
2319097a140dSpatrick   case X86::VBROADCASTF32X8rm:
2320097a140dSpatrick   case X86::VBROADCASTF64X2Z128rm:
2321097a140dSpatrick   case X86::VBROADCASTF64X2rm:
2322097a140dSpatrick   case X86::VBROADCASTF64X4rm:
2323097a140dSpatrick   case X86::VBROADCASTI32X4Z256rm:
2324097a140dSpatrick   case X86::VBROADCASTI32X4rm:
2325097a140dSpatrick   case X86::VBROADCASTI32X8rm:
2326097a140dSpatrick   case X86::VBROADCASTI64X2Z128rm:
2327097a140dSpatrick   case X86::VBROADCASTI64X2rm:
2328097a140dSpatrick   case X86::VBROADCASTI64X4rm:
2329097a140dSpatrick     assert(MI->getNumOperands() >= (1 + X86::AddrNumOperands) &&
2330097a140dSpatrick            "Unexpected number of operands!");
2331097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MI->getOperand(1 + X86::AddrDisp))) {
2332097a140dSpatrick       int NumLanes = 1;
2333097a140dSpatrick       // Override NumLanes for the broadcast instructions.
2334097a140dSpatrick       switch (MI->getOpcode()) {
2335097a140dSpatrick       case X86::VBROADCASTF128:        NumLanes = 2; break;
2336097a140dSpatrick       case X86::VBROADCASTI128:        NumLanes = 2; break;
2337097a140dSpatrick       case X86::VBROADCASTF32X4Z256rm: NumLanes = 2; break;
2338097a140dSpatrick       case X86::VBROADCASTF32X4rm:     NumLanes = 4; break;
2339097a140dSpatrick       case X86::VBROADCASTF32X8rm:     NumLanes = 2; break;
2340097a140dSpatrick       case X86::VBROADCASTF64X2Z128rm: NumLanes = 2; break;
2341097a140dSpatrick       case X86::VBROADCASTF64X2rm:     NumLanes = 4; break;
2342097a140dSpatrick       case X86::VBROADCASTF64X4rm:     NumLanes = 2; break;
2343097a140dSpatrick       case X86::VBROADCASTI32X4Z256rm: NumLanes = 2; break;
2344097a140dSpatrick       case X86::VBROADCASTI32X4rm:     NumLanes = 4; break;
2345097a140dSpatrick       case X86::VBROADCASTI32X8rm:     NumLanes = 2; break;
2346097a140dSpatrick       case X86::VBROADCASTI64X2Z128rm: NumLanes = 2; break;
2347097a140dSpatrick       case X86::VBROADCASTI64X2rm:     NumLanes = 4; break;
2348097a140dSpatrick       case X86::VBROADCASTI64X4rm:     NumLanes = 2; break;
2349097a140dSpatrick       }
2350097a140dSpatrick 
2351097a140dSpatrick       std::string Comment;
2352097a140dSpatrick       raw_string_ostream CS(Comment);
2353097a140dSpatrick       const MachineOperand &DstOp = MI->getOperand(0);
2354097a140dSpatrick       CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
2355097a140dSpatrick       if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) {
2356097a140dSpatrick         CS << "[";
2357097a140dSpatrick         for (int l = 0; l != NumLanes; ++l) {
2358097a140dSpatrick           for (int i = 0, NumElements = CDS->getNumElements(); i < NumElements;
2359097a140dSpatrick                ++i) {
2360097a140dSpatrick             if (i != 0 || l != 0)
2361097a140dSpatrick               CS << ",";
2362097a140dSpatrick             if (CDS->getElementType()->isIntegerTy())
2363097a140dSpatrick               printConstant(CDS->getElementAsAPInt(i), CS);
2364097a140dSpatrick             else if (CDS->getElementType()->isHalfTy() ||
2365097a140dSpatrick                      CDS->getElementType()->isFloatTy() ||
2366097a140dSpatrick                      CDS->getElementType()->isDoubleTy())
2367097a140dSpatrick               printConstant(CDS->getElementAsAPFloat(i), CS);
2368097a140dSpatrick             else
2369097a140dSpatrick               CS << "?";
2370097a140dSpatrick           }
2371097a140dSpatrick         }
2372097a140dSpatrick         CS << "]";
2373097a140dSpatrick         OutStreamer.AddComment(CS.str());
2374097a140dSpatrick       } else if (auto *CV = dyn_cast<ConstantVector>(C)) {
2375097a140dSpatrick         CS << "<";
2376097a140dSpatrick         for (int l = 0; l != NumLanes; ++l) {
2377097a140dSpatrick           for (int i = 0, NumOperands = CV->getNumOperands(); i < NumOperands;
2378097a140dSpatrick                ++i) {
2379097a140dSpatrick             if (i != 0 || l != 0)
2380097a140dSpatrick               CS << ",";
2381097a140dSpatrick             printConstant(CV->getOperand(i), CS);
2382097a140dSpatrick           }
2383097a140dSpatrick         }
2384097a140dSpatrick         CS << ">";
2385097a140dSpatrick         OutStreamer.AddComment(CS.str());
2386097a140dSpatrick       }
2387097a140dSpatrick     }
2388097a140dSpatrick     break;
2389097a140dSpatrick 
2390097a140dSpatrick   case X86::MOVDDUPrm:
2391097a140dSpatrick   case X86::VMOVDDUPrm:
2392097a140dSpatrick   case X86::VMOVDDUPZ128rm:
2393097a140dSpatrick   case X86::VBROADCASTSSrm:
2394097a140dSpatrick   case X86::VBROADCASTSSYrm:
2395097a140dSpatrick   case X86::VBROADCASTSSZ128rm:
2396097a140dSpatrick   case X86::VBROADCASTSSZ256rm:
2397097a140dSpatrick   case X86::VBROADCASTSSZrm:
2398097a140dSpatrick   case X86::VBROADCASTSDYrm:
2399097a140dSpatrick   case X86::VBROADCASTSDZ256rm:
2400097a140dSpatrick   case X86::VBROADCASTSDZrm:
2401097a140dSpatrick   case X86::VPBROADCASTBrm:
2402097a140dSpatrick   case X86::VPBROADCASTBYrm:
2403097a140dSpatrick   case X86::VPBROADCASTBZ128rm:
2404097a140dSpatrick   case X86::VPBROADCASTBZ256rm:
2405097a140dSpatrick   case X86::VPBROADCASTBZrm:
2406097a140dSpatrick   case X86::VPBROADCASTDrm:
2407097a140dSpatrick   case X86::VPBROADCASTDYrm:
2408097a140dSpatrick   case X86::VPBROADCASTDZ128rm:
2409097a140dSpatrick   case X86::VPBROADCASTDZ256rm:
2410097a140dSpatrick   case X86::VPBROADCASTDZrm:
2411097a140dSpatrick   case X86::VPBROADCASTQrm:
2412097a140dSpatrick   case X86::VPBROADCASTQYrm:
2413097a140dSpatrick   case X86::VPBROADCASTQZ128rm:
2414097a140dSpatrick   case X86::VPBROADCASTQZ256rm:
2415097a140dSpatrick   case X86::VPBROADCASTQZrm:
2416097a140dSpatrick   case X86::VPBROADCASTWrm:
2417097a140dSpatrick   case X86::VPBROADCASTWYrm:
2418097a140dSpatrick   case X86::VPBROADCASTWZ128rm:
2419097a140dSpatrick   case X86::VPBROADCASTWZ256rm:
2420097a140dSpatrick   case X86::VPBROADCASTWZrm:
2421097a140dSpatrick     assert(MI->getNumOperands() >= (1 + X86::AddrNumOperands) &&
2422097a140dSpatrick            "Unexpected number of operands!");
2423097a140dSpatrick     if (auto *C = getConstantFromPool(*MI, MI->getOperand(1 + X86::AddrDisp))) {
2424097a140dSpatrick       int NumElts;
2425097a140dSpatrick       switch (MI->getOpcode()) {
2426097a140dSpatrick       default: llvm_unreachable("Invalid opcode");
2427097a140dSpatrick       case X86::MOVDDUPrm:          NumElts = 2;  break;
2428097a140dSpatrick       case X86::VMOVDDUPrm:         NumElts = 2;  break;
2429097a140dSpatrick       case X86::VMOVDDUPZ128rm:     NumElts = 2;  break;
2430097a140dSpatrick       case X86::VBROADCASTSSrm:     NumElts = 4;  break;
2431097a140dSpatrick       case X86::VBROADCASTSSYrm:    NumElts = 8;  break;
2432097a140dSpatrick       case X86::VBROADCASTSSZ128rm: NumElts = 4;  break;
2433097a140dSpatrick       case X86::VBROADCASTSSZ256rm: NumElts = 8;  break;
2434097a140dSpatrick       case X86::VBROADCASTSSZrm:    NumElts = 16; break;
2435097a140dSpatrick       case X86::VBROADCASTSDYrm:    NumElts = 4;  break;
2436097a140dSpatrick       case X86::VBROADCASTSDZ256rm: NumElts = 4;  break;
2437097a140dSpatrick       case X86::VBROADCASTSDZrm:    NumElts = 8;  break;
2438097a140dSpatrick       case X86::VPBROADCASTBrm:     NumElts = 16; break;
2439097a140dSpatrick       case X86::VPBROADCASTBYrm:    NumElts = 32; break;
2440097a140dSpatrick       case X86::VPBROADCASTBZ128rm: NumElts = 16; break;
2441097a140dSpatrick       case X86::VPBROADCASTBZ256rm: NumElts = 32; break;
2442097a140dSpatrick       case X86::VPBROADCASTBZrm:    NumElts = 64; break;
2443097a140dSpatrick       case X86::VPBROADCASTDrm:     NumElts = 4;  break;
2444097a140dSpatrick       case X86::VPBROADCASTDYrm:    NumElts = 8;  break;
2445097a140dSpatrick       case X86::VPBROADCASTDZ128rm: NumElts = 4;  break;
2446097a140dSpatrick       case X86::VPBROADCASTDZ256rm: NumElts = 8;  break;
2447097a140dSpatrick       case X86::VPBROADCASTDZrm:    NumElts = 16; break;
2448097a140dSpatrick       case X86::VPBROADCASTQrm:     NumElts = 2;  break;
2449097a140dSpatrick       case X86::VPBROADCASTQYrm:    NumElts = 4;  break;
2450097a140dSpatrick       case X86::VPBROADCASTQZ128rm: NumElts = 2;  break;
2451097a140dSpatrick       case X86::VPBROADCASTQZ256rm: NumElts = 4;  break;
2452097a140dSpatrick       case X86::VPBROADCASTQZrm:    NumElts = 8;  break;
2453097a140dSpatrick       case X86::VPBROADCASTWrm:     NumElts = 8;  break;
2454097a140dSpatrick       case X86::VPBROADCASTWYrm:    NumElts = 16; break;
2455097a140dSpatrick       case X86::VPBROADCASTWZ128rm: NumElts = 8;  break;
2456097a140dSpatrick       case X86::VPBROADCASTWZ256rm: NumElts = 16; break;
2457097a140dSpatrick       case X86::VPBROADCASTWZrm:    NumElts = 32; break;
2458097a140dSpatrick       }
2459097a140dSpatrick 
2460097a140dSpatrick       std::string Comment;
2461097a140dSpatrick       raw_string_ostream CS(Comment);
2462097a140dSpatrick       const MachineOperand &DstOp = MI->getOperand(0);
2463097a140dSpatrick       CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
2464097a140dSpatrick       CS << "[";
2465097a140dSpatrick       for (int i = 0; i != NumElts; ++i) {
2466097a140dSpatrick         if (i != 0)
2467097a140dSpatrick           CS << ",";
2468097a140dSpatrick         printConstant(C, CS);
2469097a140dSpatrick       }
2470097a140dSpatrick       CS << "]";
2471097a140dSpatrick       OutStreamer.AddComment(CS.str());
2472097a140dSpatrick     }
2473097a140dSpatrick   }
2474097a140dSpatrick }
2475097a140dSpatrick 
emitInstruction(const MachineInstr * MI)2476097a140dSpatrick void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
2477*a96b3639Srobert   // FIXME: Enable feature predicate checks once all the test pass.
2478*a96b3639Srobert   // X86_MC::verifyInstructionPredicates(MI->getOpcode(),
2479*a96b3639Srobert   //                                     Subtarget->getFeatureBits());
2480*a96b3639Srobert 
248109467b48Spatrick   X86MCInstLower MCInstLowering(*MF, *this);
248209467b48Spatrick   const X86RegisterInfo *RI =
248309467b48Spatrick       MF->getSubtarget<X86Subtarget>().getRegisterInfo();
248409467b48Spatrick 
2485*a96b3639Srobert   if (MI->getOpcode() == X86::OR64rm) {
2486*a96b3639Srobert     for (auto &Opd : MI->operands()) {
2487*a96b3639Srobert       if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
2488*a96b3639Srobert                                 "swift_async_extendedFramePointerFlags") {
2489*a96b3639Srobert         ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true;
2490*a96b3639Srobert       }
2491*a96b3639Srobert     }
2492*a96b3639Srobert   }
2493*a96b3639Srobert 
249409467b48Spatrick   // Add a comment about EVEX-2-VEX compression for AVX-512 instrs that
249509467b48Spatrick   // are compressed from EVEX encoding to VEX encoding.
249609467b48Spatrick   if (TM.Options.MCOptions.ShowMCEncoding) {
249709467b48Spatrick     if (MI->getAsmPrinterFlags() & X86::AC_EVEX_2_VEX)
249809467b48Spatrick       OutStreamer->AddComment("EVEX TO VEX Compression ", false);
249909467b48Spatrick   }
250009467b48Spatrick 
2501097a140dSpatrick   // Add comments for values loaded from constant pool.
2502097a140dSpatrick   if (OutStreamer->isVerboseAsm())
2503097a140dSpatrick     addConstantComments(MI, *OutStreamer);
2504097a140dSpatrick 
250509467b48Spatrick   switch (MI->getOpcode()) {
250609467b48Spatrick   case TargetOpcode::DBG_VALUE:
250709467b48Spatrick     llvm_unreachable("Should be handled target independently");
250809467b48Spatrick 
250909467b48Spatrick   case X86::EH_RETURN:
251009467b48Spatrick   case X86::EH_RETURN64: {
251109467b48Spatrick     // Lower these as normal, but add some comments.
251209467b48Spatrick     Register Reg = MI->getOperand(0).getReg();
251309467b48Spatrick     OutStreamer->AddComment(StringRef("eh_return, addr: %") +
251409467b48Spatrick                             X86ATTInstPrinter::getRegisterName(Reg));
251509467b48Spatrick     break;
251609467b48Spatrick   }
251709467b48Spatrick   case X86::CLEANUPRET: {
251809467b48Spatrick     // Lower these as normal, but add some comments.
251909467b48Spatrick     OutStreamer->AddComment("CLEANUPRET");
252009467b48Spatrick     break;
252109467b48Spatrick   }
252209467b48Spatrick 
252309467b48Spatrick   case X86::CATCHRET: {
252409467b48Spatrick     // Lower these as normal, but add some comments.
252509467b48Spatrick     OutStreamer->AddComment("CATCHRET");
252609467b48Spatrick     break;
252709467b48Spatrick   }
252809467b48Spatrick 
252909467b48Spatrick   case X86::ENDBR32:
253009467b48Spatrick   case X86::ENDBR64: {
253109467b48Spatrick     // CurrentPatchableFunctionEntrySym can be CurrentFnBegin only for
253209467b48Spatrick     // -fpatchable-function-entry=N,0. The entry MBB is guaranteed to be
253309467b48Spatrick     // non-empty. If MI is the initial ENDBR, place the
253409467b48Spatrick     // __patchable_function_entries label after ENDBR.
253509467b48Spatrick     if (CurrentPatchableFunctionEntrySym &&
253609467b48Spatrick         CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
253709467b48Spatrick         MI == &MF->front().front()) {
253809467b48Spatrick       MCInst Inst;
253909467b48Spatrick       MCInstLowering.Lower(MI, Inst);
254009467b48Spatrick       EmitAndCountInstruction(Inst);
254109467b48Spatrick       CurrentPatchableFunctionEntrySym = createTempSymbol("patch");
2542097a140dSpatrick       OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym);
254309467b48Spatrick       return;
254409467b48Spatrick     }
254509467b48Spatrick     break;
254609467b48Spatrick   }
254709467b48Spatrick 
2548*a96b3639Srobert   case X86::TAILJMPd64:
2549*a96b3639Srobert     if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))
2550*a96b3639Srobert       EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2551*a96b3639Srobert     [[fallthrough]];
255209467b48Spatrick   case X86::TAILJMPr:
255309467b48Spatrick   case X86::TAILJMPm:
255409467b48Spatrick   case X86::TAILJMPd:
255509467b48Spatrick   case X86::TAILJMPd_CC:
255609467b48Spatrick   case X86::TAILJMPr64:
255709467b48Spatrick   case X86::TAILJMPm64:
255809467b48Spatrick   case X86::TAILJMPd64_CC:
255909467b48Spatrick   case X86::TAILJMPr64_REX:
256009467b48Spatrick   case X86::TAILJMPm64_REX:
256109467b48Spatrick     // Lower these as normal, but add some comments.
256209467b48Spatrick     OutStreamer->AddComment("TAILCALL");
256309467b48Spatrick     break;
256409467b48Spatrick 
256509467b48Spatrick   case X86::TLS_addr32:
256609467b48Spatrick   case X86::TLS_addr64:
2567a0747c9fSpatrick   case X86::TLS_addrX32:
256809467b48Spatrick   case X86::TLS_base_addr32:
256909467b48Spatrick   case X86::TLS_base_addr64:
2570a0747c9fSpatrick   case X86::TLS_base_addrX32:
257109467b48Spatrick     return LowerTlsAddr(MCInstLowering, *MI);
257209467b48Spatrick 
257309467b48Spatrick   case X86::MOVPC32r: {
257409467b48Spatrick     // This is a pseudo op for a two instruction sequence with a label, which
257509467b48Spatrick     // looks like:
257609467b48Spatrick     //     call "L1$pb"
257709467b48Spatrick     // "L1$pb":
257809467b48Spatrick     //     popl %esi
257909467b48Spatrick 
258009467b48Spatrick     // Emit the call.
258109467b48Spatrick     MCSymbol *PICBase = MF->getPICBaseSymbol();
258209467b48Spatrick     // FIXME: We would like an efficient form for this, so we don't have to do a
258309467b48Spatrick     // lot of extra uniquing.
258409467b48Spatrick     EmitAndCountInstruction(
258509467b48Spatrick         MCInstBuilder(X86::CALLpcrel32)
258609467b48Spatrick             .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
258709467b48Spatrick 
258809467b48Spatrick     const X86FrameLowering *FrameLowering =
258909467b48Spatrick         MF->getSubtarget<X86Subtarget>().getFrameLowering();
259009467b48Spatrick     bool hasFP = FrameLowering->hasFP(*MF);
259109467b48Spatrick 
259209467b48Spatrick     // TODO: This is needed only if we require precise CFA.
259309467b48Spatrick     bool HasActiveDwarfFrame = OutStreamer->getNumFrameInfos() &&
259409467b48Spatrick                                !OutStreamer->getDwarfFrameInfos().back().End;
259509467b48Spatrick 
259609467b48Spatrick     int stackGrowth = -RI->getSlotSize();
259709467b48Spatrick 
259809467b48Spatrick     if (HasActiveDwarfFrame && !hasFP) {
2599097a140dSpatrick       OutStreamer->emitCFIAdjustCfaOffset(-stackGrowth);
260009467b48Spatrick     }
260109467b48Spatrick 
260209467b48Spatrick     // Emit the label.
2603097a140dSpatrick     OutStreamer->emitLabel(PICBase);
260409467b48Spatrick 
260509467b48Spatrick     // popl $reg
260609467b48Spatrick     EmitAndCountInstruction(
260709467b48Spatrick         MCInstBuilder(X86::POP32r).addReg(MI->getOperand(0).getReg()));
260809467b48Spatrick 
260909467b48Spatrick     if (HasActiveDwarfFrame && !hasFP) {
2610097a140dSpatrick       OutStreamer->emitCFIAdjustCfaOffset(stackGrowth);
261109467b48Spatrick     }
261209467b48Spatrick     return;
261309467b48Spatrick   }
261409467b48Spatrick 
261509467b48Spatrick   case X86::ADD32ri: {
261609467b48Spatrick     // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
261709467b48Spatrick     if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
261809467b48Spatrick       break;
261909467b48Spatrick 
262009467b48Spatrick     // Okay, we have something like:
262109467b48Spatrick     //  EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
262209467b48Spatrick 
262309467b48Spatrick     // For this, we want to print something like:
262409467b48Spatrick     //   MYGLOBAL + (. - PICBASE)
262509467b48Spatrick     // However, we can't generate a ".", so just emit a new label here and refer
262609467b48Spatrick     // to it.
262709467b48Spatrick     MCSymbol *DotSym = OutContext.createTempSymbol();
2628097a140dSpatrick     OutStreamer->emitLabel(DotSym);
262909467b48Spatrick 
263009467b48Spatrick     // Now that we have emitted the label, lower the complex operand expression.
263109467b48Spatrick     MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
263209467b48Spatrick 
263309467b48Spatrick     const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
263409467b48Spatrick     const MCExpr *PICBase =
263509467b48Spatrick         MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
263609467b48Spatrick     DotExpr = MCBinaryExpr::createSub(DotExpr, PICBase, OutContext);
263709467b48Spatrick 
263809467b48Spatrick     DotExpr = MCBinaryExpr::createAdd(
263909467b48Spatrick         MCSymbolRefExpr::create(OpSym, OutContext), DotExpr, OutContext);
264009467b48Spatrick 
264109467b48Spatrick     EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)
264209467b48Spatrick                                 .addReg(MI->getOperand(0).getReg())
264309467b48Spatrick                                 .addReg(MI->getOperand(1).getReg())
264409467b48Spatrick                                 .addExpr(DotExpr));
264509467b48Spatrick     return;
264609467b48Spatrick   }
264709467b48Spatrick   case TargetOpcode::STATEPOINT:
264809467b48Spatrick     return LowerSTATEPOINT(*MI, MCInstLowering);
264909467b48Spatrick 
265009467b48Spatrick   case TargetOpcode::FAULTING_OP:
265109467b48Spatrick     return LowerFAULTING_OP(*MI, MCInstLowering);
265209467b48Spatrick 
265309467b48Spatrick   case TargetOpcode::FENTRY_CALL:
265409467b48Spatrick     return LowerFENTRY_CALL(*MI, MCInstLowering);
265509467b48Spatrick 
265609467b48Spatrick   case TargetOpcode::PATCHABLE_OP:
265709467b48Spatrick     return LowerPATCHABLE_OP(*MI, MCInstLowering);
265809467b48Spatrick 
265909467b48Spatrick   case TargetOpcode::STACKMAP:
266009467b48Spatrick     return LowerSTACKMAP(*MI);
266109467b48Spatrick 
266209467b48Spatrick   case TargetOpcode::PATCHPOINT:
266309467b48Spatrick     return LowerPATCHPOINT(*MI, MCInstLowering);
266409467b48Spatrick 
266509467b48Spatrick   case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
266609467b48Spatrick     return LowerPATCHABLE_FUNCTION_ENTER(*MI, MCInstLowering);
266709467b48Spatrick 
266809467b48Spatrick   case TargetOpcode::PATCHABLE_RET:
266909467b48Spatrick     return LowerPATCHABLE_RET(*MI, MCInstLowering);
267009467b48Spatrick 
267109467b48Spatrick   case TargetOpcode::PATCHABLE_TAIL_CALL:
267209467b48Spatrick     return LowerPATCHABLE_TAIL_CALL(*MI, MCInstLowering);
267309467b48Spatrick 
267409467b48Spatrick   case TargetOpcode::PATCHABLE_EVENT_CALL:
267509467b48Spatrick     return LowerPATCHABLE_EVENT_CALL(*MI, MCInstLowering);
267609467b48Spatrick 
267709467b48Spatrick   case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
267809467b48Spatrick     return LowerPATCHABLE_TYPED_EVENT_CALL(*MI, MCInstLowering);
267909467b48Spatrick 
268009467b48Spatrick   case X86::MORESTACK_RET:
268109467b48Spatrick     EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
268209467b48Spatrick     return;
268309467b48Spatrick 
2684*a96b3639Srobert   case X86::KCFI_CHECK:
2685*a96b3639Srobert     return LowerKCFI_CHECK(*MI);
2686*a96b3639Srobert 
2687*a96b3639Srobert   case X86::ASAN_CHECK_MEMACCESS:
2688*a96b3639Srobert     return LowerASAN_CHECK_MEMACCESS(*MI);
2689*a96b3639Srobert 
269009467b48Spatrick   case X86::MORESTACK_RET_RESTORE_R10:
269109467b48Spatrick     // Return, then restore R10.
269209467b48Spatrick     EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
269309467b48Spatrick     EmitAndCountInstruction(
269409467b48Spatrick         MCInstBuilder(X86::MOV64rr).addReg(X86::R10).addReg(X86::RAX));
269509467b48Spatrick     return;
269609467b48Spatrick 
2697adae0cfdSpatrick   case X86::RETGUARD_JMP_TRAP: {
2698adae0cfdSpatrick     // Make a symbol for the end of the trapsled and emit a jump to it
2699adae0cfdSpatrick     MCSymbol *RGSuccSym = OutContext.createTempSymbol();
2700adae0cfdSpatrick     const MCExpr *RGSuccExpr = MCSymbolRefExpr::create(RGSuccSym, OutContext);
2701adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::JCC_1)
2702adae0cfdSpatrick                               .addExpr(RGSuccExpr)
2703adae0cfdSpatrick                               .addImm(X86::COND_E));
2704adae0cfdSpatrick 
2705adae0cfdSpatrick     // Emit at least two trap instructions
2706adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2707adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2708adae0cfdSpatrick 
2709adae0cfdSpatrick     // Now .fill up to 0xe byte, so the ret happens on 0xf
2710adae0cfdSpatrick     MCSymbol *Dot = OutContext.createTempSymbol();
2711adae0cfdSpatrick     OutStreamer->emitLabel(Dot);
2712adae0cfdSpatrick     const MCExpr *DotE = MCSymbolRefExpr::create(Dot, OutContext);
2713adae0cfdSpatrick     const MCExpr *BaseE = MCSymbolRefExpr::create(
2714adae0cfdSpatrick         TM.getSymbol(&MF->getFunction()), OutContext);
2715adae0cfdSpatrick     // .fill (0xf - ((DotE - BaseE) & 0xf)), 1, 0xcc
2716adae0cfdSpatrick     const MCExpr *FillE = MCBinaryExpr::createSub(
2717adae0cfdSpatrick         MCConstantExpr::create(0xf, OutContext),
2718adae0cfdSpatrick         MCBinaryExpr::createAnd(
2719adae0cfdSpatrick           MCBinaryExpr::createSub(DotE, BaseE, OutContext),
2720adae0cfdSpatrick           MCConstantExpr::create(0xf, OutContext),
2721adae0cfdSpatrick           OutContext),
2722adae0cfdSpatrick         OutContext);
2723adae0cfdSpatrick     OutStreamer->emitFill(*FillE, 0xCC);
2724adae0cfdSpatrick 
2725adae0cfdSpatrick     // And finally emit the jump target symbol
2726adae0cfdSpatrick     OutStreamer->emitLabel(RGSuccSym);
2727adae0cfdSpatrick     return;
2728adae0cfdSpatrick   }
2729adae0cfdSpatrick 
2730adae0cfdSpatrick   case X86::JMP_TRAP: {
2731adae0cfdSpatrick     MCSymbol *RGSuccSym = OutContext.createTempSymbol();
2732adae0cfdSpatrick     const MCExpr *RGSuccExpr = MCSymbolRefExpr::create(RGSuccSym, OutContext);
2733adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::JMP_1).addExpr(RGSuccExpr));
2734adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2735adae0cfdSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::INT3));
2736*a96b3639Srobert     OutStreamer->emitValueToAlignment(Align(8), 0xCC, 1);
2737adae0cfdSpatrick     OutStreamer->emitLabel(RGSuccSym);
2738adae0cfdSpatrick     return;
2739adae0cfdSpatrick   }
2740adae0cfdSpatrick 
274109467b48Spatrick   case X86::SEH_PushReg:
274209467b48Spatrick   case X86::SEH_SaveReg:
274309467b48Spatrick   case X86::SEH_SaveXMM:
274409467b48Spatrick   case X86::SEH_StackAlloc:
274509467b48Spatrick   case X86::SEH_StackAlign:
274609467b48Spatrick   case X86::SEH_SetFrame:
274709467b48Spatrick   case X86::SEH_PushFrame:
274809467b48Spatrick   case X86::SEH_EndPrologue:
274909467b48Spatrick     EmitSEHInstruction(MI);
275009467b48Spatrick     return;
275109467b48Spatrick 
275209467b48Spatrick   case X86::SEH_Epilogue: {
275309467b48Spatrick     assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
275409467b48Spatrick     MachineBasicBlock::const_iterator MBBI(MI);
275509467b48Spatrick     // Check if preceded by a call and emit nop if so.
275609467b48Spatrick     for (MBBI = PrevCrossBBInst(MBBI);
275709467b48Spatrick          MBBI != MachineBasicBlock::const_iterator();
275809467b48Spatrick          MBBI = PrevCrossBBInst(MBBI)) {
275909467b48Spatrick       // Conservatively assume that pseudo instructions don't emit code and keep
276009467b48Spatrick       // looking for a call. We may emit an unnecessary nop in some cases.
276109467b48Spatrick       if (!MBBI->isPseudo()) {
276209467b48Spatrick         if (MBBI->isCall())
276309467b48Spatrick           EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
276409467b48Spatrick         break;
276509467b48Spatrick       }
276609467b48Spatrick     }
276709467b48Spatrick     return;
276809467b48Spatrick   }
2769a0747c9fSpatrick   case X86::UBSAN_UD1:
2770a0747c9fSpatrick     EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)
2771a0747c9fSpatrick                                 .addReg(X86::EAX)
2772a0747c9fSpatrick                                 .addReg(X86::EAX)
2773a0747c9fSpatrick                                 .addImm(1)
2774a0747c9fSpatrick                                 .addReg(X86::NoRegister)
2775a0747c9fSpatrick                                 .addImm(MI->getOperand(0).getImm())
2776a0747c9fSpatrick                                 .addReg(X86::NoRegister));
2777a0747c9fSpatrick     return;
2778*a96b3639Srobert   case X86::CALL64pcrel32:
2779*a96b3639Srobert     if (IndCSPrefix && MI->hasRegisterImplicitUseOperand(X86::R11))
2780*a96b3639Srobert       EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2781*a96b3639Srobert     break;
278209467b48Spatrick   }
278309467b48Spatrick 
278409467b48Spatrick   MCInst TmpInst;
278509467b48Spatrick   MCInstLowering.Lower(MI, TmpInst);
278609467b48Spatrick 
278709467b48Spatrick   // Stackmap shadows cannot include branch targets, so we can count the bytes
278809467b48Spatrick   // in a call towards the shadow, but must ensure that the no thread returns
278909467b48Spatrick   // in to the stackmap shadow.  The only way to achieve this is if the call
279009467b48Spatrick   // is at the end of the shadow.
279109467b48Spatrick   if (MI->isCall()) {
279209467b48Spatrick     // Count then size of the call towards the shadow
279309467b48Spatrick     SMShadowTracker.count(TmpInst, getSubtargetInfo(), CodeEmitter.get());
279409467b48Spatrick     // Then flush the shadow so that we fill with nops before the call, not
279509467b48Spatrick     // after it.
279609467b48Spatrick     SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
279709467b48Spatrick     // Then emit the call
2798097a140dSpatrick     OutStreamer->emitInstruction(TmpInst, getSubtargetInfo());
279909467b48Spatrick     return;
280009467b48Spatrick   }
280109467b48Spatrick 
280209467b48Spatrick   EmitAndCountInstruction(TmpInst);
280309467b48Spatrick }
2804adae0cfdSpatrick 
2805adae0cfdSpatrick /// Emit Trap bytes to the specified power of two alignment
emitTrapToAlignment(Align Alignment) const2806adae0cfdSpatrick void X86AsmPrinter::emitTrapToAlignment(Align Alignment) const {
2807adae0cfdSpatrick   if (Alignment == Align(1)) return;
2808*a96b3639Srobert   OutStreamer->emitValueToAlignment(Alignment, 0xCC, 1);
2809adae0cfdSpatrick }
2810