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