10b57cec5SDimitry Andric //===--- X86InstPrinterCommon.cpp - X86 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 common code for rendering MCInst instances as Intel-style
100b57cec5SDimitry Andric // and Intel-style assembly.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "X86InstPrinterCommon.h"
150b57cec5SDimitry Andric #include "X86BaseInfo.h"
165ffd83dbSDimitry Andric #include "llvm/MC/MCAsmInfo.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
2181ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
220b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
2381ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
240b57cec5SDimitry Andric #include <cassert>
2581ad6265SDimitry Andric #include <cstdint>
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric
printCondCode(const MCInst * MI,unsigned Op,raw_ostream & O)290b57cec5SDimitry Andric void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op,
300b57cec5SDimitry Andric raw_ostream &O) {
310b57cec5SDimitry Andric int64_t Imm = MI->getOperand(Op).getImm();
32*0fca6ea1SDimitry Andric unsigned Opc = MI->getOpcode();
33*0fca6ea1SDimitry Andric bool IsCMPCCXADD = X86::isCMPCCXADD(Opc);
34*0fca6ea1SDimitry Andric bool IsCCMPOrCTEST = X86::isCCMPCC(Opc) || X86::isCTESTCC(Opc);
35*0fca6ea1SDimitry Andric
36*0fca6ea1SDimitry Andric // clang-format off
370b57cec5SDimitry Andric switch (Imm) {
380b57cec5SDimitry Andric default: llvm_unreachable("Invalid condcode argument!");
390b57cec5SDimitry Andric case 0: O << "o"; break;
400b57cec5SDimitry Andric case 1: O << "no"; break;
410b57cec5SDimitry Andric case 2: O << "b"; break;
42*0fca6ea1SDimitry Andric case 3: O << (IsCMPCCXADD ? "nb" : "ae"); break;
43*0fca6ea1SDimitry Andric case 4: O << (IsCMPCCXADD ? "z" : "e"); break;
44*0fca6ea1SDimitry Andric case 5: O << (IsCMPCCXADD ? "nz" : "ne"); break;
450b57cec5SDimitry Andric case 6: O << "be"; break;
46*0fca6ea1SDimitry Andric case 7: O << (IsCMPCCXADD ? "nbe" : "a"); break;
470b57cec5SDimitry Andric case 8: O << "s"; break;
480b57cec5SDimitry Andric case 9: O << "ns"; break;
49*0fca6ea1SDimitry Andric case 0xa: O << (IsCCMPOrCTEST ? "t" : "p"); break;
50*0fca6ea1SDimitry Andric case 0xb: O << (IsCCMPOrCTEST ? "f" : "np"); break;
510b57cec5SDimitry Andric case 0xc: O << "l"; break;
52*0fca6ea1SDimitry Andric case 0xd: O << (IsCMPCCXADD ? "nl" : "ge"); break;
530b57cec5SDimitry Andric case 0xe: O << "le"; break;
54*0fca6ea1SDimitry Andric case 0xf: O << (IsCMPCCXADD ? "nle" : "g"); break;
550b57cec5SDimitry Andric }
56*0fca6ea1SDimitry Andric // clang-format on
57*0fca6ea1SDimitry Andric }
58*0fca6ea1SDimitry Andric
printCondFlags(const MCInst * MI,unsigned Op,raw_ostream & O)59*0fca6ea1SDimitry Andric void X86InstPrinterCommon::printCondFlags(const MCInst *MI, unsigned Op,
60*0fca6ea1SDimitry Andric raw_ostream &O) {
61*0fca6ea1SDimitry Andric // +----+----+----+----+
62*0fca6ea1SDimitry Andric // | OF | SF | ZF | CF |
63*0fca6ea1SDimitry Andric // +----+----+----+----+
64*0fca6ea1SDimitry Andric int64_t Imm = MI->getOperand(Op).getImm();
65*0fca6ea1SDimitry Andric assert(Imm >= 0 && Imm < 16 && "Invalid condition flags");
66*0fca6ea1SDimitry Andric O << "{dfv=";
67*0fca6ea1SDimitry Andric std::string Flags;
68*0fca6ea1SDimitry Andric if (Imm & 0x8)
69*0fca6ea1SDimitry Andric Flags += "of,";
70*0fca6ea1SDimitry Andric if (Imm & 0x4)
71*0fca6ea1SDimitry Andric Flags += "sf,";
72*0fca6ea1SDimitry Andric if (Imm & 0x2)
73*0fca6ea1SDimitry Andric Flags += "zf,";
74*0fca6ea1SDimitry Andric if (Imm & 0x1)
75*0fca6ea1SDimitry Andric Flags += "cf,";
76*0fca6ea1SDimitry Andric StringRef SimplifiedFlags = StringRef(Flags).rtrim(",");
77*0fca6ea1SDimitry Andric O << SimplifiedFlags << "}";
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric
printSSEAVXCC(const MCInst * MI,unsigned Op,raw_ostream & O)800b57cec5SDimitry Andric void X86InstPrinterCommon::printSSEAVXCC(const MCInst *MI, unsigned Op,
810b57cec5SDimitry Andric raw_ostream &O) {
820b57cec5SDimitry Andric int64_t Imm = MI->getOperand(Op).getImm();
830b57cec5SDimitry Andric switch (Imm) {
840b57cec5SDimitry Andric default: llvm_unreachable("Invalid ssecc/avxcc argument!");
850b57cec5SDimitry Andric case 0: O << "eq"; break;
860b57cec5SDimitry Andric case 1: O << "lt"; break;
870b57cec5SDimitry Andric case 2: O << "le"; break;
880b57cec5SDimitry Andric case 3: O << "unord"; break;
890b57cec5SDimitry Andric case 4: O << "neq"; break;
900b57cec5SDimitry Andric case 5: O << "nlt"; break;
910b57cec5SDimitry Andric case 6: O << "nle"; break;
920b57cec5SDimitry Andric case 7: O << "ord"; break;
930b57cec5SDimitry Andric case 8: O << "eq_uq"; break;
940b57cec5SDimitry Andric case 9: O << "nge"; break;
950b57cec5SDimitry Andric case 0xa: O << "ngt"; break;
960b57cec5SDimitry Andric case 0xb: O << "false"; break;
970b57cec5SDimitry Andric case 0xc: O << "neq_oq"; break;
980b57cec5SDimitry Andric case 0xd: O << "ge"; break;
990b57cec5SDimitry Andric case 0xe: O << "gt"; break;
1000b57cec5SDimitry Andric case 0xf: O << "true"; break;
1010b57cec5SDimitry Andric case 0x10: O << "eq_os"; break;
1020b57cec5SDimitry Andric case 0x11: O << "lt_oq"; break;
1030b57cec5SDimitry Andric case 0x12: O << "le_oq"; break;
1040b57cec5SDimitry Andric case 0x13: O << "unord_s"; break;
1050b57cec5SDimitry Andric case 0x14: O << "neq_us"; break;
1060b57cec5SDimitry Andric case 0x15: O << "nlt_uq"; break;
1070b57cec5SDimitry Andric case 0x16: O << "nle_uq"; break;
1080b57cec5SDimitry Andric case 0x17: O << "ord_s"; break;
1090b57cec5SDimitry Andric case 0x18: O << "eq_us"; break;
1100b57cec5SDimitry Andric case 0x19: O << "nge_uq"; break;
1110b57cec5SDimitry Andric case 0x1a: O << "ngt_uq"; break;
1120b57cec5SDimitry Andric case 0x1b: O << "false_os"; break;
1130b57cec5SDimitry Andric case 0x1c: O << "neq_os"; break;
1140b57cec5SDimitry Andric case 0x1d: O << "ge_oq"; break;
1150b57cec5SDimitry Andric case 0x1e: O << "gt_oq"; break;
1160b57cec5SDimitry Andric case 0x1f: O << "true_us"; break;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric
printVPCOMMnemonic(const MCInst * MI,raw_ostream & OS)1200b57cec5SDimitry Andric void X86InstPrinterCommon::printVPCOMMnemonic(const MCInst *MI,
1210b57cec5SDimitry Andric raw_ostream &OS) {
1220b57cec5SDimitry Andric OS << "vpcom";
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm();
1250b57cec5SDimitry Andric switch (Imm) {
1260b57cec5SDimitry Andric default: llvm_unreachable("Invalid vpcom argument!");
1270b57cec5SDimitry Andric case 0: OS << "lt"; break;
1280b57cec5SDimitry Andric case 1: OS << "le"; break;
1290b57cec5SDimitry Andric case 2: OS << "gt"; break;
1300b57cec5SDimitry Andric case 3: OS << "ge"; break;
1310b57cec5SDimitry Andric case 4: OS << "eq"; break;
1320b57cec5SDimitry Andric case 5: OS << "neq"; break;
1330b57cec5SDimitry Andric case 6: OS << "false"; break;
1340b57cec5SDimitry Andric case 7: OS << "true"; break;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric switch (MI->getOpcode()) {
1380b57cec5SDimitry Andric default: llvm_unreachable("Unexpected opcode!");
1390b57cec5SDimitry Andric case X86::VPCOMBmi: case X86::VPCOMBri: OS << "b\t"; break;
1400b57cec5SDimitry Andric case X86::VPCOMDmi: case X86::VPCOMDri: OS << "d\t"; break;
1410b57cec5SDimitry Andric case X86::VPCOMQmi: case X86::VPCOMQri: OS << "q\t"; break;
1420b57cec5SDimitry Andric case X86::VPCOMUBmi: case X86::VPCOMUBri: OS << "ub\t"; break;
1430b57cec5SDimitry Andric case X86::VPCOMUDmi: case X86::VPCOMUDri: OS << "ud\t"; break;
1440b57cec5SDimitry Andric case X86::VPCOMUQmi: case X86::VPCOMUQri: OS << "uq\t"; break;
1450b57cec5SDimitry Andric case X86::VPCOMUWmi: case X86::VPCOMUWri: OS << "uw\t"; break;
1460b57cec5SDimitry Andric case X86::VPCOMWmi: case X86::VPCOMWri: OS << "w\t"; break;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric
printVPCMPMnemonic(const MCInst * MI,raw_ostream & OS)1500b57cec5SDimitry Andric void X86InstPrinterCommon::printVPCMPMnemonic(const MCInst *MI,
1510b57cec5SDimitry Andric raw_ostream &OS) {
1520b57cec5SDimitry Andric OS << "vpcmp";
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric switch (MI->getOpcode()) {
1570b57cec5SDimitry Andric default: llvm_unreachable("Unexpected opcode!");
1580b57cec5SDimitry Andric case X86::VPCMPBZ128rmi: case X86::VPCMPBZ128rri:
1590b57cec5SDimitry Andric case X86::VPCMPBZ256rmi: case X86::VPCMPBZ256rri:
1600b57cec5SDimitry Andric case X86::VPCMPBZrmi: case X86::VPCMPBZrri:
1610b57cec5SDimitry Andric case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik:
1620b57cec5SDimitry Andric case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik:
1630b57cec5SDimitry Andric case X86::VPCMPBZrmik: case X86::VPCMPBZrrik:
1640b57cec5SDimitry Andric OS << "b\t";
1650b57cec5SDimitry Andric break;
1660b57cec5SDimitry Andric case X86::VPCMPDZ128rmi: case X86::VPCMPDZ128rri:
1670b57cec5SDimitry Andric case X86::VPCMPDZ256rmi: case X86::VPCMPDZ256rri:
1680b57cec5SDimitry Andric case X86::VPCMPDZrmi: case X86::VPCMPDZrri:
1690b57cec5SDimitry Andric case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik:
1700b57cec5SDimitry Andric case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik:
1710b57cec5SDimitry Andric case X86::VPCMPDZrmik: case X86::VPCMPDZrrik:
1720b57cec5SDimitry Andric case X86::VPCMPDZ128rmib: case X86::VPCMPDZ128rmibk:
1730b57cec5SDimitry Andric case X86::VPCMPDZ256rmib: case X86::VPCMPDZ256rmibk:
1740b57cec5SDimitry Andric case X86::VPCMPDZrmib: case X86::VPCMPDZrmibk:
1750b57cec5SDimitry Andric OS << "d\t";
1760b57cec5SDimitry Andric break;
1770b57cec5SDimitry Andric case X86::VPCMPQZ128rmi: case X86::VPCMPQZ128rri:
1780b57cec5SDimitry Andric case X86::VPCMPQZ256rmi: case X86::VPCMPQZ256rri:
1790b57cec5SDimitry Andric case X86::VPCMPQZrmi: case X86::VPCMPQZrri:
1800b57cec5SDimitry Andric case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik:
1810b57cec5SDimitry Andric case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik:
1820b57cec5SDimitry Andric case X86::VPCMPQZrmik: case X86::VPCMPQZrrik:
1830b57cec5SDimitry Andric case X86::VPCMPQZ128rmib: case X86::VPCMPQZ128rmibk:
1840b57cec5SDimitry Andric case X86::VPCMPQZ256rmib: case X86::VPCMPQZ256rmibk:
1850b57cec5SDimitry Andric case X86::VPCMPQZrmib: case X86::VPCMPQZrmibk:
1860b57cec5SDimitry Andric OS << "q\t";
1870b57cec5SDimitry Andric break;
1880b57cec5SDimitry Andric case X86::VPCMPUBZ128rmi: case X86::VPCMPUBZ128rri:
1890b57cec5SDimitry Andric case X86::VPCMPUBZ256rmi: case X86::VPCMPUBZ256rri:
1900b57cec5SDimitry Andric case X86::VPCMPUBZrmi: case X86::VPCMPUBZrri:
1910b57cec5SDimitry Andric case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik:
1920b57cec5SDimitry Andric case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik:
1930b57cec5SDimitry Andric case X86::VPCMPUBZrmik: case X86::VPCMPUBZrrik:
1940b57cec5SDimitry Andric OS << "ub\t";
1950b57cec5SDimitry Andric break;
1960b57cec5SDimitry Andric case X86::VPCMPUDZ128rmi: case X86::VPCMPUDZ128rri:
1970b57cec5SDimitry Andric case X86::VPCMPUDZ256rmi: case X86::VPCMPUDZ256rri:
1980b57cec5SDimitry Andric case X86::VPCMPUDZrmi: case X86::VPCMPUDZrri:
1990b57cec5SDimitry Andric case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik:
2000b57cec5SDimitry Andric case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik:
2010b57cec5SDimitry Andric case X86::VPCMPUDZrmik: case X86::VPCMPUDZrrik:
2020b57cec5SDimitry Andric case X86::VPCMPUDZ128rmib: case X86::VPCMPUDZ128rmibk:
2030b57cec5SDimitry Andric case X86::VPCMPUDZ256rmib: case X86::VPCMPUDZ256rmibk:
2040b57cec5SDimitry Andric case X86::VPCMPUDZrmib: case X86::VPCMPUDZrmibk:
2050b57cec5SDimitry Andric OS << "ud\t";
2060b57cec5SDimitry Andric break;
2070b57cec5SDimitry Andric case X86::VPCMPUQZ128rmi: case X86::VPCMPUQZ128rri:
2080b57cec5SDimitry Andric case X86::VPCMPUQZ256rmi: case X86::VPCMPUQZ256rri:
2090b57cec5SDimitry Andric case X86::VPCMPUQZrmi: case X86::VPCMPUQZrri:
2100b57cec5SDimitry Andric case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik:
2110b57cec5SDimitry Andric case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik:
2120b57cec5SDimitry Andric case X86::VPCMPUQZrmik: case X86::VPCMPUQZrrik:
2130b57cec5SDimitry Andric case X86::VPCMPUQZ128rmib: case X86::VPCMPUQZ128rmibk:
2140b57cec5SDimitry Andric case X86::VPCMPUQZ256rmib: case X86::VPCMPUQZ256rmibk:
2150b57cec5SDimitry Andric case X86::VPCMPUQZrmib: case X86::VPCMPUQZrmibk:
2160b57cec5SDimitry Andric OS << "uq\t";
2170b57cec5SDimitry Andric break;
2180b57cec5SDimitry Andric case X86::VPCMPUWZ128rmi: case X86::VPCMPUWZ128rri:
2190b57cec5SDimitry Andric case X86::VPCMPUWZ256rri: case X86::VPCMPUWZ256rmi:
2200b57cec5SDimitry Andric case X86::VPCMPUWZrmi: case X86::VPCMPUWZrri:
2210b57cec5SDimitry Andric case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik:
2220b57cec5SDimitry Andric case X86::VPCMPUWZ256rrik: case X86::VPCMPUWZ256rmik:
2230b57cec5SDimitry Andric case X86::VPCMPUWZrmik: case X86::VPCMPUWZrrik:
2240b57cec5SDimitry Andric OS << "uw\t";
2250b57cec5SDimitry Andric break;
2260b57cec5SDimitry Andric case X86::VPCMPWZ128rmi: case X86::VPCMPWZ128rri:
2270b57cec5SDimitry Andric case X86::VPCMPWZ256rmi: case X86::VPCMPWZ256rri:
2280b57cec5SDimitry Andric case X86::VPCMPWZrmi: case X86::VPCMPWZrri:
2290b57cec5SDimitry Andric case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik:
2300b57cec5SDimitry Andric case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik:
2310b57cec5SDimitry Andric case X86::VPCMPWZrmik: case X86::VPCMPWZrrik:
2320b57cec5SDimitry Andric OS << "w\t";
2330b57cec5SDimitry Andric break;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric
printCMPMnemonic(const MCInst * MI,bool IsVCmp,raw_ostream & OS)2370b57cec5SDimitry Andric void X86InstPrinterCommon::printCMPMnemonic(const MCInst *MI, bool IsVCmp,
2380b57cec5SDimitry Andric raw_ostream &OS) {
2390b57cec5SDimitry Andric OS << (IsVCmp ? "vcmp" : "cmp");
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric switch (MI->getOpcode()) {
2440b57cec5SDimitry Andric default: llvm_unreachable("Unexpected opcode!");
2450b57cec5SDimitry Andric case X86::CMPPDrmi: case X86::CMPPDrri:
2460b57cec5SDimitry Andric case X86::VCMPPDrmi: case X86::VCMPPDrri:
2470b57cec5SDimitry Andric case X86::VCMPPDYrmi: case X86::VCMPPDYrri:
2480b57cec5SDimitry Andric case X86::VCMPPDZ128rmi: case X86::VCMPPDZ128rri:
2490b57cec5SDimitry Andric case X86::VCMPPDZ256rmi: case X86::VCMPPDZ256rri:
2500b57cec5SDimitry Andric case X86::VCMPPDZrmi: case X86::VCMPPDZrri:
2510b57cec5SDimitry Andric case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik:
2520b57cec5SDimitry Andric case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik:
2530b57cec5SDimitry Andric case X86::VCMPPDZrmik: case X86::VCMPPDZrrik:
2540b57cec5SDimitry Andric case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik:
2550b57cec5SDimitry Andric case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik:
2560b57cec5SDimitry Andric case X86::VCMPPDZrmbi: case X86::VCMPPDZrmbik:
2570b57cec5SDimitry Andric case X86::VCMPPDZrrib: case X86::VCMPPDZrribk:
2580b57cec5SDimitry Andric OS << "pd\t";
2590b57cec5SDimitry Andric break;
2600b57cec5SDimitry Andric case X86::CMPPSrmi: case X86::CMPPSrri:
2610b57cec5SDimitry Andric case X86::VCMPPSrmi: case X86::VCMPPSrri:
2620b57cec5SDimitry Andric case X86::VCMPPSYrmi: case X86::VCMPPSYrri:
2630b57cec5SDimitry Andric case X86::VCMPPSZ128rmi: case X86::VCMPPSZ128rri:
2640b57cec5SDimitry Andric case X86::VCMPPSZ256rmi: case X86::VCMPPSZ256rri:
2650b57cec5SDimitry Andric case X86::VCMPPSZrmi: case X86::VCMPPSZrri:
2660b57cec5SDimitry Andric case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik:
2670b57cec5SDimitry Andric case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik:
2680b57cec5SDimitry Andric case X86::VCMPPSZrmik: case X86::VCMPPSZrrik:
2690b57cec5SDimitry Andric case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik:
2700b57cec5SDimitry Andric case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik:
2710b57cec5SDimitry Andric case X86::VCMPPSZrmbi: case X86::VCMPPSZrmbik:
2720b57cec5SDimitry Andric case X86::VCMPPSZrrib: case X86::VCMPPSZrribk:
2730b57cec5SDimitry Andric OS << "ps\t";
2740b57cec5SDimitry Andric break;
275*0fca6ea1SDimitry Andric case X86::CMPSDrmi: case X86::CMPSDrri:
276*0fca6ea1SDimitry Andric case X86::CMPSDrmi_Int: case X86::CMPSDrri_Int:
277*0fca6ea1SDimitry Andric case X86::VCMPSDrmi: case X86::VCMPSDrri:
278*0fca6ea1SDimitry Andric case X86::VCMPSDrmi_Int: case X86::VCMPSDrri_Int:
279*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi: case X86::VCMPSDZrri:
280*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi_Int: case X86::VCMPSDZrri_Int:
281*0fca6ea1SDimitry Andric case X86::VCMPSDZrmi_Intk: case X86::VCMPSDZrri_Intk:
282*0fca6ea1SDimitry Andric case X86::VCMPSDZrrib_Int: case X86::VCMPSDZrrib_Intk:
2830b57cec5SDimitry Andric OS << "sd\t";
2840b57cec5SDimitry Andric break;
285*0fca6ea1SDimitry Andric case X86::CMPSSrmi: case X86::CMPSSrri:
286*0fca6ea1SDimitry Andric case X86::CMPSSrmi_Int: case X86::CMPSSrri_Int:
287*0fca6ea1SDimitry Andric case X86::VCMPSSrmi: case X86::VCMPSSrri:
288*0fca6ea1SDimitry Andric case X86::VCMPSSrmi_Int: case X86::VCMPSSrri_Int:
289*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi: case X86::VCMPSSZrri:
290*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi_Int: case X86::VCMPSSZrri_Int:
291*0fca6ea1SDimitry Andric case X86::VCMPSSZrmi_Intk: case X86::VCMPSSZrri_Intk:
292*0fca6ea1SDimitry Andric case X86::VCMPSSZrrib_Int: case X86::VCMPSSZrrib_Intk:
2930b57cec5SDimitry Andric OS << "ss\t";
2940b57cec5SDimitry Andric break;
295349cc55cSDimitry Andric case X86::VCMPPHZ128rmi: case X86::VCMPPHZ128rri:
296349cc55cSDimitry Andric case X86::VCMPPHZ256rmi: case X86::VCMPPHZ256rri:
297349cc55cSDimitry Andric case X86::VCMPPHZrmi: case X86::VCMPPHZrri:
298349cc55cSDimitry Andric case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik:
299349cc55cSDimitry Andric case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik:
300349cc55cSDimitry Andric case X86::VCMPPHZrmik: case X86::VCMPPHZrrik:
301349cc55cSDimitry Andric case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik:
302349cc55cSDimitry Andric case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik:
303349cc55cSDimitry Andric case X86::VCMPPHZrmbi: case X86::VCMPPHZrmbik:
304349cc55cSDimitry Andric case X86::VCMPPHZrrib: case X86::VCMPPHZrribk:
305349cc55cSDimitry Andric OS << "ph\t";
306349cc55cSDimitry Andric break;
307*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi: case X86::VCMPSHZrri:
308*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi_Int: case X86::VCMPSHZrri_Int:
309*0fca6ea1SDimitry Andric case X86::VCMPSHZrrib_Int: case X86::VCMPSHZrrib_Intk:
310*0fca6ea1SDimitry Andric case X86::VCMPSHZrmi_Intk: case X86::VCMPSHZrri_Intk:
311349cc55cSDimitry Andric OS << "sh\t";
312349cc55cSDimitry Andric break;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric
printRoundingControl(const MCInst * MI,unsigned Op,raw_ostream & O)3160b57cec5SDimitry Andric void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,
3170b57cec5SDimitry Andric raw_ostream &O) {
3180b57cec5SDimitry Andric int64_t Imm = MI->getOperand(Op).getImm();
3190b57cec5SDimitry Andric switch (Imm) {
3200b57cec5SDimitry Andric default:
3210b57cec5SDimitry Andric llvm_unreachable("Invalid rounding control!");
3220b57cec5SDimitry Andric case X86::TO_NEAREST_INT:
3230b57cec5SDimitry Andric O << "{rn-sae}";
3240b57cec5SDimitry Andric break;
3250b57cec5SDimitry Andric case X86::TO_NEG_INF:
3260b57cec5SDimitry Andric O << "{rd-sae}";
3270b57cec5SDimitry Andric break;
3280b57cec5SDimitry Andric case X86::TO_POS_INF:
3290b57cec5SDimitry Andric O << "{ru-sae}";
3300b57cec5SDimitry Andric break;
3310b57cec5SDimitry Andric case X86::TO_ZERO:
3320b57cec5SDimitry Andric O << "{rz-sae}";
3330b57cec5SDimitry Andric break;
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric
3375ffd83dbSDimitry Andric /// value (e.g. for jumps and calls). In Intel-style these print slightly
3385ffd83dbSDimitry Andric /// differently than normal immediates. For example, a $ is not emitted.
3395ffd83dbSDimitry Andric ///
3405ffd83dbSDimitry Andric /// \p Address The address of the next instruction.
3415ffd83dbSDimitry Andric /// \see MCInstPrinter::printInst
printPCRelImm(const MCInst * MI,uint64_t Address,unsigned OpNo,raw_ostream & O)3425ffd83dbSDimitry Andric void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, uint64_t Address,
3435ffd83dbSDimitry Andric unsigned OpNo, raw_ostream &O) {
344e8d8bef9SDimitry Andric // Do not print the numberic target address when symbolizing.
345e8d8bef9SDimitry Andric if (SymbolizeOperands)
346e8d8bef9SDimitry Andric return;
347e8d8bef9SDimitry Andric
3480b57cec5SDimitry Andric const MCOperand &Op = MI->getOperand(OpNo);
3495ffd83dbSDimitry Andric if (Op.isImm()) {
3505ffd83dbSDimitry Andric if (PrintBranchImmAsAddress) {
3515ffd83dbSDimitry Andric uint64_t Target = Address + Op.getImm();
3525ffd83dbSDimitry Andric if (MAI.getCodePointerSize() == 4)
3535ffd83dbSDimitry Andric Target &= 0xffffffff;
3545f757f3fSDimitry Andric markup(O, Markup::Target) << formatHex(Target);
3555ffd83dbSDimitry Andric } else
3565f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatImm(Op.getImm());
3575ffd83dbSDimitry Andric } else {
3580b57cec5SDimitry Andric assert(Op.isExpr() && "unknown pcrel immediate operand");
3590b57cec5SDimitry Andric // If a symbolic branch target was added as a constant expression then print
3600b57cec5SDimitry Andric // that address in hex.
3610b57cec5SDimitry Andric const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
3620b57cec5SDimitry Andric int64_t Address;
3630b57cec5SDimitry Andric if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {
3645f757f3fSDimitry Andric markup(O, Markup::Immediate) << formatHex((uint64_t)Address);
3650b57cec5SDimitry Andric } else {
3660b57cec5SDimitry Andric // Otherwise, just print the expression.
3670b57cec5SDimitry Andric Op.getExpr()->print(O, &MAI);
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric
printOptionalSegReg(const MCInst * MI,unsigned OpNo,raw_ostream & O)3720b57cec5SDimitry Andric void X86InstPrinterCommon::printOptionalSegReg(const MCInst *MI, unsigned OpNo,
3730b57cec5SDimitry Andric raw_ostream &O) {
3740b57cec5SDimitry Andric if (MI->getOperand(OpNo).getReg()) {
3750b57cec5SDimitry Andric printOperand(MI, OpNo, O);
3760b57cec5SDimitry Andric O << ':';
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric
printInstFlags(const MCInst * MI,raw_ostream & O,const MCSubtargetInfo & STI)38081ad6265SDimitry Andric void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O,
38181ad6265SDimitry Andric const MCSubtargetInfo &STI) {
3820b57cec5SDimitry Andric const MCInstrDesc &Desc = MII.get(MI->getOpcode());
3830b57cec5SDimitry Andric uint64_t TSFlags = Desc.TSFlags;
3840b57cec5SDimitry Andric unsigned Flags = MI->getFlags();
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andric if ((TSFlags & X86II::LOCK) || (Flags & X86::IP_HAS_LOCK))
3870b57cec5SDimitry Andric O << "\tlock\t";
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric if ((TSFlags & X86II::NOTRACK) || (Flags & X86::IP_HAS_NOTRACK))
3900b57cec5SDimitry Andric O << "\tnotrack\t";
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric if (Flags & X86::IP_HAS_REPEAT_NE)
3930b57cec5SDimitry Andric O << "\trepne\t";
3940b57cec5SDimitry Andric else if (Flags & X86::IP_HAS_REPEAT)
3950b57cec5SDimitry Andric O << "\trep\t";
396e8d8bef9SDimitry Andric
397*0fca6ea1SDimitry Andric if (TSFlags & X86II::EVEX_NF && !X86::isCFCMOVCC(MI->getOpcode()))
398647cbc5dSDimitry Andric O << "\t{nf}";
399647cbc5dSDimitry Andric
400e8d8bef9SDimitry Andric // These all require a pseudo prefix
4015f757f3fSDimitry Andric if ((Flags & X86::IP_USE_VEX) ||
4025f757f3fSDimitry Andric (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix)
403e8d8bef9SDimitry Andric O << "\t{vex}";
404e8d8bef9SDimitry Andric else if (Flags & X86::IP_USE_VEX2)
405e8d8bef9SDimitry Andric O << "\t{vex2}";
406e8d8bef9SDimitry Andric else if (Flags & X86::IP_USE_VEX3)
407e8d8bef9SDimitry Andric O << "\t{vex3}";
4085f757f3fSDimitry Andric else if ((Flags & X86::IP_USE_EVEX) ||
4095f757f3fSDimitry Andric (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitEVEXPrefix)
410e8d8bef9SDimitry Andric O << "\t{evex}";
411e8d8bef9SDimitry Andric
412e8d8bef9SDimitry Andric if (Flags & X86::IP_USE_DISP8)
413e8d8bef9SDimitry Andric O << "\t{disp8}";
414e8d8bef9SDimitry Andric else if (Flags & X86::IP_USE_DISP32)
415e8d8bef9SDimitry Andric O << "\t{disp32}";
41681ad6265SDimitry Andric
41781ad6265SDimitry Andric // Determine where the memory operand starts, if present
41881ad6265SDimitry Andric int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
41981ad6265SDimitry Andric if (MemoryOperand != -1)
42081ad6265SDimitry Andric MemoryOperand += X86II::getOperandBias(Desc);
42181ad6265SDimitry Andric
42281ad6265SDimitry Andric // Address-Size override prefix
42381ad6265SDimitry Andric if (Flags & X86::IP_HAS_AD_SIZE &&
42481ad6265SDimitry Andric !X86_MC::needsAddressSizeOverride(*MI, STI, MemoryOperand, TSFlags)) {
42581ad6265SDimitry Andric if (STI.hasFeature(X86::Is16Bit) || STI.hasFeature(X86::Is64Bit))
42681ad6265SDimitry Andric O << "\taddr32\t";
42781ad6265SDimitry Andric else if (STI.hasFeature(X86::Is32Bit))
42881ad6265SDimitry Andric O << "\taddr16\t";
42981ad6265SDimitry Andric }
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric
printVKPair(const MCInst * MI,unsigned OpNo,raw_ostream & OS)4320b57cec5SDimitry Andric void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,
4330b57cec5SDimitry Andric raw_ostream &OS) {
4340b57cec5SDimitry Andric // In assembly listings, a pair is represented by one of its members, any
4350b57cec5SDimitry Andric // of the two. Here, we pick k0, k2, k4, k6, but we could as well
4360b57cec5SDimitry Andric // print K2_K3 as "k3". It would probably make a lot more sense, if
4370b57cec5SDimitry Andric // the assembly would look something like:
4380b57cec5SDimitry Andric // "vp2intersect %zmm5, %zmm7, {%k2, %k3}"
4390b57cec5SDimitry Andric // but this can work too.
4400b57cec5SDimitry Andric switch (MI->getOperand(OpNo).getReg()) {
4410b57cec5SDimitry Andric case X86::K0_K1:
4420b57cec5SDimitry Andric printRegName(OS, X86::K0);
4430b57cec5SDimitry Andric return;
4440b57cec5SDimitry Andric case X86::K2_K3:
4450b57cec5SDimitry Andric printRegName(OS, X86::K2);
4460b57cec5SDimitry Andric return;
4470b57cec5SDimitry Andric case X86::K4_K5:
4480b57cec5SDimitry Andric printRegName(OS, X86::K4);
4490b57cec5SDimitry Andric return;
4500b57cec5SDimitry Andric case X86::K6_K7:
4510b57cec5SDimitry Andric printRegName(OS, X86::K6);
4520b57cec5SDimitry Andric return;
4530b57cec5SDimitry Andric }
4540b57cec5SDimitry Andric llvm_unreachable("Unknown mask pair register name");
4550b57cec5SDimitry Andric }
456