X86InstComments.cpp revision 221345
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 "X86GenInstrNames.inc"
17#include "llvm/MC/MCInst.h"
18#include "llvm/Support/raw_ostream.h"
19#include "../Utils/X86ShuffleDecode.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    DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
140    Src1Name = getRegName(MI->getOperand(0).getReg());
141    Src2Name = getRegName(MI->getOperand(2).getReg());
142    break;
143
144  case X86::SHUFPSrri:
145    Src2Name = getRegName(MI->getOperand(2).getReg());
146    // FALL THROUGH.
147  case X86::SHUFPSrmi:
148    DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
149    Src1Name = getRegName(MI->getOperand(0).getReg());
150    break;
151
152  case X86::UNPCKLPDrr:
153    Src2Name = getRegName(MI->getOperand(2).getReg());
154    // FALL THROUGH.
155  case X86::UNPCKLPDrm:
156    DecodeUNPCKLPDMask(2, ShuffleMask);
157    Src1Name = getRegName(MI->getOperand(0).getReg());
158    break;
159  case X86::VUNPCKLPDrr:
160    Src2Name = getRegName(MI->getOperand(2).getReg());
161    // FALL THROUGH.
162  case X86::VUNPCKLPDrm:
163    DecodeUNPCKLPDMask(2, ShuffleMask);
164    Src1Name = getRegName(MI->getOperand(1).getReg());
165    break;
166  case X86::VUNPCKLPDYrr:
167    Src2Name = getRegName(MI->getOperand(2).getReg());
168    // FALL THROUGH.
169  case X86::VUNPCKLPDYrm:
170    DecodeUNPCKLPDMask(4, ShuffleMask);
171    Src1Name = getRegName(MI->getOperand(1).getReg());
172    break;
173  case X86::UNPCKLPSrr:
174    Src2Name = getRegName(MI->getOperand(2).getReg());
175    // FALL THROUGH.
176  case X86::UNPCKLPSrm:
177    DecodeUNPCKLPSMask(4, ShuffleMask);
178    Src1Name = getRegName(MI->getOperand(0).getReg());
179    break;
180  case X86::VUNPCKLPSrr:
181    Src2Name = getRegName(MI->getOperand(2).getReg());
182    // FALL THROUGH.
183  case X86::VUNPCKLPSrm:
184    DecodeUNPCKLPSMask(4, ShuffleMask);
185    Src1Name = getRegName(MI->getOperand(1).getReg());
186    break;
187  case X86::VUNPCKLPSYrr:
188    Src2Name = getRegName(MI->getOperand(2).getReg());
189    // FALL THROUGH.
190  case X86::VUNPCKLPSYrm:
191    DecodeUNPCKLPSMask(8, ShuffleMask);
192    Src1Name = getRegName(MI->getOperand(1).getReg());
193    break;
194  case X86::UNPCKHPDrr:
195    Src2Name = getRegName(MI->getOperand(2).getReg());
196    // FALL THROUGH.
197  case X86::UNPCKHPDrm:
198    DecodeUNPCKHPMask(2, ShuffleMask);
199    Src1Name = getRegName(MI->getOperand(0).getReg());
200    break;
201  case X86::UNPCKHPSrr:
202    Src2Name = getRegName(MI->getOperand(2).getReg());
203    // FALL THROUGH.
204  case X86::UNPCKHPSrm:
205    DecodeUNPCKHPMask(4, ShuffleMask);
206    Src1Name = getRegName(MI->getOperand(0).getReg());
207    break;
208  }
209
210
211  // If this was a shuffle operation, print the shuffle mask.
212  if (!ShuffleMask.empty()) {
213    if (DestName == 0) DestName = Src1Name;
214    OS << (DestName ? DestName : "mem") << " = ";
215
216    // If the two sources are the same, canonicalize the input elements to be
217    // from the first src so that we get larger element spans.
218    if (Src1Name == Src2Name) {
219      for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
220        if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
221            ShuffleMask[i] >= e)        // From second mask.
222          ShuffleMask[i] -= e;
223      }
224    }
225
226    // The shuffle mask specifies which elements of the src1/src2 fill in the
227    // destination, with a few sentinel values.  Loop through and print them
228    // out.
229    for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
230      if (i != 0)
231        OS << ',';
232      if (ShuffleMask[i] == SM_SentinelZero) {
233        OS << "zero";
234        continue;
235      }
236
237      // Otherwise, it must come from src1 or src2.  Print the span of elements
238      // that comes from this src.
239      bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
240      const char *SrcName = isSrc1 ? Src1Name : Src2Name;
241      OS << (SrcName ? SrcName : "mem") << '[';
242      bool IsFirst = true;
243      while (i != e &&
244             (int)ShuffleMask[i] >= 0 &&
245             (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
246        if (!IsFirst)
247          OS << ',';
248        else
249          IsFirst = false;
250        OS << ShuffleMask[i] % ShuffleMask.size();
251        ++i;
252      }
253      OS << ']';
254      --i;  // For loop increments element #.
255    }
256    //MI->print(OS, 0);
257    OS << "\n";
258  }
259
260}
261