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 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 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 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 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 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 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 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 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 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 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 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