blob: a7d7c554e62b476fd377dfa47979dde15d2e5ff1 [file] [log] [blame]
Chris Lattner6aa928d2010-08-28 20:42:31 +00001//===-- 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"
19using namespace llvm;
20
21//===----------------------------------------------------------------------===//
22// Vector Mask Decoding
23//===----------------------------------------------------------------------===//
24
25enum {
26 SM_SentinelZero = ~0U
27};
28
29static void DecodeINSERTPSMask(unsigned Imm,
30 SmallVectorImpl<unsigned> &ShuffleMask) {
31 // Defaults the copying the dest value.
32 ShuffleMask.push_back(0);
33 ShuffleMask.push_back(1);
34 ShuffleMask.push_back(2);
35 ShuffleMask.push_back(3);
36
37 // Decode the immediate.
38 unsigned ZMask = Imm & 15;
39 unsigned CountD = (Imm >> 4) & 3;
40 unsigned CountS = (Imm >> 6) & 3;
41
42 // CountS selects which input element to use.
43 unsigned InVal = 4+CountS;
44 // CountD specifies which element of destination to update.
45 ShuffleMask[CountD] = InVal;
46 // ZMask zaps values, potentially overriding the CountD elt.
47 if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero;
48 if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero;
49 if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero;
50 if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero;
51}
52
Chris Lattner4644a932010-08-29 03:08:08 +000053static void DecodeMOVHLPSMask(SmallVectorImpl<unsigned> &ShuffleMask) {
54 ShuffleMask.push_back(3);
55 ShuffleMask.push_back(1);
56}
57
58static void DecodeMOVLHPSMask(SmallVectorImpl<unsigned> &ShuffleMask) {
59 ShuffleMask.push_back(0);
60 ShuffleMask.push_back(2);
61}
62
63static void DecodePSHUFMask(unsigned NElts, unsigned Imm,
64 SmallVectorImpl<unsigned> &ShuffleMask) {
65 for (unsigned i = 0; i != NElts; ++i) {
66 ShuffleMask.push_back(Imm % NElts);
67 Imm /= NElts;
68 }
69}
70
71static void DecodePSHUFHWMask(unsigned Imm,
72 SmallVectorImpl<unsigned> &ShuffleMask) {
73 ShuffleMask.push_back(0);
74 ShuffleMask.push_back(1);
75 ShuffleMask.push_back(2);
76 ShuffleMask.push_back(3);
77 for (unsigned i = 0; i != 4; ++i) {
78 ShuffleMask.push_back(4+(Imm & 3));
79 Imm >>= 2;
80 }
81}
82
83static void DecodePSHUFLWMask(unsigned Imm,
84 SmallVectorImpl<unsigned> &ShuffleMask) {
85 for (unsigned i = 0; i != 4; ++i) {
86 ShuffleMask.push_back((Imm & 3));
87 Imm >>= 2;
88 }
89 ShuffleMask.push_back(4);
90 ShuffleMask.push_back(5);
91 ShuffleMask.push_back(6);
92 ShuffleMask.push_back(7);
93}
94
95static void DecodePUNPCKLMask(unsigned NElts,
96 SmallVectorImpl<unsigned> &ShuffleMask) {
97 for (unsigned i = 0; i != NElts/2; ++i) {
98 ShuffleMask.push_back(i);
99 ShuffleMask.push_back(i+NElts);
100 }
101}
102
103static void DecodePUNPCKHMask(unsigned NElts,
104 SmallVectorImpl<unsigned> &ShuffleMask) {
105 for (unsigned i = 0; i != NElts/2; ++i) {
106 ShuffleMask.push_back(i+NElts/2);
107 ShuffleMask.push_back(i+NElts+NElts/2);
108 }
109}
110
Chris Lattner6aa928d2010-08-28 20:42:31 +0000111static void DecodeSHUFPSMask(unsigned NElts, unsigned Imm,
112 SmallVectorImpl<unsigned> &ShuffleMask) {
113 // Part that reads from dest.
114 for (unsigned i = 0; i != NElts/2; ++i) {
115 ShuffleMask.push_back(Imm % NElts);
116 Imm /= NElts;
117 }
118 // Part that reads from src.
119 for (unsigned i = 0; i != NElts/2; ++i) {
120 ShuffleMask.push_back(Imm % NElts + NElts);
121 Imm /= NElts;
122 }
123}
124
Chris Lattner4644a932010-08-29 03:08:08 +0000125static void DecodeUNPCKHPMask(unsigned NElts,
126 SmallVectorImpl<unsigned> &ShuffleMask) {
127 for (unsigned i = 0; i != NElts/2; ++i) {
128 ShuffleMask.push_back(i+NElts/2); // Reads from dest
129 ShuffleMask.push_back(i+NElts+NElts/2); // Reads from src
Chris Lattner6aa928d2010-08-28 20:42:31 +0000130 }
131}
132
Chris Lattner4644a932010-08-29 03:08:08 +0000133
Chris Lattner6aa928d2010-08-28 20:42:31 +0000134/// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd
135/// etc. NElts indicates the number of elements in the vector allowing it to
136/// handle different datatypes and vector widths.
137static void DecodeUNPCKLPMask(unsigned NElts,
138 SmallVectorImpl<unsigned> &ShuffleMask) {
139 for (unsigned i = 0; i != NElts/2; ++i) {
140 ShuffleMask.push_back(i); // Reads from dest
141 ShuffleMask.push_back(i+NElts); // Reads from src
142 }
143}
144
145//===----------------------------------------------------------------------===//
146// Top Level Entrypoint
147//===----------------------------------------------------------------------===//
148
149
150/// EmitAnyX86InstComments - This function decodes x86 instructions and prints
151/// newline terminated strings to the specified string if desired. This
152/// information is shown in disassembly dumps when verbose assembly is enabled.
153void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
154 const char *(*getRegName)(unsigned)) {
155 // If this is a shuffle operation, the switch should fill in this state.
156 SmallVector<unsigned, 8> ShuffleMask;
157 const char *DestName = 0, *Src1Name = 0, *Src2Name = 0;
158
159 switch (MI->getOpcode()) {
160 case X86::INSERTPSrr:
161 Src1Name = getRegName(MI->getOperand(1).getReg());
162 Src2Name = getRegName(MI->getOperand(2).getReg());
163 DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask);
164 break;
Chris Lattner4644a932010-08-29 03:08:08 +0000165
166 case X86::MOVLHPSrr:
167 Src2Name = getRegName(MI->getOperand(2).getReg());
168 Src1Name = getRegName(MI->getOperand(0).getReg());
169 DecodeMOVLHPSMask(ShuffleMask);
170 break;
171
172 case X86::MOVHLPSrr:
173 Src2Name = getRegName(MI->getOperand(2).getReg());
174 Src1Name = getRegName(MI->getOperand(0).getReg());
175 DecodeMOVHLPSMask(ShuffleMask);
176 break;
177
Chris Lattner6aa928d2010-08-28 20:42:31 +0000178 case X86::PSHUFDri:
179 Src1Name = getRegName(MI->getOperand(1).getReg());
180 // FALL THROUGH.
181 case X86::PSHUFDmi:
182 DestName = getRegName(MI->getOperand(0).getReg());
183 DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(),
184 ShuffleMask);
185 break;
Chris Lattner4644a932010-08-29 03:08:08 +0000186
187 case X86::PSHUFHWri:
188 Src1Name = getRegName(MI->getOperand(1).getReg());
189 // FALL THROUGH.
190 case X86::PSHUFHWmi:
191 DestName = getRegName(MI->getOperand(0).getReg());
192 DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
193 ShuffleMask);
194 break;
195 case X86::PSHUFLWri:
196 Src1Name = getRegName(MI->getOperand(1).getReg());
197 // FALL THROUGH.
198 case X86::PSHUFLWmi:
199 DestName = getRegName(MI->getOperand(0).getReg());
200 DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
201 ShuffleMask);
202 break;
203
204 case X86::PUNPCKHBWrr:
205 Src2Name = getRegName(MI->getOperand(2).getReg());
206 // FALL THROUGH.
207 case X86::PUNPCKHBWrm:
208 Src1Name = getRegName(MI->getOperand(0).getReg());
209 DecodePUNPCKHMask(16, ShuffleMask);
210 break;
211 case X86::PUNPCKHWDrr:
212 Src2Name = getRegName(MI->getOperand(2).getReg());
213 // FALL THROUGH.
214 case X86::PUNPCKHWDrm:
215 Src1Name = getRegName(MI->getOperand(0).getReg());
216 DecodePUNPCKHMask(8, ShuffleMask);
217 break;
218 case X86::PUNPCKHDQrr:
219 Src2Name = getRegName(MI->getOperand(2).getReg());
220 // FALL THROUGH.
221 case X86::PUNPCKHDQrm:
222 Src1Name = getRegName(MI->getOperand(0).getReg());
223 DecodePUNPCKHMask(4, ShuffleMask);
224 break;
225 case X86::PUNPCKHQDQrr:
226 Src2Name = getRegName(MI->getOperand(2).getReg());
227 // FALL THROUGH.
228 case X86::PUNPCKHQDQrm:
229 Src1Name = getRegName(MI->getOperand(0).getReg());
230 DecodePUNPCKHMask(2, ShuffleMask);
231 break;
232
233 case X86::PUNPCKLBWrr:
234 Src2Name = getRegName(MI->getOperand(2).getReg());
235 // FALL THROUGH.
236 case X86::PUNPCKLBWrm:
237 Src1Name = getRegName(MI->getOperand(0).getReg());
238 DecodePUNPCKLMask(16, ShuffleMask);
239 break;
240 case X86::PUNPCKLWDrr:
241 Src2Name = getRegName(MI->getOperand(2).getReg());
242 // FALL THROUGH.
243 case X86::PUNPCKLWDrm:
244 Src1Name = getRegName(MI->getOperand(0).getReg());
245 DecodePUNPCKLMask(8, ShuffleMask);
246 break;
247 case X86::PUNPCKLDQrr:
248 Src2Name = getRegName(MI->getOperand(2).getReg());
249 // FALL THROUGH.
250 case X86::PUNPCKLDQrm:
251 Src1Name = getRegName(MI->getOperand(0).getReg());
252 DecodePUNPCKLMask(4, ShuffleMask);
253 break;
254 case X86::PUNPCKLQDQrr:
255 Src2Name = getRegName(MI->getOperand(2).getReg());
256 // FALL THROUGH.
257 case X86::PUNPCKLQDQrm:
258 Src1Name = getRegName(MI->getOperand(0).getReg());
259 DecodePUNPCKLMask(2, ShuffleMask);
260 break;
261
Chris Lattner6aa928d2010-08-28 20:42:31 +0000262 case X86::SHUFPDrri:
263 DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
264 Src1Name = getRegName(MI->getOperand(0).getReg());
265 Src2Name = getRegName(MI->getOperand(2).getReg());
266 break;
Chris Lattner4644a932010-08-29 03:08:08 +0000267
Chris Lattner6aa928d2010-08-28 20:42:31 +0000268 case X86::SHUFPSrri:
Chris Lattner4644a932010-08-29 03:08:08 +0000269 Src2Name = getRegName(MI->getOperand(2).getReg());
270 // FALL THROUGH.
271 case X86::SHUFPSrmi:
Chris Lattner6aa928d2010-08-28 20:42:31 +0000272 DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
273 Src1Name = getRegName(MI->getOperand(0).getReg());
Chris Lattner4644a932010-08-29 03:08:08 +0000274 break;
275
276 case X86::UNPCKLPDrr:
Chris Lattner6aa928d2010-08-28 20:42:31 +0000277 Src2Name = getRegName(MI->getOperand(2).getReg());
Chris Lattner4644a932010-08-29 03:08:08 +0000278 // FALL THROUGH.
279 case X86::UNPCKLPDrm:
280 DecodeUNPCKLPMask(2, ShuffleMask);
281 Src1Name = getRegName(MI->getOperand(0).getReg());
Chris Lattner6aa928d2010-08-28 20:42:31 +0000282 break;
283 case X86::UNPCKLPSrr:
284 Src2Name = getRegName(MI->getOperand(2).getReg());
285 // FALL THROUGH.
286 case X86::UNPCKLPSrm:
287 DecodeUNPCKLPMask(4, ShuffleMask);
288 Src1Name = getRegName(MI->getOperand(0).getReg());
289 break;
Chris Lattner4644a932010-08-29 03:08:08 +0000290 case X86::UNPCKHPDrr:
291 Src2Name = getRegName(MI->getOperand(2).getReg());
292 // FALL THROUGH.
293 case X86::UNPCKHPDrm:
294 DecodeUNPCKHPMask(2, ShuffleMask);
295 Src1Name = getRegName(MI->getOperand(0).getReg());
296 break;
297 case X86::UNPCKHPSrr:
298 Src2Name = getRegName(MI->getOperand(2).getReg());
299 // FALL THROUGH.
300 case X86::UNPCKHPSrm:
301 DecodeUNPCKHPMask(4, ShuffleMask);
302 Src1Name = getRegName(MI->getOperand(0).getReg());
303 break;
Chris Lattner6aa928d2010-08-28 20:42:31 +0000304 }
305
306
307 // If this was a shuffle operation, print the shuffle mask.
308 if (!ShuffleMask.empty()) {
309 if (DestName == 0) DestName = Src1Name;
310 OS << (DestName ? DestName : "mem") << " = ";
311
312 // If the two sources are the same, canonicalize the input elements to be
313 // from the first src so that we get larger element spans.
314 if (Src1Name == Src2Name) {
315 for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
316 if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
317 ShuffleMask[i] >= e) // From second mask.
318 ShuffleMask[i] -= e;
319 }
320 }
321
322 // The shuffle mask specifies which elements of the src1/src2 fill in the
323 // destination, with a few sentinel values. Loop through and print them
324 // out.
325 for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
326 if (i != 0)
327 OS << ',';
328 if (ShuffleMask[i] == SM_SentinelZero) {
329 OS << "zero";
330 continue;
331 }
332
333 // Otherwise, it must come from src1 or src2. Print the span of elements
334 // that comes from this src.
335 bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
336 const char *SrcName = isSrc1 ? Src1Name : Src2Name;
337 OS << (SrcName ? SrcName : "mem") << '[';
338 bool IsFirst = true;
339 while (i != e &&
340 (int)ShuffleMask[i] >= 0 &&
341 (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
342 if (!IsFirst)
343 OS << ',';
344 else
345 IsFirst = false;
346 OS << ShuffleMask[i] % ShuffleMask.size();
347 ++i;
348 }
349 OS << ']';
350 --i; // For loop increments element #.
351 }
352 //MI->print(OS, 0);
353 OS << "\n";
354 }
355
356}