[InstCombine] Signed saturation patterns
[llvm-complete.git] / lib / Target / X86 / MCTargetDesc / X86InstPrinterCommon.cpp
bloba21555076976572319fe9324b7ad14dcfed1e128
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.
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"
22 #include <cstdint>
23 #include <cassert>
25 using namespace llvm;
27 void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op,
28 raw_ostream &O) {
29 int64_t Imm = MI->getOperand(Op).getImm();
30 switch (Imm) {
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,
52 raw_ostream &O) {
53 int64_t Imm = MI->getOperand(Op).getImm();
54 switch (Imm) {
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,
92 raw_ostream &OS) {
93 OS << "vpcom";
95 int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm();
96 switch (Imm) {
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,
122 raw_ostream &OS) {
123 OS << "vpcmp";
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:
135 OS << "b\t";
136 break;
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:
146 OS << "d\t";
147 break;
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:
157 OS << "q\t";
158 break;
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:
165 OS << "ub\t";
166 break;
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:
176 OS << "ud\t";
177 break;
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:
187 OS << "uq\t";
188 break;
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:
195 OS << "uw\t";
196 break;
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:
203 OS << "w\t";
204 break;
208 void X86InstPrinterCommon::printCMPMnemonic(const MCInst *MI, bool IsVCmp,
209 raw_ostream &OS) {
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:
229 OS << "pd\t";
230 break;
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:
244 OS << "ps\t";
245 break;
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:
254 OS << "sd\t";
255 break;
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:
264 OS << "ss\t";
265 break;
269 void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,
270 raw_ostream &O) {
271 int64_t Imm = MI->getOperand(Op).getImm();
272 switch (Imm) {
273 default:
274 llvm_unreachable("Invalid rounding control!");
275 case X86::TO_NEAREST_INT:
276 O << "{rn-sae}";
277 break;
278 case X86::TO_NEG_INF:
279 O << "{rd-sae}";
280 break;
281 case X86::TO_POS_INF:
282 O << "{ru-sae}";
283 break;
284 case X86::TO_ZERO:
285 O << "{rz-sae}";
286 break;
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 raw_ostream &O) {
296 const MCOperand &Op = MI->getOperand(OpNo);
297 if (Op.isImm())
298 O << formatImm(Op.getImm());
299 else {
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());
304 int64_t Address;
305 if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {
306 O << formatHex((uint64_t)Address);
307 } else {
308 // Otherwise, just print the expression.
309 Op.getExpr()->print(O, &MAI);
314 void X86InstPrinterCommon::printOptionalSegReg(const MCInst *MI, unsigned OpNo,
315 raw_ostream &O) {
316 if (MI->getOperand(OpNo).getReg()) {
317 printOperand(MI, OpNo, O);
318 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))
328 O << "\tlock\t";
330 if ((TSFlags & X86II::NOTRACK) || (Flags & X86::IP_HAS_NOTRACK))
331 O << "\tnotrack\t";
333 if (Flags & X86::IP_HAS_REPEAT_NE)
334 O << "\trepne\t";
335 else if (Flags & X86::IP_HAS_REPEAT)
336 O << "\trep\t";
339 void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,
340 raw_ostream &OS) {
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()) {
348 case X86::K0_K1:
349 printRegName(OS, X86::K0);
350 return;
351 case X86::K2_K3:
352 printRegName(OS, X86::K2);
353 return;
354 case X86::K4_K5:
355 printRegName(OS, X86::K4);
356 return;
357 case X86::K6_K7:
358 printRegName(OS, X86::K6);
359 return;
361 llvm_unreachable("Unknown mask pair register name");