blob: 61f506521119cfd3484fcac03664468cb0b40dba [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"
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000019#include "../X86ShuffleDecode.h"
Chris Lattner6aa928d2010-08-28 20:42:31 +000020using namespace llvm;
21
22//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000023// Vector Mask Decoding for non-shuffles
24//===----------------------------------------------------------------------===//
25
26static void DecodeINSERTPSMask(unsigned Imm,
27 SmallVectorImpl<unsigned> &ShuffleMask) {
28 // Defaults the copying the dest value.
29 ShuffleMask.push_back(0);
30 ShuffleMask.push_back(1);
31 ShuffleMask.push_back(2);
32 ShuffleMask.push_back(3);
33
34 // Decode the immediate.
35 unsigned ZMask = Imm & 15;
36 unsigned CountD = (Imm >> 4) & 3;
37 unsigned CountS = (Imm >> 6) & 3;
38
39 // CountS selects which input element to use.
40 unsigned InVal = 4+CountS;
41 // CountD specifies which element of destination to update.
42 ShuffleMask[CountD] = InVal;
43 // ZMask zaps values, potentially overriding the CountD elt.
44 if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero;
45 if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero;
46 if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero;
47 if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero;
48}
49
50//===----------------------------------------------------------------------===//
Chris Lattner6aa928d2010-08-28 20:42:31 +000051// Top Level Entrypoint
52//===----------------------------------------------------------------------===//
53
Chris Lattner6aa928d2010-08-28 20:42:31 +000054/// EmitAnyX86InstComments - This function decodes x86 instructions and prints
55/// newline terminated strings to the specified string if desired. This
56/// information is shown in disassembly dumps when verbose assembly is enabled.
57void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
58 const char *(*getRegName)(unsigned)) {
59 // If this is a shuffle operation, the switch should fill in this state.
60 SmallVector<unsigned, 8> ShuffleMask;
61 const char *DestName = 0, *Src1Name = 0, *Src2Name = 0;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000062
Chris Lattner6aa928d2010-08-28 20:42:31 +000063 switch (MI->getOpcode()) {
64 case X86::INSERTPSrr:
65 Src1Name = getRegName(MI->getOperand(1).getReg());
66 Src2Name = getRegName(MI->getOperand(2).getReg());
67 DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask);
68 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000069
Chris Lattner4644a932010-08-29 03:08:08 +000070 case X86::MOVLHPSrr:
71 Src2Name = getRegName(MI->getOperand(2).getReg());
72 Src1Name = getRegName(MI->getOperand(0).getReg());
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000073 DecodeMOVLHPSMask(2, ShuffleMask);
Chris Lattner4644a932010-08-29 03:08:08 +000074 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000075
Chris Lattner4644a932010-08-29 03:08:08 +000076 case X86::MOVHLPSrr:
77 Src2Name = getRegName(MI->getOperand(2).getReg());
78 Src1Name = getRegName(MI->getOperand(0).getReg());
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000079 DecodeMOVHLPSMask(2, ShuffleMask);
Chris Lattner4644a932010-08-29 03:08:08 +000080 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000081
Chris Lattner6aa928d2010-08-28 20:42:31 +000082 case X86::PSHUFDri:
83 Src1Name = getRegName(MI->getOperand(1).getReg());
84 // FALL THROUGH.
85 case X86::PSHUFDmi:
86 DestName = getRegName(MI->getOperand(0).getReg());
87 DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(),
88 ShuffleMask);
89 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000090
Chris Lattner4644a932010-08-29 03:08:08 +000091 case X86::PSHUFHWri:
92 Src1Name = getRegName(MI->getOperand(1).getReg());
93 // FALL THROUGH.
94 case X86::PSHUFHWmi:
95 DestName = getRegName(MI->getOperand(0).getReg());
96 DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
97 ShuffleMask);
98 break;
99 case X86::PSHUFLWri:
100 Src1Name = getRegName(MI->getOperand(1).getReg());
101 // FALL THROUGH.
102 case X86::PSHUFLWmi:
103 DestName = getRegName(MI->getOperand(0).getReg());
104 DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
105 ShuffleMask);
106 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000107
Chris Lattner4644a932010-08-29 03:08:08 +0000108 case X86::PUNPCKHBWrr:
109 Src2Name = getRegName(MI->getOperand(2).getReg());
110 // FALL THROUGH.
111 case X86::PUNPCKHBWrm:
112 Src1Name = getRegName(MI->getOperand(0).getReg());
113 DecodePUNPCKHMask(16, ShuffleMask);
114 break;
115 case X86::PUNPCKHWDrr:
116 Src2Name = getRegName(MI->getOperand(2).getReg());
117 // FALL THROUGH.
118 case X86::PUNPCKHWDrm:
119 Src1Name = getRegName(MI->getOperand(0).getReg());
120 DecodePUNPCKHMask(8, ShuffleMask);
121 break;
122 case X86::PUNPCKHDQrr:
123 Src2Name = getRegName(MI->getOperand(2).getReg());
124 // FALL THROUGH.
125 case X86::PUNPCKHDQrm:
126 Src1Name = getRegName(MI->getOperand(0).getReg());
127 DecodePUNPCKHMask(4, ShuffleMask);
128 break;
129 case X86::PUNPCKHQDQrr:
130 Src2Name = getRegName(MI->getOperand(2).getReg());
131 // FALL THROUGH.
132 case X86::PUNPCKHQDQrm:
133 Src1Name = getRegName(MI->getOperand(0).getReg());
134 DecodePUNPCKHMask(2, ShuffleMask);
135 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000136
Chris Lattner4644a932010-08-29 03:08:08 +0000137 case X86::PUNPCKLBWrr:
138 Src2Name = getRegName(MI->getOperand(2).getReg());
139 // FALL THROUGH.
140 case X86::PUNPCKLBWrm:
141 Src1Name = getRegName(MI->getOperand(0).getReg());
142 DecodePUNPCKLMask(16, ShuffleMask);
143 break;
144 case X86::PUNPCKLWDrr:
145 Src2Name = getRegName(MI->getOperand(2).getReg());
146 // FALL THROUGH.
147 case X86::PUNPCKLWDrm:
148 Src1Name = getRegName(MI->getOperand(0).getReg());
149 DecodePUNPCKLMask(8, ShuffleMask);
150 break;
151 case X86::PUNPCKLDQrr:
152 Src2Name = getRegName(MI->getOperand(2).getReg());
153 // FALL THROUGH.
154 case X86::PUNPCKLDQrm:
155 Src1Name = getRegName(MI->getOperand(0).getReg());
156 DecodePUNPCKLMask(4, ShuffleMask);
157 break;
158 case X86::PUNPCKLQDQrr:
159 Src2Name = getRegName(MI->getOperand(2).getReg());
160 // FALL THROUGH.
161 case X86::PUNPCKLQDQrm:
162 Src1Name = getRegName(MI->getOperand(0).getReg());
163 DecodePUNPCKLMask(2, ShuffleMask);
164 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000165
Chris Lattner6aa928d2010-08-28 20:42:31 +0000166 case X86::SHUFPDrri:
167 DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
168 Src1Name = getRegName(MI->getOperand(0).getReg());
169 Src2Name = getRegName(MI->getOperand(2).getReg());
170 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000171
Chris Lattner6aa928d2010-08-28 20:42:31 +0000172 case X86::SHUFPSrri:
Chris Lattner4644a932010-08-29 03:08:08 +0000173 Src2Name = getRegName(MI->getOperand(2).getReg());
174 // FALL THROUGH.
175 case X86::SHUFPSrmi:
Chris Lattner6aa928d2010-08-28 20:42:31 +0000176 DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
177 Src1Name = getRegName(MI->getOperand(0).getReg());
Chris Lattner4644a932010-08-29 03:08:08 +0000178 break;
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000179
Chris Lattner4644a932010-08-29 03:08:08 +0000180 case X86::UNPCKLPDrr:
Chris Lattner6aa928d2010-08-28 20:42:31 +0000181 Src2Name = getRegName(MI->getOperand(2).getReg());
Chris Lattner4644a932010-08-29 03:08:08 +0000182 // FALL THROUGH.
183 case X86::UNPCKLPDrm:
184 DecodeUNPCKLPMask(2, ShuffleMask);
185 Src1Name = getRegName(MI->getOperand(0).getReg());
Chris Lattner6aa928d2010-08-28 20:42:31 +0000186 break;
187 case X86::UNPCKLPSrr:
188 Src2Name = getRegName(MI->getOperand(2).getReg());
189 // FALL THROUGH.
190 case X86::UNPCKLPSrm:
191 DecodeUNPCKLPMask(4, ShuffleMask);
192 Src1Name = getRegName(MI->getOperand(0).getReg());
193 break;
Chris Lattner4644a932010-08-29 03:08:08 +0000194 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;
Chris Lattner6aa928d2010-08-28 20:42:31 +0000208 }
209
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000210
Chris Lattner6aa928d2010-08-28 20:42:31 +0000211 // 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") << " = ";
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000215
Chris Lattner6aa928d2010-08-28 20:42:31 +0000216 // 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 }
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000225
Chris Lattner6aa928d2010-08-28 20:42:31 +0000226 // 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 }
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000236
Chris Lattner6aa928d2010-08-28 20:42:31 +0000237 // 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 }
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +0000259
Chris Lattner6aa928d2010-08-28 20:42:31 +0000260}