xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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