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/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, MCRegister Reg) { 36 markup(OS, Markup::Register) << getRegisterName(Reg); 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, STI); 43 44 // In 16-bit mode, print data16 as data32. 45 if (MI->getOpcode() == X86::DATA16_PREFIX && 46 STI.hasFeature(X86::Is16Bit)) { 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::CMPSDrmi: case X86::CMPSDrri: 74 case X86::CMPSDrmi_Int: case X86::CMPSDrri_Int: 75 case X86::CMPSSrmi: case X86::CMPSSrri: 76 case X86::CMPSSrmi_Int: case X86::CMPSSrri_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::VCMPSDrmi: case X86::VCMPSDrri: 109 case X86::VCMPSDZrmi: case X86::VCMPSDZrri: 110 case X86::VCMPSDrmi_Int: case X86::VCMPSDrri_Int: 111 case X86::VCMPSDZrmi_Int: case X86::VCMPSDZrri_Int: 112 case X86::VCMPSSrmi: case X86::VCMPSSrri: 113 case X86::VCMPSSZrmi: case X86::VCMPSSZrri: 114 case X86::VCMPSSrmi_Int: case X86::VCMPSSrri_Int: 115 case X86::VCMPSSZrmi_Int: case X86::VCMPSSZrri_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::VCMPSDZrmik_Int: case X86::VCMPSDZrrik_Int: 123 case X86::VCMPSSZrmik_Int: case X86::VCMPSSZrrik_Int: 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::VCMPSDZrrib_Int: case X86::VCMPSDZrribk_Int: 133 case X86::VCMPSSZrrib_Int: case X86::VCMPSSZrribk_Int: 134 case X86::VCMPPHZ128rmi: case X86::VCMPPHZ128rri: 135 case X86::VCMPPHZ256rmi: case X86::VCMPPHZ256rri: 136 case X86::VCMPPHZrmi: case X86::VCMPPHZrri: 137 case X86::VCMPSHZrmi: case X86::VCMPSHZrri: 138 case X86::VCMPSHZrmi_Int: case X86::VCMPSHZrri_Int: 139 case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik: 140 case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik: 141 case X86::VCMPPHZrmik: case X86::VCMPPHZrrik: 142 case X86::VCMPSHZrmik_Int: case X86::VCMPSHZrrik_Int: 143 case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik: 144 case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik: 145 case X86::VCMPPHZrmbi: case X86::VCMPPHZrmbik: 146 case X86::VCMPPHZrrib: case X86::VCMPPHZrribk: 147 case X86::VCMPSHZrrib_Int: case X86::VCMPSHZrribk_Int: 148 case X86::VCMPBF16Z128rmi: case X86::VCMPBF16Z128rri: 149 case X86::VCMPBF16Z256rmi: case X86::VCMPBF16Z256rri: 150 case X86::VCMPBF16Zrmi: case X86::VCMPBF16Zrri: 151 case X86::VCMPBF16Z128rmik: case X86::VCMPBF16Z128rrik: 152 case X86::VCMPBF16Z256rmik: case X86::VCMPBF16Z256rrik: 153 case X86::VCMPBF16Zrmik: case X86::VCMPBF16Zrrik: 154 case X86::VCMPBF16Z128rmbi: case X86::VCMPBF16Z128rmbik: 155 case X86::VCMPBF16Z256rmbi: case X86::VCMPBF16Z256rmbik: 156 case X86::VCMPBF16Zrmbi: case X86::VCMPBF16Zrmbik: 157 if (Imm >= 0 && Imm <= 31) { 158 OS << '\t'; 159 printCMPMnemonic(MI, /*IsVCMP*/true, OS); 160 161 unsigned CurOp = 0; 162 printOperand(MI, CurOp++, OS); 163 164 if (Desc.TSFlags & X86II::EVEX_K) { 165 // Print mask operand. 166 OS << " {"; 167 printOperand(MI, CurOp++, OS); 168 OS << "}"; 169 } 170 OS << ", "; 171 printOperand(MI, CurOp++, OS); 172 OS << ", "; 173 174 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) { 175 if (Desc.TSFlags & X86II::EVEX_B) { 176 // Broadcast form. 177 // Load size is word for TA map. Otherwise it is based on W-bit. 178 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) { 179 assert(!(Desc.TSFlags & X86II::REX_W) && "Unknown W-bit value!"); 180 printwordmem(MI, CurOp++, OS); 181 } else if (Desc.TSFlags & X86II::REX_W) { 182 printqwordmem(MI, CurOp++, OS); 183 } else { 184 printdwordmem(MI, CurOp++, OS); 185 } 186 187 // Print the number of elements broadcasted. 188 unsigned NumElts; 189 if (Desc.TSFlags & X86II::EVEX_L2) 190 NumElts = (Desc.TSFlags & X86II::REX_W) ? 8 : 16; 191 else if (Desc.TSFlags & X86II::VEX_L) 192 NumElts = (Desc.TSFlags & X86II::REX_W) ? 4 : 8; 193 else 194 NumElts = (Desc.TSFlags & X86II::REX_W) ? 2 : 4; 195 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) { 196 assert(!(Desc.TSFlags & X86II::REX_W) && "Unknown W-bit value!"); 197 NumElts *= 2; 198 } 199 OS << "{1to" << NumElts << "}"; 200 } else { 201 if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XS) { 202 if ((Desc.TSFlags & X86II::OpMapMask) == X86II::TA) 203 printwordmem(MI, CurOp++, OS); 204 else 205 printdwordmem(MI, CurOp++, OS); 206 } else if ((Desc.TSFlags & X86II::OpPrefixMask) == X86II::XD && 207 (Desc.TSFlags & X86II::OpMapMask) != X86II::TA) { 208 printqwordmem(MI, CurOp++, OS); 209 } else if (Desc.TSFlags & X86II::EVEX_L2) { 210 printzmmwordmem(MI, CurOp++, OS); 211 } else if (Desc.TSFlags & X86II::VEX_L) { 212 printymmwordmem(MI, CurOp++, OS); 213 } else { 214 printxmmwordmem(MI, CurOp++, OS); 215 } 216 } 217 } else { 218 printOperand(MI, CurOp++, OS); 219 if (Desc.TSFlags & X86II::EVEX_B) 220 OS << ", {sae}"; 221 } 222 223 return true; 224 } 225 break; 226 227 case X86::VPCOMBmi: case X86::VPCOMBri: 228 case X86::VPCOMDmi: case X86::VPCOMDri: 229 case X86::VPCOMQmi: case X86::VPCOMQri: 230 case X86::VPCOMUBmi: case X86::VPCOMUBri: 231 case X86::VPCOMUDmi: case X86::VPCOMUDri: 232 case X86::VPCOMUQmi: case X86::VPCOMUQri: 233 case X86::VPCOMUWmi: case X86::VPCOMUWri: 234 case X86::VPCOMWmi: case X86::VPCOMWri: 235 if (Imm >= 0 && Imm <= 7) { 236 OS << '\t'; 237 printVPCOMMnemonic(MI, OS); 238 printOperand(MI, 0, OS); 239 OS << ", "; 240 printOperand(MI, 1, OS); 241 OS << ", "; 242 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) 243 printxmmwordmem(MI, 2, OS); 244 else 245 printOperand(MI, 2, OS); 246 return true; 247 } 248 break; 249 250 case X86::VPCMPBZ128rmi: case X86::VPCMPBZ128rri: 251 case X86::VPCMPBZ256rmi: case X86::VPCMPBZ256rri: 252 case X86::VPCMPBZrmi: case X86::VPCMPBZrri: 253 case X86::VPCMPDZ128rmi: case X86::VPCMPDZ128rri: 254 case X86::VPCMPDZ256rmi: case X86::VPCMPDZ256rri: 255 case X86::VPCMPDZrmi: case X86::VPCMPDZrri: 256 case X86::VPCMPQZ128rmi: case X86::VPCMPQZ128rri: 257 case X86::VPCMPQZ256rmi: case X86::VPCMPQZ256rri: 258 case X86::VPCMPQZrmi: case X86::VPCMPQZrri: 259 case X86::VPCMPUBZ128rmi: case X86::VPCMPUBZ128rri: 260 case X86::VPCMPUBZ256rmi: case X86::VPCMPUBZ256rri: 261 case X86::VPCMPUBZrmi: case X86::VPCMPUBZrri: 262 case X86::VPCMPUDZ128rmi: case X86::VPCMPUDZ128rri: 263 case X86::VPCMPUDZ256rmi: case X86::VPCMPUDZ256rri: 264 case X86::VPCMPUDZrmi: case X86::VPCMPUDZrri: 265 case X86::VPCMPUQZ128rmi: case X86::VPCMPUQZ128rri: 266 case X86::VPCMPUQZ256rmi: case X86::VPCMPUQZ256rri: 267 case X86::VPCMPUQZrmi: case X86::VPCMPUQZrri: 268 case X86::VPCMPUWZ128rmi: case X86::VPCMPUWZ128rri: 269 case X86::VPCMPUWZ256rmi: case X86::VPCMPUWZ256rri: 270 case X86::VPCMPUWZrmi: case X86::VPCMPUWZrri: 271 case X86::VPCMPWZ128rmi: case X86::VPCMPWZ128rri: 272 case X86::VPCMPWZ256rmi: case X86::VPCMPWZ256rri: 273 case X86::VPCMPWZrmi: case X86::VPCMPWZrri: 274 case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik: 275 case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik: 276 case X86::VPCMPBZrmik: case X86::VPCMPBZrrik: 277 case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik: 278 case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik: 279 case X86::VPCMPDZrmik: case X86::VPCMPDZrrik: 280 case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik: 281 case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik: 282 case X86::VPCMPQZrmik: case X86::VPCMPQZrrik: 283 case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik: 284 case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik: 285 case X86::VPCMPUBZrmik: case X86::VPCMPUBZrrik: 286 case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik: 287 case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik: 288 case X86::VPCMPUDZrmik: case X86::VPCMPUDZrrik: 289 case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik: 290 case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik: 291 case X86::VPCMPUQZrmik: case X86::VPCMPUQZrrik: 292 case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik: 293 case X86::VPCMPUWZ256rmik: case X86::VPCMPUWZ256rrik: 294 case X86::VPCMPUWZrmik: case X86::VPCMPUWZrrik: 295 case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik: 296 case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik: 297 case X86::VPCMPWZrmik: case X86::VPCMPWZrrik: 298 case X86::VPCMPDZ128rmbi: case X86::VPCMPDZ128rmbik: 299 case X86::VPCMPDZ256rmbi: case X86::VPCMPDZ256rmbik: 300 case X86::VPCMPDZrmbi: case X86::VPCMPDZrmbik: 301 case X86::VPCMPQZ128rmbi: case X86::VPCMPQZ128rmbik: 302 case X86::VPCMPQZ256rmbi: case X86::VPCMPQZ256rmbik: 303 case X86::VPCMPQZrmbi: case X86::VPCMPQZrmbik: 304 case X86::VPCMPUDZ128rmbi: case X86::VPCMPUDZ128rmbik: 305 case X86::VPCMPUDZ256rmbi: case X86::VPCMPUDZ256rmbik: 306 case X86::VPCMPUDZrmbi: case X86::VPCMPUDZrmbik: 307 case X86::VPCMPUQZ128rmbi: case X86::VPCMPUQZ128rmbik: 308 case X86::VPCMPUQZ256rmbi: case X86::VPCMPUQZ256rmbik: 309 case X86::VPCMPUQZrmbi: case X86::VPCMPUQZrmbik: 310 if ((Imm >= 0 && Imm <= 2) || (Imm >= 4 && Imm <= 6)) { 311 OS << '\t'; 312 printVPCMPMnemonic(MI, OS); 313 314 unsigned CurOp = 0; 315 printOperand(MI, CurOp++, OS); 316 317 if (Desc.TSFlags & X86II::EVEX_K) { 318 // Print mask operand. 319 OS << " {"; 320 printOperand(MI, CurOp++, OS); 321 OS << "}"; 322 } 323 OS << ", "; 324 printOperand(MI, CurOp++, OS); 325 OS << ", "; 326 327 if ((Desc.TSFlags & X86II::FormMask) == X86II::MRMSrcMem) { 328 if (Desc.TSFlags & X86II::EVEX_B) { 329 // Broadcast form. 330 // Load size is based on W-bit as only D and Q are supported. 331 if (Desc.TSFlags & X86II::REX_W) 332 printqwordmem(MI, CurOp++, OS); 333 else 334 printdwordmem(MI, CurOp++, OS); 335 336 // Print the number of elements broadcasted. 337 unsigned NumElts; 338 if (Desc.TSFlags & X86II::EVEX_L2) 339 NumElts = (Desc.TSFlags & X86II::REX_W) ? 8 : 16; 340 else if (Desc.TSFlags & X86II::VEX_L) 341 NumElts = (Desc.TSFlags & X86II::REX_W) ? 4 : 8; 342 else 343 NumElts = (Desc.TSFlags & X86II::REX_W) ? 2 : 4; 344 OS << "{1to" << NumElts << "}"; 345 } else { 346 if (Desc.TSFlags & X86II::EVEX_L2) 347 printzmmwordmem(MI, CurOp++, OS); 348 else if (Desc.TSFlags & X86II::VEX_L) 349 printymmwordmem(MI, CurOp++, OS); 350 else 351 printxmmwordmem(MI, CurOp++, OS); 352 } 353 } else { 354 printOperand(MI, CurOp++, OS); 355 } 356 357 return true; 358 } 359 break; 360 } 361 362 return false; 363 } 364 365 void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 366 raw_ostream &O) { 367 const MCOperand &Op = MI->getOperand(OpNo); 368 if (Op.isReg()) { 369 printRegName(O, Op.getReg()); 370 } else if (Op.isImm()) { 371 markup(O, Markup::Immediate) << formatImm((int64_t)Op.getImm()); 372 } else { 373 assert(Op.isExpr() && "unknown operand kind in printOperand"); 374 O << "offset "; 375 Op.getExpr()->print(O, &MAI); 376 } 377 } 378 379 void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 380 raw_ostream &O) { 381 // Do not print the exact form of the memory operand if it references a known 382 // binary object. 383 if (SymbolizeOperands && MIA) { 384 uint64_t Target; 385 if (MIA->evaluateBranch(*MI, 0, 0, Target)) 386 return; 387 if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0)) 388 return; 389 } 390 const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 391 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 392 const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 393 const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 394 395 // If this has a segment register, print it. 396 printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O); 397 398 WithMarkup M = markup(O, Markup::Memory); 399 O << '['; 400 401 bool NeedPlus = false; 402 if (BaseReg.getReg()) { 403 printOperand(MI, Op+X86::AddrBaseReg, O); 404 NeedPlus = true; 405 } 406 407 if (IndexReg.getReg()) { 408 if (NeedPlus) O << " + "; 409 if (ScaleVal != 1 || !BaseReg.getReg()) 410 O << ScaleVal << '*'; 411 printOperand(MI, Op+X86::AddrIndexReg, O); 412 NeedPlus = true; 413 } 414 415 if (!DispSpec.isImm()) { 416 if (NeedPlus) O << " + "; 417 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 418 DispSpec.getExpr()->print(O, &MAI); 419 } else { 420 int64_t DispVal = DispSpec.getImm(); 421 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 422 if (NeedPlus) { 423 if (DispVal > 0) 424 O << " + "; 425 else { 426 O << " - "; 427 DispVal = -DispVal; 428 } 429 } 430 markup(O, Markup::Immediate) << formatImm(DispVal); 431 } 432 } 433 434 O << ']'; 435 } 436 437 void X86IntelInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op, 438 raw_ostream &O) { 439 // If this has a segment register, print it. 440 printOptionalSegReg(MI, Op + 1, O); 441 442 WithMarkup M = markup(O, Markup::Memory); 443 O << '['; 444 printOperand(MI, Op, O); 445 O << ']'; 446 } 447 448 void X86IntelInstPrinter::printDstIdx(const MCInst *MI, unsigned Op, 449 raw_ostream &O) { 450 // DI accesses are always ES-based. 451 O << "es:"; 452 453 WithMarkup M = markup(O, Markup::Memory); 454 O << '['; 455 printOperand(MI, Op, O); 456 O << ']'; 457 } 458 459 void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op, 460 raw_ostream &O) { 461 const MCOperand &DispSpec = MI->getOperand(Op); 462 463 // If this has a segment register, print it. 464 printOptionalSegReg(MI, Op + 1, O); 465 466 WithMarkup M = markup(O, Markup::Memory); 467 O << '['; 468 469 if (DispSpec.isImm()) { 470 markup(O, Markup::Immediate) << formatImm(DispSpec.getImm()); 471 } else { 472 assert(DispSpec.isExpr() && "non-immediate displacement?"); 473 DispSpec.getExpr()->print(O, &MAI); 474 } 475 476 O << ']'; 477 } 478 479 void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, 480 raw_ostream &O) { 481 if (MI->getOperand(Op).isExpr()) 482 return MI->getOperand(Op).getExpr()->print(O, &MAI); 483 484 markup(O, Markup::Immediate) << formatImm(MI->getOperand(Op).getImm() & 0xff); 485 } 486 487 void X86IntelInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo, 488 raw_ostream &OS) { 489 MCRegister Reg = MI->getOperand(OpNo).getReg(); 490 // Override the default printing to print st(0) instead st. 491 if (Reg == X86::ST0) 492 OS << "st(0)"; 493 else 494 printRegName(OS, Reg); 495 } 496