xref: /llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp (revision ee2722fc882ed5dbc7609686bd998b023c6645b2)
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 "X86BaseInfo.h"
16 #include "llvm/MC/MCAsmInfo.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/raw_ostream.h"
24 #include <cassert>
25 #include <cstdint>
26 
27 using namespace llvm;
28 
29 void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op,
30                                          raw_ostream &O) {
31   int64_t Imm = MI->getOperand(Op).getImm();
32   unsigned Opc = MI->getOpcode();
33   bool IsCCMPOrCTEST = X86::isCCMPCC(Opc) || X86::isCTESTCC(Opc);
34 
35   // clang-format off
36   switch (Imm) {
37   default: llvm_unreachable("Invalid condcode argument!");
38   case    0: O << "o";  break;
39   case    1: O << "no"; break;
40   case    2: O << "b";  break;
41   case    3: O << "ae"; break;
42   case    4: O << "e";  break;
43   case    5: O << "ne"; break;
44   case    6: O << "be"; break;
45   case    7: O << "a";  break;
46   case    8: O << "s";  break;
47   case    9: O << "ns"; break;
48   case  0xa: O << (IsCCMPOrCTEST ? "t" : "p");  break;
49   case  0xb: O << (IsCCMPOrCTEST ? "f" : "np"); break;
50   case  0xc: O << "l";  break;
51   case  0xd: O << "ge"; break;
52   case  0xe: O << "le"; break;
53   case  0xf: O << "g";  break;
54   }
55   // clang-format on
56 }
57 
58 void X86InstPrinterCommon::printCondFlags(const MCInst *MI, unsigned Op,
59                                           raw_ostream &O) {
60   // +----+----+----+----+
61   // | OF | SF | ZF | CF |
62   // +----+----+----+----+
63   int64_t Imm = MI->getOperand(Op).getImm();
64   assert(Imm >= 0 && Imm < 16 && "Invalid condition flags");
65   O << "{dfv=";
66   std::string Flags;
67   if (Imm & 0x8)
68     Flags += "of,";
69   if (Imm & 0x4)
70     Flags += "sf,";
71   if (Imm & 0x2)
72     Flags += "zf,";
73   if (Imm & 0x1)
74     Flags += "cf,";
75   StringRef SimplifiedFlags = StringRef(Flags).rtrim(",");
76   O << SimplifiedFlags << "}";
77 }
78 
79 void X86InstPrinterCommon::printSSEAVXCC(const MCInst *MI, unsigned Op,
80                                          raw_ostream &O) {
81   int64_t Imm = MI->getOperand(Op).getImm();
82   switch (Imm) {
83   default: llvm_unreachable("Invalid ssecc/avxcc argument!");
84   case    0: O << "eq"; break;
85   case    1: O << "lt"; break;
86   case    2: O << "le"; break;
87   case    3: O << "unord"; break;
88   case    4: O << "neq"; break;
89   case    5: O << "nlt"; break;
90   case    6: O << "nle"; break;
91   case    7: O << "ord"; break;
92   case    8: O << "eq_uq"; break;
93   case    9: O << "nge"; break;
94   case  0xa: O << "ngt"; break;
95   case  0xb: O << "false"; break;
96   case  0xc: O << "neq_oq"; break;
97   case  0xd: O << "ge"; break;
98   case  0xe: O << "gt"; break;
99   case  0xf: O << "true"; break;
100   case 0x10: O << "eq_os"; break;
101   case 0x11: O << "lt_oq"; break;
102   case 0x12: O << "le_oq"; break;
103   case 0x13: O << "unord_s"; break;
104   case 0x14: O << "neq_us"; break;
105   case 0x15: O << "nlt_uq"; break;
106   case 0x16: O << "nle_uq"; break;
107   case 0x17: O << "ord_s"; break;
108   case 0x18: O << "eq_us"; break;
109   case 0x19: O << "nge_uq"; break;
110   case 0x1a: O << "ngt_uq"; break;
111   case 0x1b: O << "false_os"; break;
112   case 0x1c: O << "neq_os"; break;
113   case 0x1d: O << "ge_oq"; break;
114   case 0x1e: O << "gt_oq"; break;
115   case 0x1f: O << "true_us"; break;
116   }
117 }
118 
119 void X86InstPrinterCommon::printVPCOMMnemonic(const MCInst *MI,
120                                               raw_ostream &OS) {
121   OS << "vpcom";
122 
123   int64_t Imm = MI->getOperand(MI->getNumOperands() - 1).getImm();
124   switch (Imm) {
125   default: llvm_unreachable("Invalid vpcom argument!");
126   case 0: OS << "lt"; break;
127   case 1: OS << "le"; break;
128   case 2: OS << "gt"; break;
129   case 3: OS << "ge"; break;
130   case 4: OS << "eq"; break;
131   case 5: OS << "neq"; break;
132   case 6: OS << "false"; break;
133   case 7: OS << "true"; break;
134   }
135 
136   switch (MI->getOpcode()) {
137   default: llvm_unreachable("Unexpected opcode!");
138   case X86::VPCOMBmi:  case X86::VPCOMBri:  OS << "b\t";  break;
139   case X86::VPCOMDmi:  case X86::VPCOMDri:  OS << "d\t";  break;
140   case X86::VPCOMQmi:  case X86::VPCOMQri:  OS << "q\t";  break;
141   case X86::VPCOMUBmi: case X86::VPCOMUBri: OS << "ub\t"; break;
142   case X86::VPCOMUDmi: case X86::VPCOMUDri: OS << "ud\t"; break;
143   case X86::VPCOMUQmi: case X86::VPCOMUQri: OS << "uq\t"; break;
144   case X86::VPCOMUWmi: case X86::VPCOMUWri: OS << "uw\t"; break;
145   case X86::VPCOMWmi:  case X86::VPCOMWri:  OS << "w\t";  break;
146   }
147 }
148 
149 void X86InstPrinterCommon::printVPCMPMnemonic(const MCInst *MI,
150                                               raw_ostream &OS) {
151   OS << "vpcmp";
152 
153   printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);
154 
155   switch (MI->getOpcode()) {
156   default: llvm_unreachable("Unexpected opcode!");
157   case X86::VPCMPBZ128rmi:  case X86::VPCMPBZ128rri:
158   case X86::VPCMPBZ256rmi:  case X86::VPCMPBZ256rri:
159   case X86::VPCMPBZrmi:     case X86::VPCMPBZrri:
160   case X86::VPCMPBZ128rmik: case X86::VPCMPBZ128rrik:
161   case X86::VPCMPBZ256rmik: case X86::VPCMPBZ256rrik:
162   case X86::VPCMPBZrmik:    case X86::VPCMPBZrrik:
163     OS << "b\t";
164     break;
165   case X86::VPCMPDZ128rmi:  case X86::VPCMPDZ128rri:
166   case X86::VPCMPDZ256rmi:  case X86::VPCMPDZ256rri:
167   case X86::VPCMPDZrmi:     case X86::VPCMPDZrri:
168   case X86::VPCMPDZ128rmik: case X86::VPCMPDZ128rrik:
169   case X86::VPCMPDZ256rmik: case X86::VPCMPDZ256rrik:
170   case X86::VPCMPDZrmik:    case X86::VPCMPDZrrik:
171   case X86::VPCMPDZ128rmbi: case X86::VPCMPDZ128rmbik:
172   case X86::VPCMPDZ256rmbi: case X86::VPCMPDZ256rmbik:
173   case X86::VPCMPDZrmbi:    case X86::VPCMPDZrmbik:
174     OS << "d\t";
175     break;
176   case X86::VPCMPQZ128rmi:  case X86::VPCMPQZ128rri:
177   case X86::VPCMPQZ256rmi:  case X86::VPCMPQZ256rri:
178   case X86::VPCMPQZrmi:     case X86::VPCMPQZrri:
179   case X86::VPCMPQZ128rmik: case X86::VPCMPQZ128rrik:
180   case X86::VPCMPQZ256rmik: case X86::VPCMPQZ256rrik:
181   case X86::VPCMPQZrmik:    case X86::VPCMPQZrrik:
182   case X86::VPCMPQZ128rmbi: case X86::VPCMPQZ128rmbik:
183   case X86::VPCMPQZ256rmbi: case X86::VPCMPQZ256rmbik:
184   case X86::VPCMPQZrmbi:    case X86::VPCMPQZrmbik:
185     OS << "q\t";
186     break;
187   case X86::VPCMPUBZ128rmi:  case X86::VPCMPUBZ128rri:
188   case X86::VPCMPUBZ256rmi:  case X86::VPCMPUBZ256rri:
189   case X86::VPCMPUBZrmi:     case X86::VPCMPUBZrri:
190   case X86::VPCMPUBZ128rmik: case X86::VPCMPUBZ128rrik:
191   case X86::VPCMPUBZ256rmik: case X86::VPCMPUBZ256rrik:
192   case X86::VPCMPUBZrmik:    case X86::VPCMPUBZrrik:
193     OS << "ub\t";
194     break;
195   case X86::VPCMPUDZ128rmi:  case X86::VPCMPUDZ128rri:
196   case X86::VPCMPUDZ256rmi:  case X86::VPCMPUDZ256rri:
197   case X86::VPCMPUDZrmi:     case X86::VPCMPUDZrri:
198   case X86::VPCMPUDZ128rmik: case X86::VPCMPUDZ128rrik:
199   case X86::VPCMPUDZ256rmik: case X86::VPCMPUDZ256rrik:
200   case X86::VPCMPUDZrmik:    case X86::VPCMPUDZrrik:
201   case X86::VPCMPUDZ128rmbi: case X86::VPCMPUDZ128rmbik:
202   case X86::VPCMPUDZ256rmbi: case X86::VPCMPUDZ256rmbik:
203   case X86::VPCMPUDZrmbi:    case X86::VPCMPUDZrmbik:
204     OS << "ud\t";
205     break;
206   case X86::VPCMPUQZ128rmi:  case X86::VPCMPUQZ128rri:
207   case X86::VPCMPUQZ256rmi:  case X86::VPCMPUQZ256rri:
208   case X86::VPCMPUQZrmi:     case X86::VPCMPUQZrri:
209   case X86::VPCMPUQZ128rmik: case X86::VPCMPUQZ128rrik:
210   case X86::VPCMPUQZ256rmik: case X86::VPCMPUQZ256rrik:
211   case X86::VPCMPUQZrmik:    case X86::VPCMPUQZrrik:
212   case X86::VPCMPUQZ128rmbi: case X86::VPCMPUQZ128rmbik:
213   case X86::VPCMPUQZ256rmbi: case X86::VPCMPUQZ256rmbik:
214   case X86::VPCMPUQZrmbi:    case X86::VPCMPUQZrmbik:
215     OS << "uq\t";
216     break;
217   case X86::VPCMPUWZ128rmi:  case X86::VPCMPUWZ128rri:
218   case X86::VPCMPUWZ256rri:  case X86::VPCMPUWZ256rmi:
219   case X86::VPCMPUWZrmi:     case X86::VPCMPUWZrri:
220   case X86::VPCMPUWZ128rmik: case X86::VPCMPUWZ128rrik:
221   case X86::VPCMPUWZ256rrik: case X86::VPCMPUWZ256rmik:
222   case X86::VPCMPUWZrmik:    case X86::VPCMPUWZrrik:
223     OS << "uw\t";
224     break;
225   case X86::VPCMPWZ128rmi:  case X86::VPCMPWZ128rri:
226   case X86::VPCMPWZ256rmi:  case X86::VPCMPWZ256rri:
227   case X86::VPCMPWZrmi:     case X86::VPCMPWZrri:
228   case X86::VPCMPWZ128rmik: case X86::VPCMPWZ128rrik:
229   case X86::VPCMPWZ256rmik: case X86::VPCMPWZ256rrik:
230   case X86::VPCMPWZrmik:    case X86::VPCMPWZrrik:
231     OS << "w\t";
232     break;
233   }
234 }
235 
236 void X86InstPrinterCommon::printCMPMnemonic(const MCInst *MI, bool IsVCmp,
237                                             raw_ostream &OS) {
238   OS << (IsVCmp ? "vcmp" : "cmp");
239 
240   printSSEAVXCC(MI, MI->getNumOperands() - 1, OS);
241 
242   switch (MI->getOpcode()) {
243   default: llvm_unreachable("Unexpected opcode!");
244   case X86::CMPPDrmi:       case X86::CMPPDrri:
245   case X86::VCMPPDrmi:      case X86::VCMPPDrri:
246   case X86::VCMPPDYrmi:     case X86::VCMPPDYrri:
247   case X86::VCMPPDZ128rmi:  case X86::VCMPPDZ128rri:
248   case X86::VCMPPDZ256rmi:  case X86::VCMPPDZ256rri:
249   case X86::VCMPPDZrmi:     case X86::VCMPPDZrri:
250   case X86::VCMPPDZ128rmik: case X86::VCMPPDZ128rrik:
251   case X86::VCMPPDZ256rmik: case X86::VCMPPDZ256rrik:
252   case X86::VCMPPDZrmik:    case X86::VCMPPDZrrik:
253   case X86::VCMPPDZ128rmbi: case X86::VCMPPDZ128rmbik:
254   case X86::VCMPPDZ256rmbi: case X86::VCMPPDZ256rmbik:
255   case X86::VCMPPDZrmbi:    case X86::VCMPPDZrmbik:
256   case X86::VCMPPDZrrib:    case X86::VCMPPDZrribk:
257     OS << "pd\t";
258     break;
259   case X86::CMPPSrmi:       case X86::CMPPSrri:
260   case X86::VCMPPSrmi:      case X86::VCMPPSrri:
261   case X86::VCMPPSYrmi:     case X86::VCMPPSYrri:
262   case X86::VCMPPSZ128rmi:  case X86::VCMPPSZ128rri:
263   case X86::VCMPPSZ256rmi:  case X86::VCMPPSZ256rri:
264   case X86::VCMPPSZrmi:     case X86::VCMPPSZrri:
265   case X86::VCMPPSZ128rmik: case X86::VCMPPSZ128rrik:
266   case X86::VCMPPSZ256rmik: case X86::VCMPPSZ256rrik:
267   case X86::VCMPPSZrmik:    case X86::VCMPPSZrrik:
268   case X86::VCMPPSZ128rmbi: case X86::VCMPPSZ128rmbik:
269   case X86::VCMPPSZ256rmbi: case X86::VCMPPSZ256rmbik:
270   case X86::VCMPPSZrmbi:    case X86::VCMPPSZrmbik:
271   case X86::VCMPPSZrrib:    case X86::VCMPPSZrribk:
272     OS << "ps\t";
273     break;
274   case X86::CMPSDrmi:        case X86::CMPSDrri:
275   case X86::CMPSDrmi_Int:    case X86::CMPSDrri_Int:
276   case X86::VCMPSDrmi:       case X86::VCMPSDrri:
277   case X86::VCMPSDrmi_Int:   case X86::VCMPSDrri_Int:
278   case X86::VCMPSDZrmi:      case X86::VCMPSDZrri:
279   case X86::VCMPSDZrmi_Int:  case X86::VCMPSDZrri_Int:
280   case X86::VCMPSDZrmik_Int: case X86::VCMPSDZrrik_Int:
281   case X86::VCMPSDZrrib_Int: case X86::VCMPSDZrribk_Int:
282     OS << "sd\t";
283     break;
284   case X86::CMPSSrmi:        case X86::CMPSSrri:
285   case X86::CMPSSrmi_Int:    case X86::CMPSSrri_Int:
286   case X86::VCMPSSrmi:       case X86::VCMPSSrri:
287   case X86::VCMPSSrmi_Int:   case X86::VCMPSSrri_Int:
288   case X86::VCMPSSZrmi:      case X86::VCMPSSZrri:
289   case X86::VCMPSSZrmi_Int:  case X86::VCMPSSZrri_Int:
290   case X86::VCMPSSZrmik_Int: case X86::VCMPSSZrrik_Int:
291   case X86::VCMPSSZrrib_Int: case X86::VCMPSSZrribk_Int:
292     OS << "ss\t";
293     break;
294   case X86::VCMPPHZ128rmi:  case X86::VCMPPHZ128rri:
295   case X86::VCMPPHZ256rmi:  case X86::VCMPPHZ256rri:
296   case X86::VCMPPHZrmi:     case X86::VCMPPHZrri:
297   case X86::VCMPPHZ128rmik: case X86::VCMPPHZ128rrik:
298   case X86::VCMPPHZ256rmik: case X86::VCMPPHZ256rrik:
299   case X86::VCMPPHZrmik:    case X86::VCMPPHZrrik:
300   case X86::VCMPPHZ128rmbi: case X86::VCMPPHZ128rmbik:
301   case X86::VCMPPHZ256rmbi: case X86::VCMPPHZ256rmbik:
302   case X86::VCMPPHZrmbi:    case X86::VCMPPHZrmbik:
303   case X86::VCMPPHZrrib:    case X86::VCMPPHZrribk:
304     OS << "ph\t";
305     break;
306   case X86::VCMPSHZrmi:      case X86::VCMPSHZrri:
307   case X86::VCMPSHZrmi_Int:  case X86::VCMPSHZrri_Int:
308   case X86::VCMPSHZrrib_Int: case X86::VCMPSHZrribk_Int:
309   case X86::VCMPSHZrmik_Int: case X86::VCMPSHZrrik_Int:
310     OS << "sh\t";
311     break;
312   case X86::VCMPBF16Z128rmi:  case X86::VCMPBF16Z128rri:
313   case X86::VCMPBF16Z256rmi:  case X86::VCMPBF16Z256rri:
314   case X86::VCMPBF16Zrmi:     case X86::VCMPBF16Zrri:
315   case X86::VCMPBF16Z128rmik: case X86::VCMPBF16Z128rrik:
316   case X86::VCMPBF16Z256rmik: case X86::VCMPBF16Z256rrik:
317   case X86::VCMPBF16Zrmik:    case X86::VCMPBF16Zrrik:
318   case X86::VCMPBF16Z128rmbi: case X86::VCMPBF16Z128rmbik:
319   case X86::VCMPBF16Z256rmbi: case X86::VCMPBF16Z256rmbik:
320   case X86::VCMPBF16Zrmbi:    case X86::VCMPBF16Zrmbik:
321     OS << "bf16\t";
322     break;
323   }
324 }
325 
326 void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,
327                                                 raw_ostream &O) {
328   int64_t Imm = MI->getOperand(Op).getImm();
329   switch (Imm) {
330   default:
331     llvm_unreachable("Invalid rounding control!");
332   case X86::TO_NEAREST_INT:
333     O << "{rn-sae}";
334     break;
335   case X86::TO_NEG_INF:
336     O << "{rd-sae}";
337     break;
338   case X86::TO_POS_INF:
339     O << "{ru-sae}";
340     break;
341   case X86::TO_ZERO:
342     O << "{rz-sae}";
343     break;
344   }
345 }
346 
347 /// value (e.g. for jumps and calls). In Intel-style these print slightly
348 /// differently than normal immediates. For example, a $ is not emitted.
349 ///
350 /// \p Address The address of the next instruction.
351 /// \see MCInstPrinter::printInst
352 void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, uint64_t Address,
353                                          unsigned OpNo, raw_ostream &O) {
354   // Do not print the numberic target address when symbolizing.
355   if (SymbolizeOperands)
356     return;
357 
358   const MCOperand &Op = MI->getOperand(OpNo);
359   if (Op.isImm()) {
360     if (PrintBranchImmAsAddress) {
361       uint64_t Target = Address + Op.getImm();
362       if (MAI.getCodePointerSize() == 4)
363         Target &= 0xffffffff;
364       markup(O, Markup::Target) << formatHex(Target);
365     } else
366       markup(O, Markup::Immediate) << formatImm(Op.getImm());
367   } else {
368     assert(Op.isExpr() && "unknown pcrel immediate operand");
369     // If a symbolic branch target was added as a constant expression then print
370     // that address in hex.
371     const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
372     int64_t Address;
373     if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {
374       markup(O, Markup::Immediate) << formatHex((uint64_t)Address);
375     } else {
376       // Otherwise, just print the expression.
377       Op.getExpr()->print(O, &MAI);
378     }
379   }
380 }
381 
382 void X86InstPrinterCommon::printOptionalSegReg(const MCInst *MI, unsigned OpNo,
383                                                raw_ostream &O) {
384   if (MI->getOperand(OpNo).getReg()) {
385     printOperand(MI, OpNo, O);
386     O << ':';
387   }
388 }
389 
390 void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O,
391                                           const MCSubtargetInfo &STI) {
392   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
393   uint64_t TSFlags = Desc.TSFlags;
394   unsigned Flags = MI->getFlags();
395 
396   if ((TSFlags & X86II::LOCK) || (Flags & X86::IP_HAS_LOCK))
397     O << "\tlock\t";
398 
399   if ((TSFlags & X86II::NOTRACK) || (Flags & X86::IP_HAS_NOTRACK))
400     O << "\tnotrack\t";
401 
402   if (Flags & X86::IP_HAS_REPEAT_NE)
403     O << "\trepne\t";
404   else if (Flags & X86::IP_HAS_REPEAT)
405     O << "\trep\t";
406 
407   if (TSFlags & X86II::EVEX_NF && !X86::isCFCMOVCC(MI->getOpcode()))
408     O << "\t{nf}";
409 
410   // These all require a pseudo prefix
411   if ((Flags & X86::IP_USE_VEX) ||
412       (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix)
413     O << "\t{vex}";
414   else if (Flags & X86::IP_USE_VEX2)
415     O << "\t{vex2}";
416   else if (Flags & X86::IP_USE_VEX3)
417     O << "\t{vex3}";
418   else if ((Flags & X86::IP_USE_EVEX) ||
419            (TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitEVEXPrefix)
420     O << "\t{evex}";
421 
422   if (Flags & X86::IP_USE_DISP8)
423     O << "\t{disp8}";
424   else if (Flags & X86::IP_USE_DISP32)
425     O << "\t{disp32}";
426 
427   // Determine where the memory operand starts, if present
428   int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
429   if (MemoryOperand != -1)
430     MemoryOperand += X86II::getOperandBias(Desc);
431 
432   // Address-Size override prefix
433   if (Flags & X86::IP_HAS_AD_SIZE &&
434       !X86_MC::needsAddressSizeOverride(*MI, STI, MemoryOperand, TSFlags)) {
435     if (STI.hasFeature(X86::Is16Bit) || STI.hasFeature(X86::Is64Bit))
436       O << "\taddr32\t";
437     else if (STI.hasFeature(X86::Is32Bit))
438       O << "\taddr16\t";
439   }
440 }
441 
442 void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,
443                                        raw_ostream &OS) {
444   // In assembly listings, a pair is represented by one of its members, any
445   // of the two.  Here, we pick k0, k2, k4, k6, but we could as well
446   // print K2_K3 as "k3".  It would probably make a lot more sense, if
447   // the assembly would look something like:
448   // "vp2intersect %zmm5, %zmm7, {%k2, %k3}"
449   // but this can work too.
450   switch (MI->getOperand(OpNo).getReg()) {
451   case X86::K0_K1:
452     printRegName(OS, X86::K0);
453     return;
454   case X86::K2_K3:
455     printRegName(OS, X86::K2);
456     return;
457   case X86::K4_K5:
458     printRegName(OS, X86::K4);
459     return;
460   case X86::K6_K7:
461     printRegName(OS, X86::K6);
462     return;
463   }
464   llvm_unreachable("Unknown mask pair register name");
465 }
466 
467 void X86InstPrinterCommon::printTILEPair(const MCInst *MI, unsigned OpNo,
468                                          raw_ostream &OS) {
469   switch (MI->getOperand(OpNo).getReg()) {
470   case X86::TMM0_TMM1:
471     printRegName(OS, X86::TMM0);
472     return;
473   case X86::TMM2_TMM3:
474     printRegName(OS, X86::TMM2);
475     return;
476   case X86::TMM4_TMM5:
477     printRegName(OS, X86::TMM4);
478     return;
479   case X86::TMM6_TMM7:
480     printRegName(OS, X86::TMM6);
481     return;
482   }
483   llvm_unreachable("Unknown mask pair register name");
484 }
485