1 //===-- X86IntelInstPrinter.cpp - Intel 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file includes code for rendering MCInst instances as Intel-style 10 // assembly. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "X86IntelInstPrinter.h" 15 #include "X86BaseInfo.h" 16 #include "X86InstComments.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInstrAnalysis.h" 20 #include "llvm/MC/MCInstrDesc.h" 21 #include "llvm/MC/MCInstrInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/Support/Casting.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include <cassert> 26 #include <cstdint> 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "asm-printer" 31 32 // Include the auto-generated portion of the assembly writer. 33 #define PRINT_ALIAS_INSTR 34 #include "X86GenAsmWriter1.inc" 35 36 void X86IntelInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 37 OS << getRegisterName(RegNo); 38 } 39 40 void X86IntelInstPrinter::printInst(const MCInst *MI, uint64_t Address, 41 StringRef Annot, const MCSubtargetInfo &STI, 42 raw_ostream &OS) { 43 printInstFlags(MI, OS, STI); 44 45 // In 16-bit mode, print data16 as data32. 46 if (MI->getOpcode() == X86::DATA16_PREFIX && 47 STI.getFeatureBits()[X86::Is16Bit]) { 48 OS << "\tdata32"; 49 } else if (!printAliasInstr(MI, Address, OS) && !printVecCompareInstr(MI, OS)) 50 printInstruction(MI, Address, OS); 51 52 // Next always print the annotation. 53 printAnnotation(OS, Annot); 54 55 // If verbose assembly is enabled, we can print some informative comments. 56 if (CommentStream) 57 EmitAnyX86InstComments(MI, *CommentStream, MII); 58 } 59 60 bool X86IntelInstPrinter::printVecCompareInstr(const MCInst *MI, raw_ostream &OS) { 61 if (MI->getNumOperands() == 0 || 62 !MI->getOperand(MI->getNumOperands() - 1).isImm()) 63 return false; 64 65 int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm(); 66 67 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 68 69 // Custom print the vector compare instructions to get the immediate 70 // translated into the mnemonic. 71 switch (MI->getOpcode()) { 72 case X86::CMPPDrmi: case X86::CMPPDrri: 73 case X86::CMPPSrmi: case X86::CMPPSrri: 74 case X86::CMPSDrm: case X86::CMPSDrr: 75 case X86::CMPSDrm_Int: case X86::CMPSDrr_Int: 76 case X86::CMPSSrm: case X86::CMPSSrr: 77 case X86::CMPSSrm_Int: case X86::CMPSSrr_Int: 78 if (Imm >= 0 && Imm <= 7) { 79 OS << '\t'; 80 printCMPMnemonic(MI, /*IsVCMP*/false, OS); 81 printOperand(MI, 0, OS); 82 OS << ", "; 83 // Skip operand 1 as its tied to the dest. 84 85 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) { 86 if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XS) 87 printdwordmem(MI, 2, OS); 88 else if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XD) 89 printqwordmem(MI, 2, OS); 90 else 91 printxmmwordmem(MI, 2, OS); 92 } else 93 printOperand(MI, 2, OS); 94 95 return true; 96 } 97 break; 98 99 case X86::VCMPPDrmi: case X86::VCMPPDrri: 100 case X86::VCMPPDYrmi: case X86::VCMPPDYrri: 101 case X86::VCMPPDZ128rmi: case X86::VCMPPDZ128rri: 102 case X86::VCMPPDZ256rmi: case X86::VCMPPDZ256rri: 103 case X86::VCMPPDZrmi: case X86::VCMPPDZrri: 104 case X86::VCMPPSrmi: case X86::VCMPPSrri: 105 case X86::VCMPPSYrmi: case X86::VCMPPSYrri: 106 case X86::VCMPPSZ128rmi: case X86::VCMPPSZ128rri: 107 case X86::VCMPPSZ256rmi: case X86::VCMPPSZ256rri: 108 case X86::VCMPPSZrmi: case X86::VCMPPSZrri: 109 case X86::VCMPSDrm: case X86::VCMPSDrr: 110 case X86::VCMPSDZrm: case X86::VCMPSDZrr: 111 case X86::VCMPSDrm_Int: case X86::VCMPSDrr_Int: 112 case X86::VCMPSDZrm_Int: case X86::VCMPSDZrr_Int: 113 case X86::VCMPSSrm: case X86::VCMPSSrr: 114 case X86::VCMPSSZrm: case X86::VCMPSSZrr: 115 case X86::VCMPSSrm_Int: case X86::VCMPSSrr_Int: 116 case X86::VCMPSSZrm_Int: case X86::VCMPSSZrr_Int: 117 case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik: 118 case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik: 119 case X86::VCMPPDZrmik: case X86::VCMPPDZrrik: 120 case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik: 121 case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik: 122 case X86::VCMPPSZrmik: case X86::VCMPPSZrrik: 123 case X86::VCMPSDZrm_Intk: case X86::VCMPSDZrr_Intk: 124 case X86::VCMPSSZrm_Intk: case X86::VCMPSSZrr_Intk: 125 case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik: 126 case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik: 127 case X86::VCMPPDZrmbi: case X86::VCMPPDZrmbik: 128 case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik: 129 case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik: 130 case X86::VCMPPSZrmbi: case X86::VCMPPSZrmbik: 131 case X86::VCMPPDZrrib: case X86::VCMPPDZrribk: 132 case X86::VCMPPSZrrib: case X86::VCMPPSZrribk: 133 case X86::VCMPSDZrrb_Int: case X86::VCMPSDZrrb_Intk: 134 case X86::VCMPSSZrrb_Int: case X86::VCMPSSZrrb_Intk: 135 case X86::VCMPPHZ128rmi: case X86::VCMPPHZ128rri: 136 case X86::VCMPPHZ256rmi: case X86::VCMPPHZ256rri: 137 case X86::VCMPPHZrmi: case X86::VCMPPHZrri: 138 case X86::VCMPSHZrm: case X86::VCMPSHZrr: 139 case X86::VCMPSHZrm_Int: case X86::VCMPSHZrr_Int: 140 case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik: 141 case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik: 142 case X86::VCMPPHZrmik: case X86::VCMPPHZrrik: 143 case X86::VCMPSHZrm_Intk: case X86::VCMPSHZrr_Intk: 144 case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik: 145 case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik: 146 case X86::VCMPPHZrmbi: case X86::VCMPPHZrmbik: 147 case X86::VCMPPHZrrib: case X86::VCMPPHZrribk: 148 case X86::VCMPSHZrrb_Int: case X86::VCMPSHZrrb_Intk: 149 if (Imm >= 0 && Imm <= 31) { 150 OS << '\t'; 151 printCMPMnemonic(MI, /*IsVCMP*/true, OS); 152 153 unsigned CurOp = 0; 154 printOperand(MI, CurOp++, OS); 155 156 if (Desc.TSFlags & X86II::EVEX_K) { 157 // Print mask operand. 158 OS << " {"; 159 printOperand(MI, CurOp++, OS); 160 OS << "}"; 161 } 162 OS << ", "; 163 printOperand(MI, CurOp++, OS); 164 OS << ", "; 165 166 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) { 167 if (Desc.TSFlags & X86II::EVEX_B) { 168 // Broadcast form. 169 // Load size is word for TA map. Otherwise it is based on W-bit. 170 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) { 171 assert(!(Desc.TSFlags & X86II::VEX_W) && "Unknown W-bit value!"); 172 printwordmem(MI, CurOp++, OS); 173 } else if (Desc.TSFlags & X86II::VEX_W) { 174 printqwordmem(MI, CurOp++, OS); 175 } else { 176 printdwordmem(MI, CurOp++, OS); 177 } 178 179 // Print the number of elements broadcasted. 180 unsigned NumElts; 181 if (Desc.TSFlags & X86II::EVEX_L2) 182 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 8 : 16; 183 else if (Desc.TSFlags & X86II::VEX_L) 184 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 4 : 8; 185 else 186 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 2 : 4; 187 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) { 188 assert(!(Desc.TSFlags & X86II::VEX_W) && "Unknown W-bit value!"); 189 NumElts *= 2; 190 } 191 OS << "{1to" << NumElts << "}"; 192 } else { 193 if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XS) { 194 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) 195 printwordmem(MI, CurOp++, OS); 196 else 197 printdwordmem(MI, CurOp++, OS); 198 } else if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XD) { 199 assert((Desc.TSFlags & X86II::OpMapMask) != X86II::TA && 200 "Unexpected op map!"); 201 printqwordmem(MI, CurOp++, OS); 202 } else if (Desc.TSFlags & X86II::EVEX_L2) { 203 printzmmwordmem(MI, CurOp++, OS); 204 } else if (Desc.TSFlags & X86II::VEX_L) { 205 printymmwordmem(MI, CurOp++, OS); 206 } else { 207 printxmmwordmem(MI, CurOp++, OS); 208 } 209 } 210 } else { 211 printOperand(MI, CurOp++, OS); 212 if (Desc.TSFlags & X86II::EVEX_B) 213 OS << ", {sae}"; 214 } 215 216 return true; 217 } 218 break; 219 220 case X86::VPCOMBmi: case X86::VPCOMBri: 221 case X86::VPCOMDmi: case X86::VPCOMDri: 222 case X86::VPCOMQmi: case X86::VPCOMQri: 223 case X86::VPCOMUBmi: case X86::VPCOMUBri: 224 case X86::VPCOMUDmi: case X86::VPCOMUDri: 225 case X86::VPCOMUQmi: case X86::VPCOMUQri: 226 case X86::VPCOMUWmi: case X86::VPCOMUWri: 227 case X86::VPCOMWmi: case X86::VPCOMWri: 228 if (Imm >= 0 && Imm <= 7) { 229 OS << '\t'; 230 printVPCOMMnemonic(MI, OS); 231 printOperand(MI, 0, OS); 232 OS << ", "; 233 printOperand(MI, 1, OS); 234 OS << ", "; 235 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) 236 printxmmwordmem(MI, 2, OS); 237 else 238 printOperand(MI, 2, OS); 239 return true; 240 } 241 break; 242 243 case X86::VPCMPBZ128rmi: case X86::VPCMPBZ128rri: 244 case X86::VPCMPBZ256rmi: case X86::VPCMPBZ256rri: 245 case X86::VPCMPBZrmi: case X86::VPCMPBZrri: 246 case X86::VPCMPDZ128rmi: case X86::VPCMPDZ128rri: 247 case X86::VPCMPDZ256rmi: case X86::VPCMPDZ256rri: 248 case X86::VPCMPDZrmi: case X86::VPCMPDZrri: 249 case X86::VPCMPQZ128rmi: case X86::VPCMPQZ128rri: 250 case X86::VPCMPQZ256rmi: case X86::VPCMPQZ256rri: 251 case X86::VPCMPQZrmi: case X86::VPCMPQZrri: 252 case X86::VPCMPUBZ128rmi: case X86::VPCMPUBZ128rri: 253 case X86::VPCMPUBZ256rmi: case X86::VPCMPUBZ256rri: 254 case X86::VPCMPUBZrmi: case X86::VPCMPUBZrri: 255 case X86::VPCMPUDZ128rmi: case X86::VPCMPUDZ128rri: 256 case X86::VPCMPUDZ256rmi: case X86::VPCMPUDZ256rri: 257 case X86::VPCMPUDZrmi: case X86::VPCMPUDZrri: 258 case X86::VPCMPUQZ128rmi: case X86::VPCMPUQZ128rri: 259 case X86::VPCMPUQZ256rmi: case X86::VPCMPUQZ256rri: 260 case X86::VPCMPUQZrmi: case X86::VPCMPUQZrri: 261 case X86::VPCMPUWZ128rmi: case X86::VPCMPUWZ128rri: 262 case X86::VPCMPUWZ256rmi: case X86::VPCMPUWZ256rri: 263 case X86::VPCMPUWZrmi: case X86::VPCMPUWZrri: 264 case X86::VPCMPWZ128rmi: case X86::VPCMPWZ128rri: 265 case X86::VPCMPWZ256rmi: case X86::VPCMPWZ256rri: 266 case X86::VPCMPWZrmi: case X86::VPCMPWZrri: 267 case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik: 268 case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik: 269 case X86::VPCMPBZrmik: case X86::VPCMPBZrrik: 270 case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik: 271 case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik: 272 case X86::VPCMPDZrmik: case X86::VPCMPDZrrik: 273 case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik: 274 case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik: 275 case X86::VPCMPQZrmik: case X86::VPCMPQZrrik: 276 case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik: 277 case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik: 278 case X86::VPCMPUBZrmik: case X86::VPCMPUBZrrik: 279 case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik: 280 case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik: 281 case X86::VPCMPUDZrmik: case X86::VPCMPUDZrrik: 282 case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik: 283 case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik: 284 case X86::VPCMPUQZrmik: case X86::VPCMPUQZrrik: 285 case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik: 286 case X86::VPCMPUWZ256rmik: case X86::VPCMPUWZ256rrik: 287 case X86::VPCMPUWZrmik: case X86::VPCMPUWZrrik: 288 case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik: 289 case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik: 290 case X86::VPCMPWZrmik: case X86::VPCMPWZrrik: 291 case X86::VPCMPDZ128rmib: case X86::VPCMPDZ128rmibk: 292 case X86::VPCMPDZ256rmib: case X86::VPCMPDZ256rmibk: 293 case X86::VPCMPDZrmib: case X86::VPCMPDZrmibk: 294 case X86::VPCMPQZ128rmib: case X86::VPCMPQZ128rmibk: 295 case X86::VPCMPQZ256rmib: case X86::VPCMPQZ256rmibk: 296 case X86::VPCMPQZrmib: case X86::VPCMPQZrmibk: 297 case X86::VPCMPUDZ128rmib: case X86::VPCMPUDZ128rmibk: 298 case X86::VPCMPUDZ256rmib: case X86::VPCMPUDZ256rmibk: 299 case X86::VPCMPUDZrmib: case X86::VPCMPUDZrmibk: 300 case X86::VPCMPUQZ128rmib: case X86::VPCMPUQZ128rmibk: 301 case X86::VPCMPUQZ256rmib: case X86::VPCMPUQZ256rmibk: 302 case X86::VPCMPUQZrmib: case X86::VPCMPUQZrmibk: 303 if ((Imm >= 0 && Imm <= 2) || (Imm >= 4 && Imm <= 6)) { 304 OS << '\t'; 305 printVPCMPMnemonic(MI, OS); 306 307 unsigned CurOp = 0; 308 printOperand(MI, CurOp++, OS); 309 310 if (Desc.TSFlags & X86II::EVEX_K) { 311 // Print mask operand. 312 OS << " {"; 313 printOperand(MI, CurOp++, OS); 314 OS << "}"; 315 } 316 OS << ", "; 317 printOperand(MI, CurOp++, OS); 318 OS << ", "; 319 320 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) { 321 if (Desc.TSFlags & X86II::EVEX_B) { 322 // Broadcast form. 323 // Load size is based on W-bit as only D and Q are supported. 324 if (Desc.TSFlags & X86II::VEX_W) 325 printqwordmem(MI, CurOp++, OS); 326 else 327 printdwordmem(MI, CurOp++, OS); 328 329 // Print the number of elements broadcasted. 330 unsigned NumElts; 331 if (Desc.TSFlags & X86II::EVEX_L2) 332 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 8 : 16; 333 else if (Desc.TSFlags & X86II::VEX_L) 334 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 4 : 8; 335 else 336 NumElts = (Desc.TSFlags & X86II::VEX_W) ? 2 : 4; 337 OS << "{1to" << NumElts << "}"; 338 } else { 339 if (Desc.TSFlags & X86II::EVEX_L2) 340 printzmmwordmem(MI, CurOp++, OS); 341 else if (Desc.TSFlags & X86II::VEX_L) 342 printymmwordmem(MI, CurOp++, OS); 343 else 344 printxmmwordmem(MI, CurOp++, OS); 345 } 346 } else { 347 printOperand(MI, CurOp++, OS); 348 } 349 350 return true; 351 } 352 break; 353 } 354 355 return false; 356 } 357 358 void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 359 raw_ostream &O) { 360 const MCOperand &Op = MI->getOperand(OpNo); 361 if (Op.isReg()) { 362 printRegName(O, Op.getReg()); 363 } else if (Op.isImm()) { 364 O << formatImm((int64_t)Op.getImm()); 365 } else { 366 assert(Op.isExpr() && "unknown operand kind in printOperand"); 367 O << "offset "; 368 Op.getExpr()->print(O, &MAI); 369 } 370 } 371 372 void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 373 raw_ostream &O) { 374 // Do not print the exact form of the memory operand if it references a known 375 // binary object. 376 if (SymbolizeOperands && MIA) { 377 uint64_t Target; 378 if (MIA->evaluateBranch(*MI, 0, 0, Target)) 379 return; 380 if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0)) 381 return; 382 } 383 const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 384 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 385 const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 386 const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 387 388 // If this has a segment register, print it. 389 printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O); 390 391 O << '['; 392 393 bool NeedPlus = false; 394 if (BaseReg.getReg()) { 395 printOperand(MI, Op+X86::AddrBaseReg, O); 396 NeedPlus = true; 397 } 398 399 if (IndexReg.getReg()) { 400 if (NeedPlus) O << " + "; 401 if (ScaleVal != 1) 402 O << ScaleVal << '*'; 403 printOperand(MI, Op+X86::AddrIndexReg, O); 404 NeedPlus = true; 405 } 406 407 if (!DispSpec.isImm()) { 408 if (NeedPlus) O << " + "; 409 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 410 DispSpec.getExpr()->print(O, &MAI); 411 } else { 412 int64_t DispVal = DispSpec.getImm(); 413 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 414 if (NeedPlus) { 415 if (DispVal > 0) 416 O << " + "; 417 else { 418 O << " - "; 419 DispVal = -DispVal; 420 } 421 } 422 O << formatImm(DispVal); 423 } 424 } 425 426 O << ']'; 427 } 428 429 void X86IntelInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op, 430 raw_ostream &O) { 431 // If this has a segment register, print it. 432 printOptionalSegReg(MI, Op + 1, O); 433 O << '['; 434 printOperand(MI, Op, O); 435 O << ']'; 436 } 437 438 void X86IntelInstPrinter::printDstIdx(const MCInst *MI, unsigned Op, 439 raw_ostream &O) { 440 // DI accesses are always ES-based. 441 O << "es:["; 442 printOperand(MI, Op, O); 443 O << ']'; 444 } 445 446 void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op, 447 raw_ostream &O) { 448 const MCOperand &DispSpec = MI->getOperand(Op); 449 450 // If this has a segment register, print it. 451 printOptionalSegReg(MI, Op + 1, O); 452 453 O << '['; 454 455 if (DispSpec.isImm()) { 456 O << formatImm(DispSpec.getImm()); 457 } else { 458 assert(DispSpec.isExpr() && "non-immediate displacement?"); 459 DispSpec.getExpr()->print(O, &MAI); 460 } 461 462 O << ']'; 463 } 464 465 void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, 466 raw_ostream &O) { 467 if (MI->getOperand(Op).isExpr()) 468 return MI->getOperand(Op).getExpr()->print(O, &MAI); 469 470 O << formatImm(MI->getOperand(Op).getImm() & 0xff); 471 } 472 473 void X86IntelInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo, 474 raw_ostream &OS) { 475 const MCOperand &Op = MI->getOperand(OpNo); 476 unsigned Reg = Op.getReg(); 477 // Override the default printing to print st(0) instead st. 478 if (Reg == X86::ST0) 479 OS << "st(0)"; 480 else 481 printRegName(OS, Reg); 482 } 483