X86InstComments.cpp revision 226633
1//===-- X86InstComments.cpp - Generate verbose-asm comments for instrs ----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This defines functionality used to emit comments about X86 instructions to
11// an output stream for -fverbose-asm.
12//
13//===----------------------------------------------------------------------===//
14
15#include "X86InstComments.h"
16#include "MCTargetDesc/X86MCTargetDesc.h"
17#include "Utils/X86ShuffleDecode.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/Support/raw_ostream.h"
20using namespace llvm;
21
22//===----------------------------------------------------------------------===//
23// Top Level Entrypoint
24//===----------------------------------------------------------------------===//
25
26/// EmitAnyX86InstComments - This function decodes x86 instructions and prints
27/// newline terminated strings to the specified string if desired.  This
28/// information is shown in disassembly dumps when verbose assembly is enabled.
29void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
30                                  const char *(*getRegName)(unsigned)) {
31  // If this is a shuffle operation, the switch should fill in this state.
32  SmallVector<unsigned, 8> ShuffleMask;
33  const char *DestName = 0, *Src1Name = 0, *Src2Name = 0;
34
35  switch (MI->getOpcode()) {
36  case X86::INSERTPSrr:
37    Src1Name = getRegName(MI->getOperand(1).getReg());
38    Src2Name = getRegName(MI->getOperand(2).getReg());
39    DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask);
40    break;
41
42  case X86::MOVLHPSrr:
43    Src2Name = getRegName(MI->getOperand(2).getReg());
44    Src1Name = getRegName(MI->getOperand(0).getReg());
45    DecodeMOVLHPSMask(2, ShuffleMask);
46    break;
47
48  case X86::MOVHLPSrr:
49    Src2Name = getRegName(MI->getOperand(2).getReg());
50    Src1Name = getRegName(MI->getOperand(0).getReg());
51    DecodeMOVHLPSMask(2, ShuffleMask);
52    break;
53
54  case X86::PSHUFDri:
55    Src1Name = getRegName(MI->getOperand(1).getReg());
56    // FALL THROUGH.
57  case X86::PSHUFDmi:
58    DestName = getRegName(MI->getOperand(0).getReg());
59    DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(),
60                    ShuffleMask);
61    break;
62
63  case X86::PSHUFHWri:
64    Src1Name = getRegName(MI->getOperand(1).getReg());
65    // FALL THROUGH.
66  case X86::PSHUFHWmi:
67    DestName = getRegName(MI->getOperand(0).getReg());
68    DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
69                      ShuffleMask);
70    break;
71  case X86::PSHUFLWri:
72    Src1Name = getRegName(MI->getOperand(1).getReg());
73    // FALL THROUGH.
74  case X86::PSHUFLWmi:
75    DestName = getRegName(MI->getOperand(0).getReg());
76    DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
77                      ShuffleMask);
78    break;
79
80  case X86::PUNPCKHBWrr:
81    Src2Name = getRegName(MI->getOperand(2).getReg());
82    // FALL THROUGH.
83  case X86::PUNPCKHBWrm:
84    Src1Name = getRegName(MI->getOperand(0).getReg());
85    DecodePUNPCKHMask(16, ShuffleMask);
86    break;
87  case X86::PUNPCKHWDrr:
88    Src2Name = getRegName(MI->getOperand(2).getReg());
89    // FALL THROUGH.
90  case X86::PUNPCKHWDrm:
91    Src1Name = getRegName(MI->getOperand(0).getReg());
92    DecodePUNPCKHMask(8, ShuffleMask);
93    break;
94  case X86::PUNPCKHDQrr:
95    Src2Name = getRegName(MI->getOperand(2).getReg());
96    // FALL THROUGH.
97  case X86::PUNPCKHDQrm:
98    Src1Name = getRegName(MI->getOperand(0).getReg());
99    DecodePUNPCKHMask(4, ShuffleMask);
100    break;
101  case X86::PUNPCKHQDQrr:
102    Src2Name = getRegName(MI->getOperand(2).getReg());
103    // FALL THROUGH.
104  case X86::PUNPCKHQDQrm:
105    Src1Name = getRegName(MI->getOperand(0).getReg());
106    DecodePUNPCKHMask(2, ShuffleMask);
107    break;
108
109  case X86::PUNPCKLBWrr:
110    Src2Name = getRegName(MI->getOperand(2).getReg());
111    // FALL THROUGH.
112  case X86::PUNPCKLBWrm:
113    Src1Name = getRegName(MI->getOperand(0).getReg());
114    DecodePUNPCKLBWMask(16, ShuffleMask);
115    break;
116  case X86::PUNPCKLWDrr:
117    Src2Name = getRegName(MI->getOperand(2).getReg());
118    // FALL THROUGH.
119  case X86::PUNPCKLWDrm:
120    Src1Name = getRegName(MI->getOperand(0).getReg());
121    DecodePUNPCKLWDMask(8, ShuffleMask);
122    break;
123  case X86::PUNPCKLDQrr:
124    Src2Name = getRegName(MI->getOperand(2).getReg());
125    // FALL THROUGH.
126  case X86::PUNPCKLDQrm:
127    Src1Name = getRegName(MI->getOperand(0).getReg());
128    DecodePUNPCKLDQMask(4, ShuffleMask);
129    break;
130  case X86::PUNPCKLQDQrr:
131    Src2Name = getRegName(MI->getOperand(2).getReg());
132    // FALL THROUGH.
133  case X86::PUNPCKLQDQrm:
134    Src1Name = getRegName(MI->getOperand(0).getReg());
135    DecodePUNPCKLQDQMask(2, ShuffleMask);
136    break;
137
138  case X86::SHUFPDrri:
139    Src2Name = getRegName(MI->getOperand(2).getReg());
140    // FALL THROUGH.
141  case X86::SHUFPDrmi:
142    DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
143    Src1Name = getRegName(MI->getOperand(0).getReg());
144    break;
145
146  case X86::SHUFPSrri:
147    Src2Name = getRegName(MI->getOperand(2).getReg());
148    // FALL THROUGH.
149  case X86::SHUFPSrmi:
150    DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
151    Src1Name = getRegName(MI->getOperand(0).getReg());
152    break;
153
154  case X86::UNPCKLPDrr:
155    Src2Name = getRegName(MI->getOperand(2).getReg());
156    // FALL THROUGH.
157  case X86::UNPCKLPDrm:
158    DecodeUNPCKLPDMask(2, ShuffleMask);
159    Src1Name = getRegName(MI->getOperand(0).getReg());
160    break;
161  case X86::VUNPCKLPDrr:
162    Src2Name = getRegName(MI->getOperand(2).getReg());
163    // FALL THROUGH.
164  case X86::VUNPCKLPDrm:
165    DecodeUNPCKLPDMask(2, ShuffleMask);
166    Src1Name = getRegName(MI->getOperand(1).getReg());
167    break;
168  case X86::VUNPCKLPDYrr:
169    Src2Name = getRegName(MI->getOperand(2).getReg());
170    // FALL THROUGH.
171  case X86::VUNPCKLPDYrm:
172    DecodeUNPCKLPDMask(4, ShuffleMask);
173    Src1Name = getRegName(MI->getOperand(1).getReg());
174    break;
175  case X86::UNPCKLPSrr:
176    Src2Name = getRegName(MI->getOperand(2).getReg());
177    // FALL THROUGH.
178  case X86::UNPCKLPSrm:
179    DecodeUNPCKLPSMask(4, ShuffleMask);
180    Src1Name = getRegName(MI->getOperand(0).getReg());
181    break;
182  case X86::VUNPCKLPSrr:
183    Src2Name = getRegName(MI->getOperand(2).getReg());
184    // FALL THROUGH.
185  case X86::VUNPCKLPSrm:
186    DecodeUNPCKLPSMask(4, ShuffleMask);
187    Src1Name = getRegName(MI->getOperand(1).getReg());
188    break;
189  case X86::VUNPCKLPSYrr:
190    Src2Name = getRegName(MI->getOperand(2).getReg());
191    // FALL THROUGH.
192  case X86::VUNPCKLPSYrm:
193    DecodeUNPCKLPSMask(8, ShuffleMask);
194    Src1Name = getRegName(MI->getOperand(1).getReg());
195    break;
196  case X86::UNPCKHPDrr:
197    Src2Name = getRegName(MI->getOperand(2).getReg());
198    // FALL THROUGH.
199  case X86::UNPCKHPDrm:
200    DecodeUNPCKHPMask(2, ShuffleMask);
201    Src1Name = getRegName(MI->getOperand(0).getReg());
202    break;
203  case X86::UNPCKHPSrr:
204    Src2Name = getRegName(MI->getOperand(2).getReg());
205    // FALL THROUGH.
206  case X86::UNPCKHPSrm:
207    DecodeUNPCKHPMask(4, ShuffleMask);
208    Src1Name = getRegName(MI->getOperand(0).getReg());
209    break;
210  case X86::VPERMILPSri:
211    DecodeVPERMILPSMask(4, MI->getOperand(2).getImm(),
212                        ShuffleMask);
213    Src1Name = getRegName(MI->getOperand(0).getReg());
214    break;
215  case X86::VPERMILPSYri:
216    DecodeVPERMILPSMask(8, MI->getOperand(2).getImm(),
217                        ShuffleMask);
218    Src1Name = getRegName(MI->getOperand(0).getReg());
219    break;
220  case X86::VPERMILPDri:
221    DecodeVPERMILPDMask(2, MI->getOperand(2).getImm(),
222                        ShuffleMask);
223    Src1Name = getRegName(MI->getOperand(0).getReg());
224    break;
225  case X86::VPERMILPDYri:
226    DecodeVPERMILPDMask(4, MI->getOperand(2).getImm(),
227                        ShuffleMask);
228    Src1Name = getRegName(MI->getOperand(0).getReg());
229    break;
230  case X86::VPERM2F128rr:
231    DecodeVPERM2F128Mask(MI->getOperand(3).getImm(), ShuffleMask);
232    Src1Name = getRegName(MI->getOperand(1).getReg());
233    Src2Name = getRegName(MI->getOperand(2).getReg());
234    break;
235  }
236
237
238  // If this was a shuffle operation, print the shuffle mask.
239  if (!ShuffleMask.empty()) {
240    if (DestName == 0) DestName = Src1Name;
241    OS << (DestName ? DestName : "mem") << " = ";
242
243    // If the two sources are the same, canonicalize the input elements to be
244    // from the first src so that we get larger element spans.
245    if (Src1Name == Src2Name) {
246      for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
247        if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
248            ShuffleMask[i] >= e)        // From second mask.
249          ShuffleMask[i] -= e;
250      }
251    }
252
253    // The shuffle mask specifies which elements of the src1/src2 fill in the
254    // destination, with a few sentinel values.  Loop through and print them
255    // out.
256    for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
257      if (i != 0)
258        OS << ',';
259      if (ShuffleMask[i] == SM_SentinelZero) {
260        OS << "zero";
261        continue;
262      }
263
264      // Otherwise, it must come from src1 or src2.  Print the span of elements
265      // that comes from this src.
266      bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
267      const char *SrcName = isSrc1 ? Src1Name : Src2Name;
268      OS << (SrcName ? SrcName : "mem") << '[';
269      bool IsFirst = true;
270      while (i != e &&
271             (int)ShuffleMask[i] >= 0 &&
272             (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
273        if (!IsFirst)
274          OS << ',';
275        else
276          IsFirst = false;
277        OS << ShuffleMask[i] % ShuffleMask.size();
278        ++i;
279      }
280      OS << ']';
281      --i;  // For loop increments element #.
282    }
283    //MI->print(OS, 0);
284    OS << "\n";
285  }
286
287}
288