brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.0 KiB · 88dd543 Raw
470 lines · cpp
1//===--- X86InstPrinterCommon.cpp - X86 assembly instruction printing -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file includes common code for rendering MCInst instances as Intel-style10// and Intel-style assembly.11//12//===----------------------------------------------------------------------===//13 14#include "X86InstPrinterCommon.h"15#include "X86BaseInfo.h"16#include "llvm/MC/MCAsmInfo.h"17#include "llvm/MC/MCExpr.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstrDesc.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCSubtargetInfo.h"22#include "llvm/Support/Casting.h"23#include "llvm/Support/raw_ostream.h"24#include <cassert>25#include <cstdint>26 27using namespace llvm;28 29void X86InstPrinterCommon::printExprOperand(raw_ostream &OS, const MCExpr &E) {30  MAI.printExpr(OS, E);31}32 33void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op,34                                         raw_ostream &O) {35  int64_t Imm = MI->getOperand(Op).getImm();36  unsigned Opc = MI->getOpcode();37  bool IsCCMPOrCTEST = X86::isCCMPCC(Opc) || X86::isCTESTCC(Opc);38 39  // clang-format off40  switch (Imm) {41  default: llvm_unreachable("Invalid condcode argument!");42  case    0: O << "o";  break;43  case    1: O << "no"; break;44  case    2: O << "b";  break;45  case    3: O << "ae"; break;46  case    4: O << "e";  break;47  case    5: O << "ne"; break;48  case    6: O << "be"; break;49  case    7: O << "a";  break;50  case    8: O << "s";  break;51  case    9: O << "ns"; break;52  case  0xa: O << (IsCCMPOrCTEST ? "t" : "p");  break;53  case  0xb: O << (IsCCMPOrCTEST ? "f" : "np"); break;54  case  0xc: O << "l";  break;55  case  0xd: O << "ge"; break;56  case  0xe: O << "le"; break;57  case  0xf: O << "g";  break;58  }59  // clang-format on60}61 62void X86InstPrinterCommon::printCondFlags(const MCInst *MI, unsigned Op,63                                          raw_ostream &O) {64  // +----+----+----+----+65  // | OF | SF | ZF | CF |66  // +----+----+----+----+67  int64_t Imm = MI->getOperand(Op).getImm();68  assert(Imm >= 0 && Imm < 16 && "Invalid condition flags");69  O << "{dfv=";70  std::string Flags;71  if (Imm & 0x8)72    Flags += "of,";73  if (Imm & 0x4)74    Flags += "sf,";75  if (Imm & 0x2)76    Flags += "zf,";77  if (Imm & 0x1)78    Flags += "cf,";79  StringRef SimplifiedFlags = StringRef(Flags).rtrim(",");80  O << SimplifiedFlags << "}";81}82 83void X86InstPrinterCommon::printSSEAVXCC(const MCInst *MI, unsigned Op,84                                         raw_ostream &O) {85  int64_t Imm = MI->getOperand(Op).getImm();86  switch (Imm) {87  default: llvm_unreachable("Invalid ssecc/avxcc argument!");88  case    0: O << "eq"; break;89  case    1: O << "lt"; break;90  case    2: O << "le"; break;91  case    3: O << "unord"; break;92  case    4: O << "neq"; break;93  case    5: O << "nlt"; break;94  case    6: O << "nle"; break;95  case    7: O << "ord"; break;96  case    8: O << "eq_uq"; break;97  case    9: O << "nge"; break;98  case  0xa: O << "ngt"; break;99  case  0xb: O << "false"; break;100  case  0xc: O << "neq_oq"; break;101  case  0xd: O << "ge"; break;102  case  0xe: O << "gt"; break;103  case  0xf: O << "true"; break;104  case 0x10: O << "eq_os"; break;105  case 0x11: O << "lt_oq"; break;106  case 0x12: O << "le_oq"; break;107  case 0x13: O << "unord_s"; break;108  case 0x14: O << "neq_us"; break;109  case 0x15: O << "nlt_uq"; break;110  case 0x16: O << "nle_uq"; break;111  case 0x17: O << "ord_s"; break;112  case 0x18: O << "eq_us"; break;113  case 0x19: O << "nge_uq"; break;114  case 0x1a: O << "ngt_uq"; break;115  case 0x1b: O << "false_os"; break;116  case 0x1c: O << "neq_os"; break;117  case 0x1d: O << "ge_oq"; break;118  case 0x1e: O << "gt_oq"; break;119  case 0x1f: O << "true_us"; break;120  }121}122 123void X86InstPrinterCommon::printVPCOMMnemonic(const MCInst *MI,124                                              raw_ostream &OS) {125  OS << "vpcom";126 127  int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm();128  switch (Imm) {129  default: llvm_unreachable("Invalid vpcom argument!");130  case 0: OS << "lt"; break;131  case 1: OS << "le"; break;132  case 2: OS << "gt"; break;133  case 3: OS << "ge"; break;134  case 4: OS << "eq"; break;135  case 5: OS << "neq"; break;136  case 6: OS << "false"; break;137  case 7: OS << "true"; break;138  }139 140  switch (MI->getOpcode()) {141  default: llvm_unreachable("Unexpected opcode!");142  case X86::VPCOMBmi:  case X86::VPCOMBri:  OS << "b\t";  break;143  case X86::VPCOMDmi:  case X86::VPCOMDri:  OS << "d\t";  break;144  case X86::VPCOMQmi:  case X86::VPCOMQri:  OS << "q\t";  break;145  case X86::VPCOMUBmi: case X86::VPCOMUBri: OS << "ub\t"; break;146  case X86::VPCOMUDmi: case X86::VPCOMUDri: OS << "ud\t"; break;147  case X86::VPCOMUQmi: case X86::VPCOMUQri: OS << "uq\t"; break;148  case X86::VPCOMUWmi: case X86::VPCOMUWri: OS << "uw\t"; break;149  case X86::VPCOMWmi:  case X86::VPCOMWri:  OS << "w\t";  break;150  }151}152 153void X86InstPrinterCommon::printVPCMPMnemonic(const MCInst *MI,154                                              raw_ostream &OS) {155  OS << "vpcmp";156 157  printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);158 159  switch (MI->getOpcode()) {160  default: llvm_unreachable("Unexpected opcode!");161  case X86::VPCMPBZ128rmi:  case X86::VPCMPBZ128rri:162  case X86::VPCMPBZ256rmi:  case X86::VPCMPBZ256rri:163  case X86::VPCMPBZrmi:     case X86::VPCMPBZrri:164  case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik:165  case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik:166  case X86::VPCMPBZrmik:    case X86::VPCMPBZrrik:167    OS << "b\t";168    break;169  case X86::VPCMPDZ128rmi:  case X86::VPCMPDZ128rri:170  case X86::VPCMPDZ256rmi:  case X86::VPCMPDZ256rri:171  case X86::VPCMPDZrmi:     case X86::VPCMPDZrri:172  case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik:173  case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik:174  case X86::VPCMPDZrmik:    case X86::VPCMPDZrrik:175  case X86::VPCMPDZ128rmbi: case X86::VPCMPDZ128rmbik:176  case X86::VPCMPDZ256rmbi: case X86::VPCMPDZ256rmbik:177  case X86::VPCMPDZrmbi:    case X86::VPCMPDZrmbik:178    OS << "d\t";179    break;180  case X86::VPCMPQZ128rmi:  case X86::VPCMPQZ128rri:181  case X86::VPCMPQZ256rmi:  case X86::VPCMPQZ256rri:182  case X86::VPCMPQZrmi:     case X86::VPCMPQZrri:183  case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik:184  case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik:185  case X86::VPCMPQZrmik:    case X86::VPCMPQZrrik:186  case X86::VPCMPQZ128rmbi: case X86::VPCMPQZ128rmbik:187  case X86::VPCMPQZ256rmbi: case X86::VPCMPQZ256rmbik:188  case X86::VPCMPQZrmbi:    case X86::VPCMPQZrmbik:189    OS << "q\t";190    break;191  case X86::VPCMPUBZ128rmi:  case X86::VPCMPUBZ128rri:192  case X86::VPCMPUBZ256rmi:  case X86::VPCMPUBZ256rri:193  case X86::VPCMPUBZrmi:     case X86::VPCMPUBZrri:194  case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik:195  case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik:196  case X86::VPCMPUBZrmik:    case X86::VPCMPUBZrrik:197    OS << "ub\t";198    break;199  case X86::VPCMPUDZ128rmi:  case X86::VPCMPUDZ128rri:200  case X86::VPCMPUDZ256rmi:  case X86::VPCMPUDZ256rri:201  case X86::VPCMPUDZrmi:     case X86::VPCMPUDZrri:202  case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik:203  case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik:204  case X86::VPCMPUDZrmik:    case X86::VPCMPUDZrrik:205  case X86::VPCMPUDZ128rmbi: case X86::VPCMPUDZ128rmbik:206  case X86::VPCMPUDZ256rmbi: case X86::VPCMPUDZ256rmbik:207  case X86::VPCMPUDZrmbi:    case X86::VPCMPUDZrmbik:208    OS << "ud\t";209    break;210  case X86::VPCMPUQZ128rmi:  case X86::VPCMPUQZ128rri:211  case X86::VPCMPUQZ256rmi:  case X86::VPCMPUQZ256rri:212  case X86::VPCMPUQZrmi:     case X86::VPCMPUQZrri:213  case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik:214  case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik:215  case X86::VPCMPUQZrmik:    case X86::VPCMPUQZrrik:216  case X86::VPCMPUQZ128rmbi: case X86::VPCMPUQZ128rmbik:217  case X86::VPCMPUQZ256rmbi: case X86::VPCMPUQZ256rmbik:218  case X86::VPCMPUQZrmbi:    case X86::VPCMPUQZrmbik:219    OS << "uq\t";220    break;221  case X86::VPCMPUWZ128rmi:  case X86::VPCMPUWZ128rri:222  case X86::VPCMPUWZ256rri:  case X86::VPCMPUWZ256rmi:223  case X86::VPCMPUWZrmi:     case X86::VPCMPUWZrri:224  case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik:225  case X86::VPCMPUWZ256rrik: case X86::VPCMPUWZ256rmik:226  case X86::VPCMPUWZrmik:    case X86::VPCMPUWZrrik:227    OS << "uw\t";228    break;229  case X86::VPCMPWZ128rmi:  case X86::VPCMPWZ128rri:230  case X86::VPCMPWZ256rmi:  case X86::VPCMPWZ256rri:231  case X86::VPCMPWZrmi:     case X86::VPCMPWZrri:232  case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik:233  case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik:234  case X86::VPCMPWZrmik:    case X86::VPCMPWZrrik:235    OS << "w\t";236    break;237  }238}239 240void X86InstPrinterCommon::printCMPMnemonic(const MCInst *MI, bool IsVCmp,241                                            raw_ostream &OS) {242  OS << (IsVCmp ? "vcmp" : "cmp");243 244  printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);245 246  switch (MI->getOpcode()) {247  default: llvm_unreachable("Unexpected opcode!");248  case X86::CMPPDrmi:       case X86::CMPPDrri:249  case X86::VCMPPDrmi:      case X86::VCMPPDrri:250  case X86::VCMPPDYrmi:     case X86::VCMPPDYrri:251  case X86::VCMPPDZ128rmi:  case X86::VCMPPDZ128rri:252  case X86::VCMPPDZ256rmi:  case X86::VCMPPDZ256rri:253  case X86::VCMPPDZrmi:     case X86::VCMPPDZrri:254  case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik:255  case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik:256  case X86::VCMPPDZrmik:    case X86::VCMPPDZrrik:257  case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik:258  case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik:259  case X86::VCMPPDZrmbi:    case X86::VCMPPDZrmbik:260  case X86::VCMPPDZrrib:    case X86::VCMPPDZrribk:261    OS << "pd\t";262    break;263  case X86::CMPPSrmi:       case X86::CMPPSrri:264  case X86::VCMPPSrmi:      case X86::VCMPPSrri:265  case X86::VCMPPSYrmi:     case X86::VCMPPSYrri:266  case X86::VCMPPSZ128rmi:  case X86::VCMPPSZ128rri:267  case X86::VCMPPSZ256rmi:  case X86::VCMPPSZ256rri:268  case X86::VCMPPSZrmi:     case X86::VCMPPSZrri:269  case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik:270  case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik:271  case X86::VCMPPSZrmik:    case X86::VCMPPSZrrik:272  case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik:273  case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik:274  case X86::VCMPPSZrmbi:    case X86::VCMPPSZrmbik:275  case X86::VCMPPSZrrib:    case X86::VCMPPSZrribk:276    OS << "ps\t";277    break;278  case X86::CMPSDrmi:        case X86::CMPSDrri:279  case X86::CMPSDrmi_Int:    case X86::CMPSDrri_Int:280  case X86::VCMPSDrmi:       case X86::VCMPSDrri:281  case X86::VCMPSDrmi_Int:   case X86::VCMPSDrri_Int:282  case X86::VCMPSDZrmi:      case X86::VCMPSDZrri:283  case X86::VCMPSDZrmi_Int:  case X86::VCMPSDZrri_Int:284  case X86::VCMPSDZrmik_Int: case X86::VCMPSDZrrik_Int:285  case X86::VCMPSDZrrib_Int: case X86::VCMPSDZrribk_Int:286    OS << "sd\t";287    break;288  case X86::CMPSSrmi:        case X86::CMPSSrri:289  case X86::CMPSSrmi_Int:    case X86::CMPSSrri_Int:290  case X86::VCMPSSrmi:       case X86::VCMPSSrri:291  case X86::VCMPSSrmi_Int:   case X86::VCMPSSrri_Int:292  case X86::VCMPSSZrmi:      case X86::VCMPSSZrri:293  case X86::VCMPSSZrmi_Int:  case X86::VCMPSSZrri_Int:294  case X86::VCMPSSZrmik_Int: case X86::VCMPSSZrrik_Int:295  case X86::VCMPSSZrrib_Int: case X86::VCMPSSZrribk_Int:296    OS << "ss\t";297    break;298  case X86::VCMPPHZ128rmi:  case X86::VCMPPHZ128rri:299  case X86::VCMPPHZ256rmi:  case X86::VCMPPHZ256rri:300  case X86::VCMPPHZrmi:     case X86::VCMPPHZrri:301  case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik:302  case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik:303  case X86::VCMPPHZrmik:    case X86::VCMPPHZrrik:304  case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik:305  case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik:306  case X86::VCMPPHZrmbi:    case X86::VCMPPHZrmbik:307  case X86::VCMPPHZrrib:    case X86::VCMPPHZrribk:308    OS << "ph\t";309    break;310  case X86::VCMPSHZrmi:      case X86::VCMPSHZrri:311  case X86::VCMPSHZrmi_Int:  case X86::VCMPSHZrri_Int:312  case X86::VCMPSHZrrib_Int: case X86::VCMPSHZrribk_Int:313  case X86::VCMPSHZrmik_Int: case X86::VCMPSHZrrik_Int:314    OS << "sh\t";315    break;316  case X86::VCMPBF16Z128rmi:  case X86::VCMPBF16Z128rri:317  case X86::VCMPBF16Z256rmi:  case X86::VCMPBF16Z256rri:318  case X86::VCMPBF16Zrmi:     case X86::VCMPBF16Zrri:319  case X86::VCMPBF16Z128rmik: case X86::VCMPBF16Z128rrik:320  case X86::VCMPBF16Z256rmik: case X86::VCMPBF16Z256rrik:321  case X86::VCMPBF16Zrmik:    case X86::VCMPBF16Zrrik:322  case X86::VCMPBF16Z128rmbi: case X86::VCMPBF16Z128rmbik:323  case X86::VCMPBF16Z256rmbi: case X86::VCMPBF16Z256rmbik:324  case X86::VCMPBF16Zrmbi:    case X86::VCMPBF16Zrmbik:325    OS << "bf16\t";326    break;327  }328}329 330void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,331                                                raw_ostream &O) {332  int64_t Imm = MI->getOperand(Op).getImm();333  switch (Imm) {334  default:335    llvm_unreachable("Invalid rounding control!");336  case X86::TO_NEAREST_INT:337    O << "{rn-sae}";338    break;339  case X86::TO_NEG_INF:340    O << "{rd-sae}";341    break;342  case X86::TO_POS_INF:343    O << "{ru-sae}";344    break;345  case X86::TO_ZERO:346    O << "{rz-sae}";347    break;348  }349}350 351/// value (e.g. for jumps and calls). In Intel-style these print slightly352/// differently than normal immediates. For example, a $ is not emitted.353///354/// \p Address The address of the next instruction.355/// \see MCInstPrinter::printInst356void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, uint64_t Address,357                                         unsigned OpNo, raw_ostream &O) {358  // Do not print the numberic target address when symbolizing.359  if (SymbolizeOperands)360    return;361 362  const MCOperand &Op = MI->getOperand(OpNo);363  if (Op.isImm()) {364    if (PrintBranchImmAsAddress) {365      uint64_t Target = Address + Op.getImm();366      if (MAI.getCodePointerSize() == 4)367        Target &= 0xffffffff;368      markup(O, Markup::Target) << formatHex(Target);369    } else370      markup(O, Markup::Immediate) << formatImm(Op.getImm());371  } else {372    assert(Op.isExpr() && "unknown pcrel immediate operand");373    // If a symbolic branch target was added as a constant expression then print374    // that address in hex.375    const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());376    int64_t Address;377    if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {378      markup(O, Markup::Immediate) << formatHex((uint64_t)Address);379    } else {380      // Otherwise, just print the expression.381      printExprOperand(O, *Op.getExpr());382    }383  }384}385 386void X86InstPrinterCommon::printOptionalSegReg(const MCInst *MI, unsigned OpNo,387                                               raw_ostream &O) {388  if (MI->getOperand(OpNo).getReg()) {389    printOperand(MI, OpNo, O);390    O << ':';391  }392}393 394void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O,395                                          const MCSubtargetInfo &STI) {396  const MCInstrDesc &Desc = MII.get(MI->getOpcode());397  uint64_t TSFlags = Desc.TSFlags;398  unsigned Flags = MI->getFlags();399 400  if ((TSFlags & X86II::LOCK) || (Flags & X86::IP_HAS_LOCK))401    O << "\tlock\t";402 403  if ((TSFlags & X86II::NOTRACK) || (Flags & X86::IP_HAS_NOTRACK))404    O << "\tnotrack\t";405 406  if (Flags & X86::IP_HAS_REPEAT_NE)407    O << "\trepne\t";408  else if (Flags & X86::IP_HAS_REPEAT)409    O << "\trep\t";410 411  if (TSFlags & X86II::EVEX_NF && !X86::isCFCMOVCC(MI->getOpcode()))412    O << "\t{nf}";413 414  // These all require a pseudo prefix415  if ((Flags & X86::IP_USE_VEX) ||416      (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix)417    O << "\t{vex}";418  else if (Flags & X86::IP_USE_VEX2)419    O << "\t{vex2}";420  else if (Flags & X86::IP_USE_VEX3)421    O << "\t{vex3}";422  else if ((Flags & X86::IP_USE_EVEX) ||423           (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitEVEXPrefix)424    O << "\t{evex}";425 426  if (Flags & X86::IP_USE_DISP8)427    O << "\t{disp8}";428  else if (Flags & X86::IP_USE_DISP32)429    O << "\t{disp32}";430 431  // Determine where the memory operand starts, if present432  int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);433  if (MemoryOperand != -1)434    MemoryOperand += X86II::getOperandBias(Desc);435 436  // Address-Size override prefix437  if (Flags & X86::IP_HAS_AD_SIZE &&438      !X86_MC::needsAddressSizeOverride(*MI, STI, MemoryOperand, TSFlags)) {439    if (STI.hasFeature(X86::Is16Bit) || STI.hasFeature(X86::Is64Bit))440      O << "\taddr32\t";441    else if (STI.hasFeature(X86::Is32Bit))442      O << "\taddr16\t";443  }444}445 446void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,447                                       raw_ostream &OS) {448  // In assembly listings, a pair is represented by one of its members, any449  // of the two.  Here, we pick k0, k2, k4, k6, but we could as well450  // print K2_K3 as "k3".  It would probably make a lot more sense, if451  // the assembly would look something like:452  // "vp2intersect %zmm5, %zmm7, {%k2, %k3}"453  // but this can work too.454  switch (MI->getOperand(OpNo).getReg().id()) {455  case X86::K0_K1:456    printRegName(OS, X86::K0);457    return;458  case X86::K2_K3:459    printRegName(OS, X86::K2);460    return;461  case X86::K4_K5:462    printRegName(OS, X86::K4);463    return;464  case X86::K6_K7:465    printRegName(OS, X86::K6);466    return;467  }468  llvm_unreachable("Unknown mask pair register name");469}470