/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/X86/InstPrinter/X86InstPrinterCommon.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- X86InstPrinterCommon.cpp - X86 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 common code for rendering MCInst instances as Intel-style |
10 | | // and Intel-style assembly. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "X86InstPrinterCommon.h" |
15 | | #include "MCTargetDesc/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" |
22 | | #include <cstdint> |
23 | | #include <cassert> |
24 | | |
25 | | using namespace llvm; |
26 | | |
27 | | void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op, |
28 | 38.3k | raw_ostream &O) { |
29 | 38.3k | int64_t Imm = MI->getOperand(Op).getImm(); |
30 | 38.3k | switch (Imm) { |
31 | 38.3k | default: 0 llvm_unreachable0 ("Invalid condcode argument!"); |
32 | 38.3k | case 0: O << "o"; break618 ; |
33 | 38.3k | case 1: O << "no"; break251 ; |
34 | 38.3k | case 2: O << "b"; break2.22k ; |
35 | 38.3k | case 3: O << "ae"; break1.62k ; |
36 | 38.3k | case 4: O << "e"; break16.1k ; |
37 | 38.3k | case 5: O << "ne"; break9.09k ; |
38 | 38.3k | case 6: O << "be"; break1.02k ; |
39 | 38.3k | case 7: O << "a"; break1.46k ; |
40 | 38.3k | case 8: O << "s"; break670 ; |
41 | 38.3k | case 9: O << "ns"; break923 ; |
42 | 38.3k | case 0xa: O << "p"; break391 ; |
43 | 38.3k | case 0xb: O << "np"; break559 ; |
44 | 38.3k | case 0xc: O << "l"; break934 ; |
45 | 38.3k | case 0xd: O << "ge"; break689 ; |
46 | 38.3k | case 0xe: O << "le"; break890 ; |
47 | 38.3k | case 0xf: O << "g"; break832 ; |
48 | 38.3k | } |
49 | 38.3k | } |
50 | | |
51 | | void X86InstPrinterCommon::printSSEAVXCC(const MCInst *MI, unsigned Op, |
52 | 6.86k | raw_ostream &O) { |
53 | 6.86k | int64_t Imm = MI->getOperand(Op).getImm(); |
54 | 6.86k | switch (Imm) { |
55 | 6.86k | default: 0 llvm_unreachable0 ("Invalid ssecc/avxcc argument!"); |
56 | 6.86k | case 0: O << "eq"; break2.53k ; |
57 | 6.86k | case 1: O << "lt"; break1.44k ; |
58 | 6.86k | case 2: O << "le"; break497 ; |
59 | 6.86k | case 3: O << "unord"; break205 ; |
60 | 6.86k | case 4: O << "neq"; break382 ; |
61 | 6.86k | case 5: O << "nlt"; break730 ; |
62 | 6.86k | case 6: O << "nle"; break377 ; |
63 | 6.86k | case 7: O << "ord"; break143 ; |
64 | 6.86k | case 8: O << "eq_uq"; break40 ; |
65 | 6.86k | case 9: O << "nge"; break26 ; |
66 | 6.86k | case 0xa: O << "ngt"; break16 ; |
67 | 6.86k | case 0xb: O << "false"; break20 ; |
68 | 6.86k | case 0xc: O << "neq_oq"; break42 ; |
69 | 6.86k | case 0xd: O << "ge"; break37 ; |
70 | 6.86k | case 0xe: O << "gt"; break21 ; |
71 | 6.86k | case 0xf: O << "true"; break80 ; |
72 | 6.86k | case 0x10: O << "eq_os"; break16 ; |
73 | 6.86k | case 0x11: O << "lt_oq"; break22 ; |
74 | 6.86k | case 0x12: O << "le_oq"; break16 ; |
75 | 6.86k | case 0x13: O << "unord_s"; break16 ; |
76 | 6.86k | case 0x14: O << "neq_us"; break16 ; |
77 | 6.86k | case 0x15: O << "nlt_uq"; break16 ; |
78 | 6.86k | case 0x16: O << "nle_uq"; break16 ; |
79 | 6.86k | case 0x17: O << "ord_s"; break16 ; |
80 | 6.86k | case 0x18: O << "eq_us"; break16 ; |
81 | 6.86k | case 0x19: O << "nge_uq"; break16 ; |
82 | 6.86k | case 0x1a: O << "ngt_uq"; break16 ; |
83 | 6.86k | case 0x1b: O << "false_os"; break16 ; |
84 | 6.86k | case 0x1c: O << "neq_os"; break16 ; |
85 | 6.86k | case 0x1d: O << "ge_oq"; break16 ; |
86 | 6.86k | case 0x1e: O << "gt_oq"; break16 ; |
87 | 6.86k | case 0x1f: O << "true_us"; break22 ; |
88 | 6.86k | } |
89 | 6.86k | } |
90 | | |
91 | | void X86InstPrinterCommon::printVPCOMMnemonic(const MCInst *MI, |
92 | 664 | raw_ostream &OS) { |
93 | 664 | OS << "vpcom"; |
94 | 664 | |
95 | 664 | int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm(); |
96 | 664 | switch (Imm) { |
97 | 664 | default: 0 llvm_unreachable0 ("Invalid vpcom argument!"); |
98 | 664 | case 0: OS << "lt"; break327 ; |
99 | 664 | case 1: OS << "le"; break28 ; |
100 | 664 | case 2: OS << "gt"; break148 ; |
101 | 664 | case 3: OS << "ge"; break28 ; |
102 | 664 | case 4: OS << "eq"; break99 ; |
103 | 664 | case 5: OS << "neq"; break30 ; |
104 | 664 | case 6: OS << "false"; break2 ; |
105 | 664 | case 7: OS << "true"; break2 ; |
106 | 664 | } |
107 | 664 | |
108 | 664 | switch (MI->getOpcode()) { |
109 | 664 | default: 0 llvm_unreachable0 ("Unexpected opcode!"); |
110 | 664 | case X86::VPCOMBmi: 106 case X86::VPCOMBri: OS << "b\t"; break106 ; |
111 | 106 | case X86::VPCOMDmi: 95 case X86::VPCOMDri: OS << "d\t"; break95 ; |
112 | 133 | case X86::VPCOMQmi: case X86::VPCOMQri: OS << "q\t"; break; |
113 | 133 | case X86::VPCOMUBmi: 54 case X86::VPCOMUBri: OS << "ub\t"; break54 ; |
114 | 54 | case X86::VPCOMUDmi: 48 case X86::VPCOMUDri: OS << "ud\t"; break48 ; |
115 | 59 | case X86::VPCOMUQmi: case X86::VPCOMUQri: OS << "uq\t"; break; |
116 | 60 | case X86::VPCOMUWmi: case X86::VPCOMUWri: OS << "uw\t"; break; |
117 | 109 | case X86::VPCOMWmi: case X86::VPCOMWri: OS << "w\t"; break; |
118 | 664 | } |
119 | 664 | } |
120 | | |
121 | | void X86InstPrinterCommon::printVPCMPMnemonic(const MCInst *MI, |
122 | 1.96k | raw_ostream &OS) { |
123 | 1.96k | OS << "vpcmp"; |
124 | 1.96k | |
125 | 1.96k | printSSEAVXCC(MI, MI->getNumOperands() - 1, OS); |
126 | 1.96k | |
127 | 1.96k | switch (MI->getOpcode()) { |
128 | 1.96k | default: 0 llvm_unreachable0 ("Unexpected opcode!"); |
129 | 1.96k | case X86::VPCMPBZ128rmi: 116 case X86::VPCMPBZ128rri: |
130 | 116 | case X86::VPCMPBZ256rmi: case X86::VPCMPBZ256rri: |
131 | 116 | case X86::VPCMPBZrmi: case X86::VPCMPBZrri: |
132 | 116 | case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik: |
133 | 116 | case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik: |
134 | 116 | case X86::VPCMPBZrmik: case X86::VPCMPBZrrik: |
135 | 116 | OS << "b\t"; |
136 | 116 | break; |
137 | 367 | case X86::VPCMPDZ128rmi: case X86::VPCMPDZ128rri: |
138 | 367 | case X86::VPCMPDZ256rmi: case X86::VPCMPDZ256rri: |
139 | 367 | case X86::VPCMPDZrmi: case X86::VPCMPDZrri: |
140 | 367 | case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik: |
141 | 367 | case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik: |
142 | 367 | case X86::VPCMPDZrmik: case X86::VPCMPDZrrik: |
143 | 367 | case X86::VPCMPDZ128rmib: case X86::VPCMPDZ128rmibk: |
144 | 367 | case X86::VPCMPDZ256rmib: case X86::VPCMPDZ256rmibk: |
145 | 367 | case X86::VPCMPDZrmib: case X86::VPCMPDZrmibk: |
146 | 367 | OS << "d\t"; |
147 | 367 | break; |
148 | 367 | case X86::VPCMPQZ128rmi: 324 case X86::VPCMPQZ128rri: |
149 | 324 | case X86::VPCMPQZ256rmi: case X86::VPCMPQZ256rri: |
150 | 324 | case X86::VPCMPQZrmi: case X86::VPCMPQZrri: |
151 | 324 | case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik: |
152 | 324 | case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik: |
153 | 324 | case X86::VPCMPQZrmik: case X86::VPCMPQZrrik: |
154 | 324 | case X86::VPCMPQZ128rmib: case X86::VPCMPQZ128rmibk: |
155 | 324 | case X86::VPCMPQZ256rmib: case X86::VPCMPQZ256rmibk: |
156 | 324 | case X86::VPCMPQZrmib: case X86::VPCMPQZrmibk: |
157 | 324 | OS << "q\t"; |
158 | 324 | break; |
159 | 324 | case X86::VPCMPUBZ128rmi: 138 case X86::VPCMPUBZ128rri: |
160 | 138 | case X86::VPCMPUBZ256rmi: case X86::VPCMPUBZ256rri: |
161 | 138 | case X86::VPCMPUBZrmi: case X86::VPCMPUBZrri: |
162 | 138 | case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik: |
163 | 138 | case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik: |
164 | 138 | case X86::VPCMPUBZrmik: case X86::VPCMPUBZrrik: |
165 | 138 | OS << "ub\t"; |
166 | 138 | break; |
167 | 383 | case X86::VPCMPUDZ128rmi: case X86::VPCMPUDZ128rri: |
168 | 383 | case X86::VPCMPUDZ256rmi: case X86::VPCMPUDZ256rri: |
169 | 383 | case X86::VPCMPUDZrmi: case X86::VPCMPUDZrri: |
170 | 383 | case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik: |
171 | 383 | case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik: |
172 | 383 | case X86::VPCMPUDZrmik: case X86::VPCMPUDZrrik: |
173 | 383 | case X86::VPCMPUDZ128rmib: case X86::VPCMPUDZ128rmibk: |
174 | 383 | case X86::VPCMPUDZ256rmib: case X86::VPCMPUDZ256rmibk: |
175 | 383 | case X86::VPCMPUDZrmib: case X86::VPCMPUDZrmibk: |
176 | 383 | OS << "ud\t"; |
177 | 383 | break; |
178 | 383 | case X86::VPCMPUQZ128rmi: 366 case X86::VPCMPUQZ128rri: |
179 | 366 | case X86::VPCMPUQZ256rmi: case X86::VPCMPUQZ256rri: |
180 | 366 | case X86::VPCMPUQZrmi: case X86::VPCMPUQZrri: |
181 | 366 | case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik: |
182 | 366 | case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik: |
183 | 366 | case X86::VPCMPUQZrmik: case X86::VPCMPUQZrrik: |
184 | 366 | case X86::VPCMPUQZ128rmib: case X86::VPCMPUQZ128rmibk: |
185 | 366 | case X86::VPCMPUQZ256rmib: case X86::VPCMPUQZ256rmibk: |
186 | 366 | case X86::VPCMPUQZrmib: case X86::VPCMPUQZrmibk: |
187 | 366 | OS << "uq\t"; |
188 | 366 | break; |
189 | 366 | case X86::VPCMPUWZ128rmi: 138 case X86::VPCMPUWZ128rri: |
190 | 138 | case X86::VPCMPUWZ256rri: case X86::VPCMPUWZ256rmi: |
191 | 138 | case X86::VPCMPUWZrmi: case X86::VPCMPUWZrri: |
192 | 138 | case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik: |
193 | 138 | case X86::VPCMPUWZ256rrik: case X86::VPCMPUWZ256rmik: |
194 | 138 | case X86::VPCMPUWZrmik: case X86::VPCMPUWZrrik: |
195 | 138 | OS << "uw\t"; |
196 | 138 | break; |
197 | 138 | case X86::VPCMPWZ128rmi: 130 case X86::VPCMPWZ128rri: |
198 | 130 | case X86::VPCMPWZ256rmi: case X86::VPCMPWZ256rri: |
199 | 130 | case X86::VPCMPWZrmi: case X86::VPCMPWZrri: |
200 | 130 | case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik: |
201 | 130 | case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik: |
202 | 130 | case X86::VPCMPWZrmik: case X86::VPCMPWZrrik: |
203 | 130 | OS << "w\t"; |
204 | 130 | break; |
205 | 1.96k | } |
206 | 1.96k | } |
207 | | |
208 | | void X86InstPrinterCommon::printCMPMnemonic(const MCInst *MI, bool IsVCmp, |
209 | 4.90k | raw_ostream &OS) { |
210 | 4.90k | OS << (IsVCmp ? "vcmp"3.85k : "cmp"1.04k ); |
211 | 4.90k | |
212 | 4.90k | printSSEAVXCC(MI, MI->getNumOperands() - 1, OS); |
213 | 4.90k | |
214 | 4.90k | switch (MI->getOpcode()) { |
215 | 4.90k | default: 0 llvm_unreachable0 ("Unexpected opcode!"); |
216 | 4.90k | case X86::CMPPDrmi: 1.67k case X86::CMPPDrri: |
217 | 1.67k | case X86::VCMPPDrmi: case X86::VCMPPDrri: |
218 | 1.67k | case X86::VCMPPDYrmi: case X86::VCMPPDYrri: |
219 | 1.67k | case X86::VCMPPDZ128rmi: case X86::VCMPPDZ128rri: |
220 | 1.67k | case X86::VCMPPDZ256rmi: case X86::VCMPPDZ256rri: |
221 | 1.67k | case X86::VCMPPDZrmi: case X86::VCMPPDZrri: |
222 | 1.67k | case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik: |
223 | 1.67k | case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik: |
224 | 1.67k | case X86::VCMPPDZrmik: case X86::VCMPPDZrrik: |
225 | 1.67k | case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik: |
226 | 1.67k | case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik: |
227 | 1.67k | case X86::VCMPPDZrmbi: case X86::VCMPPDZrmbik: |
228 | 1.67k | case X86::VCMPPDZrrib: case X86::VCMPPDZrribk: |
229 | 1.67k | OS << "pd\t"; |
230 | 1.67k | break; |
231 | 2.09k | case X86::CMPPSrmi: case X86::CMPPSrri: |
232 | 2.09k | case X86::VCMPPSrmi: case X86::VCMPPSrri: |
233 | 2.09k | case X86::VCMPPSYrmi: case X86::VCMPPSYrri: |
234 | 2.09k | case X86::VCMPPSZ128rmi: case X86::VCMPPSZ128rri: |
235 | 2.09k | case X86::VCMPPSZ256rmi: case X86::VCMPPSZ256rri: |
236 | 2.09k | case X86::VCMPPSZrmi: case X86::VCMPPSZrri: |
237 | 2.09k | case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik: |
238 | 2.09k | case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik: |
239 | 2.09k | case X86::VCMPPSZrmik: case X86::VCMPPSZrrik: |
240 | 2.09k | case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik: |
241 | 2.09k | case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik: |
242 | 2.09k | case X86::VCMPPSZrmbi: case X86::VCMPPSZrmbik: |
243 | 2.09k | case X86::VCMPPSZrrib: case X86::VCMPPSZrribk: |
244 | 2.09k | OS << "ps\t"; |
245 | 2.09k | break; |
246 | 2.09k | case X86::CMPSDrm: 536 case X86::CMPSDrr: |
247 | 536 | case X86::CMPSDrm_Int: case X86::CMPSDrr_Int: |
248 | 536 | case X86::VCMPSDrm: case X86::VCMPSDrr: |
249 | 536 | case X86::VCMPSDrm_Int: case X86::VCMPSDrr_Int: |
250 | 536 | case X86::VCMPSDZrm: case X86::VCMPSDZrr: |
251 | 536 | case X86::VCMPSDZrm_Int: case X86::VCMPSDZrr_Int: |
252 | 536 | case X86::VCMPSDZrm_Intk: case X86::VCMPSDZrr_Intk: |
253 | 536 | case X86::VCMPSDZrrb_Int: case X86::VCMPSDZrrb_Intk: |
254 | 536 | OS << "sd\t"; |
255 | 536 | break; |
256 | 595 | case X86::CMPSSrm: case X86::CMPSSrr: |
257 | 595 | case X86::CMPSSrm_Int: case X86::CMPSSrr_Int: |
258 | 595 | case X86::VCMPSSrm: case X86::VCMPSSrr: |
259 | 595 | case X86::VCMPSSrm_Int: case X86::VCMPSSrr_Int: |
260 | 595 | case X86::VCMPSSZrm: case X86::VCMPSSZrr: |
261 | 595 | case X86::VCMPSSZrm_Int: case X86::VCMPSSZrr_Int: |
262 | 595 | case X86::VCMPSSZrm_Intk: case X86::VCMPSSZrr_Intk: |
263 | 595 | case X86::VCMPSSZrrb_Int: case X86::VCMPSSZrrb_Intk: |
264 | 595 | OS << "ss\t"; |
265 | 595 | break; |
266 | 4.90k | } |
267 | 4.90k | } |
268 | | |
269 | | void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op, |
270 | 5.14k | raw_ostream &O) { |
271 | 5.14k | int64_t Imm = MI->getOperand(Op).getImm(); |
272 | 5.14k | switch (Imm) { |
273 | 5.14k | default: |
274 | 0 | llvm_unreachable("Invalid rounding control!"); |
275 | 5.14k | case X86::TO_NEAREST_INT: |
276 | 1.49k | O << "{rn-sae}"; |
277 | 1.49k | break; |
278 | 5.14k | case X86::TO_NEG_INF: |
279 | 1.18k | O << "{rd-sae}"; |
280 | 1.18k | break; |
281 | 5.14k | case X86::TO_POS_INF: |
282 | 1.19k | O << "{ru-sae}"; |
283 | 1.19k | break; |
284 | 5.14k | case X86::TO_ZERO: |
285 | 1.26k | O << "{rz-sae}"; |
286 | 1.26k | break; |
287 | 5.14k | } |
288 | 5.14k | } |
289 | | |
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, |
295 | 55.0k | raw_ostream &O) { |
296 | 55.0k | const MCOperand &Op = MI->getOperand(OpNo); |
297 | 55.0k | if (Op.isImm()) |
298 | 28.7k | O << formatImm(Op.getImm()); |
299 | 26.2k | else { |
300 | 26.2k | assert(Op.isExpr() && "unknown pcrel immediate operand"); |
301 | 26.2k | // If a symbolic branch target was added as a constant expression then print |
302 | 26.2k | // that address in hex. |
303 | 26.2k | const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr()); |
304 | 26.2k | int64_t Address; |
305 | 26.2k | if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)104 ) { |
306 | 104 | O << formatHex((uint64_t)Address); |
307 | 26.1k | } else { |
308 | 26.1k | // Otherwise, just print the expression. |
309 | 26.1k | Op.getExpr()->print(O, &MAI); |
310 | 26.1k | } |
311 | 26.2k | } |
312 | 55.0k | } |
313 | | |
314 | | void X86InstPrinterCommon::printOptionalSegReg(const MCInst *MI, unsigned OpNo, |
315 | 332k | raw_ostream &O) { |
316 | 332k | if (MI->getOperand(OpNo).getReg()) { |
317 | 1.82k | printOperand(MI, OpNo, O); |
318 | 1.82k | O << ':'; |
319 | 1.82k | } |
320 | 332k | } |
321 | | |
322 | 1.12M | void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O) { |
323 | 1.12M | const MCInstrDesc &Desc = MII.get(MI->getOpcode()); |
324 | 1.12M | uint64_t TSFlags = Desc.TSFlags; |
325 | 1.12M | unsigned Flags = MI->getFlags(); |
326 | 1.12M | |
327 | 1.12M | if ((TSFlags & X86II::LOCK) || (Flags & X86::IP_HAS_LOCK)1.12M ) |
328 | 887 | O << "\tlock\t"; |
329 | 1.12M | |
330 | 1.12M | if ((TSFlags & X86II::NOTRACK) || (Flags & X86::IP_HAS_NOTRACK)1.12M ) |
331 | 10 | O << "\tnotrack\t"; |
332 | 1.12M | |
333 | 1.12M | if (Flags & X86::IP_HAS_REPEAT_NE) |
334 | 99 | O << "\trepne\t"; |
335 | 1.12M | else if (Flags & X86::IP_HAS_REPEAT) |
336 | 128 | O << "\trep\t"; |
337 | 1.12M | } |