xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp (revision 7ef62cebc2f965b0f640263e179276928885e33d)
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, MCRegister Reg) const {
37   OS << markup("<reg:") << getRegisterName(Reg) << markup(">");
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 << markup("<imm:") << formatImm((int64_t)Op.getImm()) << markup(">");
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 << markup("<mem:") << '[';
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 << markup("<imm:") << formatImm(DispVal) << markup(">");
423     }
424   }
425 
426   O << ']' << markup(">");
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 << markup("<mem:") << '[';
434   printOperand(MI, Op, O);
435   O << ']' << markup(">");
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:" << markup("<mem:") << '[';
442   printOperand(MI, Op, O);
443   O << ']' << markup(">");
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 << markup("<mem:") << '[';
454 
455   if (DispSpec.isImm()) {
456     O << markup("<imm:") << formatImm(DispSpec.getImm()) << markup(">");
457   } else {
458     assert(DispSpec.isExpr() && "non-immediate displacement?");
459     DispSpec.getExpr()->print(O, &MAI);
460   }
461 
462   O << ']' << markup(">");
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 << markup("<imm:") << formatImm(MI->getOperand(Op).getImm() & 0xff)
471     << markup(">");
472 }
473 
474 void X86IntelInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo,
475                                             raw_ostream &OS) {
476   const MCOperand &Op = MI->getOperand(OpNo);
477   unsigned Reg = Op.getReg();
478   // Override the default printing to print st(0) instead st.
479   if (Reg == X86::ST0)
480     OS << "st(0)";
481   else
482     printRegName(OS, Reg);
483 }
484