10b57cec5SDimitry Andric //===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file includes code for rendering MCInst instances as Intel-style
100b57cec5SDimitry Andric // assembly.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "X86IntelInstPrinter.h"
150b57cec5SDimitry Andric #include "X86BaseInfo.h"
160b57cec5SDimitry Andric #include "X86InstComments.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
19e8d8bef9SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
230b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
250b57cec5SDimitry Andric #include <cassert>
260b57cec5SDimitry Andric #include <cstdint>
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric using namespace llvm;
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric #define DEBUG_TYPE "asm-printer"
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric // Include the auto-generated portion of the assembly writer.
330b57cec5SDimitry Andric #define PRINT_ALIAS_INSTR
340b57cec5SDimitry Andric #include "X86GenAsmWriter1.inc"
350b57cec5SDimitry Andric
printRegName(raw_ostream & OS,MCRegister Reg) const36bdd1243dSDimitry Andric void X86IntelInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
375f757f3fSDimitry Andric markup(OS, Markup::Register) << getRegisterName(Reg);
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)40480093f4SDimitry Andric void X86IntelInstPrinter::printInst(const MCInst *MI, uint64_t Address,
41480093f4SDimitry Andric StringRef Annot, const MCSubtargetInfo &STI,
42480093f4SDimitry Andric raw_ostream &OS) {
4381ad6265SDimitry Andric printInstFlags(MI, OS, STI);
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric // In 16-bit mode, print data16 as data32.
460b57cec5SDimitry Andric if (MI->getOpcode() == X86::DATA16_PREFIX &&
4706c3fb27SDimitry Andric STI.hasFeature(X86::Is16Bit)) {
480b57cec5SDimitry Andric OS << "\tdata32";
495ffd83dbSDimitry Andric } else if (!printAliasInstr(MI, Address, OS) && !printVecCompareInstr(MI, OS))
50480093f4SDimitry Andric printInstruction(MI, Address, OS);
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric // Next always print the annotation.
530b57cec5SDimitry Andric printAnnotation(OS, Annot);
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // If verbose assembly is enabled, we can print some informative comments.
560b57cec5SDimitry Andric if (CommentStream)
570b57cec5SDimitry Andric EmitAnyX86InstComments(MI, *CommentStream, MII);
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
printVecCompareInstr(const MCInst * MI,raw_ostream & OS)600b57cec5SDimitry Andric bool X86IntelInstPrinter::printVecCompareInstr(const MCInst *MI, raw_ostream &OS) {
610b57cec5SDimitry Andric if (MI->getNumOperands() == 0 ||
620b57cec5SDimitry Andric !MI->getOperand(MI->getNumOperands() - 1).isImm())
630b57cec5SDimitry Andric return false;
640b57cec5SDimitry Andric
650b57cec5SDimitry Andric int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm();
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric const MCInstrDesc &Desc = MII.get(MI->getOpcode());
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric // Custom print the vector compare instructions to get the immediate
700b57cec5SDimitry Andric // translated into the mnemonic.
710b57cec5SDimitry Andric switch (MI->getOpcode()) {
720b57cec5SDimitry Andric case X86::CMPPDrmi: case X86::CMPPDrri:
730b57cec5SDimitry Andric case X86::CMPPSrmi: case X86::CMPPSrri:
74*0fca6ea1SDimitry Andric case X86::CMPSDrmi: case X86::CMPSDrri:
75*0fca6ea1SDimitry Andric case X86::CMPSDrmi_Int: case X86::CMPSDrri_Int:
76*0fca6ea1SDimitry Andric case X86::CMPSSrmi: case X86::CMPSSrri:
77*0fca6ea1SDimitry Andric case X86::CMPSSrmi_Int: case X86::CMPSSrri_Int:
780b57cec5SDimitry Andric if (Imm >= 0 && Imm <= 7) {
790b57cec5SDimitry Andric OS << '\t';
800b57cec5SDimitry Andric printCMPMnemonic(MI, /*IsVCMP*/false, OS);
810b57cec5SDimitry Andric printOperand(MI, 0, OS);
820b57cec5SDimitry Andric OS << ", ";
830b57cec5SDimitry Andric // Skip operand 1 as its tied to the dest.
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) {
860b57cec5SDimitry Andric if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XS)
870b57cec5SDimitry Andric printdwordmem(MI, 2, OS);
880b57cec5SDimitry Andric else if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XD)
890b57cec5SDimitry Andric printqwordmem(MI, 2, OS);
900b57cec5SDimitry Andric else
910b57cec5SDimitry Andric printxmmwordmem(MI, 2, OS);
920b57cec5SDimitry Andric } else
930b57cec5SDimitry Andric printOperand(MI, 2, OS);
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric return true;
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric break;
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric case X86::VCMPPDrmi: case X86::VCMPPDrri:
1000b57cec5SDimitry Andric case X86::VCMPPDYrmi: case X86::VCMPPDYrri:
1010b57cec5SDimitry Andric case X86::VCMPPDZ128rmi: case X86::VCMPPDZ128rri:
1020b57cec5SDimitry Andric case X86::VCMPPDZ256rmi: case X86::VCMPPDZ256rri:
1030b57cec5SDimitry Andric case X86::VCMPPDZrmi: case X86::VCMPPDZrri:
1040b57cec5SDimitry Andric case X86::VCMPPSrmi: case X86::VCMPPSrri:
1050b57cec5SDimitry Andric case X86::VCMPPSYrmi: case X86::VCMPPSYrri:
1060b57cec5SDimitry Andric case X86::VCMPPSZ128rmi: case X86::VCMPPSZ128rri:
1070b57cec5SDimitry Andric case X86::VCMPPSZ256rmi: case X86::VCMPPSZ256rri:
1080b57cec5SDimitry Andric case X86::VCMPPSZrmi: case X86::VCMPPSZrri:
109*0fca6ea1SDimitry Andric case X86::VCMPSDrmi: case X86::VCMPSDrri:
110*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi: case X86::VCMPSDZrri:
111*0fca6ea1SDimitry Andric case X86::VCMPSDrmi_Int: case X86::VCMPSDrri_Int:
112*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi_Int: case X86::VCMPSDZrri_Int:
113*0fca6ea1SDimitry Andric case X86::VCMPSSrmi: case X86::VCMPSSrri:
114*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi: case X86::VCMPSSZrri:
115*0fca6ea1SDimitry Andric case X86::VCMPSSrmi_Int: case X86::VCMPSSrri_Int:
116*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi_Int: case X86::VCMPSSZrri_Int:
1170b57cec5SDimitry Andric case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik:
1180b57cec5SDimitry Andric case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik:
1190b57cec5SDimitry Andric case X86::VCMPPDZrmik: case X86::VCMPPDZrrik:
1200b57cec5SDimitry Andric case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik:
1210b57cec5SDimitry Andric case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik:
1220b57cec5SDimitry Andric case X86::VCMPPSZrmik: case X86::VCMPPSZrrik:
123*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi_Intk: case X86::VCMPSDZrri_Intk:
124*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi_Intk: case X86::VCMPSSZrri_Intk:
1250b57cec5SDimitry Andric case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik:
1260b57cec5SDimitry Andric case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik:
1270b57cec5SDimitry Andric case X86::VCMPPDZrmbi: case X86::VCMPPDZrmbik:
1280b57cec5SDimitry Andric case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik:
1290b57cec5SDimitry Andric case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik:
1300b57cec5SDimitry Andric case X86::VCMPPSZrmbi: case X86::VCMPPSZrmbik:
1310b57cec5SDimitry Andric case X86::VCMPPDZrrib: case X86::VCMPPDZrribk:
1320b57cec5SDimitry Andric case X86::VCMPPSZrrib: case X86::VCMPPSZrribk:
133*0fca6ea1SDimitry Andric case X86::VCMPSDZrrib_Int: case X86::VCMPSDZrrib_Intk:
134*0fca6ea1SDimitry Andric case X86::VCMPSSZrrib_Int: case X86::VCMPSSZrrib_Intk:
135349cc55cSDimitry Andric case X86::VCMPPHZ128rmi: case X86::VCMPPHZ128rri:
136349cc55cSDimitry Andric case X86::VCMPPHZ256rmi: case X86::VCMPPHZ256rri:
137349cc55cSDimitry Andric case X86::VCMPPHZrmi: case X86::VCMPPHZrri:
138*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi: case X86::VCMPSHZrri:
139*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi_Int: case X86::VCMPSHZrri_Int:
140349cc55cSDimitry Andric case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik:
141349cc55cSDimitry Andric case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik:
142349cc55cSDimitry Andric case X86::VCMPPHZrmik: case X86::VCMPPHZrrik:
143*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi_Intk: case X86::VCMPSHZrri_Intk:
144349cc55cSDimitry Andric case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik:
145349cc55cSDimitry Andric case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik:
146349cc55cSDimitry Andric case X86::VCMPPHZrmbi: case X86::VCMPPHZrmbik:
147349cc55cSDimitry Andric case X86::VCMPPHZrrib: case X86::VCMPPHZrribk:
148*0fca6ea1SDimitry Andric case X86::VCMPSHZrrib_Int: case X86::VCMPSHZrrib_Intk:
1490b57cec5SDimitry Andric if (Imm >= 0 && Imm <= 31) {
1500b57cec5SDimitry Andric OS << '\t';
1510b57cec5SDimitry Andric printCMPMnemonic(MI, /*IsVCMP*/true, OS);
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric unsigned CurOp = 0;
1540b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_K) {
1570b57cec5SDimitry Andric // Print mask operand.
1580b57cec5SDimitry Andric OS << " {";
1590b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
1600b57cec5SDimitry Andric OS << "}";
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric OS << ", ";
1630b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
1640b57cec5SDimitry Andric OS << ", ";
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) {
1670b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_B) {
1680b57cec5SDimitry Andric // Broadcast form.
169349cc55cSDimitry Andric // Load size is word for TA map. Otherwise it is based on W-bit.
170349cc55cSDimitry Andric if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) {
17106c3fb27SDimitry Andric assert(!(Desc.TSFlags & X86II::REX_W) && "Unknown W-bit value!");
172349cc55cSDimitry Andric printwordmem(MI, CurOp++, OS);
17306c3fb27SDimitry Andric } else if (Desc.TSFlags & X86II::REX_W) {
1740b57cec5SDimitry Andric printqwordmem(MI, CurOp++, OS);
175349cc55cSDimitry Andric } else {
1760b57cec5SDimitry Andric printdwordmem(MI, CurOp++, OS);
177349cc55cSDimitry Andric }
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric // Print the number of elements broadcasted.
1800b57cec5SDimitry Andric unsigned NumElts;
1810b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_L2)
18206c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 8 : 16;
1830b57cec5SDimitry Andric else if (Desc.TSFlags & X86II::VEX_L)
18406c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 4 : 8;
1850b57cec5SDimitry Andric else
18606c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 2 : 4;
187349cc55cSDimitry Andric if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) {
18806c3fb27SDimitry Andric assert(!(Desc.TSFlags & X86II::REX_W) && "Unknown W-bit value!");
189349cc55cSDimitry Andric NumElts *= 2;
190349cc55cSDimitry Andric }
1910b57cec5SDimitry Andric OS << "{1to" << NumElts << "}";
1920b57cec5SDimitry Andric } else {
193349cc55cSDimitry Andric if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XS) {
194349cc55cSDimitry Andric if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA)
195349cc55cSDimitry Andric printwordmem(MI, CurOp++, OS);
1960b57cec5SDimitry Andric else
197349cc55cSDimitry Andric printdwordmem(MI, CurOp++, OS);
198349cc55cSDimitry Andric } else if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XD) {
199349cc55cSDimitry Andric assert((Desc.TSFlags & X86II::OpMapMask) != X86II::TA &&
200349cc55cSDimitry Andric "Unexpected op map!");
201349cc55cSDimitry Andric printqwordmem(MI, CurOp++, OS);
202349cc55cSDimitry Andric } else if (Desc.TSFlags & X86II::EVEX_L2) {
203349cc55cSDimitry Andric printzmmwordmem(MI, CurOp++, OS);
204349cc55cSDimitry Andric } else if (Desc.TSFlags & X86II::VEX_L) {
205349cc55cSDimitry Andric printymmwordmem(MI, CurOp++, OS);
206349cc55cSDimitry Andric } else {
2070b57cec5SDimitry Andric printxmmwordmem(MI, CurOp++, OS);
2080b57cec5SDimitry Andric }
209349cc55cSDimitry Andric }
2100b57cec5SDimitry Andric } else {
2110b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
2120b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_B)
2130b57cec5SDimitry Andric OS << ", {sae}";
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric return true;
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric break;
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric case X86::VPCOMBmi: case X86::VPCOMBri:
2210b57cec5SDimitry Andric case X86::VPCOMDmi: case X86::VPCOMDri:
2220b57cec5SDimitry Andric case X86::VPCOMQmi: case X86::VPCOMQri:
2230b57cec5SDimitry Andric case X86::VPCOMUBmi: case X86::VPCOMUBri:
2240b57cec5SDimitry Andric case X86::VPCOMUDmi: case X86::VPCOMUDri:
2250b57cec5SDimitry Andric case X86::VPCOMUQmi: case X86::VPCOMUQri:
2260b57cec5SDimitry Andric case X86::VPCOMUWmi: case X86::VPCOMUWri:
2270b57cec5SDimitry Andric case X86::VPCOMWmi: case X86::VPCOMWri:
2280b57cec5SDimitry Andric if (Imm >= 0 && Imm <= 7) {
2290b57cec5SDimitry Andric OS << '\t';
2300b57cec5SDimitry Andric printVPCOMMnemonic(MI, OS);
2310b57cec5SDimitry Andric printOperand(MI, 0, OS);
2320b57cec5SDimitry Andric OS << ", ";
2330b57cec5SDimitry Andric printOperand(MI, 1, OS);
2340b57cec5SDimitry Andric OS << ", ";
2350b57cec5SDimitry Andric if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem)
2360b57cec5SDimitry Andric printxmmwordmem(MI, 2, OS);
2370b57cec5SDimitry Andric else
2380b57cec5SDimitry Andric printOperand(MI, 2, OS);
2390b57cec5SDimitry Andric return true;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric break;
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric case X86::VPCMPBZ128rmi: case X86::VPCMPBZ128rri:
2440b57cec5SDimitry Andric case X86::VPCMPBZ256rmi: case X86::VPCMPBZ256rri:
2450b57cec5SDimitry Andric case X86::VPCMPBZrmi: case X86::VPCMPBZrri:
2460b57cec5SDimitry Andric case X86::VPCMPDZ128rmi: case X86::VPCMPDZ128rri:
2470b57cec5SDimitry Andric case X86::VPCMPDZ256rmi: case X86::VPCMPDZ256rri:
2480b57cec5SDimitry Andric case X86::VPCMPDZrmi: case X86::VPCMPDZrri:
2490b57cec5SDimitry Andric case X86::VPCMPQZ128rmi: case X86::VPCMPQZ128rri:
2500b57cec5SDimitry Andric case X86::VPCMPQZ256rmi: case X86::VPCMPQZ256rri:
2510b57cec5SDimitry Andric case X86::VPCMPQZrmi: case X86::VPCMPQZrri:
2520b57cec5SDimitry Andric case X86::VPCMPUBZ128rmi: case X86::VPCMPUBZ128rri:
2530b57cec5SDimitry Andric case X86::VPCMPUBZ256rmi: case X86::VPCMPUBZ256rri:
2540b57cec5SDimitry Andric case X86::VPCMPUBZrmi: case X86::VPCMPUBZrri:
2550b57cec5SDimitry Andric case X86::VPCMPUDZ128rmi: case X86::VPCMPUDZ128rri:
2560b57cec5SDimitry Andric case X86::VPCMPUDZ256rmi: case X86::VPCMPUDZ256rri:
2570b57cec5SDimitry Andric case X86::VPCMPUDZrmi: case X86::VPCMPUDZrri:
2580b57cec5SDimitry Andric case X86::VPCMPUQZ128rmi: case X86::VPCMPUQZ128rri:
2590b57cec5SDimitry Andric case X86::VPCMPUQZ256rmi: case X86::VPCMPUQZ256rri:
2600b57cec5SDimitry Andric case X86::VPCMPUQZrmi: case X86::VPCMPUQZrri:
2610b57cec5SDimitry Andric case X86::VPCMPUWZ128rmi: case X86::VPCMPUWZ128rri:
2620b57cec5SDimitry Andric case X86::VPCMPUWZ256rmi: case X86::VPCMPUWZ256rri:
2630b57cec5SDimitry Andric case X86::VPCMPUWZrmi: case X86::VPCMPUWZrri:
2640b57cec5SDimitry Andric case X86::VPCMPWZ128rmi: case X86::VPCMPWZ128rri:
2650b57cec5SDimitry Andric case X86::VPCMPWZ256rmi: case X86::VPCMPWZ256rri:
2660b57cec5SDimitry Andric case X86::VPCMPWZrmi: case X86::VPCMPWZrri:
2670b57cec5SDimitry Andric case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik:
2680b57cec5SDimitry Andric case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik:
2690b57cec5SDimitry Andric case X86::VPCMPBZrmik: case X86::VPCMPBZrrik:
2700b57cec5SDimitry Andric case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik:
2710b57cec5SDimitry Andric case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik:
2720b57cec5SDimitry Andric case X86::VPCMPDZrmik: case X86::VPCMPDZrrik:
2730b57cec5SDimitry Andric case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik:
2740b57cec5SDimitry Andric case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik:
2750b57cec5SDimitry Andric case X86::VPCMPQZrmik: case X86::VPCMPQZrrik:
2760b57cec5SDimitry Andric case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik:
2770b57cec5SDimitry Andric case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik:
2780b57cec5SDimitry Andric case X86::VPCMPUBZrmik: case X86::VPCMPUBZrrik:
2790b57cec5SDimitry Andric case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik:
2800b57cec5SDimitry Andric case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik:
2810b57cec5SDimitry Andric case X86::VPCMPUDZrmik: case X86::VPCMPUDZrrik:
2820b57cec5SDimitry Andric case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik:
2830b57cec5SDimitry Andric case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik:
2840b57cec5SDimitry Andric case X86::VPCMPUQZrmik: case X86::VPCMPUQZrrik:
2850b57cec5SDimitry Andric case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik:
2860b57cec5SDimitry Andric case X86::VPCMPUWZ256rmik: case X86::VPCMPUWZ256rrik:
2870b57cec5SDimitry Andric case X86::VPCMPUWZrmik: case X86::VPCMPUWZrrik:
2880b57cec5SDimitry Andric case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik:
2890b57cec5SDimitry Andric case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik:
2900b57cec5SDimitry Andric case X86::VPCMPWZrmik: case X86::VPCMPWZrrik:
2910b57cec5SDimitry Andric case X86::VPCMPDZ128rmib: case X86::VPCMPDZ128rmibk:
2920b57cec5SDimitry Andric case X86::VPCMPDZ256rmib: case X86::VPCMPDZ256rmibk:
2930b57cec5SDimitry Andric case X86::VPCMPDZrmib: case X86::VPCMPDZrmibk:
2940b57cec5SDimitry Andric case X86::VPCMPQZ128rmib: case X86::VPCMPQZ128rmibk:
2950b57cec5SDimitry Andric case X86::VPCMPQZ256rmib: case X86::VPCMPQZ256rmibk:
2960b57cec5SDimitry Andric case X86::VPCMPQZrmib: case X86::VPCMPQZrmibk:
2970b57cec5SDimitry Andric case X86::VPCMPUDZ128rmib: case X86::VPCMPUDZ128rmibk:
2980b57cec5SDimitry Andric case X86::VPCMPUDZ256rmib: case X86::VPCMPUDZ256rmibk:
2990b57cec5SDimitry Andric case X86::VPCMPUDZrmib: case X86::VPCMPUDZrmibk:
3000b57cec5SDimitry Andric case X86::VPCMPUQZ128rmib: case X86::VPCMPUQZ128rmibk:
3010b57cec5SDimitry Andric case X86::VPCMPUQZ256rmib: case X86::VPCMPUQZ256rmibk:
3020b57cec5SDimitry Andric case X86::VPCMPUQZrmib: case X86::VPCMPUQZrmibk:
3030b57cec5SDimitry Andric if ((Imm >= 0 && Imm <= 2) || (Imm >= 4 && Imm <= 6)) {
3040b57cec5SDimitry Andric OS << '\t';
3050b57cec5SDimitry Andric printVPCMPMnemonic(MI, OS);
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric unsigned CurOp = 0;
3080b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_K) {
3110b57cec5SDimitry Andric // Print mask operand.
3120b57cec5SDimitry Andric OS << " {";
3130b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
3140b57cec5SDimitry Andric OS << "}";
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric OS << ", ";
3170b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
3180b57cec5SDimitry Andric OS << ", ";
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) {
3210b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_B) {
3220b57cec5SDimitry Andric // Broadcast form.
3230b57cec5SDimitry Andric // Load size is based on W-bit as only D and Q are supported.
32406c3fb27SDimitry Andric if (Desc.TSFlags & X86II::REX_W)
3250b57cec5SDimitry Andric printqwordmem(MI, CurOp++, OS);
3260b57cec5SDimitry Andric else
3270b57cec5SDimitry Andric printdwordmem(MI, CurOp++, OS);
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric // Print the number of elements broadcasted.
3300b57cec5SDimitry Andric unsigned NumElts;
3310b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_L2)
33206c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 8 : 16;
3330b57cec5SDimitry Andric else if (Desc.TSFlags & X86II::VEX_L)
33406c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 4 : 8;
3350b57cec5SDimitry Andric else
33606c3fb27SDimitry Andric NumElts = (Desc.TSFlags & X86II::REX_W) ? 2 : 4;
3370b57cec5SDimitry Andric OS << "{1to" << NumElts << "}";
3380b57cec5SDimitry Andric } else {
3390b57cec5SDimitry Andric if (Desc.TSFlags & X86II::EVEX_L2)
3400b57cec5SDimitry Andric printzmmwordmem(MI, CurOp++, OS);
3410b57cec5SDimitry Andric else if (Desc.TSFlags & X86II::VEX_L)
3420b57cec5SDimitry Andric printymmwordmem(MI, CurOp++, OS);
3430b57cec5SDimitry Andric else
3440b57cec5SDimitry Andric printxmmwordmem(MI, CurOp++, OS);
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric } else {
3470b57cec5SDimitry Andric printOperand(MI, CurOp++, OS);
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric return true;
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric break;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric return false;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3580b57cec5SDimitry Andric void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
3590b57cec5SDimitry Andric raw_ostream &O) {
3600b57cec5SDimitry Andric const MCOperand &Op = MI->getOperand(OpNo);
3610b57cec5SDimitry Andric if (Op.isReg()) {
3620b57cec5SDimitry Andric printRegName(O, Op.getReg());
3630b57cec5SDimitry Andric } else if (Op.isImm()) {
3645f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatImm((int64_t)Op.getImm());
3650b57cec5SDimitry Andric } else {
3660b57cec5SDimitry Andric assert(Op.isExpr() && "unknown operand kind in printOperand");
3670b57cec5SDimitry Andric O << "offset ";
3680b57cec5SDimitry Andric Op.getExpr()->print(O, &MAI);
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric
printMemReference(const MCInst * MI,unsigned Op,raw_ostream & O)3720b57cec5SDimitry Andric void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
3730b57cec5SDimitry Andric raw_ostream &O) {
374e8d8bef9SDimitry Andric // Do not print the exact form of the memory operand if it references a known
375e8d8bef9SDimitry Andric // binary object.
376e8d8bef9SDimitry Andric if (SymbolizeOperands && MIA) {
377e8d8bef9SDimitry Andric uint64_t Target;
378e8d8bef9SDimitry Andric if (MIA->evaluateBranch(*MI, 0, 0, Target))
379e8d8bef9SDimitry Andric return;
380349cc55cSDimitry Andric if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0))
381e8d8bef9SDimitry Andric return;
382e8d8bef9SDimitry Andric }
3830b57cec5SDimitry Andric const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg);
3840b57cec5SDimitry Andric unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
3850b57cec5SDimitry Andric const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
3860b57cec5SDimitry Andric const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andric // If this has a segment register, print it.
3890b57cec5SDimitry Andric printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O);
3900b57cec5SDimitry Andric
3915f757f3fSDimitry Andric WithMarkup M = markup(O, Markup::Memory);
3925f757f3fSDimitry Andric O << '[';
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andric bool NeedPlus = false;
3950b57cec5SDimitry Andric if (BaseReg.getReg()) {
3960b57cec5SDimitry Andric printOperand(MI, Op+X86::AddrBaseReg, O);
3970b57cec5SDimitry Andric NeedPlus = true;
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric if (IndexReg.getReg()) {
4010b57cec5SDimitry Andric if (NeedPlus) O << " + ";
40206c3fb27SDimitry Andric if (ScaleVal != 1 || !BaseReg.getReg())
4030b57cec5SDimitry Andric O << ScaleVal << '*';
4040b57cec5SDimitry Andric printOperand(MI, Op+X86::AddrIndexReg, O);
4050b57cec5SDimitry Andric NeedPlus = true;
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric if (!DispSpec.isImm()) {
4090b57cec5SDimitry Andric if (NeedPlus) O << " + ";
4100b57cec5SDimitry Andric assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
4110b57cec5SDimitry Andric DispSpec.getExpr()->print(O, &MAI);
4120b57cec5SDimitry Andric } else {
4130b57cec5SDimitry Andric int64_t DispVal = DispSpec.getImm();
4140b57cec5SDimitry Andric if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
4150b57cec5SDimitry Andric if (NeedPlus) {
4160b57cec5SDimitry Andric if (DispVal > 0)
4170b57cec5SDimitry Andric O << " + ";
4180b57cec5SDimitry Andric else {
4190b57cec5SDimitry Andric O << " - ";
4200b57cec5SDimitry Andric DispVal = -DispVal;
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric }
4235f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatImm(DispVal);
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric
4275f757f3fSDimitry Andric O << ']';
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric
printSrcIdx(const MCInst * MI,unsigned Op,raw_ostream & O)4300b57cec5SDimitry Andric void X86IntelInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
4310b57cec5SDimitry Andric raw_ostream &O) {
4320b57cec5SDimitry Andric // If this has a segment register, print it.
4330b57cec5SDimitry Andric printOptionalSegReg(MI, Op + 1, O);
4345f757f3fSDimitry Andric
4355f757f3fSDimitry Andric WithMarkup M = markup(O, Markup::Memory);
4365f757f3fSDimitry Andric O << '[';
4370b57cec5SDimitry Andric printOperand(MI, Op, O);
4385f757f3fSDimitry Andric O << ']';
4390b57cec5SDimitry Andric }
4400b57cec5SDimitry Andric
printDstIdx(const MCInst * MI,unsigned Op,raw_ostream & O)4410b57cec5SDimitry Andric void X86IntelInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
4420b57cec5SDimitry Andric raw_ostream &O) {
4430b57cec5SDimitry Andric // DI accesses are always ES-based.
4445f757f3fSDimitry Andric O << "es:";
4455f757f3fSDimitry Andric
4465f757f3fSDimitry Andric WithMarkup M = markup(O, Markup::Memory);
4475f757f3fSDimitry Andric O << '[';
4480b57cec5SDimitry Andric printOperand(MI, Op, O);
4495f757f3fSDimitry Andric O << ']';
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric
printMemOffset(const MCInst * MI,unsigned Op,raw_ostream & O)4520b57cec5SDimitry Andric void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
4530b57cec5SDimitry Andric raw_ostream &O) {
4540b57cec5SDimitry Andric const MCOperand &DispSpec = MI->getOperand(Op);
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric // If this has a segment register, print it.
4570b57cec5SDimitry Andric printOptionalSegReg(MI, Op + 1, O);
4580b57cec5SDimitry Andric
4595f757f3fSDimitry Andric WithMarkup M = markup(O, Markup::Memory);
4605f757f3fSDimitry Andric O << '[';
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric if (DispSpec.isImm()) {
4635f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatImm(DispSpec.getImm());
4640b57cec5SDimitry Andric } else {
4650b57cec5SDimitry Andric assert(DispSpec.isExpr() && "non-immediate displacement?");
4660b57cec5SDimitry Andric DispSpec.getExpr()->print(O, &MAI);
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric
4695f757f3fSDimitry Andric O << ']';
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric
printU8Imm(const MCInst * MI,unsigned Op,raw_ostream & O)4720b57cec5SDimitry Andric void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op,
4730b57cec5SDimitry Andric raw_ostream &O) {
4740b57cec5SDimitry Andric if (MI->getOperand(Op).isExpr())
4750b57cec5SDimitry Andric return MI->getOperand(Op).getExpr()->print(O, &MAI);
4760b57cec5SDimitry Andric
4775f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatImm(MI->getOperand(Op).getImm() & 0xff);
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric
printSTiRegOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)4800b57cec5SDimitry Andric void X86IntelInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo,
4810b57cec5SDimitry Andric raw_ostream &OS) {
4820b57cec5SDimitry Andric const MCOperand &Op = MI->getOperand(OpNo);
4830b57cec5SDimitry Andric unsigned Reg = Op.getReg();
4840b57cec5SDimitry Andric // Override the default printing to print st(0) instead st.
4850b57cec5SDimitry Andric if (Reg == X86::ST0)
4860b57cec5SDimitry Andric OS << "st(0)";
4870b57cec5SDimitry Andric else
4880b57cec5SDimitry Andric printRegName(OS, Reg);
4890b57cec5SDimitry Andric }
490