1 //===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===//
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
7 //===----------------------------------------------------------------------===//
9 // This file includes code for rendering MCInst instances as Intel-style
12 //===----------------------------------------------------------------------===//
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"
29 #define DEBUG_TYPE "asm-printer"
31 // Include the auto-generated portion of the assembly writer.
32 #define PRINT_ALIAS_INSTR
33 #include "X86GenAsmWriter1.inc"
35 void X86IntelInstPrinter::printRegName(raw_ostream
&OS
, unsigned RegNo
) const {
36 OS
<< getRegisterName(RegNo
);
39 void X86IntelInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&OS
,
41 const MCSubtargetInfo
&STI
) {
42 printInstFlags(MI
, OS
);
44 // In 16-bit mode, print data16 as data32.
45 if (MI
->getOpcode() == X86::DATA16_PREFIX
&&
46 STI
.getFeatureBits()[X86::Mode16Bit
]) {
48 } else if (!printAliasInstr(MI
, OS
) &&
49 !printVecCompareInstr(MI
, OS
))
50 printInstruction(MI
, OS
);
52 // Next always print the annotation.
53 printAnnotation(OS
, Annot
);
55 // If verbose assembly is enabled, we can print some informative comments.
57 EmitAnyX86InstComments(MI
, *CommentStream
, MII
);
60 bool X86IntelInstPrinter::printVecCompareInstr(const MCInst
*MI
, raw_ostream
&OS
) {
61 if (MI
->getNumOperands() == 0 ||
62 !MI
->getOperand(MI
->getNumOperands() - 1).isImm())
65 int64_t Imm
= MI
->getOperand(MI
->getNumOperands() - 1).getImm();
67 const MCInstrDesc
&Desc
= MII
.get(MI
->getOpcode());
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) {
80 printCMPMnemonic(MI
, /*IsVCMP*/false, OS
);
81 printOperand(MI
, 0, OS
);
83 // Skip operand 1 as its tied to the dest.
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
);
91 printxmmwordmem(MI
, 2, OS
);
93 printOperand(MI
, 2, OS
);
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 if (Imm
>= 0 && Imm
<= 31) {
137 printCMPMnemonic(MI
, /*IsVCMP*/true, OS
);
140 printOperand(MI
, CurOp
++, OS
);
142 if (Desc
.TSFlags
& X86II::EVEX_K
) {
143 // Print mask operand.
145 printOperand(MI
, CurOp
++, OS
);
149 printOperand(MI
, CurOp
++, OS
);
152 if ((Desc
.TSFlags
& X86II::FormMask
) == X86II::MRMSrcMem
) {
153 if (Desc
.TSFlags
& X86II::EVEX_B
) {
155 // Load size is based on W-bit.
156 if (Desc
.TSFlags
& X86II::VEX_W
)
157 printqwordmem(MI
, CurOp
++, OS
);
159 printdwordmem(MI
, CurOp
++, OS
);
161 // Print the number of elements broadcasted.
163 if (Desc
.TSFlags
& X86II::EVEX_L2
)
164 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 8 : 16;
165 else if (Desc
.TSFlags
& X86II::VEX_L
)
166 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 4 : 8;
168 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 2 : 4;
169 OS
<< "{1to" << NumElts
<< "}";
171 if ((Desc
.TSFlags
& X86II::OpPrefixMask
) == X86II::XS
)
172 printdwordmem(MI
, CurOp
++, OS
);
173 else if ((Desc
.TSFlags
& X86II::OpPrefixMask
) == X86II::XD
)
174 printqwordmem(MI
, CurOp
++, OS
);
175 else if (Desc
.TSFlags
& X86II::EVEX_L2
)
176 printzmmwordmem(MI
, CurOp
++, OS
);
177 else if (Desc
.TSFlags
& X86II::VEX_L
)
178 printymmwordmem(MI
, CurOp
++, OS
);
180 printxmmwordmem(MI
, CurOp
++, OS
);
183 printOperand(MI
, CurOp
++, OS
);
184 if (Desc
.TSFlags
& X86II::EVEX_B
)
192 case X86::VPCOMBmi
: case X86::VPCOMBri
:
193 case X86::VPCOMDmi
: case X86::VPCOMDri
:
194 case X86::VPCOMQmi
: case X86::VPCOMQri
:
195 case X86::VPCOMUBmi
: case X86::VPCOMUBri
:
196 case X86::VPCOMUDmi
: case X86::VPCOMUDri
:
197 case X86::VPCOMUQmi
: case X86::VPCOMUQri
:
198 case X86::VPCOMUWmi
: case X86::VPCOMUWri
:
199 case X86::VPCOMWmi
: case X86::VPCOMWri
:
200 if (Imm
>= 0 && Imm
<= 7) {
202 printVPCOMMnemonic(MI
, OS
);
203 printOperand(MI
, 0, OS
);
205 printOperand(MI
, 1, OS
);
207 if ((Desc
.TSFlags
& X86II::FormMask
) == X86II::MRMSrcMem
)
208 printxmmwordmem(MI
, 2, OS
);
210 printOperand(MI
, 2, OS
);
215 case X86::VPCMPBZ128rmi
: case X86::VPCMPBZ128rri
:
216 case X86::VPCMPBZ256rmi
: case X86::VPCMPBZ256rri
:
217 case X86::VPCMPBZrmi
: case X86::VPCMPBZrri
:
218 case X86::VPCMPDZ128rmi
: case X86::VPCMPDZ128rri
:
219 case X86::VPCMPDZ256rmi
: case X86::VPCMPDZ256rri
:
220 case X86::VPCMPDZrmi
: case X86::VPCMPDZrri
:
221 case X86::VPCMPQZ128rmi
: case X86::VPCMPQZ128rri
:
222 case X86::VPCMPQZ256rmi
: case X86::VPCMPQZ256rri
:
223 case X86::VPCMPQZrmi
: case X86::VPCMPQZrri
:
224 case X86::VPCMPUBZ128rmi
: case X86::VPCMPUBZ128rri
:
225 case X86::VPCMPUBZ256rmi
: case X86::VPCMPUBZ256rri
:
226 case X86::VPCMPUBZrmi
: case X86::VPCMPUBZrri
:
227 case X86::VPCMPUDZ128rmi
: case X86::VPCMPUDZ128rri
:
228 case X86::VPCMPUDZ256rmi
: case X86::VPCMPUDZ256rri
:
229 case X86::VPCMPUDZrmi
: case X86::VPCMPUDZrri
:
230 case X86::VPCMPUQZ128rmi
: case X86::VPCMPUQZ128rri
:
231 case X86::VPCMPUQZ256rmi
: case X86::VPCMPUQZ256rri
:
232 case X86::VPCMPUQZrmi
: case X86::VPCMPUQZrri
:
233 case X86::VPCMPUWZ128rmi
: case X86::VPCMPUWZ128rri
:
234 case X86::VPCMPUWZ256rmi
: case X86::VPCMPUWZ256rri
:
235 case X86::VPCMPUWZrmi
: case X86::VPCMPUWZrri
:
236 case X86::VPCMPWZ128rmi
: case X86::VPCMPWZ128rri
:
237 case X86::VPCMPWZ256rmi
: case X86::VPCMPWZ256rri
:
238 case X86::VPCMPWZrmi
: case X86::VPCMPWZrri
:
239 case X86::VPCMPBZ128rmik
: case X86::VPCMPBZ128rrik
:
240 case X86::VPCMPBZ256rmik
: case X86::VPCMPBZ256rrik
:
241 case X86::VPCMPBZrmik
: case X86::VPCMPBZrrik
:
242 case X86::VPCMPDZ128rmik
: case X86::VPCMPDZ128rrik
:
243 case X86::VPCMPDZ256rmik
: case X86::VPCMPDZ256rrik
:
244 case X86::VPCMPDZrmik
: case X86::VPCMPDZrrik
:
245 case X86::VPCMPQZ128rmik
: case X86::VPCMPQZ128rrik
:
246 case X86::VPCMPQZ256rmik
: case X86::VPCMPQZ256rrik
:
247 case X86::VPCMPQZrmik
: case X86::VPCMPQZrrik
:
248 case X86::VPCMPUBZ128rmik
: case X86::VPCMPUBZ128rrik
:
249 case X86::VPCMPUBZ256rmik
: case X86::VPCMPUBZ256rrik
:
250 case X86::VPCMPUBZrmik
: case X86::VPCMPUBZrrik
:
251 case X86::VPCMPUDZ128rmik
: case X86::VPCMPUDZ128rrik
:
252 case X86::VPCMPUDZ256rmik
: case X86::VPCMPUDZ256rrik
:
253 case X86::VPCMPUDZrmik
: case X86::VPCMPUDZrrik
:
254 case X86::VPCMPUQZ128rmik
: case X86::VPCMPUQZ128rrik
:
255 case X86::VPCMPUQZ256rmik
: case X86::VPCMPUQZ256rrik
:
256 case X86::VPCMPUQZrmik
: case X86::VPCMPUQZrrik
:
257 case X86::VPCMPUWZ128rmik
: case X86::VPCMPUWZ128rrik
:
258 case X86::VPCMPUWZ256rmik
: case X86::VPCMPUWZ256rrik
:
259 case X86::VPCMPUWZrmik
: case X86::VPCMPUWZrrik
:
260 case X86::VPCMPWZ128rmik
: case X86::VPCMPWZ128rrik
:
261 case X86::VPCMPWZ256rmik
: case X86::VPCMPWZ256rrik
:
262 case X86::VPCMPWZrmik
: case X86::VPCMPWZrrik
:
263 case X86::VPCMPDZ128rmib
: case X86::VPCMPDZ128rmibk
:
264 case X86::VPCMPDZ256rmib
: case X86::VPCMPDZ256rmibk
:
265 case X86::VPCMPDZrmib
: case X86::VPCMPDZrmibk
:
266 case X86::VPCMPQZ128rmib
: case X86::VPCMPQZ128rmibk
:
267 case X86::VPCMPQZ256rmib
: case X86::VPCMPQZ256rmibk
:
268 case X86::VPCMPQZrmib
: case X86::VPCMPQZrmibk
:
269 case X86::VPCMPUDZ128rmib
: case X86::VPCMPUDZ128rmibk
:
270 case X86::VPCMPUDZ256rmib
: case X86::VPCMPUDZ256rmibk
:
271 case X86::VPCMPUDZrmib
: case X86::VPCMPUDZrmibk
:
272 case X86::VPCMPUQZ128rmib
: case X86::VPCMPUQZ128rmibk
:
273 case X86::VPCMPUQZ256rmib
: case X86::VPCMPUQZ256rmibk
:
274 case X86::VPCMPUQZrmib
: case X86::VPCMPUQZrmibk
:
275 if ((Imm
>= 0 && Imm
<= 2) || (Imm
>= 4 && Imm
<= 6)) {
277 printVPCMPMnemonic(MI
, OS
);
280 printOperand(MI
, CurOp
++, OS
);
282 if (Desc
.TSFlags
& X86II::EVEX_K
) {
283 // Print mask operand.
285 printOperand(MI
, CurOp
++, OS
);
289 printOperand(MI
, CurOp
++, OS
);
292 if ((Desc
.TSFlags
& X86II::FormMask
) == X86II::MRMSrcMem
) {
293 if (Desc
.TSFlags
& X86II::EVEX_B
) {
295 // Load size is based on W-bit as only D and Q are supported.
296 if (Desc
.TSFlags
& X86II::VEX_W
)
297 printqwordmem(MI
, CurOp
++, OS
);
299 printdwordmem(MI
, CurOp
++, OS
);
301 // Print the number of elements broadcasted.
303 if (Desc
.TSFlags
& X86II::EVEX_L2
)
304 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 8 : 16;
305 else if (Desc
.TSFlags
& X86II::VEX_L
)
306 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 4 : 8;
308 NumElts
= (Desc
.TSFlags
& X86II::VEX_W
) ? 2 : 4;
309 OS
<< "{1to" << NumElts
<< "}";
311 if (Desc
.TSFlags
& X86II::EVEX_L2
)
312 printzmmwordmem(MI
, CurOp
++, OS
);
313 else if (Desc
.TSFlags
& X86II::VEX_L
)
314 printymmwordmem(MI
, CurOp
++, OS
);
316 printxmmwordmem(MI
, CurOp
++, OS
);
319 printOperand(MI
, CurOp
++, OS
);
330 void X86IntelInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
332 const MCOperand
&Op
= MI
->getOperand(OpNo
);
334 printRegName(O
, Op
.getReg());
335 } else if (Op
.isImm()) {
336 O
<< formatImm((int64_t)Op
.getImm());
338 assert(Op
.isExpr() && "unknown operand kind in printOperand");
340 Op
.getExpr()->print(O
, &MAI
);
344 void X86IntelInstPrinter::printMemReference(const MCInst
*MI
, unsigned Op
,
346 const MCOperand
&BaseReg
= MI
->getOperand(Op
+X86::AddrBaseReg
);
347 unsigned ScaleVal
= MI
->getOperand(Op
+X86::AddrScaleAmt
).getImm();
348 const MCOperand
&IndexReg
= MI
->getOperand(Op
+X86::AddrIndexReg
);
349 const MCOperand
&DispSpec
= MI
->getOperand(Op
+X86::AddrDisp
);
351 // If this has a segment register, print it.
352 printOptionalSegReg(MI
, Op
+ X86::AddrSegmentReg
, O
);
356 bool NeedPlus
= false;
357 if (BaseReg
.getReg()) {
358 printOperand(MI
, Op
+X86::AddrBaseReg
, O
);
362 if (IndexReg
.getReg()) {
363 if (NeedPlus
) O
<< " + ";
365 O
<< ScaleVal
<< '*';
366 printOperand(MI
, Op
+X86::AddrIndexReg
, O
);
370 if (!DispSpec
.isImm()) {
371 if (NeedPlus
) O
<< " + ";
372 assert(DispSpec
.isExpr() && "non-immediate displacement for LEA?");
373 DispSpec
.getExpr()->print(O
, &MAI
);
375 int64_t DispVal
= DispSpec
.getImm();
376 if (DispVal
|| (!IndexReg
.getReg() && !BaseReg
.getReg())) {
385 O
<< formatImm(DispVal
);
392 void X86IntelInstPrinter::printSrcIdx(const MCInst
*MI
, unsigned Op
,
394 // If this has a segment register, print it.
395 printOptionalSegReg(MI
, Op
+ 1, O
);
397 printOperand(MI
, Op
, O
);
401 void X86IntelInstPrinter::printDstIdx(const MCInst
*MI
, unsigned Op
,
403 // DI accesses are always ES-based.
405 printOperand(MI
, Op
, O
);
409 void X86IntelInstPrinter::printMemOffset(const MCInst
*MI
, unsigned Op
,
411 const MCOperand
&DispSpec
= MI
->getOperand(Op
);
413 // If this has a segment register, print it.
414 printOptionalSegReg(MI
, Op
+ 1, O
);
418 if (DispSpec
.isImm()) {
419 O
<< formatImm(DispSpec
.getImm());
421 assert(DispSpec
.isExpr() && "non-immediate displacement?");
422 DispSpec
.getExpr()->print(O
, &MAI
);
428 void X86IntelInstPrinter::printU8Imm(const MCInst
*MI
, unsigned Op
,
430 if (MI
->getOperand(Op
).isExpr())
431 return MI
->getOperand(Op
).getExpr()->print(O
, &MAI
);
433 O
<< formatImm(MI
->getOperand(Op
).getImm() & 0xff);
436 void X86IntelInstPrinter::printSTiRegOperand(const MCInst
*MI
, unsigned OpNo
,
438 const MCOperand
&Op
= MI
->getOperand(OpNo
);
439 unsigned Reg
= Op
.getReg();
440 // Override the default printing to print st(0) instead st.
444 printRegName(OS
, Reg
);