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