1 //===-- X86InstComments.cpp - Generate verbose-asm comments for instrs ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This defines functionality used to emit comments about X86 instructions to
11 // an output stream for -fverbose-asm.
13 //===----------------------------------------------------------------------===//
15 #include "X86InstComments.h"
16 #include "MCTargetDesc/X86MCTargetDesc.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "../Utils/X86ShuffleDecode.h"
22 //===----------------------------------------------------------------------===//
23 // Top Level Entrypoint
24 //===----------------------------------------------------------------------===//
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.
29 void 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;
35 switch (MI
->getOpcode()) {
37 Src1Name
= getRegName(MI
->getOperand(1).getReg());
38 Src2Name
= getRegName(MI
->getOperand(2).getReg());
39 DecodeINSERTPSMask(MI
->getOperand(3).getImm(), ShuffleMask
);
43 Src2Name
= getRegName(MI
->getOperand(2).getReg());
44 Src1Name
= getRegName(MI
->getOperand(0).getReg());
45 DecodeMOVLHPSMask(2, ShuffleMask
);
49 Src2Name
= getRegName(MI
->getOperand(2).getReg());
50 Src1Name
= getRegName(MI
->getOperand(0).getReg());
51 DecodeMOVHLPSMask(2, ShuffleMask
);
55 Src1Name
= getRegName(MI
->getOperand(1).getReg());
58 DestName
= getRegName(MI
->getOperand(0).getReg());
59 DecodePSHUFMask(4, MI
->getOperand(MI
->getNumOperands()-1).getImm(),
64 Src1Name
= getRegName(MI
->getOperand(1).getReg());
67 DestName
= getRegName(MI
->getOperand(0).getReg());
68 DecodePSHUFHWMask(MI
->getOperand(MI
->getNumOperands()-1).getImm(),
72 Src1Name
= getRegName(MI
->getOperand(1).getReg());
75 DestName
= getRegName(MI
->getOperand(0).getReg());
76 DecodePSHUFLWMask(MI
->getOperand(MI
->getNumOperands()-1).getImm(),
80 case X86::PUNPCKHBWrr
:
81 Src2Name
= getRegName(MI
->getOperand(2).getReg());
83 case X86::PUNPCKHBWrm
:
84 Src1Name
= getRegName(MI
->getOperand(0).getReg());
85 DecodePUNPCKHMask(16, ShuffleMask
);
87 case X86::PUNPCKHWDrr
:
88 Src2Name
= getRegName(MI
->getOperand(2).getReg());
90 case X86::PUNPCKHWDrm
:
91 Src1Name
= getRegName(MI
->getOperand(0).getReg());
92 DecodePUNPCKHMask(8, ShuffleMask
);
94 case X86::PUNPCKHDQrr
:
95 Src2Name
= getRegName(MI
->getOperand(2).getReg());
97 case X86::PUNPCKHDQrm
:
98 Src1Name
= getRegName(MI
->getOperand(0).getReg());
99 DecodePUNPCKHMask(4, ShuffleMask
);
101 case X86::PUNPCKHQDQrr
:
102 Src2Name
= getRegName(MI
->getOperand(2).getReg());
104 case X86::PUNPCKHQDQrm
:
105 Src1Name
= getRegName(MI
->getOperand(0).getReg());
106 DecodePUNPCKHMask(2, ShuffleMask
);
109 case X86::PUNPCKLBWrr
:
110 Src2Name
= getRegName(MI
->getOperand(2).getReg());
112 case X86::PUNPCKLBWrm
:
113 Src1Name
= getRegName(MI
->getOperand(0).getReg());
114 DecodePUNPCKLBWMask(16, ShuffleMask
);
116 case X86::PUNPCKLWDrr
:
117 Src2Name
= getRegName(MI
->getOperand(2).getReg());
119 case X86::PUNPCKLWDrm
:
120 Src1Name
= getRegName(MI
->getOperand(0).getReg());
121 DecodePUNPCKLWDMask(8, ShuffleMask
);
123 case X86::PUNPCKLDQrr
:
124 Src2Name
= getRegName(MI
->getOperand(2).getReg());
126 case X86::PUNPCKLDQrm
:
127 Src1Name
= getRegName(MI
->getOperand(0).getReg());
128 DecodePUNPCKLDQMask(4, ShuffleMask
);
130 case X86::PUNPCKLQDQrr
:
131 Src2Name
= getRegName(MI
->getOperand(2).getReg());
133 case X86::PUNPCKLQDQrm
:
134 Src1Name
= getRegName(MI
->getOperand(0).getReg());
135 DecodePUNPCKLQDQMask(2, ShuffleMask
);
139 DecodeSHUFPSMask(2, MI
->getOperand(3).getImm(), ShuffleMask
);
140 Src1Name
= getRegName(MI
->getOperand(0).getReg());
141 Src2Name
= getRegName(MI
->getOperand(2).getReg());
145 Src2Name
= getRegName(MI
->getOperand(2).getReg());
148 DecodeSHUFPSMask(4, MI
->getOperand(3).getImm(), ShuffleMask
);
149 Src1Name
= getRegName(MI
->getOperand(0).getReg());
152 case X86::UNPCKLPDrr
:
153 Src2Name
= getRegName(MI
->getOperand(2).getReg());
155 case X86::UNPCKLPDrm
:
156 DecodeUNPCKLPDMask(2, ShuffleMask
);
157 Src1Name
= getRegName(MI
->getOperand(0).getReg());
159 case X86::VUNPCKLPDrr
:
160 Src2Name
= getRegName(MI
->getOperand(2).getReg());
162 case X86::VUNPCKLPDrm
:
163 DecodeUNPCKLPDMask(2, ShuffleMask
);
164 Src1Name
= getRegName(MI
->getOperand(1).getReg());
166 case X86::VUNPCKLPDYrr
:
167 Src2Name
= getRegName(MI
->getOperand(2).getReg());
169 case X86::VUNPCKLPDYrm
:
170 DecodeUNPCKLPDMask(4, ShuffleMask
);
171 Src1Name
= getRegName(MI
->getOperand(1).getReg());
173 case X86::UNPCKLPSrr
:
174 Src2Name
= getRegName(MI
->getOperand(2).getReg());
176 case X86::UNPCKLPSrm
:
177 DecodeUNPCKLPSMask(4, ShuffleMask
);
178 Src1Name
= getRegName(MI
->getOperand(0).getReg());
180 case X86::VUNPCKLPSrr
:
181 Src2Name
= getRegName(MI
->getOperand(2).getReg());
183 case X86::VUNPCKLPSrm
:
184 DecodeUNPCKLPSMask(4, ShuffleMask
);
185 Src1Name
= getRegName(MI
->getOperand(1).getReg());
187 case X86::VUNPCKLPSYrr
:
188 Src2Name
= getRegName(MI
->getOperand(2).getReg());
190 case X86::VUNPCKLPSYrm
:
191 DecodeUNPCKLPSMask(8, ShuffleMask
);
192 Src1Name
= getRegName(MI
->getOperand(1).getReg());
194 case X86::UNPCKHPDrr
:
195 Src2Name
= getRegName(MI
->getOperand(2).getReg());
197 case X86::UNPCKHPDrm
:
198 DecodeUNPCKHPMask(2, ShuffleMask
);
199 Src1Name
= getRegName(MI
->getOperand(0).getReg());
201 case X86::UNPCKHPSrr
:
202 Src2Name
= getRegName(MI
->getOperand(2).getReg());
204 case X86::UNPCKHPSrm
:
205 DecodeUNPCKHPMask(4, ShuffleMask
);
206 Src1Name
= getRegName(MI
->getOperand(0).getReg());
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") << " = ";
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.
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
229 for (unsigned i
= 0, e
= ShuffleMask
.size(); i
!= e
; ++i
) {
232 if (ShuffleMask
[i
] == SM_SentinelZero
) {
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") << '[';
244 (int)ShuffleMask
[i
] >= 0 &&
245 (ShuffleMask
[i
] < ShuffleMask
.size()) == isSrc1
) {
250 OS
<< ShuffleMask
[i
] % ShuffleMask
.size();
254 --i
; // For loop increments element #.