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