1*9880d681SAndroid Build Coastguard Worker //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains code to lower X86 MachineInstrs to their corresponding
11*9880d681SAndroid Build Coastguard Worker // MCInst records.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "X86AsmPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "X86RegisterInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "X86ShuffleDecodeConstantPool.h"
18*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/X86ATTInstPrinter.h"
19*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/X86BaseInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "Utils/X86ShuffleDecode.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/iterator_range.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineOperand.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfoImpls.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/StackMaps.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalValue.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixup.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstBuilder.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLoweringObjectFile.h"
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker using namespace llvm;
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker namespace {
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker /// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
53*9880d681SAndroid Build Coastguard Worker class X86MCInstLower {
54*9880d681SAndroid Build Coastguard Worker MCContext &Ctx;
55*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF;
56*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM;
57*9880d681SAndroid Build Coastguard Worker const MCAsmInfo &MAI;
58*9880d681SAndroid Build Coastguard Worker X86AsmPrinter &AsmPrinter;
59*9880d681SAndroid Build Coastguard Worker public:
60*9880d681SAndroid Build Coastguard Worker X86MCInstLower(const MachineFunction &MF, X86AsmPrinter &asmprinter);
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker Optional<MCOperand> LowerMachineOperand(const MachineInstr *MI,
63*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO) const;
64*9880d681SAndroid Build Coastguard Worker void Lower(const MachineInstr *MI, MCInst &OutMI) const;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const;
67*9880d681SAndroid Build Coastguard Worker MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker private:
70*9880d681SAndroid Build Coastguard Worker MachineModuleInfoMachO &getMachOMMI() const;
getMang() const71*9880d681SAndroid Build Coastguard Worker Mangler *getMang() const {
72*9880d681SAndroid Build Coastguard Worker return AsmPrinter.Mang;
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker };
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker // Emit a minimal sequence of nops spanning NumBytes bytes.
79*9880d681SAndroid Build Coastguard Worker static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
80*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI);
81*9880d681SAndroid Build Coastguard Worker
count(MCInst & Inst,const MCSubtargetInfo & STI,MCCodeEmitter * CodeEmitter)82*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,
83*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
84*9880d681SAndroid Build Coastguard Worker MCCodeEmitter *CodeEmitter) {
85*9880d681SAndroid Build Coastguard Worker if (InShadow) {
86*9880d681SAndroid Build Coastguard Worker SmallString<256> Code;
87*9880d681SAndroid Build Coastguard Worker SmallVector<MCFixup, 4> Fixups;
88*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(Code);
89*9880d681SAndroid Build Coastguard Worker CodeEmitter->encodeInstruction(Inst, VecOS, Fixups, STI);
90*9880d681SAndroid Build Coastguard Worker CurrentShadowSize += Code.size();
91*9880d681SAndroid Build Coastguard Worker if (CurrentShadowSize >= RequiredShadowSize)
92*9880d681SAndroid Build Coastguard Worker InShadow = false; // The shadow is big enough. Stop counting.
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker
emitShadowPadding(MCStreamer & OutStreamer,const MCSubtargetInfo & STI)96*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
97*9880d681SAndroid Build Coastguard Worker MCStreamer &OutStreamer, const MCSubtargetInfo &STI) {
98*9880d681SAndroid Build Coastguard Worker if (InShadow && CurrentShadowSize < RequiredShadowSize) {
99*9880d681SAndroid Build Coastguard Worker InShadow = false;
100*9880d681SAndroid Build Coastguard Worker EmitNops(OutStreamer, RequiredShadowSize - CurrentShadowSize,
101*9880d681SAndroid Build Coastguard Worker MF->getSubtarget<X86Subtarget>().is64Bit(), STI);
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker }
104*9880d681SAndroid Build Coastguard Worker
EmitAndCountInstruction(MCInst & Inst)105*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
106*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(Inst, getSubtargetInfo());
107*9880d681SAndroid Build Coastguard Worker SMShadowTracker.count(Inst, getSubtargetInfo(), CodeEmitter.get());
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
X86MCInstLower(const MachineFunction & mf,X86AsmPrinter & asmprinter)110*9880d681SAndroid Build Coastguard Worker X86MCInstLower::X86MCInstLower(const MachineFunction &mf,
111*9880d681SAndroid Build Coastguard Worker X86AsmPrinter &asmprinter)
112*9880d681SAndroid Build Coastguard Worker : Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()), MAI(*TM.getMCAsmInfo()),
113*9880d681SAndroid Build Coastguard Worker AsmPrinter(asmprinter) {}
114*9880d681SAndroid Build Coastguard Worker
getMachOMMI() const115*9880d681SAndroid Build Coastguard Worker MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
116*9880d681SAndroid Build Coastguard Worker return MF.getMMI().getObjFileInfo<MachineModuleInfoMachO>();
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker /// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
121*9880d681SAndroid Build Coastguard Worker /// operand to an MCSymbol.
122*9880d681SAndroid Build Coastguard Worker MCSymbol *X86MCInstLower::
GetSymbolFromOperand(const MachineOperand & MO) const123*9880d681SAndroid Build Coastguard Worker GetSymbolFromOperand(const MachineOperand &MO) const {
124*9880d681SAndroid Build Coastguard Worker const DataLayout &DL = MF.getDataLayout();
125*9880d681SAndroid Build Coastguard Worker assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference");
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker MCSymbol *Sym = nullptr;
128*9880d681SAndroid Build Coastguard Worker SmallString<128> Name;
129*9880d681SAndroid Build Coastguard Worker StringRef Suffix;
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker switch (MO.getTargetFlags()) {
132*9880d681SAndroid Build Coastguard Worker case X86II::MO_DLLIMPORT:
133*9880d681SAndroid Build Coastguard Worker // Handle dllimport linkage.
134*9880d681SAndroid Build Coastguard Worker Name += "__imp_";
135*9880d681SAndroid Build Coastguard Worker break;
136*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY:
137*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
138*9880d681SAndroid Build Coastguard Worker Suffix = "$non_lazy_ptr";
139*9880d681SAndroid Build Coastguard Worker break;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker if (!Suffix.empty())
143*9880d681SAndroid Build Coastguard Worker Name += DL.getPrivateGlobalPrefix();
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker if (MO.isGlobal()) {
146*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV = MO.getGlobal();
147*9880d681SAndroid Build Coastguard Worker AsmPrinter.getNameWithPrefix(Name, GV);
148*9880d681SAndroid Build Coastguard Worker } else if (MO.isSymbol()) {
149*9880d681SAndroid Build Coastguard Worker Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
150*9880d681SAndroid Build Coastguard Worker } else if (MO.isMBB()) {
151*9880d681SAndroid Build Coastguard Worker assert(Suffix.empty());
152*9880d681SAndroid Build Coastguard Worker Sym = MO.getMBB()->getSymbol();
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker Name += Suffix;
156*9880d681SAndroid Build Coastguard Worker if (!Sym)
157*9880d681SAndroid Build Coastguard Worker Sym = Ctx.getOrCreateSymbol(Name);
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker // If the target flags on the operand changes the name of the symbol, do that
160*9880d681SAndroid Build Coastguard Worker // before we return the symbol.
161*9880d681SAndroid Build Coastguard Worker switch (MO.getTargetFlags()) {
162*9880d681SAndroid Build Coastguard Worker default: break;
163*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY:
164*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
165*9880d681SAndroid Build Coastguard Worker MachineModuleInfoImpl::StubValueTy &StubSym =
166*9880d681SAndroid Build Coastguard Worker getMachOMMI().getGVStubEntry(Sym);
167*9880d681SAndroid Build Coastguard Worker if (!StubSym.getPointer()) {
168*9880d681SAndroid Build Coastguard Worker assert(MO.isGlobal() && "Extern symbol not handled yet");
169*9880d681SAndroid Build Coastguard Worker StubSym =
170*9880d681SAndroid Build Coastguard Worker MachineModuleInfoImpl::
171*9880d681SAndroid Build Coastguard Worker StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()),
172*9880d681SAndroid Build Coastguard Worker !MO.getGlobal()->hasInternalLinkage());
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker break;
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker return Sym;
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const181*9880d681SAndroid Build Coastguard Worker MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
182*9880d681SAndroid Build Coastguard Worker MCSymbol *Sym) const {
183*9880d681SAndroid Build Coastguard Worker // FIXME: We would like an efficient form for this, so we don't have to do a
184*9880d681SAndroid Build Coastguard Worker // lot of extra uniquing.
185*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = nullptr;
186*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker switch (MO.getTargetFlags()) {
189*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unknown target flag on GV operand");
190*9880d681SAndroid Build Coastguard Worker case X86II::MO_NO_FLAG: // No flag.
191*9880d681SAndroid Build Coastguard Worker // These affect the name of the symbol, not any suffix.
192*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY:
193*9880d681SAndroid Build Coastguard Worker case X86II::MO_DLLIMPORT:
194*9880d681SAndroid Build Coastguard Worker break;
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break;
197*9880d681SAndroid Build Coastguard Worker case X86II::MO_TLVP_PIC_BASE:
198*9880d681SAndroid Build Coastguard Worker Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
199*9880d681SAndroid Build Coastguard Worker // Subtract the pic base.
200*9880d681SAndroid Build Coastguard Worker Expr = MCBinaryExpr::createSub(Expr,
201*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(MF.getPICBaseSymbol(),
202*9880d681SAndroid Build Coastguard Worker Ctx),
203*9880d681SAndroid Build Coastguard Worker Ctx);
204*9880d681SAndroid Build Coastguard Worker break;
205*9880d681SAndroid Build Coastguard Worker case X86II::MO_SECREL: RefKind = MCSymbolRefExpr::VK_SECREL; break;
206*9880d681SAndroid Build Coastguard Worker case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break;
207*9880d681SAndroid Build Coastguard Worker case X86II::MO_TLSLD: RefKind = MCSymbolRefExpr::VK_TLSLD; break;
208*9880d681SAndroid Build Coastguard Worker case X86II::MO_TLSLDM: RefKind = MCSymbolRefExpr::VK_TLSLDM; break;
209*9880d681SAndroid Build Coastguard Worker case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
210*9880d681SAndroid Build Coastguard Worker case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
211*9880d681SAndroid Build Coastguard Worker case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break;
212*9880d681SAndroid Build Coastguard Worker case X86II::MO_DTPOFF: RefKind = MCSymbolRefExpr::VK_DTPOFF; break;
213*9880d681SAndroid Build Coastguard Worker case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break;
214*9880d681SAndroid Build Coastguard Worker case X86II::MO_GOTNTPOFF: RefKind = MCSymbolRefExpr::VK_GOTNTPOFF; break;
215*9880d681SAndroid Build Coastguard Worker case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;
216*9880d681SAndroid Build Coastguard Worker case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break;
217*9880d681SAndroid Build Coastguard Worker case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break;
218*9880d681SAndroid Build Coastguard Worker case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break;
219*9880d681SAndroid Build Coastguard Worker case X86II::MO_PIC_BASE_OFFSET:
220*9880d681SAndroid Build Coastguard Worker case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
221*9880d681SAndroid Build Coastguard Worker Expr = MCSymbolRefExpr::create(Sym, Ctx);
222*9880d681SAndroid Build Coastguard Worker // Subtract the pic base.
223*9880d681SAndroid Build Coastguard Worker Expr = MCBinaryExpr::createSub(Expr,
224*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx),
225*9880d681SAndroid Build Coastguard Worker Ctx);
226*9880d681SAndroid Build Coastguard Worker if (MO.isJTI()) {
227*9880d681SAndroid Build Coastguard Worker assert(MAI.doesSetDirectiveSuppressReloc());
228*9880d681SAndroid Build Coastguard Worker // If .set directive is supported, use it to reduce the number of
229*9880d681SAndroid Build Coastguard Worker // relocations the assembler will generate for differences between
230*9880d681SAndroid Build Coastguard Worker // local labels. This is only safe when the symbols are in the same
231*9880d681SAndroid Build Coastguard Worker // section so we are restricting it to jumptable references.
232*9880d681SAndroid Build Coastguard Worker MCSymbol *Label = Ctx.createTempSymbol();
233*9880d681SAndroid Build Coastguard Worker AsmPrinter.OutStreamer->EmitAssignment(Label, Expr);
234*9880d681SAndroid Build Coastguard Worker Expr = MCSymbolRefExpr::create(Label, Ctx);
235*9880d681SAndroid Build Coastguard Worker }
236*9880d681SAndroid Build Coastguard Worker break;
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker if (!Expr)
240*9880d681SAndroid Build Coastguard Worker Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
243*9880d681SAndroid Build Coastguard Worker Expr = MCBinaryExpr::createAdd(Expr,
244*9880d681SAndroid Build Coastguard Worker MCConstantExpr::create(MO.getOffset(), Ctx),
245*9880d681SAndroid Build Coastguard Worker Ctx);
246*9880d681SAndroid Build Coastguard Worker return MCOperand::createExpr(Expr);
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker /// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
251*9880d681SAndroid Build Coastguard Worker /// a short fixed-register form.
SimplifyShortImmForm(MCInst & Inst,unsigned Opcode)252*9880d681SAndroid Build Coastguard Worker static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
253*9880d681SAndroid Build Coastguard Worker unsigned ImmOp = Inst.getNumOperands() - 1;
254*9880d681SAndroid Build Coastguard Worker assert(Inst.getOperand(0).isReg() &&
255*9880d681SAndroid Build Coastguard Worker (Inst.getOperand(ImmOp).isImm() || Inst.getOperand(ImmOp).isExpr()) &&
256*9880d681SAndroid Build Coastguard Worker ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() &&
257*9880d681SAndroid Build Coastguard Worker Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) ||
258*9880d681SAndroid Build Coastguard Worker Inst.getNumOperands() == 2) && "Unexpected instruction!");
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker // Check whether the destination register can be fixed.
261*9880d681SAndroid Build Coastguard Worker unsigned Reg = Inst.getOperand(0).getReg();
262*9880d681SAndroid Build Coastguard Worker if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
263*9880d681SAndroid Build Coastguard Worker return;
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker // If so, rewrite the instruction.
266*9880d681SAndroid Build Coastguard Worker MCOperand Saved = Inst.getOperand(ImmOp);
267*9880d681SAndroid Build Coastguard Worker Inst = MCInst();
268*9880d681SAndroid Build Coastguard Worker Inst.setOpcode(Opcode);
269*9880d681SAndroid Build Coastguard Worker Inst.addOperand(Saved);
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker /// \brief If a movsx instruction has a shorter encoding for the used register
273*9880d681SAndroid Build Coastguard Worker /// simplify the instruction to use it instead.
SimplifyMOVSX(MCInst & Inst)274*9880d681SAndroid Build Coastguard Worker static void SimplifyMOVSX(MCInst &Inst) {
275*9880d681SAndroid Build Coastguard Worker unsigned NewOpcode = 0;
276*9880d681SAndroid Build Coastguard Worker unsigned Op0 = Inst.getOperand(0).getReg(), Op1 = Inst.getOperand(1).getReg();
277*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
278*9880d681SAndroid Build Coastguard Worker default:
279*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected instruction!");
280*9880d681SAndroid Build Coastguard Worker case X86::MOVSX16rr8: // movsbw %al, %ax --> cbtw
281*9880d681SAndroid Build Coastguard Worker if (Op0 == X86::AX && Op1 == X86::AL)
282*9880d681SAndroid Build Coastguard Worker NewOpcode = X86::CBW;
283*9880d681SAndroid Build Coastguard Worker break;
284*9880d681SAndroid Build Coastguard Worker case X86::MOVSX32rr16: // movswl %ax, %eax --> cwtl
285*9880d681SAndroid Build Coastguard Worker if (Op0 == X86::EAX && Op1 == X86::AX)
286*9880d681SAndroid Build Coastguard Worker NewOpcode = X86::CWDE;
287*9880d681SAndroid Build Coastguard Worker break;
288*9880d681SAndroid Build Coastguard Worker case X86::MOVSX64rr32: // movslq %eax, %rax --> cltq
289*9880d681SAndroid Build Coastguard Worker if (Op0 == X86::RAX && Op1 == X86::EAX)
290*9880d681SAndroid Build Coastguard Worker NewOpcode = X86::CDQE;
291*9880d681SAndroid Build Coastguard Worker break;
292*9880d681SAndroid Build Coastguard Worker }
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker if (NewOpcode != 0) {
295*9880d681SAndroid Build Coastguard Worker Inst = MCInst();
296*9880d681SAndroid Build Coastguard Worker Inst.setOpcode(NewOpcode);
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker /// \brief Simplify things like MOV32rm to MOV32o32a.
SimplifyShortMoveForm(X86AsmPrinter & Printer,MCInst & Inst,unsigned Opcode)301*9880d681SAndroid Build Coastguard Worker static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst,
302*9880d681SAndroid Build Coastguard Worker unsigned Opcode) {
303*9880d681SAndroid Build Coastguard Worker // Don't make these simplifications in 64-bit mode; other assemblers don't
304*9880d681SAndroid Build Coastguard Worker // perform them because they make the code larger.
305*9880d681SAndroid Build Coastguard Worker if (Printer.getSubtarget().is64Bit())
306*9880d681SAndroid Build Coastguard Worker return;
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
309*9880d681SAndroid Build Coastguard Worker unsigned AddrBase = IsStore;
310*9880d681SAndroid Build Coastguard Worker unsigned RegOp = IsStore ? 0 : 5;
311*9880d681SAndroid Build Coastguard Worker unsigned AddrOp = AddrBase + 3;
312*9880d681SAndroid Build Coastguard Worker assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
313*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrBaseReg).isReg() &&
314*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrScaleAmt).isImm() &&
315*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrIndexReg).isReg() &&
316*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrSegmentReg).isReg() &&
317*9880d681SAndroid Build Coastguard Worker (Inst.getOperand(AddrOp).isExpr() ||
318*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrOp).isImm()) &&
319*9880d681SAndroid Build Coastguard Worker "Unexpected instruction!");
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker // Check whether the destination register can be fixed.
322*9880d681SAndroid Build Coastguard Worker unsigned Reg = Inst.getOperand(RegOp).getReg();
323*9880d681SAndroid Build Coastguard Worker if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
324*9880d681SAndroid Build Coastguard Worker return;
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker // Check whether this is an absolute address.
327*9880d681SAndroid Build Coastguard Worker // FIXME: We know TLVP symbol refs aren't, but there should be a better way
328*9880d681SAndroid Build Coastguard Worker // to do this here.
329*9880d681SAndroid Build Coastguard Worker bool Absolute = true;
330*9880d681SAndroid Build Coastguard Worker if (Inst.getOperand(AddrOp).isExpr()) {
331*9880d681SAndroid Build Coastguard Worker const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
332*9880d681SAndroid Build Coastguard Worker if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE))
333*9880d681SAndroid Build Coastguard Worker if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
334*9880d681SAndroid Build Coastguard Worker Absolute = false;
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker if (Absolute &&
338*9880d681SAndroid Build Coastguard Worker (Inst.getOperand(AddrBase + X86::AddrBaseReg).getReg() != 0 ||
339*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrScaleAmt).getImm() != 1 ||
340*9880d681SAndroid Build Coastguard Worker Inst.getOperand(AddrBase + X86::AddrIndexReg).getReg() != 0))
341*9880d681SAndroid Build Coastguard Worker return;
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker // If so, rewrite the instruction.
344*9880d681SAndroid Build Coastguard Worker MCOperand Saved = Inst.getOperand(AddrOp);
345*9880d681SAndroid Build Coastguard Worker MCOperand Seg = Inst.getOperand(AddrBase + X86::AddrSegmentReg);
346*9880d681SAndroid Build Coastguard Worker Inst = MCInst();
347*9880d681SAndroid Build Coastguard Worker Inst.setOpcode(Opcode);
348*9880d681SAndroid Build Coastguard Worker Inst.addOperand(Saved);
349*9880d681SAndroid Build Coastguard Worker Inst.addOperand(Seg);
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
getRetOpcode(const X86Subtarget & Subtarget)352*9880d681SAndroid Build Coastguard Worker static unsigned getRetOpcode(const X86Subtarget &Subtarget) {
353*9880d681SAndroid Build Coastguard Worker return Subtarget.is64Bit() ? X86::RETQ : X86::RETL;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker Optional<MCOperand>
LowerMachineOperand(const MachineInstr * MI,const MachineOperand & MO) const357*9880d681SAndroid Build Coastguard Worker X86MCInstLower::LowerMachineOperand(const MachineInstr *MI,
358*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO) const {
359*9880d681SAndroid Build Coastguard Worker switch (MO.getType()) {
360*9880d681SAndroid Build Coastguard Worker default:
361*9880d681SAndroid Build Coastguard Worker MI->dump();
362*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unknown operand type");
363*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Register:
364*9880d681SAndroid Build Coastguard Worker // Ignore all implicit register operands.
365*9880d681SAndroid Build Coastguard Worker if (MO.isImplicit())
366*9880d681SAndroid Build Coastguard Worker return None;
367*9880d681SAndroid Build Coastguard Worker return MCOperand::createReg(MO.getReg());
368*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
369*9880d681SAndroid Build Coastguard Worker return MCOperand::createImm(MO.getImm());
370*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_MachineBasicBlock:
371*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_GlobalAddress:
372*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ExternalSymbol:
373*9880d681SAndroid Build Coastguard Worker return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
374*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_MCSymbol:
375*9880d681SAndroid Build Coastguard Worker return LowerSymbolOperand(MO, MO.getMCSymbol());
376*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_JumpTableIndex:
377*9880d681SAndroid Build Coastguard Worker return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
378*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ConstantPoolIndex:
379*9880d681SAndroid Build Coastguard Worker return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
380*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_BlockAddress:
381*9880d681SAndroid Build Coastguard Worker return LowerSymbolOperand(
382*9880d681SAndroid Build Coastguard Worker MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
383*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_RegisterMask:
384*9880d681SAndroid Build Coastguard Worker // Ignore call clobbers.
385*9880d681SAndroid Build Coastguard Worker return None;
386*9880d681SAndroid Build Coastguard Worker }
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
Lower(const MachineInstr * MI,MCInst & OutMI) const389*9880d681SAndroid Build Coastguard Worker void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
390*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(MI->getOpcode());
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Worker for (const MachineOperand &MO : MI->operands())
393*9880d681SAndroid Build Coastguard Worker if (auto MaybeMCOp = LowerMachineOperand(MI, MO))
394*9880d681SAndroid Build Coastguard Worker OutMI.addOperand(MaybeMCOp.getValue());
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Worker // Handle a few special cases to eliminate operand modifiers.
397*9880d681SAndroid Build Coastguard Worker ReSimplify:
398*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
399*9880d681SAndroid Build Coastguard Worker case X86::LEA64_32r:
400*9880d681SAndroid Build Coastguard Worker case X86::LEA64r:
401*9880d681SAndroid Build Coastguard Worker case X86::LEA16r:
402*9880d681SAndroid Build Coastguard Worker case X86::LEA32r:
403*9880d681SAndroid Build Coastguard Worker // LEA should have a segment register, but it must be empty.
404*9880d681SAndroid Build Coastguard Worker assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands &&
405*9880d681SAndroid Build Coastguard Worker "Unexpected # of LEA operands");
406*9880d681SAndroid Build Coastguard Worker assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 &&
407*9880d681SAndroid Build Coastguard Worker "LEA has segment specified!");
408*9880d681SAndroid Build Coastguard Worker break;
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker // Commute operands to get a smaller encoding by using VEX.R instead of VEX.B
411*9880d681SAndroid Build Coastguard Worker // if one of the registers is extended, but other isn't.
412*9880d681SAndroid Build Coastguard Worker case X86::VMOVZPQILo2PQIrr:
413*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPDrr:
414*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPDYrr:
415*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPSrr:
416*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPSYrr:
417*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQArr:
418*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQAYrr:
419*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQUrr:
420*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQUYrr:
421*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPDrr:
422*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPDYrr:
423*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPSrr:
424*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPSYrr: {
425*9880d681SAndroid Build Coastguard Worker if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) &&
426*9880d681SAndroid Build Coastguard Worker X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg())) {
427*9880d681SAndroid Build Coastguard Worker unsigned NewOpc;
428*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
429*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
430*9880d681SAndroid Build Coastguard Worker case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break;
431*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
432*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
433*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
434*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
435*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
436*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
437*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
438*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
439*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
440*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
441*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
442*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(NewOpc);
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker break;
447*9880d681SAndroid Build Coastguard Worker }
448*9880d681SAndroid Build Coastguard Worker case X86::VMOVSDrr:
449*9880d681SAndroid Build Coastguard Worker case X86::VMOVSSrr: {
450*9880d681SAndroid Build Coastguard Worker if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) &&
451*9880d681SAndroid Build Coastguard Worker X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) {
452*9880d681SAndroid Build Coastguard Worker unsigned NewOpc;
453*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
454*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
455*9880d681SAndroid Build Coastguard Worker case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
456*9880d681SAndroid Build Coastguard Worker case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
457*9880d681SAndroid Build Coastguard Worker }
458*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(NewOpc);
459*9880d681SAndroid Build Coastguard Worker }
460*9880d681SAndroid Build Coastguard Worker break;
461*9880d681SAndroid Build Coastguard Worker }
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have register
464*9880d681SAndroid Build Coastguard Worker // inputs modeled as normal uses instead of implicit uses. As such, truncate
465*9880d681SAndroid Build Coastguard Worker // off all but the first operand (the callee). FIXME: Change isel.
466*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr64:
467*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr64_REX:
468*9880d681SAndroid Build Coastguard Worker case X86::CALL64r:
469*9880d681SAndroid Build Coastguard Worker case X86::CALL64pcrel32: {
470*9880d681SAndroid Build Coastguard Worker unsigned Opcode = OutMI.getOpcode();
471*9880d681SAndroid Build Coastguard Worker MCOperand Saved = OutMI.getOperand(0);
472*9880d681SAndroid Build Coastguard Worker OutMI = MCInst();
473*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(Opcode);
474*9880d681SAndroid Build Coastguard Worker OutMI.addOperand(Saved);
475*9880d681SAndroid Build Coastguard Worker break;
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker case X86::EH_RETURN:
479*9880d681SAndroid Build Coastguard Worker case X86::EH_RETURN64: {
480*9880d681SAndroid Build Coastguard Worker OutMI = MCInst();
481*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
482*9880d681SAndroid Build Coastguard Worker break;
483*9880d681SAndroid Build Coastguard Worker }
484*9880d681SAndroid Build Coastguard Worker
485*9880d681SAndroid Build Coastguard Worker case X86::CLEANUPRET: {
486*9880d681SAndroid Build Coastguard Worker // Replace CATCHRET with the appropriate RET.
487*9880d681SAndroid Build Coastguard Worker OutMI = MCInst();
488*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
489*9880d681SAndroid Build Coastguard Worker break;
490*9880d681SAndroid Build Coastguard Worker }
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker case X86::CATCHRET: {
493*9880d681SAndroid Build Coastguard Worker // Replace CATCHRET with the appropriate RET.
494*9880d681SAndroid Build Coastguard Worker const X86Subtarget &Subtarget = AsmPrinter.getSubtarget();
495*9880d681SAndroid Build Coastguard Worker unsigned ReturnReg = Subtarget.is64Bit() ? X86::RAX : X86::EAX;
496*9880d681SAndroid Build Coastguard Worker OutMI = MCInst();
497*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(getRetOpcode(Subtarget));
498*9880d681SAndroid Build Coastguard Worker OutMI.addOperand(MCOperand::createReg(ReturnReg));
499*9880d681SAndroid Build Coastguard Worker break;
500*9880d681SAndroid Build Coastguard Worker }
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions.
503*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr:
504*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd:
505*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd64: {
506*9880d681SAndroid Build Coastguard Worker unsigned Opcode;
507*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
508*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
509*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr: Opcode = X86::JMP32r; break;
510*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd:
511*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd64: Opcode = X86::JMP_1; break;
512*9880d681SAndroid Build Coastguard Worker }
513*9880d681SAndroid Build Coastguard Worker
514*9880d681SAndroid Build Coastguard Worker MCOperand Saved = OutMI.getOperand(0);
515*9880d681SAndroid Build Coastguard Worker OutMI = MCInst();
516*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(Opcode);
517*9880d681SAndroid Build Coastguard Worker OutMI.addOperand(Saved);
518*9880d681SAndroid Build Coastguard Worker break;
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker case X86::DEC16r:
522*9880d681SAndroid Build Coastguard Worker case X86::DEC32r:
523*9880d681SAndroid Build Coastguard Worker case X86::INC16r:
524*9880d681SAndroid Build Coastguard Worker case X86::INC32r:
525*9880d681SAndroid Build Coastguard Worker // If we aren't in 64-bit mode we can use the 1-byte inc/dec instructions.
526*9880d681SAndroid Build Coastguard Worker if (!AsmPrinter.getSubtarget().is64Bit()) {
527*9880d681SAndroid Build Coastguard Worker unsigned Opcode;
528*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
529*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
530*9880d681SAndroid Build Coastguard Worker case X86::DEC16r: Opcode = X86::DEC16r_alt; break;
531*9880d681SAndroid Build Coastguard Worker case X86::DEC32r: Opcode = X86::DEC32r_alt; break;
532*9880d681SAndroid Build Coastguard Worker case X86::INC16r: Opcode = X86::INC16r_alt; break;
533*9880d681SAndroid Build Coastguard Worker case X86::INC32r: Opcode = X86::INC32r_alt; break;
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker OutMI.setOpcode(Opcode);
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker break;
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker // These are pseudo-ops for OR to help with the OR->ADD transformation. We do
540*9880d681SAndroid Build Coastguard Worker // this with an ugly goto in case the resultant OR uses EAX and needs the
541*9880d681SAndroid Build Coastguard Worker // short form.
542*9880d681SAndroid Build Coastguard Worker case X86::ADD16rr_DB: OutMI.setOpcode(X86::OR16rr); goto ReSimplify;
543*9880d681SAndroid Build Coastguard Worker case X86::ADD32rr_DB: OutMI.setOpcode(X86::OR32rr); goto ReSimplify;
544*9880d681SAndroid Build Coastguard Worker case X86::ADD64rr_DB: OutMI.setOpcode(X86::OR64rr); goto ReSimplify;
545*9880d681SAndroid Build Coastguard Worker case X86::ADD16ri_DB: OutMI.setOpcode(X86::OR16ri); goto ReSimplify;
546*9880d681SAndroid Build Coastguard Worker case X86::ADD32ri_DB: OutMI.setOpcode(X86::OR32ri); goto ReSimplify;
547*9880d681SAndroid Build Coastguard Worker case X86::ADD64ri32_DB: OutMI.setOpcode(X86::OR64ri32); goto ReSimplify;
548*9880d681SAndroid Build Coastguard Worker case X86::ADD16ri8_DB: OutMI.setOpcode(X86::OR16ri8); goto ReSimplify;
549*9880d681SAndroid Build Coastguard Worker case X86::ADD32ri8_DB: OutMI.setOpcode(X86::OR32ri8); goto ReSimplify;
550*9880d681SAndroid Build Coastguard Worker case X86::ADD64ri8_DB: OutMI.setOpcode(X86::OR64ri8); goto ReSimplify;
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker // Atomic load and store require a separate pseudo-inst because Acquire
553*9880d681SAndroid Build Coastguard Worker // implies mayStore and Release implies mayLoad; fix these to regular MOV
554*9880d681SAndroid Build Coastguard Worker // instructions here
555*9880d681SAndroid Build Coastguard Worker case X86::ACQUIRE_MOV8rm: OutMI.setOpcode(X86::MOV8rm); goto ReSimplify;
556*9880d681SAndroid Build Coastguard Worker case X86::ACQUIRE_MOV16rm: OutMI.setOpcode(X86::MOV16rm); goto ReSimplify;
557*9880d681SAndroid Build Coastguard Worker case X86::ACQUIRE_MOV32rm: OutMI.setOpcode(X86::MOV32rm); goto ReSimplify;
558*9880d681SAndroid Build Coastguard Worker case X86::ACQUIRE_MOV64rm: OutMI.setOpcode(X86::MOV64rm); goto ReSimplify;
559*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV8mr: OutMI.setOpcode(X86::MOV8mr); goto ReSimplify;
560*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV16mr: OutMI.setOpcode(X86::MOV16mr); goto ReSimplify;
561*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV32mr: OutMI.setOpcode(X86::MOV32mr); goto ReSimplify;
562*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV64mr: OutMI.setOpcode(X86::MOV64mr); goto ReSimplify;
563*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV8mi: OutMI.setOpcode(X86::MOV8mi); goto ReSimplify;
564*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV16mi: OutMI.setOpcode(X86::MOV16mi); goto ReSimplify;
565*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV32mi: OutMI.setOpcode(X86::MOV32mi); goto ReSimplify;
566*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_MOV64mi32: OutMI.setOpcode(X86::MOV64mi32); goto ReSimplify;
567*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD8mi: OutMI.setOpcode(X86::ADD8mi); goto ReSimplify;
568*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD8mr: OutMI.setOpcode(X86::ADD8mr); goto ReSimplify;
569*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD32mi: OutMI.setOpcode(X86::ADD32mi); goto ReSimplify;
570*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD32mr: OutMI.setOpcode(X86::ADD32mr); goto ReSimplify;
571*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD64mi32: OutMI.setOpcode(X86::ADD64mi32); goto ReSimplify;
572*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_ADD64mr: OutMI.setOpcode(X86::ADD64mr); goto ReSimplify;
573*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND8mi: OutMI.setOpcode(X86::AND8mi); goto ReSimplify;
574*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND8mr: OutMI.setOpcode(X86::AND8mr); goto ReSimplify;
575*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND32mi: OutMI.setOpcode(X86::AND32mi); goto ReSimplify;
576*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND32mr: OutMI.setOpcode(X86::AND32mr); goto ReSimplify;
577*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND64mi32: OutMI.setOpcode(X86::AND64mi32); goto ReSimplify;
578*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_AND64mr: OutMI.setOpcode(X86::AND64mr); goto ReSimplify;
579*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR8mi: OutMI.setOpcode(X86::OR8mi); goto ReSimplify;
580*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR8mr: OutMI.setOpcode(X86::OR8mr); goto ReSimplify;
581*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR32mi: OutMI.setOpcode(X86::OR32mi); goto ReSimplify;
582*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR32mr: OutMI.setOpcode(X86::OR32mr); goto ReSimplify;
583*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR64mi32: OutMI.setOpcode(X86::OR64mi32); goto ReSimplify;
584*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_OR64mr: OutMI.setOpcode(X86::OR64mr); goto ReSimplify;
585*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR8mi: OutMI.setOpcode(X86::XOR8mi); goto ReSimplify;
586*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR8mr: OutMI.setOpcode(X86::XOR8mr); goto ReSimplify;
587*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR32mi: OutMI.setOpcode(X86::XOR32mi); goto ReSimplify;
588*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR32mr: OutMI.setOpcode(X86::XOR32mr); goto ReSimplify;
589*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR64mi32: OutMI.setOpcode(X86::XOR64mi32); goto ReSimplify;
590*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_XOR64mr: OutMI.setOpcode(X86::XOR64mr); goto ReSimplify;
591*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_INC8m: OutMI.setOpcode(X86::INC8m); goto ReSimplify;
592*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_INC16m: OutMI.setOpcode(X86::INC16m); goto ReSimplify;
593*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_INC32m: OutMI.setOpcode(X86::INC32m); goto ReSimplify;
594*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_INC64m: OutMI.setOpcode(X86::INC64m); goto ReSimplify;
595*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_DEC8m: OutMI.setOpcode(X86::DEC8m); goto ReSimplify;
596*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_DEC16m: OutMI.setOpcode(X86::DEC16m); goto ReSimplify;
597*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_DEC32m: OutMI.setOpcode(X86::DEC32m); goto ReSimplify;
598*9880d681SAndroid Build Coastguard Worker case X86::RELEASE_DEC64m: OutMI.setOpcode(X86::DEC64m); goto ReSimplify;
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker // We don't currently select the correct instruction form for instructions
601*9880d681SAndroid Build Coastguard Worker // which have a short %eax, etc. form. Handle this by custom lowering, for
602*9880d681SAndroid Build Coastguard Worker // now.
603*9880d681SAndroid Build Coastguard Worker //
604*9880d681SAndroid Build Coastguard Worker // Note, we are currently not handling the following instructions:
605*9880d681SAndroid Build Coastguard Worker // MOV64ao8, MOV64o8a
606*9880d681SAndroid Build Coastguard Worker // XCHG16ar, XCHG32ar, XCHG64ar
607*9880d681SAndroid Build Coastguard Worker case X86::MOV8mr_NOREX:
608*9880d681SAndroid Build Coastguard Worker case X86::MOV8mr:
609*9880d681SAndroid Build Coastguard Worker case X86::MOV8rm_NOREX:
610*9880d681SAndroid Build Coastguard Worker case X86::MOV8rm:
611*9880d681SAndroid Build Coastguard Worker case X86::MOV16mr:
612*9880d681SAndroid Build Coastguard Worker case X86::MOV16rm:
613*9880d681SAndroid Build Coastguard Worker case X86::MOV32mr:
614*9880d681SAndroid Build Coastguard Worker case X86::MOV32rm: {
615*9880d681SAndroid Build Coastguard Worker unsigned NewOpc;
616*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
617*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
618*9880d681SAndroid Build Coastguard Worker case X86::MOV8mr_NOREX:
619*9880d681SAndroid Build Coastguard Worker case X86::MOV8mr: NewOpc = X86::MOV8o32a; break;
620*9880d681SAndroid Build Coastguard Worker case X86::MOV8rm_NOREX:
621*9880d681SAndroid Build Coastguard Worker case X86::MOV8rm: NewOpc = X86::MOV8ao32; break;
622*9880d681SAndroid Build Coastguard Worker case X86::MOV16mr: NewOpc = X86::MOV16o32a; break;
623*9880d681SAndroid Build Coastguard Worker case X86::MOV16rm: NewOpc = X86::MOV16ao32; break;
624*9880d681SAndroid Build Coastguard Worker case X86::MOV32mr: NewOpc = X86::MOV32o32a; break;
625*9880d681SAndroid Build Coastguard Worker case X86::MOV32rm: NewOpc = X86::MOV32ao32; break;
626*9880d681SAndroid Build Coastguard Worker }
627*9880d681SAndroid Build Coastguard Worker SimplifyShortMoveForm(AsmPrinter, OutMI, NewOpc);
628*9880d681SAndroid Build Coastguard Worker break;
629*9880d681SAndroid Build Coastguard Worker }
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker case X86::ADC8ri: case X86::ADC16ri: case X86::ADC32ri: case X86::ADC64ri32:
632*9880d681SAndroid Build Coastguard Worker case X86::ADD8ri: case X86::ADD16ri: case X86::ADD32ri: case X86::ADD64ri32:
633*9880d681SAndroid Build Coastguard Worker case X86::AND8ri: case X86::AND16ri: case X86::AND32ri: case X86::AND64ri32:
634*9880d681SAndroid Build Coastguard Worker case X86::CMP8ri: case X86::CMP16ri: case X86::CMP32ri: case X86::CMP64ri32:
635*9880d681SAndroid Build Coastguard Worker case X86::OR8ri: case X86::OR16ri: case X86::OR32ri: case X86::OR64ri32:
636*9880d681SAndroid Build Coastguard Worker case X86::SBB8ri: case X86::SBB16ri: case X86::SBB32ri: case X86::SBB64ri32:
637*9880d681SAndroid Build Coastguard Worker case X86::SUB8ri: case X86::SUB16ri: case X86::SUB32ri: case X86::SUB64ri32:
638*9880d681SAndroid Build Coastguard Worker case X86::TEST8ri:case X86::TEST16ri:case X86::TEST32ri:case X86::TEST64ri32:
639*9880d681SAndroid Build Coastguard Worker case X86::XOR8ri: case X86::XOR16ri: case X86::XOR32ri: case X86::XOR64ri32: {
640*9880d681SAndroid Build Coastguard Worker unsigned NewOpc;
641*9880d681SAndroid Build Coastguard Worker switch (OutMI.getOpcode()) {
642*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
643*9880d681SAndroid Build Coastguard Worker case X86::ADC8ri: NewOpc = X86::ADC8i8; break;
644*9880d681SAndroid Build Coastguard Worker case X86::ADC16ri: NewOpc = X86::ADC16i16; break;
645*9880d681SAndroid Build Coastguard Worker case X86::ADC32ri: NewOpc = X86::ADC32i32; break;
646*9880d681SAndroid Build Coastguard Worker case X86::ADC64ri32: NewOpc = X86::ADC64i32; break;
647*9880d681SAndroid Build Coastguard Worker case X86::ADD8ri: NewOpc = X86::ADD8i8; break;
648*9880d681SAndroid Build Coastguard Worker case X86::ADD16ri: NewOpc = X86::ADD16i16; break;
649*9880d681SAndroid Build Coastguard Worker case X86::ADD32ri: NewOpc = X86::ADD32i32; break;
650*9880d681SAndroid Build Coastguard Worker case X86::ADD64ri32: NewOpc = X86::ADD64i32; break;
651*9880d681SAndroid Build Coastguard Worker case X86::AND8ri: NewOpc = X86::AND8i8; break;
652*9880d681SAndroid Build Coastguard Worker case X86::AND16ri: NewOpc = X86::AND16i16; break;
653*9880d681SAndroid Build Coastguard Worker case X86::AND32ri: NewOpc = X86::AND32i32; break;
654*9880d681SAndroid Build Coastguard Worker case X86::AND64ri32: NewOpc = X86::AND64i32; break;
655*9880d681SAndroid Build Coastguard Worker case X86::CMP8ri: NewOpc = X86::CMP8i8; break;
656*9880d681SAndroid Build Coastguard Worker case X86::CMP16ri: NewOpc = X86::CMP16i16; break;
657*9880d681SAndroid Build Coastguard Worker case X86::CMP32ri: NewOpc = X86::CMP32i32; break;
658*9880d681SAndroid Build Coastguard Worker case X86::CMP64ri32: NewOpc = X86::CMP64i32; break;
659*9880d681SAndroid Build Coastguard Worker case X86::OR8ri: NewOpc = X86::OR8i8; break;
660*9880d681SAndroid Build Coastguard Worker case X86::OR16ri: NewOpc = X86::OR16i16; break;
661*9880d681SAndroid Build Coastguard Worker case X86::OR32ri: NewOpc = X86::OR32i32; break;
662*9880d681SAndroid Build Coastguard Worker case X86::OR64ri32: NewOpc = X86::OR64i32; break;
663*9880d681SAndroid Build Coastguard Worker case X86::SBB8ri: NewOpc = X86::SBB8i8; break;
664*9880d681SAndroid Build Coastguard Worker case X86::SBB16ri: NewOpc = X86::SBB16i16; break;
665*9880d681SAndroid Build Coastguard Worker case X86::SBB32ri: NewOpc = X86::SBB32i32; break;
666*9880d681SAndroid Build Coastguard Worker case X86::SBB64ri32: NewOpc = X86::SBB64i32; break;
667*9880d681SAndroid Build Coastguard Worker case X86::SUB8ri: NewOpc = X86::SUB8i8; break;
668*9880d681SAndroid Build Coastguard Worker case X86::SUB16ri: NewOpc = X86::SUB16i16; break;
669*9880d681SAndroid Build Coastguard Worker case X86::SUB32ri: NewOpc = X86::SUB32i32; break;
670*9880d681SAndroid Build Coastguard Worker case X86::SUB64ri32: NewOpc = X86::SUB64i32; break;
671*9880d681SAndroid Build Coastguard Worker case X86::TEST8ri: NewOpc = X86::TEST8i8; break;
672*9880d681SAndroid Build Coastguard Worker case X86::TEST16ri: NewOpc = X86::TEST16i16; break;
673*9880d681SAndroid Build Coastguard Worker case X86::TEST32ri: NewOpc = X86::TEST32i32; break;
674*9880d681SAndroid Build Coastguard Worker case X86::TEST64ri32: NewOpc = X86::TEST64i32; break;
675*9880d681SAndroid Build Coastguard Worker case X86::XOR8ri: NewOpc = X86::XOR8i8; break;
676*9880d681SAndroid Build Coastguard Worker case X86::XOR16ri: NewOpc = X86::XOR16i16; break;
677*9880d681SAndroid Build Coastguard Worker case X86::XOR32ri: NewOpc = X86::XOR32i32; break;
678*9880d681SAndroid Build Coastguard Worker case X86::XOR64ri32: NewOpc = X86::XOR64i32; break;
679*9880d681SAndroid Build Coastguard Worker }
680*9880d681SAndroid Build Coastguard Worker SimplifyShortImmForm(OutMI, NewOpc);
681*9880d681SAndroid Build Coastguard Worker break;
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // Try to shrink some forms of movsx.
685*9880d681SAndroid Build Coastguard Worker case X86::MOVSX16rr8:
686*9880d681SAndroid Build Coastguard Worker case X86::MOVSX32rr16:
687*9880d681SAndroid Build Coastguard Worker case X86::MOVSX64rr32:
688*9880d681SAndroid Build Coastguard Worker SimplifyMOVSX(OutMI);
689*9880d681SAndroid Build Coastguard Worker break;
690*9880d681SAndroid Build Coastguard Worker }
691*9880d681SAndroid Build Coastguard Worker }
692*9880d681SAndroid Build Coastguard Worker
LowerTlsAddr(X86MCInstLower & MCInstLowering,const MachineInstr & MI)693*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
694*9880d681SAndroid Build Coastguard Worker const MachineInstr &MI) {
695*9880d681SAndroid Build Coastguard Worker
696*9880d681SAndroid Build Coastguard Worker bool is64Bits = MI.getOpcode() == X86::TLS_addr64 ||
697*9880d681SAndroid Build Coastguard Worker MI.getOpcode() == X86::TLS_base_addr64;
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker bool needsPadding = MI.getOpcode() == X86::TLS_addr64;
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker MCContext &context = OutStreamer->getContext();
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker if (needsPadding)
704*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VariantKind SRVK;
707*9880d681SAndroid Build Coastguard Worker switch (MI.getOpcode()) {
708*9880d681SAndroid Build Coastguard Worker case X86::TLS_addr32:
709*9880d681SAndroid Build Coastguard Worker case X86::TLS_addr64:
710*9880d681SAndroid Build Coastguard Worker SRVK = MCSymbolRefExpr::VK_TLSGD;
711*9880d681SAndroid Build Coastguard Worker break;
712*9880d681SAndroid Build Coastguard Worker case X86::TLS_base_addr32:
713*9880d681SAndroid Build Coastguard Worker SRVK = MCSymbolRefExpr::VK_TLSLDM;
714*9880d681SAndroid Build Coastguard Worker break;
715*9880d681SAndroid Build Coastguard Worker case X86::TLS_base_addr64:
716*9880d681SAndroid Build Coastguard Worker SRVK = MCSymbolRefExpr::VK_TLSLD;
717*9880d681SAndroid Build Coastguard Worker break;
718*9880d681SAndroid Build Coastguard Worker default:
719*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unexpected opcode");
720*9880d681SAndroid Build Coastguard Worker }
721*9880d681SAndroid Build Coastguard Worker
722*9880d681SAndroid Build Coastguard Worker MCSymbol *sym = MCInstLowering.GetSymbolFromOperand(MI.getOperand(3));
723*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *symRef = MCSymbolRefExpr::create(sym, SRVK, context);
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker MCInst LEA;
726*9880d681SAndroid Build Coastguard Worker if (is64Bits) {
727*9880d681SAndroid Build Coastguard Worker LEA.setOpcode(X86::LEA64r);
728*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::RDI)); // dest
729*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::RIP)); // base
730*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createImm(1)); // scale
731*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // index
732*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createExpr(symRef)); // disp
733*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // seg
734*9880d681SAndroid Build Coastguard Worker } else if (SRVK == MCSymbolRefExpr::VK_TLSLDM) {
735*9880d681SAndroid Build Coastguard Worker LEA.setOpcode(X86::LEA32r);
736*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::EAX)); // dest
737*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::EBX)); // base
738*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createImm(1)); // scale
739*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // index
740*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createExpr(symRef)); // disp
741*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // seg
742*9880d681SAndroid Build Coastguard Worker } else {
743*9880d681SAndroid Build Coastguard Worker LEA.setOpcode(X86::LEA32r);
744*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::EAX)); // dest
745*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // base
746*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createImm(1)); // scale
747*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(X86::EBX)); // index
748*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createExpr(symRef)); // disp
749*9880d681SAndroid Build Coastguard Worker LEA.addOperand(MCOperand::createReg(0)); // seg
750*9880d681SAndroid Build Coastguard Worker }
751*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(LEA);
752*9880d681SAndroid Build Coastguard Worker
753*9880d681SAndroid Build Coastguard Worker if (needsPadding) {
754*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
755*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
756*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
757*9880d681SAndroid Build Coastguard Worker }
758*9880d681SAndroid Build Coastguard Worker
759*9880d681SAndroid Build Coastguard Worker StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr";
760*9880d681SAndroid Build Coastguard Worker MCSymbol *tlsGetAddr = context.getOrCreateSymbol(name);
761*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *tlsRef =
762*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(tlsGetAddr,
763*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VK_PLT,
764*9880d681SAndroid Build Coastguard Worker context);
765*9880d681SAndroid Build Coastguard Worker
766*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32
767*9880d681SAndroid Build Coastguard Worker : X86::CALLpcrel32)
768*9880d681SAndroid Build Coastguard Worker .addExpr(tlsRef));
769*9880d681SAndroid Build Coastguard Worker }
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Worker /// \brief Emit the largest nop instruction smaller than or equal to \p NumBytes
772*9880d681SAndroid Build Coastguard Worker /// bytes. Return the size of nop emitted.
EmitNop(MCStreamer & OS,unsigned NumBytes,bool Is64Bit,const MCSubtargetInfo & STI)773*9880d681SAndroid Build Coastguard Worker static unsigned EmitNop(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
774*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
775*9880d681SAndroid Build Coastguard Worker // This works only for 64bit. For 32bit we have to do additional checking if
776*9880d681SAndroid Build Coastguard Worker // the CPU supports multi-byte nops.
777*9880d681SAndroid Build Coastguard Worker assert(Is64Bit && "EmitNops only supports X86-64");
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker unsigned NopSize;
780*9880d681SAndroid Build Coastguard Worker unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
781*9880d681SAndroid Build Coastguard Worker Opc = IndexReg = Displacement = SegmentReg = 0;
782*9880d681SAndroid Build Coastguard Worker BaseReg = X86::RAX;
783*9880d681SAndroid Build Coastguard Worker ScaleVal = 1;
784*9880d681SAndroid Build Coastguard Worker switch (NumBytes) {
785*9880d681SAndroid Build Coastguard Worker case 0: llvm_unreachable("Zero nops?"); break;
786*9880d681SAndroid Build Coastguard Worker case 1: NopSize = 1; Opc = X86::NOOP; break;
787*9880d681SAndroid Build Coastguard Worker case 2: NopSize = 2; Opc = X86::XCHG16ar; break;
788*9880d681SAndroid Build Coastguard Worker case 3: NopSize = 3; Opc = X86::NOOPL; break;
789*9880d681SAndroid Build Coastguard Worker case 4: NopSize = 4; Opc = X86::NOOPL; Displacement = 8; break;
790*9880d681SAndroid Build Coastguard Worker case 5: NopSize = 5; Opc = X86::NOOPL; Displacement = 8;
791*9880d681SAndroid Build Coastguard Worker IndexReg = X86::RAX; break;
792*9880d681SAndroid Build Coastguard Worker case 6: NopSize = 6; Opc = X86::NOOPW; Displacement = 8;
793*9880d681SAndroid Build Coastguard Worker IndexReg = X86::RAX; break;
794*9880d681SAndroid Build Coastguard Worker case 7: NopSize = 7; Opc = X86::NOOPL; Displacement = 512; break;
795*9880d681SAndroid Build Coastguard Worker case 8: NopSize = 8; Opc = X86::NOOPL; Displacement = 512;
796*9880d681SAndroid Build Coastguard Worker IndexReg = X86::RAX; break;
797*9880d681SAndroid Build Coastguard Worker case 9: NopSize = 9; Opc = X86::NOOPW; Displacement = 512;
798*9880d681SAndroid Build Coastguard Worker IndexReg = X86::RAX; break;
799*9880d681SAndroid Build Coastguard Worker default: NopSize = 10; Opc = X86::NOOPW; Displacement = 512;
800*9880d681SAndroid Build Coastguard Worker IndexReg = X86::RAX; SegmentReg = X86::CS; break;
801*9880d681SAndroid Build Coastguard Worker }
802*9880d681SAndroid Build Coastguard Worker
803*9880d681SAndroid Build Coastguard Worker unsigned NumPrefixes = std::min(NumBytes - NopSize, 5U);
804*9880d681SAndroid Build Coastguard Worker NopSize += NumPrefixes;
805*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != NumPrefixes; ++i)
806*9880d681SAndroid Build Coastguard Worker OS.EmitBytes("\x66");
807*9880d681SAndroid Build Coastguard Worker
808*9880d681SAndroid Build Coastguard Worker switch (Opc) {
809*9880d681SAndroid Build Coastguard Worker default:
810*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected opcode");
811*9880d681SAndroid Build Coastguard Worker break;
812*9880d681SAndroid Build Coastguard Worker case X86::NOOP:
813*9880d681SAndroid Build Coastguard Worker OS.EmitInstruction(MCInstBuilder(Opc), STI);
814*9880d681SAndroid Build Coastguard Worker break;
815*9880d681SAndroid Build Coastguard Worker case X86::XCHG16ar:
816*9880d681SAndroid Build Coastguard Worker OS.EmitInstruction(MCInstBuilder(Opc).addReg(X86::AX), STI);
817*9880d681SAndroid Build Coastguard Worker break;
818*9880d681SAndroid Build Coastguard Worker case X86::NOOPL:
819*9880d681SAndroid Build Coastguard Worker case X86::NOOPW:
820*9880d681SAndroid Build Coastguard Worker OS.EmitInstruction(MCInstBuilder(Opc)
821*9880d681SAndroid Build Coastguard Worker .addReg(BaseReg)
822*9880d681SAndroid Build Coastguard Worker .addImm(ScaleVal)
823*9880d681SAndroid Build Coastguard Worker .addReg(IndexReg)
824*9880d681SAndroid Build Coastguard Worker .addImm(Displacement)
825*9880d681SAndroid Build Coastguard Worker .addReg(SegmentReg),
826*9880d681SAndroid Build Coastguard Worker STI);
827*9880d681SAndroid Build Coastguard Worker break;
828*9880d681SAndroid Build Coastguard Worker }
829*9880d681SAndroid Build Coastguard Worker assert(NopSize <= NumBytes && "We overemitted?");
830*9880d681SAndroid Build Coastguard Worker return NopSize;
831*9880d681SAndroid Build Coastguard Worker }
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker /// \brief Emit the optimal amount of multi-byte nops on X86.
EmitNops(MCStreamer & OS,unsigned NumBytes,bool Is64Bit,const MCSubtargetInfo & STI)834*9880d681SAndroid Build Coastguard Worker static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
835*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
836*9880d681SAndroid Build Coastguard Worker unsigned NopsToEmit = NumBytes;
837*9880d681SAndroid Build Coastguard Worker (void)NopsToEmit;
838*9880d681SAndroid Build Coastguard Worker while (NumBytes) {
839*9880d681SAndroid Build Coastguard Worker NumBytes -= EmitNop(OS, NumBytes, Is64Bit, STI);
840*9880d681SAndroid Build Coastguard Worker assert(NopsToEmit >= NumBytes && "Emitted more than I asked for!");
841*9880d681SAndroid Build Coastguard Worker }
842*9880d681SAndroid Build Coastguard Worker }
843*9880d681SAndroid Build Coastguard Worker
LowerSTATEPOINT(const MachineInstr & MI,X86MCInstLower & MCIL)844*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
845*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
846*9880d681SAndroid Build Coastguard Worker assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker StatepointOpers SOpers(&MI);
849*9880d681SAndroid Build Coastguard Worker if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
850*9880d681SAndroid Build Coastguard Worker EmitNops(*OutStreamer, PatchBytes, Subtarget->is64Bit(),
851*9880d681SAndroid Build Coastguard Worker getSubtargetInfo());
852*9880d681SAndroid Build Coastguard Worker } else {
853*9880d681SAndroid Build Coastguard Worker // Lower call target and choose correct opcode
854*9880d681SAndroid Build Coastguard Worker const MachineOperand &CallTarget = SOpers.getCallTarget();
855*9880d681SAndroid Build Coastguard Worker MCOperand CallTargetMCOp;
856*9880d681SAndroid Build Coastguard Worker unsigned CallOpcode;
857*9880d681SAndroid Build Coastguard Worker switch (CallTarget.getType()) {
858*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_GlobalAddress:
859*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ExternalSymbol:
860*9880d681SAndroid Build Coastguard Worker CallTargetMCOp = MCIL.LowerSymbolOperand(
861*9880d681SAndroid Build Coastguard Worker CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
862*9880d681SAndroid Build Coastguard Worker CallOpcode = X86::CALL64pcrel32;
863*9880d681SAndroid Build Coastguard Worker // Currently, we only support relative addressing with statepoints.
864*9880d681SAndroid Build Coastguard Worker // Otherwise, we'll need a scratch register to hold the target
865*9880d681SAndroid Build Coastguard Worker // address. You'll fail asserts during load & relocation if this
866*9880d681SAndroid Build Coastguard Worker // symbol is to far away. (TODO: support non-relative addressing)
867*9880d681SAndroid Build Coastguard Worker break;
868*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
869*9880d681SAndroid Build Coastguard Worker CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
870*9880d681SAndroid Build Coastguard Worker CallOpcode = X86::CALL64pcrel32;
871*9880d681SAndroid Build Coastguard Worker // Currently, we only support relative addressing with statepoints.
872*9880d681SAndroid Build Coastguard Worker // Otherwise, we'll need a scratch register to hold the target
873*9880d681SAndroid Build Coastguard Worker // immediate. You'll fail asserts during load & relocation if this
874*9880d681SAndroid Build Coastguard Worker // address is to far away. (TODO: support non-relative addressing)
875*9880d681SAndroid Build Coastguard Worker break;
876*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Register:
877*9880d681SAndroid Build Coastguard Worker CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
878*9880d681SAndroid Build Coastguard Worker CallOpcode = X86::CALL64r;
879*9880d681SAndroid Build Coastguard Worker break;
880*9880d681SAndroid Build Coastguard Worker default:
881*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unsupported operand type in statepoint call target");
882*9880d681SAndroid Build Coastguard Worker break;
883*9880d681SAndroid Build Coastguard Worker }
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker // Emit call
886*9880d681SAndroid Build Coastguard Worker MCInst CallInst;
887*9880d681SAndroid Build Coastguard Worker CallInst.setOpcode(CallOpcode);
888*9880d681SAndroid Build Coastguard Worker CallInst.addOperand(CallTargetMCOp);
889*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
890*9880d681SAndroid Build Coastguard Worker }
891*9880d681SAndroid Build Coastguard Worker
892*9880d681SAndroid Build Coastguard Worker // Record our statepoint node in the same section used by STACKMAP
893*9880d681SAndroid Build Coastguard Worker // and PATCHPOINT
894*9880d681SAndroid Build Coastguard Worker SM.recordStatepoint(MI);
895*9880d681SAndroid Build Coastguard Worker }
896*9880d681SAndroid Build Coastguard Worker
LowerFAULTING_LOAD_OP(const MachineInstr & MI,X86MCInstLower & MCIL)897*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerFAULTING_LOAD_OP(const MachineInstr &MI,
898*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
899*9880d681SAndroid Build Coastguard Worker // FAULTING_LOAD_OP <def>, <MBB handler>, <load opcode>, <load operands>
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker unsigned LoadDefRegister = MI.getOperand(0).getReg();
902*9880d681SAndroid Build Coastguard Worker MCSymbol *HandlerLabel = MI.getOperand(1).getMBB()->getSymbol();
903*9880d681SAndroid Build Coastguard Worker unsigned LoadOpcode = MI.getOperand(2).getImm();
904*9880d681SAndroid Build Coastguard Worker unsigned LoadOperandsBeginIdx = 3;
905*9880d681SAndroid Build Coastguard Worker
906*9880d681SAndroid Build Coastguard Worker FM.recordFaultingOp(FaultMaps::FaultingLoad, HandlerLabel);
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker MCInst LoadMI;
909*9880d681SAndroid Build Coastguard Worker LoadMI.setOpcode(LoadOpcode);
910*9880d681SAndroid Build Coastguard Worker
911*9880d681SAndroid Build Coastguard Worker if (LoadDefRegister != X86::NoRegister)
912*9880d681SAndroid Build Coastguard Worker LoadMI.addOperand(MCOperand::createReg(LoadDefRegister));
913*9880d681SAndroid Build Coastguard Worker
914*9880d681SAndroid Build Coastguard Worker for (auto I = MI.operands_begin() + LoadOperandsBeginIdx,
915*9880d681SAndroid Build Coastguard Worker E = MI.operands_end();
916*9880d681SAndroid Build Coastguard Worker I != E; ++I)
917*9880d681SAndroid Build Coastguard Worker if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, *I))
918*9880d681SAndroid Build Coastguard Worker LoadMI.addOperand(MaybeOperand.getValue());
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(LoadMI, getSubtargetInfo());
921*9880d681SAndroid Build Coastguard Worker }
922*9880d681SAndroid Build Coastguard Worker
LowerPATCHABLE_OP(const MachineInstr & MI,X86MCInstLower & MCIL)923*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
924*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
925*9880d681SAndroid Build Coastguard Worker // PATCHABLE_OP minsize, opcode, operands
926*9880d681SAndroid Build Coastguard Worker
927*9880d681SAndroid Build Coastguard Worker unsigned MinSize = MI.getOperand(0).getImm();
928*9880d681SAndroid Build Coastguard Worker unsigned Opcode = MI.getOperand(1).getImm();
929*9880d681SAndroid Build Coastguard Worker
930*9880d681SAndroid Build Coastguard Worker MCInst MCI;
931*9880d681SAndroid Build Coastguard Worker MCI.setOpcode(Opcode);
932*9880d681SAndroid Build Coastguard Worker for (auto &MO : make_range(MI.operands_begin() + 2, MI.operands_end()))
933*9880d681SAndroid Build Coastguard Worker if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
934*9880d681SAndroid Build Coastguard Worker MCI.addOperand(MaybeOperand.getValue());
935*9880d681SAndroid Build Coastguard Worker
936*9880d681SAndroid Build Coastguard Worker SmallString<256> Code;
937*9880d681SAndroid Build Coastguard Worker SmallVector<MCFixup, 4> Fixups;
938*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(Code);
939*9880d681SAndroid Build Coastguard Worker CodeEmitter->encodeInstruction(MCI, VecOS, Fixups, getSubtargetInfo());
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker if (Code.size() < MinSize) {
942*9880d681SAndroid Build Coastguard Worker if (MinSize == 2 && Opcode == X86::PUSH64r) {
943*9880d681SAndroid Build Coastguard Worker // This is an optimization that lets us get away without emitting a nop in
944*9880d681SAndroid Build Coastguard Worker // many cases.
945*9880d681SAndroid Build Coastguard Worker //
946*9880d681SAndroid Build Coastguard Worker // NB! In some cases the encoding for PUSH64r (e.g. PUSH64r %R9) takes two
947*9880d681SAndroid Build Coastguard Worker // bytes too, so the check on MinSize is important.
948*9880d681SAndroid Build Coastguard Worker MCI.setOpcode(X86::PUSH64rmr);
949*9880d681SAndroid Build Coastguard Worker } else {
950*9880d681SAndroid Build Coastguard Worker unsigned NopSize = EmitNop(*OutStreamer, MinSize, Subtarget->is64Bit(),
951*9880d681SAndroid Build Coastguard Worker getSubtargetInfo());
952*9880d681SAndroid Build Coastguard Worker assert(NopSize == MinSize && "Could not implement MinSize!");
953*9880d681SAndroid Build Coastguard Worker (void) NopSize;
954*9880d681SAndroid Build Coastguard Worker }
955*9880d681SAndroid Build Coastguard Worker }
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(MCI, getSubtargetInfo());
958*9880d681SAndroid Build Coastguard Worker }
959*9880d681SAndroid Build Coastguard Worker
960*9880d681SAndroid Build Coastguard Worker // Lower a stackmap of the form:
961*9880d681SAndroid Build Coastguard Worker // <id>, <shadowBytes>, ...
LowerSTACKMAP(const MachineInstr & MI)962*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
963*9880d681SAndroid Build Coastguard Worker SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
964*9880d681SAndroid Build Coastguard Worker SM.recordStackMap(MI);
965*9880d681SAndroid Build Coastguard Worker unsigned NumShadowBytes = MI.getOperand(1).getImm();
966*9880d681SAndroid Build Coastguard Worker SMShadowTracker.reset(NumShadowBytes);
967*9880d681SAndroid Build Coastguard Worker }
968*9880d681SAndroid Build Coastguard Worker
969*9880d681SAndroid Build Coastguard Worker // Lower a patchpoint of the form:
970*9880d681SAndroid Build Coastguard Worker // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
LowerPATCHPOINT(const MachineInstr & MI,X86MCInstLower & MCIL)971*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
972*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
973*9880d681SAndroid Build Coastguard Worker assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");
974*9880d681SAndroid Build Coastguard Worker
975*9880d681SAndroid Build Coastguard Worker SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
976*9880d681SAndroid Build Coastguard Worker
977*9880d681SAndroid Build Coastguard Worker SM.recordPatchPoint(MI);
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Worker PatchPointOpers opers(&MI);
980*9880d681SAndroid Build Coastguard Worker unsigned ScratchIdx = opers.getNextScratchIdx();
981*9880d681SAndroid Build Coastguard Worker unsigned EncodedBytes = 0;
982*9880d681SAndroid Build Coastguard Worker const MachineOperand &CalleeMO =
983*9880d681SAndroid Build Coastguard Worker opers.getMetaOper(PatchPointOpers::TargetPos);
984*9880d681SAndroid Build Coastguard Worker
985*9880d681SAndroid Build Coastguard Worker // Check for null target. If target is non-null (i.e. is non-zero or is
986*9880d681SAndroid Build Coastguard Worker // symbolic) then emit a call.
987*9880d681SAndroid Build Coastguard Worker if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {
988*9880d681SAndroid Build Coastguard Worker MCOperand CalleeMCOp;
989*9880d681SAndroid Build Coastguard Worker switch (CalleeMO.getType()) {
990*9880d681SAndroid Build Coastguard Worker default:
991*9880d681SAndroid Build Coastguard Worker /// FIXME: Add a verifier check for bad callee types.
992*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unrecognized callee operand type.");
993*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
994*9880d681SAndroid Build Coastguard Worker if (CalleeMO.getImm())
995*9880d681SAndroid Build Coastguard Worker CalleeMCOp = MCOperand::createImm(CalleeMO.getImm());
996*9880d681SAndroid Build Coastguard Worker break;
997*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_ExternalSymbol:
998*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_GlobalAddress:
999*9880d681SAndroid Build Coastguard Worker CalleeMCOp =
1000*9880d681SAndroid Build Coastguard Worker MCIL.LowerSymbolOperand(CalleeMO,
1001*9880d681SAndroid Build Coastguard Worker MCIL.GetSymbolFromOperand(CalleeMO));
1002*9880d681SAndroid Build Coastguard Worker break;
1003*9880d681SAndroid Build Coastguard Worker }
1004*9880d681SAndroid Build Coastguard Worker
1005*9880d681SAndroid Build Coastguard Worker // Emit MOV to materialize the target address and the CALL to target.
1006*9880d681SAndroid Build Coastguard Worker // This is encoded with 12-13 bytes, depending on which register is used.
1007*9880d681SAndroid Build Coastguard Worker unsigned ScratchReg = MI.getOperand(ScratchIdx).getReg();
1008*9880d681SAndroid Build Coastguard Worker if (X86II::isX86_64ExtendedReg(ScratchReg))
1009*9880d681SAndroid Build Coastguard Worker EncodedBytes = 13;
1010*9880d681SAndroid Build Coastguard Worker else
1011*9880d681SAndroid Build Coastguard Worker EncodedBytes = 12;
1012*9880d681SAndroid Build Coastguard Worker
1013*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(
1014*9880d681SAndroid Build Coastguard Worker MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));
1015*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
1016*9880d681SAndroid Build Coastguard Worker }
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker // Emit padding.
1019*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
1020*9880d681SAndroid Build Coastguard Worker assert(NumBytes >= EncodedBytes &&
1021*9880d681SAndroid Build Coastguard Worker "Patchpoint can't request size less than the length of a call.");
1022*9880d681SAndroid Build Coastguard Worker
1023*9880d681SAndroid Build Coastguard Worker EmitNops(*OutStreamer, NumBytes - EncodedBytes, Subtarget->is64Bit(),
1024*9880d681SAndroid Build Coastguard Worker getSubtargetInfo());
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker
recordSled(MCSymbol * Sled,const MachineInstr & MI,SledKind Kind)1027*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,
1028*9880d681SAndroid Build Coastguard Worker SledKind Kind) {
1029*9880d681SAndroid Build Coastguard Worker auto Fn = MI.getParent()->getParent()->getFunction();
1030*9880d681SAndroid Build Coastguard Worker auto Attr = Fn->getFnAttribute("function-instrument");
1031*9880d681SAndroid Build Coastguard Worker bool AlwaysInstrument =
1032*9880d681SAndroid Build Coastguard Worker Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always";
1033*9880d681SAndroid Build Coastguard Worker Sleds.emplace_back(
1034*9880d681SAndroid Build Coastguard Worker XRayFunctionEntry{Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn});
1035*9880d681SAndroid Build Coastguard Worker }
1036*9880d681SAndroid Build Coastguard Worker
LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr & MI,X86MCInstLower & MCIL)1037*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
1038*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
1039*9880d681SAndroid Build Coastguard Worker // We want to emit the following pattern:
1040*9880d681SAndroid Build Coastguard Worker //
1041*9880d681SAndroid Build Coastguard Worker // .Lxray_sled_N:
1042*9880d681SAndroid Build Coastguard Worker // .palign 2, ...
1043*9880d681SAndroid Build Coastguard Worker // jmp .tmpN
1044*9880d681SAndroid Build Coastguard Worker // # 9 bytes worth of noops
1045*9880d681SAndroid Build Coastguard Worker // .tmpN
1046*9880d681SAndroid Build Coastguard Worker //
1047*9880d681SAndroid Build Coastguard Worker // We need the 9 bytes because at runtime, we'd be patching over the full 11
1048*9880d681SAndroid Build Coastguard Worker // bytes with the following pattern:
1049*9880d681SAndroid Build Coastguard Worker //
1050*9880d681SAndroid Build Coastguard Worker // mov %r10, <function id, 32-bit> // 6 bytes
1051*9880d681SAndroid Build Coastguard Worker // call <relative offset, 32-bits> // 5 bytes
1052*9880d681SAndroid Build Coastguard Worker //
1053*9880d681SAndroid Build Coastguard Worker auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1054*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(CurSled);
1055*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitCodeAlignment(4);
1056*9880d681SAndroid Build Coastguard Worker auto Target = OutContext.createTempSymbol();
1057*9880d681SAndroid Build Coastguard Worker
1058*9880d681SAndroid Build Coastguard Worker // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
1059*9880d681SAndroid Build Coastguard Worker // an operand (computed as an offset from the jmp instruction).
1060*9880d681SAndroid Build Coastguard Worker // FIXME: Find another less hacky way do force the relative jump.
1061*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitBytes("\xeb\x09");
1062*9880d681SAndroid Build Coastguard Worker EmitNops(*OutStreamer, 9, Subtarget->is64Bit(), getSubtargetInfo());
1063*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(Target);
1064*9880d681SAndroid Build Coastguard Worker recordSled(CurSled, MI, SledKind::FUNCTION_ENTER);
1065*9880d681SAndroid Build Coastguard Worker }
1066*9880d681SAndroid Build Coastguard Worker
LowerPATCHABLE_RET(const MachineInstr & MI,X86MCInstLower & MCIL)1067*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI,
1068*9880d681SAndroid Build Coastguard Worker X86MCInstLower &MCIL) {
1069*9880d681SAndroid Build Coastguard Worker // Since PATCHABLE_RET takes the opcode of the return statement as an
1070*9880d681SAndroid Build Coastguard Worker // argument, we use that to emit the correct form of the RET that we want.
1071*9880d681SAndroid Build Coastguard Worker // i.e. when we see this:
1072*9880d681SAndroid Build Coastguard Worker //
1073*9880d681SAndroid Build Coastguard Worker // PATCHABLE_RET X86::RET ...
1074*9880d681SAndroid Build Coastguard Worker //
1075*9880d681SAndroid Build Coastguard Worker // We should emit the RET followed by sleds.
1076*9880d681SAndroid Build Coastguard Worker //
1077*9880d681SAndroid Build Coastguard Worker // .Lxray_sled_N:
1078*9880d681SAndroid Build Coastguard Worker // ret # or equivalent instruction
1079*9880d681SAndroid Build Coastguard Worker // # 10 bytes worth of noops
1080*9880d681SAndroid Build Coastguard Worker //
1081*9880d681SAndroid Build Coastguard Worker // This just makes sure that the alignment for the next instruction is 2.
1082*9880d681SAndroid Build Coastguard Worker auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1083*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(CurSled);
1084*9880d681SAndroid Build Coastguard Worker unsigned OpCode = MI.getOperand(0).getImm();
1085*9880d681SAndroid Build Coastguard Worker MCInst Ret;
1086*9880d681SAndroid Build Coastguard Worker Ret.setOpcode(OpCode);
1087*9880d681SAndroid Build Coastguard Worker for (auto &MO : make_range(MI.operands_begin() + 1, MI.operands_end()))
1088*9880d681SAndroid Build Coastguard Worker if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
1089*9880d681SAndroid Build Coastguard Worker Ret.addOperand(MaybeOperand.getValue());
1090*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(Ret, getSubtargetInfo());
1091*9880d681SAndroid Build Coastguard Worker EmitNops(*OutStreamer, 10, Subtarget->is64Bit(), getSubtargetInfo());
1092*9880d681SAndroid Build Coastguard Worker recordSled(CurSled, MI, SledKind::FUNCTION_EXIT);
1093*9880d681SAndroid Build Coastguard Worker }
1094*9880d681SAndroid Build Coastguard Worker
EmitXRayTable()1095*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::EmitXRayTable() {
1096*9880d681SAndroid Build Coastguard Worker if (Sleds.empty())
1097*9880d681SAndroid Build Coastguard Worker return;
1098*9880d681SAndroid Build Coastguard Worker if (Subtarget->isTargetELF()) {
1099*9880d681SAndroid Build Coastguard Worker auto *Section = OutContext.getELFSection(
1100*9880d681SAndroid Build Coastguard Worker "xray_instr_map", ELF::SHT_PROGBITS,
1101*9880d681SAndroid Build Coastguard Worker ELF::SHF_ALLOC | ELF::SHF_GROUP | ELF::SHF_MERGE, 0,
1102*9880d681SAndroid Build Coastguard Worker CurrentFnSym->getName());
1103*9880d681SAndroid Build Coastguard Worker auto PrevSection = OutStreamer->getCurrentSectionOnly();
1104*9880d681SAndroid Build Coastguard Worker OutStreamer->SwitchSection(Section);
1105*9880d681SAndroid Build Coastguard Worker for (const auto &Sled : Sleds) {
1106*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitSymbolValue(Sled.Sled, 8);
1107*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitSymbolValue(CurrentFnSym, 8);
1108*9880d681SAndroid Build Coastguard Worker auto Kind = static_cast<uint8_t>(Sled.Kind);
1109*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitBytes(
1110*9880d681SAndroid Build Coastguard Worker StringRef(reinterpret_cast<const char *>(&Kind), 1));
1111*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitBytes(
1112*9880d681SAndroid Build Coastguard Worker StringRef(reinterpret_cast<const char *>(&Sled.AlwaysInstrument), 1));
1113*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitZeros(14);
1114*9880d681SAndroid Build Coastguard Worker }
1115*9880d681SAndroid Build Coastguard Worker OutStreamer->SwitchSection(PrevSection);
1116*9880d681SAndroid Build Coastguard Worker }
1117*9880d681SAndroid Build Coastguard Worker Sleds.clear();
1118*9880d681SAndroid Build Coastguard Worker }
1119*9880d681SAndroid Build Coastguard Worker
1120*9880d681SAndroid Build Coastguard Worker // Returns instruction preceding MBBI in MachineFunction.
1121*9880d681SAndroid Build Coastguard Worker // If MBBI is the first instruction of the first basic block, returns null.
1122*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock::const_iterator
PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI)1123*9880d681SAndroid Build Coastguard Worker PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI) {
1124*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *MBB = MBBI->getParent();
1125*9880d681SAndroid Build Coastguard Worker while (MBBI == MBB->begin()) {
1126*9880d681SAndroid Build Coastguard Worker if (MBB == &MBB->getParent()->front())
1127*9880d681SAndroid Build Coastguard Worker return MachineBasicBlock::const_iterator();
1128*9880d681SAndroid Build Coastguard Worker MBB = MBB->getPrevNode();
1129*9880d681SAndroid Build Coastguard Worker MBBI = MBB->end();
1130*9880d681SAndroid Build Coastguard Worker }
1131*9880d681SAndroid Build Coastguard Worker return --MBBI;
1132*9880d681SAndroid Build Coastguard Worker }
1133*9880d681SAndroid Build Coastguard Worker
getConstantFromPool(const MachineInstr & MI,const MachineOperand & Op)1134*9880d681SAndroid Build Coastguard Worker static const Constant *getConstantFromPool(const MachineInstr &MI,
1135*9880d681SAndroid Build Coastguard Worker const MachineOperand &Op) {
1136*9880d681SAndroid Build Coastguard Worker if (!Op.isCPI())
1137*9880d681SAndroid Build Coastguard Worker return nullptr;
1138*9880d681SAndroid Build Coastguard Worker
1139*9880d681SAndroid Build Coastguard Worker ArrayRef<MachineConstantPoolEntry> Constants =
1140*9880d681SAndroid Build Coastguard Worker MI.getParent()->getParent()->getConstantPool()->getConstants();
1141*9880d681SAndroid Build Coastguard Worker const MachineConstantPoolEntry &ConstantEntry =
1142*9880d681SAndroid Build Coastguard Worker Constants[Op.getIndex()];
1143*9880d681SAndroid Build Coastguard Worker
1144*9880d681SAndroid Build Coastguard Worker // Bail if this is a machine constant pool entry, we won't be able to dig out
1145*9880d681SAndroid Build Coastguard Worker // anything useful.
1146*9880d681SAndroid Build Coastguard Worker if (ConstantEntry.isMachineConstantPoolEntry())
1147*9880d681SAndroid Build Coastguard Worker return nullptr;
1148*9880d681SAndroid Build Coastguard Worker
1149*9880d681SAndroid Build Coastguard Worker auto *C = dyn_cast<Constant>(ConstantEntry.Val.ConstVal);
1150*9880d681SAndroid Build Coastguard Worker assert((!C || ConstantEntry.getType() == C->getType()) &&
1151*9880d681SAndroid Build Coastguard Worker "Expected a constant of the same type!");
1152*9880d681SAndroid Build Coastguard Worker return C;
1153*9880d681SAndroid Build Coastguard Worker }
1154*9880d681SAndroid Build Coastguard Worker
getShuffleComment(const MachineOperand & DstOp,const MachineOperand & SrcOp1,const MachineOperand & SrcOp2,ArrayRef<int> Mask)1155*9880d681SAndroid Build Coastguard Worker static std::string getShuffleComment(const MachineOperand &DstOp,
1156*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp1,
1157*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp2,
1158*9880d681SAndroid Build Coastguard Worker ArrayRef<int> Mask) {
1159*9880d681SAndroid Build Coastguard Worker std::string Comment;
1160*9880d681SAndroid Build Coastguard Worker
1161*9880d681SAndroid Build Coastguard Worker // Compute the name for a register. This is really goofy because we have
1162*9880d681SAndroid Build Coastguard Worker // multiple instruction printers that could (in theory) use different
1163*9880d681SAndroid Build Coastguard Worker // names. Fortunately most people use the ATT style (outside of Windows)
1164*9880d681SAndroid Build Coastguard Worker // and they actually agree on register naming here. Ultimately, this is
1165*9880d681SAndroid Build Coastguard Worker // a comment, and so its OK if it isn't perfect.
1166*9880d681SAndroid Build Coastguard Worker auto GetRegisterName = [](unsigned RegNum) -> StringRef {
1167*9880d681SAndroid Build Coastguard Worker return X86ATTInstPrinter::getRegisterName(RegNum);
1168*9880d681SAndroid Build Coastguard Worker };
1169*9880d681SAndroid Build Coastguard Worker
1170*9880d681SAndroid Build Coastguard Worker // TODO: Add support for specifying an AVX512 style mask register in the comment.
1171*9880d681SAndroid Build Coastguard Worker StringRef DstName = DstOp.isReg() ? GetRegisterName(DstOp.getReg()) : "mem";
1172*9880d681SAndroid Build Coastguard Worker StringRef Src1Name =
1173*9880d681SAndroid Build Coastguard Worker SrcOp1.isReg() ? GetRegisterName(SrcOp1.getReg()) : "mem";
1174*9880d681SAndroid Build Coastguard Worker StringRef Src2Name =
1175*9880d681SAndroid Build Coastguard Worker SrcOp2.isReg() ? GetRegisterName(SrcOp2.getReg()) : "mem";
1176*9880d681SAndroid Build Coastguard Worker
1177*9880d681SAndroid Build Coastguard Worker // One source operand, fix the mask to print all elements in one span.
1178*9880d681SAndroid Build Coastguard Worker SmallVector<int, 8> ShuffleMask(Mask.begin(), Mask.end());
1179*9880d681SAndroid Build Coastguard Worker if (Src1Name == Src2Name)
1180*9880d681SAndroid Build Coastguard Worker for (int i = 0, e = ShuffleMask.size(); i != e; ++i)
1181*9880d681SAndroid Build Coastguard Worker if (ShuffleMask[i] >= e)
1182*9880d681SAndroid Build Coastguard Worker ShuffleMask[i] -= e;
1183*9880d681SAndroid Build Coastguard Worker
1184*9880d681SAndroid Build Coastguard Worker raw_string_ostream CS(Comment);
1185*9880d681SAndroid Build Coastguard Worker CS << DstName << " = ";
1186*9880d681SAndroid Build Coastguard Worker for (int i = 0, e = ShuffleMask.size(); i != e; ++i) {
1187*9880d681SAndroid Build Coastguard Worker if (i != 0)
1188*9880d681SAndroid Build Coastguard Worker CS << ",";
1189*9880d681SAndroid Build Coastguard Worker if (ShuffleMask[i] == SM_SentinelZero) {
1190*9880d681SAndroid Build Coastguard Worker CS << "zero";
1191*9880d681SAndroid Build Coastguard Worker continue;
1192*9880d681SAndroid Build Coastguard Worker }
1193*9880d681SAndroid Build Coastguard Worker
1194*9880d681SAndroid Build Coastguard Worker // Otherwise, it must come from src1 or src2. Print the span of elements
1195*9880d681SAndroid Build Coastguard Worker // that comes from this src.
1196*9880d681SAndroid Build Coastguard Worker bool isSrc1 = ShuffleMask[i] < (int)e;
1197*9880d681SAndroid Build Coastguard Worker CS << (isSrc1 ? Src1Name : Src2Name) << '[';
1198*9880d681SAndroid Build Coastguard Worker
1199*9880d681SAndroid Build Coastguard Worker bool IsFirst = true;
1200*9880d681SAndroid Build Coastguard Worker while (i != e && ShuffleMask[i] != SM_SentinelZero &&
1201*9880d681SAndroid Build Coastguard Worker (ShuffleMask[i] < (int)e) == isSrc1) {
1202*9880d681SAndroid Build Coastguard Worker if (!IsFirst)
1203*9880d681SAndroid Build Coastguard Worker CS << ',';
1204*9880d681SAndroid Build Coastguard Worker else
1205*9880d681SAndroid Build Coastguard Worker IsFirst = false;
1206*9880d681SAndroid Build Coastguard Worker if (ShuffleMask[i] == SM_SentinelUndef)
1207*9880d681SAndroid Build Coastguard Worker CS << "u";
1208*9880d681SAndroid Build Coastguard Worker else
1209*9880d681SAndroid Build Coastguard Worker CS << ShuffleMask[i] % (int)e;
1210*9880d681SAndroid Build Coastguard Worker ++i;
1211*9880d681SAndroid Build Coastguard Worker }
1212*9880d681SAndroid Build Coastguard Worker CS << ']';
1213*9880d681SAndroid Build Coastguard Worker --i; // For loop increments element #.
1214*9880d681SAndroid Build Coastguard Worker }
1215*9880d681SAndroid Build Coastguard Worker CS.flush();
1216*9880d681SAndroid Build Coastguard Worker
1217*9880d681SAndroid Build Coastguard Worker return Comment;
1218*9880d681SAndroid Build Coastguard Worker }
1219*9880d681SAndroid Build Coastguard Worker
EmitInstruction(const MachineInstr * MI)1220*9880d681SAndroid Build Coastguard Worker void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
1221*9880d681SAndroid Build Coastguard Worker X86MCInstLower MCInstLowering(*MF, *this);
1222*9880d681SAndroid Build Coastguard Worker const X86RegisterInfo *RI = MF->getSubtarget<X86Subtarget>().getRegisterInfo();
1223*9880d681SAndroid Build Coastguard Worker
1224*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
1225*9880d681SAndroid Build Coastguard Worker case TargetOpcode::DBG_VALUE:
1226*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Should be handled target independently");
1227*9880d681SAndroid Build Coastguard Worker
1228*9880d681SAndroid Build Coastguard Worker // Emit nothing here but a comment if we can.
1229*9880d681SAndroid Build Coastguard Worker case X86::Int_MemBarrier:
1230*9880d681SAndroid Build Coastguard Worker OutStreamer->emitRawComment("MEMBARRIER");
1231*9880d681SAndroid Build Coastguard Worker return;
1232*9880d681SAndroid Build Coastguard Worker
1233*9880d681SAndroid Build Coastguard Worker
1234*9880d681SAndroid Build Coastguard Worker case X86::EH_RETURN:
1235*9880d681SAndroid Build Coastguard Worker case X86::EH_RETURN64: {
1236*9880d681SAndroid Build Coastguard Worker // Lower these as normal, but add some comments.
1237*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(0).getReg();
1238*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(StringRef("eh_return, addr: %") +
1239*9880d681SAndroid Build Coastguard Worker X86ATTInstPrinter::getRegisterName(Reg));
1240*9880d681SAndroid Build Coastguard Worker break;
1241*9880d681SAndroid Build Coastguard Worker }
1242*9880d681SAndroid Build Coastguard Worker case X86::CLEANUPRET: {
1243*9880d681SAndroid Build Coastguard Worker // Lower these as normal, but add some comments.
1244*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment("CLEANUPRET");
1245*9880d681SAndroid Build Coastguard Worker break;
1246*9880d681SAndroid Build Coastguard Worker }
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker case X86::CATCHRET: {
1249*9880d681SAndroid Build Coastguard Worker // Lower these as normal, but add some comments.
1250*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment("CATCHRET");
1251*9880d681SAndroid Build Coastguard Worker break;
1252*9880d681SAndroid Build Coastguard Worker }
1253*9880d681SAndroid Build Coastguard Worker
1254*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr:
1255*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPm:
1256*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd:
1257*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr64:
1258*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPm64:
1259*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd64:
1260*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPr64_REX:
1261*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPm64_REX:
1262*9880d681SAndroid Build Coastguard Worker case X86::TAILJMPd64_REX:
1263*9880d681SAndroid Build Coastguard Worker // Lower these as normal, but add some comments.
1264*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment("TAILCALL");
1265*9880d681SAndroid Build Coastguard Worker break;
1266*9880d681SAndroid Build Coastguard Worker
1267*9880d681SAndroid Build Coastguard Worker case X86::TLS_addr32:
1268*9880d681SAndroid Build Coastguard Worker case X86::TLS_addr64:
1269*9880d681SAndroid Build Coastguard Worker case X86::TLS_base_addr32:
1270*9880d681SAndroid Build Coastguard Worker case X86::TLS_base_addr64:
1271*9880d681SAndroid Build Coastguard Worker return LowerTlsAddr(MCInstLowering, *MI);
1272*9880d681SAndroid Build Coastguard Worker
1273*9880d681SAndroid Build Coastguard Worker case X86::MOVPC32r: {
1274*9880d681SAndroid Build Coastguard Worker // This is a pseudo op for a two instruction sequence with a label, which
1275*9880d681SAndroid Build Coastguard Worker // looks like:
1276*9880d681SAndroid Build Coastguard Worker // call "L1$pb"
1277*9880d681SAndroid Build Coastguard Worker // "L1$pb":
1278*9880d681SAndroid Build Coastguard Worker // popl %esi
1279*9880d681SAndroid Build Coastguard Worker
1280*9880d681SAndroid Build Coastguard Worker // Emit the call.
1281*9880d681SAndroid Build Coastguard Worker MCSymbol *PICBase = MF->getPICBaseSymbol();
1282*9880d681SAndroid Build Coastguard Worker // FIXME: We would like an efficient form for this, so we don't have to do a
1283*9880d681SAndroid Build Coastguard Worker // lot of extra uniquing.
1284*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::CALLpcrel32)
1285*9880d681SAndroid Build Coastguard Worker .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
1286*9880d681SAndroid Build Coastguard Worker
1287*9880d681SAndroid Build Coastguard Worker const X86FrameLowering* FrameLowering =
1288*9880d681SAndroid Build Coastguard Worker MF->getSubtarget<X86Subtarget>().getFrameLowering();
1289*9880d681SAndroid Build Coastguard Worker bool hasFP = FrameLowering->hasFP(*MF);
1290*9880d681SAndroid Build Coastguard Worker
1291*9880d681SAndroid Build Coastguard Worker // TODO: This is needed only if we require precise CFA.
1292*9880d681SAndroid Build Coastguard Worker bool HasActiveDwarfFrame = OutStreamer->getNumFrameInfos() &&
1293*9880d681SAndroid Build Coastguard Worker !OutStreamer->getDwarfFrameInfos().back().End;
1294*9880d681SAndroid Build Coastguard Worker
1295*9880d681SAndroid Build Coastguard Worker int stackGrowth = -RI->getSlotSize();
1296*9880d681SAndroid Build Coastguard Worker
1297*9880d681SAndroid Build Coastguard Worker if (HasActiveDwarfFrame && !hasFP) {
1298*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitCFIAdjustCfaOffset(-stackGrowth);
1299*9880d681SAndroid Build Coastguard Worker }
1300*9880d681SAndroid Build Coastguard Worker
1301*9880d681SAndroid Build Coastguard Worker // Emit the label.
1302*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(PICBase);
1303*9880d681SAndroid Build Coastguard Worker
1304*9880d681SAndroid Build Coastguard Worker // popl $reg
1305*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::POP32r)
1306*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg()));
1307*9880d681SAndroid Build Coastguard Worker
1308*9880d681SAndroid Build Coastguard Worker if (HasActiveDwarfFrame && !hasFP) {
1309*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitCFIAdjustCfaOffset(stackGrowth);
1310*9880d681SAndroid Build Coastguard Worker }
1311*9880d681SAndroid Build Coastguard Worker return;
1312*9880d681SAndroid Build Coastguard Worker }
1313*9880d681SAndroid Build Coastguard Worker
1314*9880d681SAndroid Build Coastguard Worker case X86::ADD32ri: {
1315*9880d681SAndroid Build Coastguard Worker // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
1316*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
1317*9880d681SAndroid Build Coastguard Worker break;
1318*9880d681SAndroid Build Coastguard Worker
1319*9880d681SAndroid Build Coastguard Worker // Okay, we have something like:
1320*9880d681SAndroid Build Coastguard Worker // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
1321*9880d681SAndroid Build Coastguard Worker
1322*9880d681SAndroid Build Coastguard Worker // For this, we want to print something like:
1323*9880d681SAndroid Build Coastguard Worker // MYGLOBAL + (. - PICBASE)
1324*9880d681SAndroid Build Coastguard Worker // However, we can't generate a ".", so just emit a new label here and refer
1325*9880d681SAndroid Build Coastguard Worker // to it.
1326*9880d681SAndroid Build Coastguard Worker MCSymbol *DotSym = OutContext.createTempSymbol();
1327*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(DotSym);
1328*9880d681SAndroid Build Coastguard Worker
1329*9880d681SAndroid Build Coastguard Worker // Now that we have emitted the label, lower the complex operand expression.
1330*9880d681SAndroid Build Coastguard Worker MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
1331*9880d681SAndroid Build Coastguard Worker
1332*9880d681SAndroid Build Coastguard Worker const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
1333*9880d681SAndroid Build Coastguard Worker const MCExpr *PICBase =
1334*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
1335*9880d681SAndroid Build Coastguard Worker DotExpr = MCBinaryExpr::createSub(DotExpr, PICBase, OutContext);
1336*9880d681SAndroid Build Coastguard Worker
1337*9880d681SAndroid Build Coastguard Worker DotExpr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(OpSym,OutContext),
1338*9880d681SAndroid Build Coastguard Worker DotExpr, OutContext);
1339*9880d681SAndroid Build Coastguard Worker
1340*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)
1341*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
1342*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
1343*9880d681SAndroid Build Coastguard Worker .addExpr(DotExpr));
1344*9880d681SAndroid Build Coastguard Worker return;
1345*9880d681SAndroid Build Coastguard Worker }
1346*9880d681SAndroid Build Coastguard Worker case TargetOpcode::STATEPOINT:
1347*9880d681SAndroid Build Coastguard Worker return LowerSTATEPOINT(*MI, MCInstLowering);
1348*9880d681SAndroid Build Coastguard Worker
1349*9880d681SAndroid Build Coastguard Worker case TargetOpcode::FAULTING_LOAD_OP:
1350*9880d681SAndroid Build Coastguard Worker return LowerFAULTING_LOAD_OP(*MI, MCInstLowering);
1351*9880d681SAndroid Build Coastguard Worker
1352*9880d681SAndroid Build Coastguard Worker case TargetOpcode::PATCHABLE_OP:
1353*9880d681SAndroid Build Coastguard Worker return LowerPATCHABLE_OP(*MI, MCInstLowering);
1354*9880d681SAndroid Build Coastguard Worker
1355*9880d681SAndroid Build Coastguard Worker case TargetOpcode::STACKMAP:
1356*9880d681SAndroid Build Coastguard Worker return LowerSTACKMAP(*MI);
1357*9880d681SAndroid Build Coastguard Worker
1358*9880d681SAndroid Build Coastguard Worker case TargetOpcode::PATCHPOINT:
1359*9880d681SAndroid Build Coastguard Worker return LowerPATCHPOINT(*MI, MCInstLowering);
1360*9880d681SAndroid Build Coastguard Worker
1361*9880d681SAndroid Build Coastguard Worker case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1362*9880d681SAndroid Build Coastguard Worker return LowerPATCHABLE_FUNCTION_ENTER(*MI, MCInstLowering);
1363*9880d681SAndroid Build Coastguard Worker
1364*9880d681SAndroid Build Coastguard Worker case TargetOpcode::PATCHABLE_RET:
1365*9880d681SAndroid Build Coastguard Worker return LowerPATCHABLE_RET(*MI, MCInstLowering);
1366*9880d681SAndroid Build Coastguard Worker
1367*9880d681SAndroid Build Coastguard Worker case X86::MORESTACK_RET:
1368*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
1369*9880d681SAndroid Build Coastguard Worker return;
1370*9880d681SAndroid Build Coastguard Worker
1371*9880d681SAndroid Build Coastguard Worker case X86::MORESTACK_RET_RESTORE_R10:
1372*9880d681SAndroid Build Coastguard Worker // Return, then restore R10.
1373*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
1374*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::MOV64rr)
1375*9880d681SAndroid Build Coastguard Worker .addReg(X86::R10)
1376*9880d681SAndroid Build Coastguard Worker .addReg(X86::RAX));
1377*9880d681SAndroid Build Coastguard Worker return;
1378*9880d681SAndroid Build Coastguard Worker
1379*9880d681SAndroid Build Coastguard Worker case X86::SEH_PushReg:
1380*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFIPushReg(RI->getSEHRegNum(MI->getOperand(0).getImm()));
1381*9880d681SAndroid Build Coastguard Worker return;
1382*9880d681SAndroid Build Coastguard Worker
1383*9880d681SAndroid Build Coastguard Worker case X86::SEH_SaveReg:
1384*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFISaveReg(RI->getSEHRegNum(MI->getOperand(0).getImm()),
1385*9880d681SAndroid Build Coastguard Worker MI->getOperand(1).getImm());
1386*9880d681SAndroid Build Coastguard Worker return;
1387*9880d681SAndroid Build Coastguard Worker
1388*9880d681SAndroid Build Coastguard Worker case X86::SEH_SaveXMM:
1389*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFISaveXMM(RI->getSEHRegNum(MI->getOperand(0).getImm()),
1390*9880d681SAndroid Build Coastguard Worker MI->getOperand(1).getImm());
1391*9880d681SAndroid Build Coastguard Worker return;
1392*9880d681SAndroid Build Coastguard Worker
1393*9880d681SAndroid Build Coastguard Worker case X86::SEH_StackAlloc:
1394*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFIAllocStack(MI->getOperand(0).getImm());
1395*9880d681SAndroid Build Coastguard Worker return;
1396*9880d681SAndroid Build Coastguard Worker
1397*9880d681SAndroid Build Coastguard Worker case X86::SEH_SetFrame:
1398*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFISetFrame(RI->getSEHRegNum(MI->getOperand(0).getImm()),
1399*9880d681SAndroid Build Coastguard Worker MI->getOperand(1).getImm());
1400*9880d681SAndroid Build Coastguard Worker return;
1401*9880d681SAndroid Build Coastguard Worker
1402*9880d681SAndroid Build Coastguard Worker case X86::SEH_PushFrame:
1403*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFIPushFrame(MI->getOperand(0).getImm());
1404*9880d681SAndroid Build Coastguard Worker return;
1405*9880d681SAndroid Build Coastguard Worker
1406*9880d681SAndroid Build Coastguard Worker case X86::SEH_EndPrologue:
1407*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitWinCFIEndProlog();
1408*9880d681SAndroid Build Coastguard Worker return;
1409*9880d681SAndroid Build Coastguard Worker
1410*9880d681SAndroid Build Coastguard Worker case X86::SEH_Epilogue: {
1411*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::const_iterator MBBI(MI);
1412*9880d681SAndroid Build Coastguard Worker // Check if preceded by a call and emit nop if so.
1413*9880d681SAndroid Build Coastguard Worker for (MBBI = PrevCrossBBInst(MBBI);
1414*9880d681SAndroid Build Coastguard Worker MBBI != MachineBasicBlock::const_iterator();
1415*9880d681SAndroid Build Coastguard Worker MBBI = PrevCrossBBInst(MBBI)) {
1416*9880d681SAndroid Build Coastguard Worker // Conservatively assume that pseudo instructions don't emit code and keep
1417*9880d681SAndroid Build Coastguard Worker // looking for a call. We may emit an unnecessary nop in some cases.
1418*9880d681SAndroid Build Coastguard Worker if (!MBBI->isPseudo()) {
1419*9880d681SAndroid Build Coastguard Worker if (MBBI->isCall())
1420*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
1421*9880d681SAndroid Build Coastguard Worker break;
1422*9880d681SAndroid Build Coastguard Worker }
1423*9880d681SAndroid Build Coastguard Worker }
1424*9880d681SAndroid Build Coastguard Worker return;
1425*9880d681SAndroid Build Coastguard Worker }
1426*9880d681SAndroid Build Coastguard Worker
1427*9880d681SAndroid Build Coastguard Worker // Lower PSHUFB and VPERMILP normally but add a comment if we can find
1428*9880d681SAndroid Build Coastguard Worker // a constant shuffle mask. We won't be able to do this at the MC layer
1429*9880d681SAndroid Build Coastguard Worker // because the mask isn't an immediate.
1430*9880d681SAndroid Build Coastguard Worker case X86::PSHUFBrm:
1431*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBrm:
1432*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBYrm:
1433*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rm:
1434*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rmk:
1435*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rmkz:
1436*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rm:
1437*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rmk:
1438*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rmkz:
1439*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrm:
1440*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrmk:
1441*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrmkz: {
1442*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1443*9880d681SAndroid Build Coastguard Worker break;
1444*9880d681SAndroid Build Coastguard Worker unsigned SrcIdx, MaskIdx;
1445*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
1446*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
1447*9880d681SAndroid Build Coastguard Worker case X86::PSHUFBrm:
1448*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBrm:
1449*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBYrm:
1450*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rm:
1451*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rm:
1452*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrm:
1453*9880d681SAndroid Build Coastguard Worker SrcIdx = 1; MaskIdx = 5; break;
1454*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rmkz:
1455*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rmkz:
1456*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrmkz:
1457*9880d681SAndroid Build Coastguard Worker SrcIdx = 2; MaskIdx = 6; break;
1458*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ128rmk:
1459*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZ256rmk:
1460*9880d681SAndroid Build Coastguard Worker case X86::VPSHUFBZrmk:
1461*9880d681SAndroid Build Coastguard Worker SrcIdx = 3; MaskIdx = 7; break;
1462*9880d681SAndroid Build Coastguard Worker }
1463*9880d681SAndroid Build Coastguard Worker
1464*9880d681SAndroid Build Coastguard Worker assert(MI->getNumOperands() >= 6 &&
1465*9880d681SAndroid Build Coastguard Worker "We should always have at least 6 operands!");
1466*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1467*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp = MI->getOperand(SrcIdx);
1468*9880d681SAndroid Build Coastguard Worker const MachineOperand &MaskOp = MI->getOperand(MaskIdx);
1469*9880d681SAndroid Build Coastguard Worker
1470*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MaskOp)) {
1471*9880d681SAndroid Build Coastguard Worker SmallVector<int, 16> Mask;
1472*9880d681SAndroid Build Coastguard Worker DecodePSHUFBMask(C, Mask);
1473*9880d681SAndroid Build Coastguard Worker if (!Mask.empty())
1474*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp, SrcOp, Mask));
1475*9880d681SAndroid Build Coastguard Worker }
1476*9880d681SAndroid Build Coastguard Worker break;
1477*9880d681SAndroid Build Coastguard Worker }
1478*9880d681SAndroid Build Coastguard Worker
1479*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPDrm:
1480*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPDYrm:
1481*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPDZ128rm:
1482*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPDZ256rm:
1483*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPDZrm: {
1484*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1485*9880d681SAndroid Build Coastguard Worker break;
1486*9880d681SAndroid Build Coastguard Worker assert(MI->getNumOperands() > 5 &&
1487*9880d681SAndroid Build Coastguard Worker "We should always have at least 5 operands!");
1488*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1489*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp = MI->getOperand(1);
1490*9880d681SAndroid Build Coastguard Worker const MachineOperand &MaskOp = MI->getOperand(5);
1491*9880d681SAndroid Build Coastguard Worker
1492*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MaskOp)) {
1493*9880d681SAndroid Build Coastguard Worker SmallVector<int, 8> Mask;
1494*9880d681SAndroid Build Coastguard Worker DecodeVPERMILPMask(C, 64, Mask);
1495*9880d681SAndroid Build Coastguard Worker if (!Mask.empty())
1496*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp, SrcOp, Mask));
1497*9880d681SAndroid Build Coastguard Worker }
1498*9880d681SAndroid Build Coastguard Worker break;
1499*9880d681SAndroid Build Coastguard Worker }
1500*9880d681SAndroid Build Coastguard Worker
1501*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPSrm:
1502*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPSYrm:
1503*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPSZ128rm:
1504*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPSZ256rm:
1505*9880d681SAndroid Build Coastguard Worker case X86::VPERMILPSZrm: {
1506*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1507*9880d681SAndroid Build Coastguard Worker break;
1508*9880d681SAndroid Build Coastguard Worker assert(MI->getNumOperands() > 5 &&
1509*9880d681SAndroid Build Coastguard Worker "We should always have at least 5 operands!");
1510*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1511*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp = MI->getOperand(1);
1512*9880d681SAndroid Build Coastguard Worker const MachineOperand &MaskOp = MI->getOperand(5);
1513*9880d681SAndroid Build Coastguard Worker
1514*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MaskOp)) {
1515*9880d681SAndroid Build Coastguard Worker SmallVector<int, 16> Mask;
1516*9880d681SAndroid Build Coastguard Worker DecodeVPERMILPMask(C, 32, Mask);
1517*9880d681SAndroid Build Coastguard Worker if (!Mask.empty())
1518*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp, SrcOp, Mask));
1519*9880d681SAndroid Build Coastguard Worker }
1520*9880d681SAndroid Build Coastguard Worker break;
1521*9880d681SAndroid Build Coastguard Worker }
1522*9880d681SAndroid Build Coastguard Worker
1523*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PDrm:
1524*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PSrm:
1525*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PDrmY:
1526*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PSrmY: {
1527*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1528*9880d681SAndroid Build Coastguard Worker break;
1529*9880d681SAndroid Build Coastguard Worker assert(MI->getNumOperands() > 7 &&
1530*9880d681SAndroid Build Coastguard Worker "We should always have at least 7 operands!");
1531*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1532*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp1 = MI->getOperand(1);
1533*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp2 = MI->getOperand(2);
1534*9880d681SAndroid Build Coastguard Worker const MachineOperand &MaskOp = MI->getOperand(6);
1535*9880d681SAndroid Build Coastguard Worker const MachineOperand &CtrlOp = MI->getOperand(MI->getNumOperands() - 1);
1536*9880d681SAndroid Build Coastguard Worker
1537*9880d681SAndroid Build Coastguard Worker if (!CtrlOp.isImm())
1538*9880d681SAndroid Build Coastguard Worker break;
1539*9880d681SAndroid Build Coastguard Worker
1540*9880d681SAndroid Build Coastguard Worker unsigned ElSize;
1541*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
1542*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Invalid opcode");
1543*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PSrm: case X86::VPERMIL2PSrmY: ElSize = 32; break;
1544*9880d681SAndroid Build Coastguard Worker case X86::VPERMIL2PDrm: case X86::VPERMIL2PDrmY: ElSize = 64; break;
1545*9880d681SAndroid Build Coastguard Worker }
1546*9880d681SAndroid Build Coastguard Worker
1547*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MaskOp)) {
1548*9880d681SAndroid Build Coastguard Worker SmallVector<int, 16> Mask;
1549*9880d681SAndroid Build Coastguard Worker DecodeVPERMIL2PMask(C, (unsigned)CtrlOp.getImm(), ElSize, Mask);
1550*9880d681SAndroid Build Coastguard Worker if (!Mask.empty())
1551*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp1, SrcOp2, Mask));
1552*9880d681SAndroid Build Coastguard Worker }
1553*9880d681SAndroid Build Coastguard Worker break;
1554*9880d681SAndroid Build Coastguard Worker }
1555*9880d681SAndroid Build Coastguard Worker
1556*9880d681SAndroid Build Coastguard Worker case X86::VPPERMrrm: {
1557*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1558*9880d681SAndroid Build Coastguard Worker break;
1559*9880d681SAndroid Build Coastguard Worker assert(MI->getNumOperands() > 6 &&
1560*9880d681SAndroid Build Coastguard Worker "We should always have at least 6 operands!");
1561*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1562*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp1 = MI->getOperand(1);
1563*9880d681SAndroid Build Coastguard Worker const MachineOperand &SrcOp2 = MI->getOperand(2);
1564*9880d681SAndroid Build Coastguard Worker const MachineOperand &MaskOp = MI->getOperand(6);
1565*9880d681SAndroid Build Coastguard Worker
1566*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MaskOp)) {
1567*9880d681SAndroid Build Coastguard Worker SmallVector<int, 16> Mask;
1568*9880d681SAndroid Build Coastguard Worker DecodeVPPERMMask(C, Mask);
1569*9880d681SAndroid Build Coastguard Worker if (!Mask.empty())
1570*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp1, SrcOp2, Mask));
1571*9880d681SAndroid Build Coastguard Worker }
1572*9880d681SAndroid Build Coastguard Worker break;
1573*9880d681SAndroid Build Coastguard Worker }
1574*9880d681SAndroid Build Coastguard Worker
1575*9880d681SAndroid Build Coastguard Worker #define MOV_CASE(Prefix, Suffix) \
1576*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVAPD##Suffix##rm: \
1577*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVAPS##Suffix##rm: \
1578*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVUPD##Suffix##rm: \
1579*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVUPS##Suffix##rm: \
1580*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVDQA##Suffix##rm: \
1581*9880d681SAndroid Build Coastguard Worker case X86::Prefix##MOVDQU##Suffix##rm:
1582*9880d681SAndroid Build Coastguard Worker
1583*9880d681SAndroid Build Coastguard Worker #define MOV_AVX512_CASE(Suffix) \
1584*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQA64##Suffix##rm: \
1585*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQA32##Suffix##rm: \
1586*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQU64##Suffix##rm: \
1587*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQU32##Suffix##rm: \
1588*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQU16##Suffix##rm: \
1589*9880d681SAndroid Build Coastguard Worker case X86::VMOVDQU8##Suffix##rm: \
1590*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPS##Suffix##rm: \
1591*9880d681SAndroid Build Coastguard Worker case X86::VMOVAPD##Suffix##rm: \
1592*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPS##Suffix##rm: \
1593*9880d681SAndroid Build Coastguard Worker case X86::VMOVUPD##Suffix##rm:
1594*9880d681SAndroid Build Coastguard Worker
1595*9880d681SAndroid Build Coastguard Worker #define CASE_ALL_MOV_RM() \
1596*9880d681SAndroid Build Coastguard Worker MOV_CASE(, ) /* SSE */ \
1597*9880d681SAndroid Build Coastguard Worker MOV_CASE(V, ) /* AVX-128 */ \
1598*9880d681SAndroid Build Coastguard Worker MOV_CASE(V, Y) /* AVX-256 */ \
1599*9880d681SAndroid Build Coastguard Worker MOV_AVX512_CASE(Z) \
1600*9880d681SAndroid Build Coastguard Worker MOV_AVX512_CASE(Z256) \
1601*9880d681SAndroid Build Coastguard Worker MOV_AVX512_CASE(Z128)
1602*9880d681SAndroid Build Coastguard Worker
1603*9880d681SAndroid Build Coastguard Worker // For loads from a constant pool to a vector register, print the constant
1604*9880d681SAndroid Build Coastguard Worker // loaded.
1605*9880d681SAndroid Build Coastguard Worker CASE_ALL_MOV_RM()
1606*9880d681SAndroid Build Coastguard Worker if (!OutStreamer->isVerboseAsm())
1607*9880d681SAndroid Build Coastguard Worker break;
1608*9880d681SAndroid Build Coastguard Worker if (MI->getNumOperands() > 4)
1609*9880d681SAndroid Build Coastguard Worker if (auto *C = getConstantFromPool(*MI, MI->getOperand(4))) {
1610*9880d681SAndroid Build Coastguard Worker std::string Comment;
1611*9880d681SAndroid Build Coastguard Worker raw_string_ostream CS(Comment);
1612*9880d681SAndroid Build Coastguard Worker const MachineOperand &DstOp = MI->getOperand(0);
1613*9880d681SAndroid Build Coastguard Worker CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
1614*9880d681SAndroid Build Coastguard Worker if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) {
1615*9880d681SAndroid Build Coastguard Worker CS << "[";
1616*9880d681SAndroid Build Coastguard Worker for (int i = 0, NumElements = CDS->getNumElements(); i < NumElements; ++i) {
1617*9880d681SAndroid Build Coastguard Worker if (i != 0)
1618*9880d681SAndroid Build Coastguard Worker CS << ",";
1619*9880d681SAndroid Build Coastguard Worker if (CDS->getElementType()->isIntegerTy())
1620*9880d681SAndroid Build Coastguard Worker CS << CDS->getElementAsInteger(i);
1621*9880d681SAndroid Build Coastguard Worker else if (CDS->getElementType()->isFloatTy())
1622*9880d681SAndroid Build Coastguard Worker CS << CDS->getElementAsFloat(i);
1623*9880d681SAndroid Build Coastguard Worker else if (CDS->getElementType()->isDoubleTy())
1624*9880d681SAndroid Build Coastguard Worker CS << CDS->getElementAsDouble(i);
1625*9880d681SAndroid Build Coastguard Worker else
1626*9880d681SAndroid Build Coastguard Worker CS << "?";
1627*9880d681SAndroid Build Coastguard Worker }
1628*9880d681SAndroid Build Coastguard Worker CS << "]";
1629*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(CS.str());
1630*9880d681SAndroid Build Coastguard Worker } else if (auto *CV = dyn_cast<ConstantVector>(C)) {
1631*9880d681SAndroid Build Coastguard Worker CS << "<";
1632*9880d681SAndroid Build Coastguard Worker for (int i = 0, NumOperands = CV->getNumOperands(); i < NumOperands; ++i) {
1633*9880d681SAndroid Build Coastguard Worker if (i != 0)
1634*9880d681SAndroid Build Coastguard Worker CS << ",";
1635*9880d681SAndroid Build Coastguard Worker Constant *COp = CV->getOperand(i);
1636*9880d681SAndroid Build Coastguard Worker if (isa<UndefValue>(COp)) {
1637*9880d681SAndroid Build Coastguard Worker CS << "u";
1638*9880d681SAndroid Build Coastguard Worker } else if (auto *CI = dyn_cast<ConstantInt>(COp)) {
1639*9880d681SAndroid Build Coastguard Worker if (CI->getBitWidth() <= 64) {
1640*9880d681SAndroid Build Coastguard Worker CS << CI->getZExtValue();
1641*9880d681SAndroid Build Coastguard Worker } else {
1642*9880d681SAndroid Build Coastguard Worker // print multi-word constant as (w0,w1)
1643*9880d681SAndroid Build Coastguard Worker const auto &Val = CI->getValue();
1644*9880d681SAndroid Build Coastguard Worker CS << "(";
1645*9880d681SAndroid Build Coastguard Worker for (int i = 0, N = Val.getNumWords(); i < N; ++i) {
1646*9880d681SAndroid Build Coastguard Worker if (i > 0)
1647*9880d681SAndroid Build Coastguard Worker CS << ",";
1648*9880d681SAndroid Build Coastguard Worker CS << Val.getRawData()[i];
1649*9880d681SAndroid Build Coastguard Worker }
1650*9880d681SAndroid Build Coastguard Worker CS << ")";
1651*9880d681SAndroid Build Coastguard Worker }
1652*9880d681SAndroid Build Coastguard Worker } else if (auto *CF = dyn_cast<ConstantFP>(COp)) {
1653*9880d681SAndroid Build Coastguard Worker SmallString<32> Str;
1654*9880d681SAndroid Build Coastguard Worker CF->getValueAPF().toString(Str);
1655*9880d681SAndroid Build Coastguard Worker CS << Str;
1656*9880d681SAndroid Build Coastguard Worker } else {
1657*9880d681SAndroid Build Coastguard Worker CS << "?";
1658*9880d681SAndroid Build Coastguard Worker }
1659*9880d681SAndroid Build Coastguard Worker }
1660*9880d681SAndroid Build Coastguard Worker CS << ">";
1661*9880d681SAndroid Build Coastguard Worker OutStreamer->AddComment(CS.str());
1662*9880d681SAndroid Build Coastguard Worker }
1663*9880d681SAndroid Build Coastguard Worker }
1664*9880d681SAndroid Build Coastguard Worker break;
1665*9880d681SAndroid Build Coastguard Worker }
1666*9880d681SAndroid Build Coastguard Worker
1667*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
1668*9880d681SAndroid Build Coastguard Worker MCInstLowering.Lower(MI, TmpInst);
1669*9880d681SAndroid Build Coastguard Worker
1670*9880d681SAndroid Build Coastguard Worker // Stackmap shadows cannot include branch targets, so we can count the bytes
1671*9880d681SAndroid Build Coastguard Worker // in a call towards the shadow, but must ensure that the no thread returns
1672*9880d681SAndroid Build Coastguard Worker // in to the stackmap shadow. The only way to achieve this is if the call
1673*9880d681SAndroid Build Coastguard Worker // is at the end of the shadow.
1674*9880d681SAndroid Build Coastguard Worker if (MI->isCall()) {
1675*9880d681SAndroid Build Coastguard Worker // Count then size of the call towards the shadow
1676*9880d681SAndroid Build Coastguard Worker SMShadowTracker.count(TmpInst, getSubtargetInfo(), CodeEmitter.get());
1677*9880d681SAndroid Build Coastguard Worker // Then flush the shadow so that we fill with nops before the call, not
1678*9880d681SAndroid Build Coastguard Worker // after it.
1679*9880d681SAndroid Build Coastguard Worker SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
1680*9880d681SAndroid Build Coastguard Worker // Then emit the call
1681*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitInstruction(TmpInst, getSubtargetInfo());
1682*9880d681SAndroid Build Coastguard Worker return;
1683*9880d681SAndroid Build Coastguard Worker }
1684*9880d681SAndroid Build Coastguard Worker
1685*9880d681SAndroid Build Coastguard Worker EmitAndCountInstruction(TmpInst);
1686*9880d681SAndroid Build Coastguard Worker }
1687