1 //===--- X86InstPrinterCommon.cpp - X86 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 common code for rendering MCInst instances as Intel-style
10 // and Intel-style assembly.
12 //===----------------------------------------------------------------------===//
14 #include "X86InstPrinterCommon.h"
15 #include "X86BaseInfo.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrDesc.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Support/Casting.h"
27 void X86InstPrinterCommon::printCondCode(const MCInst
*MI
, unsigned Op
,
29 int64_t Imm
= MI
->getOperand(Op
).getImm();
31 default: llvm_unreachable("Invalid condcode argument!");
32 case 0: O
<< "o"; break;
33 case 1: O
<< "no"; break;
34 case 2: O
<< "b"; break;
35 case 3: O
<< "ae"; break;
36 case 4: O
<< "e"; break;
37 case 5: O
<< "ne"; break;
38 case 6: O
<< "be"; break;
39 case 7: O
<< "a"; break;
40 case 8: O
<< "s"; break;
41 case 9: O
<< "ns"; break;
42 case 0xa: O
<< "p"; break;
43 case 0xb: O
<< "np"; break;
44 case 0xc: O
<< "l"; break;
45 case 0xd: O
<< "ge"; break;
46 case 0xe: O
<< "le"; break;
47 case 0xf: O
<< "g"; break;
51 void X86InstPrinterCommon::printSSEAVXCC(const MCInst
*MI
, unsigned Op
,
53 int64_t Imm
= MI
->getOperand(Op
).getImm();
55 default: llvm_unreachable("Invalid ssecc/avxcc argument!");
56 case 0: O
<< "eq"; break;
57 case 1: O
<< "lt"; break;
58 case 2: O
<< "le"; break;
59 case 3: O
<< "unord"; break;
60 case 4: O
<< "neq"; break;
61 case 5: O
<< "nlt"; break;
62 case 6: O
<< "nle"; break;
63 case 7: O
<< "ord"; break;
64 case 8: O
<< "eq_uq"; break;
65 case 9: O
<< "nge"; break;
66 case 0xa: O
<< "ngt"; break;
67 case 0xb: O
<< "false"; break;
68 case 0xc: O
<< "neq_oq"; break;
69 case 0xd: O
<< "ge"; break;
70 case 0xe: O
<< "gt"; break;
71 case 0xf: O
<< "true"; break;
72 case 0x10: O
<< "eq_os"; break;
73 case 0x11: O
<< "lt_oq"; break;
74 case 0x12: O
<< "le_oq"; break;
75 case 0x13: O
<< "unord_s"; break;
76 case 0x14: O
<< "neq_us"; break;
77 case 0x15: O
<< "nlt_uq"; break;
78 case 0x16: O
<< "nle_uq"; break;
79 case 0x17: O
<< "ord_s"; break;
80 case 0x18: O
<< "eq_us"; break;
81 case 0x19: O
<< "nge_uq"; break;
82 case 0x1a: O
<< "ngt_uq"; break;
83 case 0x1b: O
<< "false_os"; break;
84 case 0x1c: O
<< "neq_os"; break;
85 case 0x1d: O
<< "ge_oq"; break;
86 case 0x1e: O
<< "gt_oq"; break;
87 case 0x1f: O
<< "true_us"; break;
91 void X86InstPrinterCommon::printVPCOMMnemonic(const MCInst
*MI
,
95 int64_t Imm
= MI
->getOperand(MI
->getNumOperands() - 1).getImm();
97 default: llvm_unreachable("Invalid vpcom argument!");
98 case 0: OS
<< "lt"; break;
99 case 1: OS
<< "le"; break;
100 case 2: OS
<< "gt"; break;
101 case 3: OS
<< "ge"; break;
102 case 4: OS
<< "eq"; break;
103 case 5: OS
<< "neq"; break;
104 case 6: OS
<< "false"; break;
105 case 7: OS
<< "true"; break;
108 switch (MI
->getOpcode()) {
109 default: llvm_unreachable("Unexpected opcode!");
110 case X86::VPCOMBmi
: case X86::VPCOMBri
: OS
<< "b\t"; break;
111 case X86::VPCOMDmi
: case X86::VPCOMDri
: OS
<< "d\t"; break;
112 case X86::VPCOMQmi
: case X86::VPCOMQri
: OS
<< "q\t"; break;
113 case X86::VPCOMUBmi
: case X86::VPCOMUBri
: OS
<< "ub\t"; break;
114 case X86::VPCOMUDmi
: case X86::VPCOMUDri
: OS
<< "ud\t"; break;
115 case X86::VPCOMUQmi
: case X86::VPCOMUQri
: OS
<< "uq\t"; break;
116 case X86::VPCOMUWmi
: case X86::VPCOMUWri
: OS
<< "uw\t"; break;
117 case X86::VPCOMWmi
: case X86::VPCOMWri
: OS
<< "w\t"; break;
121 void X86InstPrinterCommon::printVPCMPMnemonic(const MCInst
*MI
,
125 printSSEAVXCC(MI
, MI
->getNumOperands() - 1, OS
);
127 switch (MI
->getOpcode()) {
128 default: llvm_unreachable("Unexpected opcode!");
129 case X86::VPCMPBZ128rmi
: case X86::VPCMPBZ128rri
:
130 case X86::VPCMPBZ256rmi
: case X86::VPCMPBZ256rri
:
131 case X86::VPCMPBZrmi
: case X86::VPCMPBZrri
:
132 case X86::VPCMPBZ128rmik
: case X86::VPCMPBZ128rrik
:
133 case X86::VPCMPBZ256rmik
: case X86::VPCMPBZ256rrik
:
134 case X86::VPCMPBZrmik
: case X86::VPCMPBZrrik
:
137 case X86::VPCMPDZ128rmi
: case X86::VPCMPDZ128rri
:
138 case X86::VPCMPDZ256rmi
: case X86::VPCMPDZ256rri
:
139 case X86::VPCMPDZrmi
: case X86::VPCMPDZrri
:
140 case X86::VPCMPDZ128rmik
: case X86::VPCMPDZ128rrik
:
141 case X86::VPCMPDZ256rmik
: case X86::VPCMPDZ256rrik
:
142 case X86::VPCMPDZrmik
: case X86::VPCMPDZrrik
:
143 case X86::VPCMPDZ128rmib
: case X86::VPCMPDZ128rmibk
:
144 case X86::VPCMPDZ256rmib
: case X86::VPCMPDZ256rmibk
:
145 case X86::VPCMPDZrmib
: case X86::VPCMPDZrmibk
:
148 case X86::VPCMPQZ128rmi
: case X86::VPCMPQZ128rri
:
149 case X86::VPCMPQZ256rmi
: case X86::VPCMPQZ256rri
:
150 case X86::VPCMPQZrmi
: case X86::VPCMPQZrri
:
151 case X86::VPCMPQZ128rmik
: case X86::VPCMPQZ128rrik
:
152 case X86::VPCMPQZ256rmik
: case X86::VPCMPQZ256rrik
:
153 case X86::VPCMPQZrmik
: case X86::VPCMPQZrrik
:
154 case X86::VPCMPQZ128rmib
: case X86::VPCMPQZ128rmibk
:
155 case X86::VPCMPQZ256rmib
: case X86::VPCMPQZ256rmibk
:
156 case X86::VPCMPQZrmib
: case X86::VPCMPQZrmibk
:
159 case X86::VPCMPUBZ128rmi
: case X86::VPCMPUBZ128rri
:
160 case X86::VPCMPUBZ256rmi
: case X86::VPCMPUBZ256rri
:
161 case X86::VPCMPUBZrmi
: case X86::VPCMPUBZrri
:
162 case X86::VPCMPUBZ128rmik
: case X86::VPCMPUBZ128rrik
:
163 case X86::VPCMPUBZ256rmik
: case X86::VPCMPUBZ256rrik
:
164 case X86::VPCMPUBZrmik
: case X86::VPCMPUBZrrik
:
167 case X86::VPCMPUDZ128rmi
: case X86::VPCMPUDZ128rri
:
168 case X86::VPCMPUDZ256rmi
: case X86::VPCMPUDZ256rri
:
169 case X86::VPCMPUDZrmi
: case X86::VPCMPUDZrri
:
170 case X86::VPCMPUDZ128rmik
: case X86::VPCMPUDZ128rrik
:
171 case X86::VPCMPUDZ256rmik
: case X86::VPCMPUDZ256rrik
:
172 case X86::VPCMPUDZrmik
: case X86::VPCMPUDZrrik
:
173 case X86::VPCMPUDZ128rmib
: case X86::VPCMPUDZ128rmibk
:
174 case X86::VPCMPUDZ256rmib
: case X86::VPCMPUDZ256rmibk
:
175 case X86::VPCMPUDZrmib
: case X86::VPCMPUDZrmibk
:
178 case X86::VPCMPUQZ128rmi
: case X86::VPCMPUQZ128rri
:
179 case X86::VPCMPUQZ256rmi
: case X86::VPCMPUQZ256rri
:
180 case X86::VPCMPUQZrmi
: case X86::VPCMPUQZrri
:
181 case X86::VPCMPUQZ128rmik
: case X86::VPCMPUQZ128rrik
:
182 case X86::VPCMPUQZ256rmik
: case X86::VPCMPUQZ256rrik
:
183 case X86::VPCMPUQZrmik
: case X86::VPCMPUQZrrik
:
184 case X86::VPCMPUQZ128rmib
: case X86::VPCMPUQZ128rmibk
:
185 case X86::VPCMPUQZ256rmib
: case X86::VPCMPUQZ256rmibk
:
186 case X86::VPCMPUQZrmib
: case X86::VPCMPUQZrmibk
:
189 case X86::VPCMPUWZ128rmi
: case X86::VPCMPUWZ128rri
:
190 case X86::VPCMPUWZ256rri
: case X86::VPCMPUWZ256rmi
:
191 case X86::VPCMPUWZrmi
: case X86::VPCMPUWZrri
:
192 case X86::VPCMPUWZ128rmik
: case X86::VPCMPUWZ128rrik
:
193 case X86::VPCMPUWZ256rrik
: case X86::VPCMPUWZ256rmik
:
194 case X86::VPCMPUWZrmik
: case X86::VPCMPUWZrrik
:
197 case X86::VPCMPWZ128rmi
: case X86::VPCMPWZ128rri
:
198 case X86::VPCMPWZ256rmi
: case X86::VPCMPWZ256rri
:
199 case X86::VPCMPWZrmi
: case X86::VPCMPWZrri
:
200 case X86::VPCMPWZ128rmik
: case X86::VPCMPWZ128rrik
:
201 case X86::VPCMPWZ256rmik
: case X86::VPCMPWZ256rrik
:
202 case X86::VPCMPWZrmik
: case X86::VPCMPWZrrik
:
208 void X86InstPrinterCommon::printCMPMnemonic(const MCInst
*MI
, bool IsVCmp
,
210 OS
<< (IsVCmp
? "vcmp" : "cmp");
212 printSSEAVXCC(MI
, MI
->getNumOperands() - 1, OS
);
214 switch (MI
->getOpcode()) {
215 default: llvm_unreachable("Unexpected opcode!");
216 case X86::CMPPDrmi
: case X86::CMPPDrri
:
217 case X86::VCMPPDrmi
: case X86::VCMPPDrri
:
218 case X86::VCMPPDYrmi
: case X86::VCMPPDYrri
:
219 case X86::VCMPPDZ128rmi
: case X86::VCMPPDZ128rri
:
220 case X86::VCMPPDZ256rmi
: case X86::VCMPPDZ256rri
:
221 case X86::VCMPPDZrmi
: case X86::VCMPPDZrri
:
222 case X86::VCMPPDZ128rmik
: case X86::VCMPPDZ128rrik
:
223 case X86::VCMPPDZ256rmik
: case X86::VCMPPDZ256rrik
:
224 case X86::VCMPPDZrmik
: case X86::VCMPPDZrrik
:
225 case X86::VCMPPDZ128rmbi
: case X86::VCMPPDZ128rmbik
:
226 case X86::VCMPPDZ256rmbi
: case X86::VCMPPDZ256rmbik
:
227 case X86::VCMPPDZrmbi
: case X86::VCMPPDZrmbik
:
228 case X86::VCMPPDZrrib
: case X86::VCMPPDZrribk
:
231 case X86::CMPPSrmi
: case X86::CMPPSrri
:
232 case X86::VCMPPSrmi
: case X86::VCMPPSrri
:
233 case X86::VCMPPSYrmi
: case X86::VCMPPSYrri
:
234 case X86::VCMPPSZ128rmi
: case X86::VCMPPSZ128rri
:
235 case X86::VCMPPSZ256rmi
: case X86::VCMPPSZ256rri
:
236 case X86::VCMPPSZrmi
: case X86::VCMPPSZrri
:
237 case X86::VCMPPSZ128rmik
: case X86::VCMPPSZ128rrik
:
238 case X86::VCMPPSZ256rmik
: case X86::VCMPPSZ256rrik
:
239 case X86::VCMPPSZrmik
: case X86::VCMPPSZrrik
:
240 case X86::VCMPPSZ128rmbi
: case X86::VCMPPSZ128rmbik
:
241 case X86::VCMPPSZ256rmbi
: case X86::VCMPPSZ256rmbik
:
242 case X86::VCMPPSZrmbi
: case X86::VCMPPSZrmbik
:
243 case X86::VCMPPSZrrib
: case X86::VCMPPSZrribk
:
246 case X86::CMPSDrm
: case X86::CMPSDrr
:
247 case X86::CMPSDrm_Int
: case X86::CMPSDrr_Int
:
248 case X86::VCMPSDrm
: case X86::VCMPSDrr
:
249 case X86::VCMPSDrm_Int
: case X86::VCMPSDrr_Int
:
250 case X86::VCMPSDZrm
: case X86::VCMPSDZrr
:
251 case X86::VCMPSDZrm_Int
: case X86::VCMPSDZrr_Int
:
252 case X86::VCMPSDZrm_Intk
: case X86::VCMPSDZrr_Intk
:
253 case X86::VCMPSDZrrb_Int
: case X86::VCMPSDZrrb_Intk
:
256 case X86::CMPSSrm
: case X86::CMPSSrr
:
257 case X86::CMPSSrm_Int
: case X86::CMPSSrr_Int
:
258 case X86::VCMPSSrm
: case X86::VCMPSSrr
:
259 case X86::VCMPSSrm_Int
: case X86::VCMPSSrr_Int
:
260 case X86::VCMPSSZrm
: case X86::VCMPSSZrr
:
261 case X86::VCMPSSZrm_Int
: case X86::VCMPSSZrr_Int
:
262 case X86::VCMPSSZrm_Intk
: case X86::VCMPSSZrr_Intk
:
263 case X86::VCMPSSZrrb_Int
: case X86::VCMPSSZrrb_Intk
:
269 void X86InstPrinterCommon::printRoundingControl(const MCInst
*MI
, unsigned Op
,
271 int64_t Imm
= MI
->getOperand(Op
).getImm();
274 llvm_unreachable("Invalid rounding control!");
275 case X86::TO_NEAREST_INT
:
278 case X86::TO_NEG_INF
:
281 case X86::TO_POS_INF
:
290 /// printPCRelImm - This is used to print an immediate value that ends up
291 /// being encoded as a pc-relative value (e.g. for jumps and calls). In
292 /// Intel-style these print slightly differently than normal immediates.
293 /// for example, a $ is not emitted.
294 void X86InstPrinterCommon::printPCRelImm(const MCInst
*MI
, unsigned OpNo
,
296 const MCOperand
&Op
= MI
->getOperand(OpNo
);
298 O
<< formatImm(Op
.getImm());
300 assert(Op
.isExpr() && "unknown pcrel immediate operand");
301 // If a symbolic branch target was added as a constant expression then print
302 // that address in hex.
303 const MCConstantExpr
*BranchTarget
= dyn_cast
<MCConstantExpr
>(Op
.getExpr());
305 if (BranchTarget
&& BranchTarget
->evaluateAsAbsolute(Address
)) {
306 O
<< formatHex((uint64_t)Address
);
308 // Otherwise, just print the expression.
309 Op
.getExpr()->print(O
, &MAI
);
314 void X86InstPrinterCommon::printOptionalSegReg(const MCInst
*MI
, unsigned OpNo
,
316 if (MI
->getOperand(OpNo
).getReg()) {
317 printOperand(MI
, OpNo
, O
);
322 void X86InstPrinterCommon::printInstFlags(const MCInst
*MI
, raw_ostream
&O
) {
323 const MCInstrDesc
&Desc
= MII
.get(MI
->getOpcode());
324 uint64_t TSFlags
= Desc
.TSFlags
;
325 unsigned Flags
= MI
->getFlags();
327 if ((TSFlags
& X86II::LOCK
) || (Flags
& X86::IP_HAS_LOCK
))
330 if ((TSFlags
& X86II::NOTRACK
) || (Flags
& X86::IP_HAS_NOTRACK
))
333 if (Flags
& X86::IP_HAS_REPEAT_NE
)
335 else if (Flags
& X86::IP_HAS_REPEAT
)
339 void X86InstPrinterCommon::printVKPair(const MCInst
*MI
, unsigned OpNo
,
341 // In assembly listings, a pair is represented by one of its members, any
342 // of the two. Here, we pick k0, k2, k4, k6, but we could as well
343 // print K2_K3 as "k3". It would probably make a lot more sense, if
344 // the assembly would look something like:
345 // "vp2intersect %zmm5, %zmm7, {%k2, %k3}"
346 // but this can work too.
347 switch (MI
->getOperand(OpNo
).getReg()) {
349 printRegName(OS
, X86::K0
);
352 printRegName(OS
, X86::K2
);
355 printRegName(OS
, X86::K4
);
358 printRegName(OS
, X86::K6
);
361 llvm_unreachable("Unknown mask pair register name");