Line data Source code
1 : //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
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 : // \file
9 : //===----------------------------------------------------------------------===//
10 :
11 : #include "AMDGPUInstPrinter.h"
12 : #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
13 : #include "SIDefines.h"
14 : #include "Utils/AMDGPUAsmUtils.h"
15 : #include "Utils/AMDGPUBaseInfo.h"
16 : #include "llvm/MC/MCExpr.h"
17 : #include "llvm/MC/MCInst.h"
18 : #include "llvm/MC/MCInstrDesc.h"
19 : #include "llvm/MC/MCInstrInfo.h"
20 : #include "llvm/MC/MCRegisterInfo.h"
21 : #include "llvm/MC/MCSubtargetInfo.h"
22 : #include "llvm/Support/ErrorHandling.h"
23 : #include "llvm/Support/MathExtras.h"
24 : #include "llvm/Support/raw_ostream.h"
25 : #include <cassert>
26 :
27 : using namespace llvm;
28 : using namespace llvm::AMDGPU;
29 :
30 591813 : void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
31 : StringRef Annot, const MCSubtargetInfo &STI) {
32 : OS.flush();
33 591813 : printInstruction(MI, STI, OS);
34 591813 : printAnnotation(OS, Annot);
35 591813 : }
36 :
37 30690 : void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
38 : const MCSubtargetInfo &STI,
39 : raw_ostream &O) {
40 61380 : O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
41 30690 : }
42 :
43 0 : void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
44 : raw_ostream &O) {
45 0 : O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
46 0 : }
47 :
48 7903 : void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
49 : const MCSubtargetInfo &STI,
50 : raw_ostream &O) {
51 : // It's possible to end up with a 32-bit literal used with a 16-bit operand
52 : // with ignored high bits. Print as 32-bit anyway in that case.
53 7903 : int64_t Imm = MI->getOperand(OpNo).getImm();
54 7903 : if (isInt<16>(Imm) || isUInt<16>(Imm))
55 7899 : O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
56 : else
57 4 : printU32ImmOperand(MI, OpNo, STI, O);
58 7903 : }
59 :
60 3671 : void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
61 : raw_ostream &O) {
62 7342 : O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
63 3671 : }
64 :
65 7708 : void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
66 : raw_ostream &O) {
67 15416 : O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
68 7708 : }
69 :
70 31042 : void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
71 : raw_ostream &O) {
72 62084 : O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
73 31042 : }
74 :
75 1652 : void AMDGPUInstPrinter::printS13ImmDecOperand(const MCInst *MI, unsigned OpNo,
76 : raw_ostream &O) {
77 4956 : O << formatDec(SignExtend32<13>(MI->getOperand(OpNo).getImm()));
78 1652 : }
79 :
80 27250 : void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
81 : const MCSubtargetInfo &STI,
82 : raw_ostream &O) {
83 54500 : O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
84 27250 : }
85 :
86 234151 : void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
87 : raw_ostream &O, StringRef BitName) {
88 234151 : if (MI->getOperand(OpNo).getImm()) {
89 6725 : O << ' ' << BitName;
90 : }
91 234151 : }
92 :
93 0 : void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
94 : raw_ostream &O) {
95 0 : printNamedBit(MI, OpNo, O, "offen");
96 0 : }
97 :
98 0 : void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
99 : raw_ostream &O) {
100 0 : printNamedBit(MI, OpNo, O, "idxen");
101 0 : }
102 :
103 0 : void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
104 : raw_ostream &O) {
105 0 : printNamedBit(MI, OpNo, O, "addr64");
106 0 : }
107 :
108 0 : void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
109 : raw_ostream &O) {
110 0 : if (MI->getOperand(OpNo).getImm()) {
111 0 : O << " offset:";
112 0 : printU16ImmDecOperand(MI, OpNo, O);
113 : }
114 0 : }
115 :
116 65166 : void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
117 : const MCSubtargetInfo &STI,
118 : raw_ostream &O) {
119 65166 : uint16_t Imm = MI->getOperand(OpNo).getImm();
120 65166 : if (Imm != 0) {
121 61994 : O << ((OpNo == 0)? "offset:" : " offset:");
122 31019 : printU16ImmDecOperand(MI, OpNo, O);
123 : }
124 65166 : }
125 :
126 4549 : void AMDGPUInstPrinter::printOffsetS13(const MCInst *MI, unsigned OpNo,
127 : const MCSubtargetInfo &STI,
128 : raw_ostream &O) {
129 4549 : uint16_t Imm = MI->getOperand(OpNo).getImm();
130 4549 : if (Imm != 0) {
131 3304 : O << ((OpNo == 0)? "offset:" : " offset:");
132 1652 : printS13ImmDecOperand(MI, OpNo, O);
133 : }
134 4549 : }
135 :
136 4531 : void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
137 : const MCSubtargetInfo &STI,
138 : raw_ostream &O) {
139 4531 : if (MI->getOperand(OpNo).getImm()) {
140 3409 : O << " offset0:";
141 3409 : printU8ImmDecOperand(MI, OpNo, O);
142 : }
143 4531 : }
144 :
145 4531 : void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
146 : const MCSubtargetInfo &STI,
147 : raw_ostream &O) {
148 4531 : if (MI->getOperand(OpNo).getImm()) {
149 4299 : O << " offset1:";
150 4299 : printU8ImmDecOperand(MI, OpNo, O);
151 : }
152 4531 : }
153 :
154 11997 : void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
155 : const MCSubtargetInfo &STI,
156 : raw_ostream &O) {
157 11997 : printU32ImmOperand(MI, OpNo, STI, O);
158 11997 : }
159 :
160 15049 : void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
161 : const MCSubtargetInfo &STI,
162 : raw_ostream &O) {
163 15049 : printU32ImmOperand(MI, OpNo, STI, O);
164 15049 : }
165 :
166 42 : void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
167 : const MCSubtargetInfo &STI,
168 : raw_ostream &O) {
169 42 : printU32ImmOperand(MI, OpNo, STI, O);
170 42 : }
171 :
172 15496 : void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
173 : const MCSubtargetInfo &STI, raw_ostream &O) {
174 15496 : printNamedBit(MI, OpNo, O, "gds");
175 15496 : }
176 :
177 86957 : void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
178 : const MCSubtargetInfo &STI, raw_ostream &O) {
179 86957 : printNamedBit(MI, OpNo, O, "glc");
180 86957 : }
181 :
182 63848 : void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
183 : const MCSubtargetInfo &STI, raw_ostream &O) {
184 63848 : printNamedBit(MI, OpNo, O, "slc");
185 63848 : }
186 :
187 43542 : void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
188 : const MCSubtargetInfo &STI, raw_ostream &O) {
189 43542 : printNamedBit(MI, OpNo, O, "tfe");
190 43542 : }
191 :
192 5138 : void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
193 : const MCSubtargetInfo &STI, raw_ostream &O) {
194 5138 : if (MI->getOperand(OpNo).getImm()) {
195 4856 : O << " dmask:";
196 4856 : printU16ImmOperand(MI, OpNo, STI, O);
197 : }
198 5138 : }
199 :
200 5138 : void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
201 : const MCSubtargetInfo &STI, raw_ostream &O) {
202 5138 : printNamedBit(MI, OpNo, O, "unorm");
203 5138 : }
204 :
205 5138 : void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
206 : const MCSubtargetInfo &STI, raw_ostream &O) {
207 5138 : printNamedBit(MI, OpNo, O, "da");
208 5138 : }
209 :
210 5138 : void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
211 : const MCSubtargetInfo &STI, raw_ostream &O) {
212 5138 : if (STI.hasFeature(AMDGPU::FeatureR128A16))
213 1583 : printNamedBit(MI, OpNo, O, "a16");
214 : else
215 3555 : printNamedBit(MI, OpNo, O, "r128");
216 5138 : }
217 :
218 5138 : void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
219 : const MCSubtargetInfo &STI, raw_ostream &O) {
220 5138 : printNamedBit(MI, OpNo, O, "lwe");
221 5138 : }
222 :
223 3756 : void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
224 : const MCSubtargetInfo &STI, raw_ostream &O) {
225 3756 : printNamedBit(MI, OpNo, O, "d16");
226 3756 : }
227 :
228 737 : void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
229 : const MCSubtargetInfo &STI,
230 : raw_ostream &O) {
231 737 : if (MI->getOperand(OpNo).getImm())
232 113 : O << " compr";
233 737 : }
234 :
235 737 : void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
236 : const MCSubtargetInfo &STI,
237 : raw_ostream &O) {
238 737 : if (MI->getOperand(OpNo).getImm())
239 202 : O << " vm";
240 737 : }
241 :
242 318 : void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
243 : const MCSubtargetInfo &STI,
244 : raw_ostream &O) {
245 318 : if (unsigned Val = MI->getOperand(OpNo).getImm()) {
246 318 : O << " dfmt:" << (Val & 15);
247 318 : O << ", nfmt:" << (Val >> 4);
248 : }
249 318 : }
250 :
251 1227144 : void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
252 : const MCRegisterInfo &MRI) {
253 1227144 : switch (RegNo) {
254 7704 : case AMDGPU::VCC:
255 7704 : O << "vcc";
256 7704 : return;
257 0 : case AMDGPU::SCC:
258 0 : O << "scc";
259 0 : return;
260 5829 : case AMDGPU::EXEC:
261 5829 : O << "exec";
262 5829 : return;
263 9629 : case AMDGPU::M0:
264 9629 : O << "m0";
265 9629 : return;
266 0 : case AMDGPU::FLAT_SCR:
267 0 : O << "flat_scratch";
268 0 : return;
269 4 : case AMDGPU::XNACK_MASK:
270 4 : O << "xnack_mask";
271 4 : return;
272 7136 : case AMDGPU::VCC_LO:
273 7136 : O << "vcc_lo";
274 7136 : return;
275 7136 : case AMDGPU::VCC_HI:
276 7136 : O << "vcc_hi";
277 7136 : return;
278 2870 : case AMDGPU::TBA_LO:
279 2870 : O << "tba_lo";
280 2870 : return;
281 2870 : case AMDGPU::TBA_HI:
282 2870 : O << "tba_hi";
283 2870 : return;
284 2884 : case AMDGPU::TMA_LO:
285 2884 : O << "tma_lo";
286 2884 : return;
287 2877 : case AMDGPU::TMA_HI:
288 2877 : O << "tma_hi";
289 2877 : return;
290 6922 : case AMDGPU::EXEC_LO:
291 6922 : O << "exec_lo";
292 6922 : return;
293 6915 : case AMDGPU::EXEC_HI:
294 6915 : O << "exec_hi";
295 6915 : return;
296 0 : case AMDGPU::FLAT_SCR_LO:
297 0 : O << "flat_scratch_lo";
298 0 : return;
299 0 : case AMDGPU::FLAT_SCR_HI:
300 0 : O << "flat_scratch_hi";
301 0 : return;
302 3 : case AMDGPU::XNACK_MASK_LO:
303 3 : O << "xnack_mask_lo";
304 3 : return;
305 4 : case AMDGPU::XNACK_MASK_HI:
306 4 : O << "xnack_mask_hi";
307 4 : return;
308 : case AMDGPU::FP_REG:
309 : case AMDGPU::SP_REG:
310 : case AMDGPU::SCRATCH_WAVE_OFFSET_REG:
311 : case AMDGPU::PRIVATE_RSRC_REG:
312 : llvm_unreachable("pseudo-register should not ever be emitted");
313 : default:
314 : break;
315 : }
316 :
317 : // The low 8 bits of the encoding value is the register index, for both VGPRs
318 : // and SGPRs.
319 1164361 : unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1);
320 :
321 : unsigned NumRegs;
322 1164361 : if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) {
323 : O << 'v';
324 : NumRegs = 1;
325 560451 : } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) {
326 : O << 's';
327 : NumRegs = 1;
328 331588 : } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) {
329 : O <<'v';
330 : NumRegs = 2;
331 242927 : } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) {
332 : O << 's';
333 : NumRegs = 2;
334 108211 : } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) {
335 : O << 'v';
336 : NumRegs = 4;
337 89905 : } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) {
338 : O << 's';
339 : NumRegs = 4;
340 36660 : } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) {
341 : O << 'v';
342 : NumRegs = 3;
343 35429 : } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) {
344 : O << 'v';
345 : NumRegs = 8;
346 35297 : } else if (MRI.getRegClass(AMDGPU::SGPR_256RegClassID).contains(RegNo)) {
347 : O << 's';
348 : NumRegs = 8;
349 29078 : } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) {
350 : O << 'v';
351 : NumRegs = 16;
352 29066 : } else if (MRI.getRegClass(AMDGPU::SGPR_512RegClassID).contains(RegNo)) {
353 : O << 's';
354 : NumRegs = 16;
355 : } else {
356 28536 : O << getRegisterName(RegNo);
357 28536 : return;
358 : }
359 :
360 : if (NumRegs == 1) {
361 : O << RegIdx;
362 832773 : return;
363 : }
364 :
365 303052 : O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
366 : }
367 :
368 243659 : void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
369 : const MCSubtargetInfo &STI, raw_ostream &O) {
370 487318 : if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
371 73978 : O << "_e64 ";
372 169681 : else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
373 15341 : O << "_dpp ";
374 154340 : else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
375 34348 : O << "_sdwa ";
376 : else
377 119992 : O << "_e32 ";
378 :
379 243659 : printOperand(MI, OpNo, STI, O);
380 243659 : }
381 :
382 676 : void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
383 : const MCSubtargetInfo &STI, raw_ostream &O) {
384 676 : if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
385 178 : O << " ";
386 : else
387 498 : O << "_e32 ";
388 :
389 676 : printOperand(MI, OpNo, STI, O);
390 676 : }
391 :
392 12888 : void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
393 : const MCSubtargetInfo &STI,
394 : raw_ostream &O) {
395 12888 : int16_t SImm = static_cast<int16_t>(Imm);
396 12888 : if (SImm >= -16 && SImm <= 64) {
397 : O << SImm;
398 7276 : return;
399 : }
400 :
401 5612 : if (Imm == 0x3C00)
402 97 : O<< "1.0";
403 5515 : else if (Imm == 0xBC00)
404 21 : O<< "-1.0";
405 5494 : else if (Imm == 0x3800)
406 2121 : O<< "0.5";
407 3373 : else if (Imm == 0xB800)
408 9 : O<< "-0.5";
409 3364 : else if (Imm == 0x4000)
410 70 : O<< "2.0";
411 3294 : else if (Imm == 0xC000)
412 23 : O<< "-2.0";
413 3271 : else if (Imm == 0x4400)
414 65 : O<< "4.0";
415 3206 : else if (Imm == 0xC400)
416 2071 : O<< "-4.0";
417 1135 : else if (Imm == 0x3118) {
418 : assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
419 17 : O << "0.15915494";
420 : } else
421 1118 : O << formatHex(static_cast<uint64_t>(Imm));
422 : }
423 :
424 357 : void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
425 : const MCSubtargetInfo &STI,
426 : raw_ostream &O) {
427 : uint16_t Lo16 = static_cast<uint16_t>(Imm);
428 357 : printImmediate16(Lo16, STI, O);
429 357 : }
430 :
431 137218 : void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
432 : const MCSubtargetInfo &STI,
433 : raw_ostream &O) {
434 137218 : int32_t SImm = static_cast<int32_t>(Imm);
435 137218 : if (SImm >= -16 && SImm <= 64) {
436 : O << SImm;
437 102017 : return;
438 : }
439 :
440 : if (Imm == FloatToBits(0.0f))
441 : O << "0.0";
442 35201 : else if (Imm == FloatToBits(1.0f))
443 935 : O << "1.0";
444 34266 : else if (Imm == FloatToBits(-1.0f))
445 135 : O << "-1.0";
446 34131 : else if (Imm == FloatToBits(0.5f))
447 4919 : O << "0.5";
448 29212 : else if (Imm == FloatToBits(-0.5f))
449 21 : O << "-0.5";
450 29191 : else if (Imm == FloatToBits(2.0f))
451 380 : O << "2.0";
452 28811 : else if (Imm == FloatToBits(-2.0f))
453 101 : O << "-2.0";
454 28710 : else if (Imm == FloatToBits(4.0f))
455 333 : O << "4.0";
456 28377 : else if (Imm == FloatToBits(-4.0f))
457 4804 : O << "-4.0";
458 23573 : else if (Imm == 0x3e22f983 &&
459 : STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
460 93 : O << "0.15915494";
461 : else
462 23480 : O << formatHex(static_cast<uint64_t>(Imm));
463 : }
464 :
465 10577 : void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
466 : const MCSubtargetInfo &STI,
467 : raw_ostream &O) {
468 10577 : int64_t SImm = static_cast<int64_t>(Imm);
469 10577 : if (SImm >= -16 && SImm <= 64) {
470 4581 : O << SImm;
471 4581 : return;
472 : }
473 :
474 : if (Imm == DoubleToBits(0.0))
475 : O << "0.0";
476 5996 : else if (Imm == DoubleToBits(1.0))
477 169 : O << "1.0";
478 5827 : else if (Imm == DoubleToBits(-1.0))
479 33 : O << "-1.0";
480 5794 : else if (Imm == DoubleToBits(0.5))
481 1970 : O << "0.5";
482 3824 : else if (Imm == DoubleToBits(-0.5))
483 4 : O << "-0.5";
484 3820 : else if (Imm == DoubleToBits(2.0))
485 43 : O << "2.0";
486 3777 : else if (Imm == DoubleToBits(-2.0))
487 4 : O << "-2.0";
488 3773 : else if (Imm == DoubleToBits(4.0))
489 35 : O << "4.0";
490 3738 : else if (Imm == DoubleToBits(-4.0))
491 1947 : O << "-4.0";
492 1791 : else if (Imm == 0x3fc45f306dc9c882 &&
493 : STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
494 19 : O << "0.15915494";
495 : else {
496 : assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
497 :
498 : // In rare situations, we will have a 32-bit literal in a 64-bit
499 : // operand. This is technically allowed for the encoding of s_mov_b64.
500 1772 : O << formatHex(static_cast<uint64_t>(Imm));
501 : }
502 : }
503 :
504 1387985 : void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
505 : const MCSubtargetInfo &STI,
506 : raw_ostream &O) {
507 1387985 : if (OpNo >= MI->getNumOperands()) {
508 0 : O << "/*Missing OP" << OpNo << "*/";
509 0 : return;
510 : }
511 :
512 : const MCOperand &Op = MI->getOperand(OpNo);
513 1387985 : if (Op.isReg()) {
514 1224025 : printRegOperand(Op.getReg(), O, MRI);
515 163960 : } else if (Op.isImm()) {
516 160857 : const MCInstrDesc &Desc = MII.get(MI->getOpcode());
517 160857 : switch (Desc.OpInfo[OpNo].OperandType) {
518 137218 : case AMDGPU::OPERAND_REG_IMM_INT32:
519 : case AMDGPU::OPERAND_REG_IMM_FP32:
520 : case AMDGPU::OPERAND_REG_INLINE_C_INT32:
521 : case AMDGPU::OPERAND_REG_INLINE_C_FP32:
522 : case MCOI::OPERAND_IMMEDIATE:
523 137218 : printImmediate32(Op.getImm(), STI, O);
524 137218 : break;
525 10577 : case AMDGPU::OPERAND_REG_IMM_INT64:
526 : case AMDGPU::OPERAND_REG_IMM_FP64:
527 : case AMDGPU::OPERAND_REG_INLINE_C_INT64:
528 : case AMDGPU::OPERAND_REG_INLINE_C_FP64:
529 10577 : printImmediate64(Op.getImm(), STI, O);
530 10577 : break;
531 12531 : case AMDGPU::OPERAND_REG_INLINE_C_INT16:
532 : case AMDGPU::OPERAND_REG_INLINE_C_FP16:
533 : case AMDGPU::OPERAND_REG_IMM_INT16:
534 : case AMDGPU::OPERAND_REG_IMM_FP16:
535 12531 : printImmediate16(Op.getImm(), STI, O);
536 12531 : break;
537 357 : case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
538 : case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
539 357 : printImmediateV216(Op.getImm(), STI, O);
540 357 : break;
541 174 : case MCOI::OPERAND_UNKNOWN:
542 : case MCOI::OPERAND_PCREL:
543 174 : O << formatDec(Op.getImm());
544 174 : break;
545 0 : case MCOI::OPERAND_REGISTER:
546 : // FIXME: This should be removed and handled somewhere else. Seems to come
547 : // from a disassembler bug.
548 0 : O << "/*invalid immediate*/";
549 0 : break;
550 0 : default:
551 : // We hit this for the immediate instruction bits that don't yet have a
552 : // custom printer.
553 0 : llvm_unreachable("unexpected immediate operand type");
554 : }
555 3103 : } else if (Op.isFPImm()) {
556 : // We special case 0.0 because otherwise it will be printed as an integer.
557 0 : if (Op.getFPImm() == 0.0)
558 0 : O << "0.0";
559 : else {
560 0 : const MCInstrDesc &Desc = MII.get(MI->getOpcode());
561 0 : int RCID = Desc.OpInfo[OpNo].RegClass;
562 0 : unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
563 0 : if (RCBits == 32)
564 0 : printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
565 0 : else if (RCBits == 64)
566 0 : printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
567 : else
568 0 : llvm_unreachable("Invalid register class size");
569 : }
570 3103 : } else if (Op.isExpr()) {
571 3103 : const MCExpr *Exp = Op.getExpr();
572 3103 : Exp->print(O, &MAI);
573 : } else {
574 0 : O << "/*INV_OP*/";
575 : }
576 : }
577 :
578 152882 : void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
579 : unsigned OpNo,
580 : const MCSubtargetInfo &STI,
581 : raw_ostream &O) {
582 152882 : unsigned InputModifiers = MI->getOperand(OpNo).getImm();
583 :
584 : // Use 'neg(...)' instead of '-' to avoid ambiguity.
585 : // This is important for integer literals because
586 : // -1 is not the same value as neg(1).
587 : bool NegMnemo = false;
588 :
589 152882 : if (InputModifiers & SISrcMods::NEG) {
590 15502 : if (OpNo + 1 < MI->getNumOperands() &&
591 7751 : (InputModifiers & SISrcMods::ABS) == 0) {
592 : const MCOperand &Op = MI->getOperand(OpNo + 1);
593 7462 : NegMnemo = Op.isImm() || Op.isFPImm();
594 : }
595 : if (NegMnemo) {
596 32 : O << "neg(";
597 : } else {
598 : O << '-';
599 : }
600 : }
601 :
602 152882 : if (InputModifiers & SISrcMods::ABS)
603 : O << '|';
604 152882 : printOperand(MI, OpNo + 1, STI, O);
605 152882 : if (InputModifiers & SISrcMods::ABS)
606 : O << '|';
607 :
608 152882 : if (NegMnemo) {
609 : O << ')';
610 : }
611 152882 : }
612 :
613 38825 : void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
614 : unsigned OpNo,
615 : const MCSubtargetInfo &STI,
616 : raw_ostream &O) {
617 38825 : unsigned InputModifiers = MI->getOperand(OpNo).getImm();
618 38825 : if (InputModifiers & SISrcMods::SEXT)
619 1752 : O << "sext(";
620 38825 : printOperand(MI, OpNo + 1, STI, O);
621 38825 : if (InputModifiers & SISrcMods::SEXT)
622 : O << ')';
623 38825 : }
624 :
625 15345 : void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
626 : const MCSubtargetInfo &STI,
627 : raw_ostream &O) {
628 : using namespace AMDGPU::DPP;
629 :
630 15345 : unsigned Imm = MI->getOperand(OpNo).getImm();
631 15345 : if (Imm <= DppCtrl::QUAD_PERM_LAST) {
632 7396 : O << " quad_perm:[";
633 7396 : O << formatDec(Imm & 0x3) << ',';
634 7396 : O << formatDec((Imm & 0xc) >> 2) << ',';
635 7396 : O << formatDec((Imm & 0x30) >> 4) << ',';
636 14792 : O << formatDec((Imm & 0xc0) >> 6) << ']';
637 7949 : } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
638 : (Imm <= DppCtrl::ROW_SHL_LAST)) {
639 1485 : O << " row_shl:";
640 1485 : printU4ImmDecOperand(MI, OpNo, O);
641 6464 : } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
642 : (Imm <= DppCtrl::ROW_SHR_LAST)) {
643 1133 : O << " row_shr:";
644 1133 : printU4ImmDecOperand(MI, OpNo, O);
645 5331 : } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
646 : (Imm <= DppCtrl::ROW_ROR_LAST)) {
647 1053 : O << " row_ror:";
648 1053 : printU4ImmDecOperand(MI, OpNo, O);
649 4278 : } else if (Imm == DppCtrl::WAVE_SHL1) {
650 528 : O << " wave_shl:1";
651 3750 : } else if (Imm == DppCtrl::WAVE_ROL1) {
652 528 : O << " wave_rol:1";
653 3222 : } else if (Imm == DppCtrl::WAVE_SHR1) {
654 548 : O << " wave_shr:1";
655 2674 : } else if (Imm == DppCtrl::WAVE_ROR1) {
656 528 : O << " wave_ror:1";
657 2146 : } else if (Imm == DppCtrl::ROW_MIRROR) {
658 526 : O << " row_mirror";
659 1620 : } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
660 526 : O << " row_half_mirror";
661 1094 : } else if (Imm == DppCtrl::BCAST15) {
662 548 : O << " row_bcast:15";
663 546 : } else if (Imm == DppCtrl::BCAST31) {
664 546 : O << " row_bcast:31";
665 : } else {
666 0 : O << " /* Invalid dpp_ctrl value */";
667 : }
668 15345 : }
669 :
670 15345 : void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
671 : const MCSubtargetInfo &STI,
672 : raw_ostream &O) {
673 15345 : O << " row_mask:";
674 15345 : printU4ImmOperand(MI, OpNo, STI, O);
675 15345 : }
676 :
677 15345 : void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
678 : const MCSubtargetInfo &STI,
679 : raw_ostream &O) {
680 15345 : O << " bank_mask:";
681 15345 : printU4ImmOperand(MI, OpNo, STI, O);
682 15345 : }
683 :
684 15345 : void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
685 : const MCSubtargetInfo &STI,
686 : raw_ostream &O) {
687 15345 : unsigned Imm = MI->getOperand(OpNo).getImm();
688 15345 : if (Imm) {
689 1012 : O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
690 : }
691 15345 : }
692 :
693 89997 : void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
694 : raw_ostream &O) {
695 : using namespace llvm::AMDGPU::SDWA;
696 :
697 89997 : unsigned Imm = MI->getOperand(OpNo).getImm();
698 89997 : switch (Imm) {
699 3011 : case SdwaSel::BYTE_0: O << "BYTE_0"; break;
700 2701 : case SdwaSel::BYTE_1: O << "BYTE_1"; break;
701 3073 : case SdwaSel::BYTE_2: O << "BYTE_2"; break;
702 2633 : case SdwaSel::BYTE_3: O << "BYTE_3"; break;
703 3328 : case SdwaSel::WORD_0: O << "WORD_0"; break;
704 4310 : case SdwaSel::WORD_1: O << "WORD_1"; break;
705 70941 : case SdwaSel::DWORD: O << "DWORD"; break;
706 0 : default: llvm_unreachable("Invalid SDWA data select operand");
707 : }
708 89997 : }
709 :
710 19869 : void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
711 : const MCSubtargetInfo &STI,
712 : raw_ostream &O) {
713 19869 : O << "dst_sel:";
714 19869 : printSDWASel(MI, OpNo, O);
715 19869 : }
716 :
717 39522 : void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
718 : const MCSubtargetInfo &STI,
719 : raw_ostream &O) {
720 39522 : O << "src0_sel:";
721 39522 : printSDWASel(MI, OpNo, O);
722 39522 : }
723 :
724 30606 : void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
725 : const MCSubtargetInfo &STI,
726 : raw_ostream &O) {
727 30606 : O << "src1_sel:";
728 30606 : printSDWASel(MI, OpNo, O);
729 30606 : }
730 :
731 19869 : void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
732 : const MCSubtargetInfo &STI,
733 : raw_ostream &O) {
734 : using namespace llvm::AMDGPU::SDWA;
735 :
736 19869 : O << "dst_unused:";
737 19869 : unsigned Imm = MI->getOperand(OpNo).getImm();
738 19869 : switch (Imm) {
739 18346 : case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
740 530 : case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
741 993 : case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
742 0 : default: llvm_unreachable("Invalid SDWA dest_unused operand");
743 : }
744 19869 : }
745 :
746 : template <unsigned N>
747 2948 : void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
748 : const MCSubtargetInfo &STI,
749 : raw_ostream &O) {
750 2948 : unsigned Opc = MI->getOpcode();
751 2948 : int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
752 2948 : unsigned En = MI->getOperand(EnIdx).getImm();
753 :
754 2211 : int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
755 :
756 : // If compr is set, print as src0, src0, src1, src1
757 4422 : if (MI->getOperand(ComprIdx).getImm()) {
758 : if (N == 1 || N == 2)
759 226 : --OpNo;
760 : else if (N == 3)
761 113 : OpNo -= 2;
762 : }
763 :
764 2948 : if (En & (1 << N))
765 4886 : printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
766 : else
767 505 : O << "off";
768 2948 : }
769 737 :
770 : void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
771 : const MCSubtargetInfo &STI,
772 737 : raw_ostream &O) {
773 737 : printExpSrcN<0>(MI, OpNo, STI, O);
774 737 : }
775 :
776 737 : void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
777 : const MCSubtargetInfo &STI,
778 : raw_ostream &O) {
779 1474 : printExpSrcN<1>(MI, OpNo, STI, O);
780 : }
781 :
782 : void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
783 113 : const MCSubtargetInfo &STI,
784 : raw_ostream &O) {
785 : printExpSrcN<2>(MI, OpNo, STI, O);
786 737 : }
787 1228 :
788 : void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
789 123 : const MCSubtargetInfo &STI,
790 737 : raw_ostream &O) {
791 737 : printExpSrcN<3>(MI, OpNo, STI, O);
792 : }
793 :
794 737 : void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
795 737 : const MCSubtargetInfo &STI,
796 737 : raw_ostream &O) {
797 : // This is really a 6 bit field.
798 737 : uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
799 :
800 : if (Tgt <= 7)
801 1474 : O << " mrt" << Tgt;
802 : else if (Tgt == 8)
803 113 : O << " mrtz";
804 : else if (Tgt == 9)
805 : O << " null";
806 : else if (Tgt >= 12 && Tgt <= 15)
807 : O << " pos" << Tgt - 12;
808 737 : else if (Tgt >= 32 && Tgt <= 63)
809 1210 : O << " param" << Tgt - 32;
810 : else {
811 132 : // Reserved values 10, 11
812 737 : O << " invalid_target_" << Tgt;
813 737 : }
814 : }
815 :
816 737 : static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
817 737 : bool IsPacked, bool HasDstSel) {
818 737 : int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
819 :
820 737 : for (int I = 0; I < NumOps; ++I) {
821 : if (!!(Ops[I] & Mod) != DefaultValue)
822 : return false;
823 1474 : }
824 :
825 113 : if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
826 : return false;
827 :
828 : return true;
829 : }
830 737 :
831 1206 : void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
832 : StringRef Name,
833 134 : unsigned Mod,
834 737 : raw_ostream &O) {
835 737 : unsigned Opc = MI->getOpcode();
836 : int NumOps = 0;
837 : int Ops[3];
838 737 :
839 737 : for (int OpName : { AMDGPU::OpName::src0_modifiers,
840 737 : AMDGPU::OpName::src1_modifiers,
841 : AMDGPU::OpName::src2_modifiers }) {
842 : int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
843 : if (Idx == -1)
844 : break;
845 :
846 : Ops[NumOps++] = MI->getOperand(Idx).getImm();
847 : }
848 :
849 : const bool HasDstSel =
850 : NumOps > 0 &&
851 : Mod == SISrcMods::OP_SEL_0 &&
852 737 : MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
853 1242 :
854 : const bool IsPacked =
855 116 : MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
856 737 :
857 : if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
858 737 : return;
859 :
860 : O << Name;
861 737 : for (int I = 0; I < NumOps; ++I) {
862 737 : if (I != 0)
863 : O << ',';
864 737 :
865 : O << !!(Ops[I] & Mod);
866 : }
867 737 :
868 737 : if (HasDstSel) {
869 : O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
870 737 : }
871 :
872 : O << ']';
873 737 : }
874 737 :
875 : void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
876 737 : const MCSubtargetInfo &STI,
877 : raw_ostream &O) {
878 : printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
879 737 : }
880 737 :
881 : void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
882 737 : const MCSubtargetInfo &STI,
883 : raw_ostream &O) {
884 : printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
885 : }
886 737 :
887 : void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
888 737 : const MCSubtargetInfo &STI,
889 474 : raw_ostream &O) {
890 263 : printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
891 37 : }
892 226 :
893 24 : void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
894 202 : const MCSubtargetInfo &STI,
895 51 : raw_ostream &O) {
896 151 : printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
897 135 : }
898 :
899 : void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
900 16 : const MCSubtargetInfo &STI,
901 : raw_ostream &O) {
902 737 : unsigned Imm = MI->getOperand(OpNum).getImm();
903 : switch (Imm) {
904 : case 0:
905 : O << "p10";
906 16875 : break;
907 : case 1:
908 53985 : O << "p20";
909 39054 : break;
910 : case 2:
911 : O << "p0";
912 : break;
913 14931 : default:
914 : O << "invalid_param_" << Imm;
915 : }
916 : }
917 :
918 : void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
919 16875 : const MCSubtargetInfo &STI,
920 : raw_ostream &O) {
921 : unsigned Attr = MI->getOperand(OpNum).getImm();
922 : O << "attr" << Attr;
923 16875 : }
924 :
925 : void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
926 : const MCSubtargetInfo &STI,
927 91981 : raw_ostream &O) {
928 : unsigned Chan = MI->getOperand(OpNum).getImm();
929 58231 : O << '.' << "xyzw"[Chan & 0x3];
930 50625 : }
931 50625 :
932 : void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
933 : const MCSubtargetInfo &STI,
934 82712 : raw_ostream &O) {
935 : unsigned Val = MI->getOperand(OpNo).getImm();
936 : if (Val == 0) {
937 : O << " 0";
938 33750 : return;
939 16875 : }
940 14328 :
941 : if (Val & VGPRIndexMode::DST_ENABLE)
942 : O << " dst";
943 16875 :
944 : if (Val & VGPRIndexMode::SRC0_ENABLE)
945 16875 : O << " src0";
946 14855 :
947 : if (Val & VGPRIndexMode::SRC1_ENABLE)
948 2020 : O << " src1";
949 7461 :
950 5441 : if (Val & VGPRIndexMode::SRC2_ENABLE)
951 : O << " src2";
952 : }
953 5441 :
954 : void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
955 : const MCSubtargetInfo &STI,
956 2020 : raw_ostream &O) {
957 355 : printOperand(MI, OpNo, STI, O);
958 : O << ", ";
959 : printOperand(MI, OpNo + 1, STI, O);
960 : }
961 :
962 : void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
963 7164 : raw_ostream &O, StringRef Asm,
964 : StringRef Default) {
965 : const MCOperand &Op = MI->getOperand(OpNo);
966 7164 : assert(Op.isImm());
967 7164 : if (Op.getImm() == 1) {
968 : O << Asm;
969 3869 : } else {
970 : O << Default;
971 : }
972 3869 : }
973 3869 :
974 : void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
975 2921 : raw_ostream &O, char Asm) {
976 : const MCOperand &Op = MI->getOperand(OpNo);
977 : assert(Op.isImm());
978 2921 : if (Op.getImm() == 1)
979 2921 : O << Asm;
980 : }
981 2921 :
982 : void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
983 : const MCSubtargetInfo &STI,
984 2921 : raw_ostream &O) {
985 2921 : if (MI->getOperand(OpNo).getImm())
986 : O << " high";
987 244 : }
988 :
989 : void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
990 244 : const MCSubtargetInfo &STI,
991 244 : raw_ostream &O) {
992 160 : if (MI->getOperand(OpNo).getImm())
993 160 : O << " clamp";
994 160 : }
995 20 :
996 20 : void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
997 20 : const MCSubtargetInfo &STI,
998 46 : raw_ostream &O) {
999 46 : int Imm = MI->getOperand(OpNo).getImm();
1000 46 : if (Imm == SIOutMods::MUL2)
1001 18 : O << " mul:2";
1002 18 : else if (Imm == SIOutMods::MUL4)
1003 : O << " mul:4";
1004 244 : else if (Imm == SIOutMods::DIV2)
1005 : O << " div:2";
1006 1374 : }
1007 :
1008 : void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1009 1374 : const MCSubtargetInfo &STI,
1010 1374 : raw_ostream &O) {
1011 1374 : using namespace llvm::AMDGPU::SendMsg;
1012 :
1013 1374 : const unsigned SImm16 = MI->getOperand(OpNo).getImm();
1014 : const unsigned Id = SImm16 & ID_MASK_;
1015 : do {
1016 1374 : if (Id == ID_INTERRUPT) {
1017 1374 : if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0.
1018 1374 : break;
1019 : O << "sendmsg(" << IdSymbolic[Id] << ')';
1020 112 : return;
1021 : }
1022 : if (Id == ID_GS || Id == ID_GS_DONE) {
1023 112 : if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0.
1024 112 : break;
1025 49 : const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_;
1026 49 : const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
1027 : if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only.
1028 : break;
1029 63 : if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits.
1030 32 : break;
1031 : O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs];
1032 63 : if (OpGs != OP_GS_NOP) { O << ", " << StreamId; }
1033 39 : O << ')';
1034 : return;
1035 63 : }
1036 9 : if (Id == ID_SYSMSG) {
1037 : if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0.
1038 63 : break;
1039 8 : const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_;
1040 : if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown.
1041 : break;
1042 0 : O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')';
1043 : return;
1044 : }
1045 0 : } while (false);
1046 0 : O << SImm16; // Unknown simm16 code.
1047 0 : }
1048 0 :
1049 : static void printSwizzleBitmask(const uint16_t AndMask,
1050 156391 : const uint16_t OrMask,
1051 : const uint16_t XorMask,
1052 : raw_ostream &O) {
1053 : using namespace llvm::AMDGPU::Swizzle;
1054 :
1055 156391 : uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1056 26524 : uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1057 :
1058 129867 : O << "\"";
1059 :
1060 156391 : for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1061 : uint16_t p0 = Probe0 & Mask;
1062 373179 : uint16_t p1 = Probe1 & Mask;
1063 :
1064 : if (p0 == p1) {
1065 : if (p0 == 0) {
1066 373179 : O << "0";
1067 : } else {
1068 373179 : O << "1";
1069 : }
1070 410 : } else {
1071 : if (p0 == 0) {
1072 : O << "p";
1073 410 : } else {
1074 32 : O << "i";
1075 410 : }
1076 : }
1077 89143 : }
1078 :
1079 : O << "\"";
1080 89143 : }
1081 2211 :
1082 89143 : void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1083 : const MCSubtargetInfo &STI,
1084 30550 : raw_ostream &O) {
1085 : using namespace llvm::AMDGPU::Swizzle;
1086 :
1087 30550 : uint16_t Imm = MI->getOperand(OpNo).getImm();
1088 30550 : if (Imm == 0) {
1089 581 : return;
1090 29969 : }
1091 583 :
1092 29386 : O << " offset:";
1093 576 :
1094 30550 : if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1095 :
1096 128 : O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1097 : for (auto i = 0; i < LANE_NUM; ++i) {
1098 : O << ",";
1099 : O << formatDec(Imm & LANE_MASK);
1100 : Imm >>= LANE_SHIFT;
1101 128 : }
1102 128 : O << ")";
1103 :
1104 128 : } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1105 34 :
1106 : uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1107 18 : uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1108 18 : uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1109 :
1110 94 : if (AndMask == BITMASK_MAX &&
1111 72 : OrMask == 0 &&
1112 : countPopulation(XorMask) == 1) {
1113 72 :
1114 72 : O << "swizzle(" << IdSymbolic[ID_SWAP];
1115 72 : O << ",";
1116 : O << formatDec(XorMask);
1117 68 : O << ")";
1118 :
1119 68 : } else if (AndMask == BITMASK_MAX &&
1120 68 : OrMask == 0 && XorMask > 0 &&
1121 : isPowerOf2_64(XorMask + 1)) {
1122 68 :
1123 : O << "swizzle(" << IdSymbolic[ID_REVERSE];
1124 22 : O << ",";
1125 15 : O << formatDec(XorMask + 1);
1126 : O << ")";
1127 15 :
1128 15 : } else {
1129 :
1130 10 : uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1131 10 : if (GroupSize > 1 &&
1132 : isPowerOf2_64(GroupSize) &&
1133 : OrMask < GroupSize &&
1134 : XorMask == 0) {
1135 :
1136 : O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1137 55 : O << ",";
1138 : O << formatDec(GroupSize);
1139 : O << ",";
1140 : O << formatDec(OrMask);
1141 : O << ")";
1142 :
1143 55 : } else {
1144 55 : O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1145 : O << ",";
1146 55 : printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1147 : O << ")";
1148 330 : }
1149 275 : }
1150 275 : } else {
1151 : printU16ImmDecOperand(MI, OpNo, O);
1152 275 : }
1153 234 : }
1154 209 :
1155 : void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1156 25 : const MCSubtargetInfo &STI,
1157 : raw_ostream &O) {
1158 : AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1159 41 :
1160 27 : unsigned SImm16 = MI->getOperand(OpNo).getImm();
1161 : unsigned Vmcnt, Expcnt, Lgkmcnt;
1162 14 : decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1163 :
1164 : bool NeedSpace = false;
1165 :
1166 : if (Vmcnt != getVmcntBitMask(ISA)) {
1167 55 : O << "vmcnt(" << Vmcnt << ')';
1168 55 : NeedSpace = true;
1169 : }
1170 281 :
1171 : if (Expcnt != getExpcntBitMask(ISA)) {
1172 : if (NeedSpace)
1173 : O << ' ';
1174 : O << "expcnt(" << Expcnt << ')';
1175 281 : NeedSpace = true;
1176 281 : }
1177 :
1178 : if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1179 : if (NeedSpace)
1180 248 : O << ' ';
1181 : O << "lgkmcnt(" << Lgkmcnt << ')';
1182 248 : }
1183 : }
1184 14 :
1185 70 : void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1186 56 : const MCSubtargetInfo &STI, raw_ostream &O) {
1187 56 : using namespace llvm::AMDGPU::Hwreg;
1188 56 :
1189 : unsigned SImm16 = MI->getOperand(OpNo).getImm();
1190 14 : const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_;
1191 : const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_;
1192 234 : const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1;
1193 :
1194 211 : O << "hwreg(";
1195 211 : unsigned Last = ID_SYMBOLIC_LAST_;
1196 211 : if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI) || AMDGPU::isVI(STI))
1197 : Last = ID_SYMBOLIC_FIRST_GFX9_;
1198 422 : if (ID_SYMBOLIC_FIRST_ <= Id && Id < Last && IdSymbolic[Id]) {
1199 211 : O << IdSymbolic[Id];
1200 : } else {
1201 : O << Id;
1202 44 : }
1203 44 : if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) {
1204 44 : O << ", " << Offset << ", " << Width;
1205 44 : }
1206 : O << ')';
1207 : }
1208 167 :
1209 35 : #include "AMDGPUGenAsmWriter.inc"
1210 :
1211 35 : void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
1212 35 : StringRef Annot, const MCSubtargetInfo &STI) {
1213 35 : O.flush();
1214 35 : printInstruction(MI, O);
1215 : printAnnotation(O, Annot);
1216 : }
1217 :
1218 132 : void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1219 : raw_ostream &O) {
1220 132 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1221 132 : }
1222 91 :
1223 : void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1224 77 : raw_ostream &O) {
1225 77 : int BankSwizzle = MI->getOperand(OpNo).getImm();
1226 77 : switch (BankSwizzle) {
1227 77 : case 1:
1228 77 : O << "BS:VEC_021/SCL_122";
1229 77 : break;
1230 : case 2:
1231 : O << "BS:VEC_120/SCL_212";
1232 55 : break;
1233 55 : case 3:
1234 55 : O << "BS:VEC_102/SCL_221";
1235 55 : break;
1236 : case 4:
1237 : O << "BS:VEC_201";
1238 : break;
1239 23 : case 5:
1240 : O << "BS:VEC_210";
1241 : break;
1242 : default:
1243 39832 : break;
1244 : }
1245 : }
1246 39832 :
1247 : void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1248 39832 : raw_ostream &O) {
1249 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1250 39832 : }
1251 :
1252 : void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1253 : raw_ostream &O) {
1254 39832 : unsigned CT = MI->getOperand(OpNo).getImm();
1255 18209 : switch (CT) {
1256 : case 0:
1257 : O << 'U';
1258 : break;
1259 39832 : case 1:
1260 3960 : O << 'N';
1261 : break;
1262 3960 : default:
1263 : break;
1264 : }
1265 : }
1266 39832 :
1267 24362 : void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1268 : raw_ostream &O) {
1269 24362 : int KCacheMode = MI->getOperand(OpNo).getImm();
1270 : if (KCacheMode > 0) {
1271 39832 : int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1272 : O << "CB" << KCacheBank << ':';
1273 342 : int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1274 : int LineSize = (KCacheMode == 1) ? 16 : 32;
1275 : O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1276 : }
1277 342 : }
1278 342 :
1279 342 : void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1280 342 : raw_ostream &O) {
1281 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1282 342 : }
1283 :
1284 342 : void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1285 : raw_ostream &O) {
1286 342 : const MCOperand &Op = MI->getOperand(OpNo);
1287 281 : assert(Op.isImm() || Op.isExpr());
1288 : if (Op.isImm()) {
1289 : int64_t Imm = Op.getImm();
1290 : O << Imm << '(' << BitsToFloat(Imm) << ')';
1291 342 : }
1292 580 : if (Op.isExpr()) {
1293 : Op.getExpr()->print(O << '@', &MAI);
1294 : }
1295 342 : }
1296 :
1297 : void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1298 : raw_ostream &O) {
1299 83295 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1300 : }
1301 :
1302 83295 : void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1303 83295 : raw_ostream &O) {
1304 83295 : switch (MI->getOperand(OpNo).getImm()) {
1305 : default: break;
1306 138388 : case 1:
1307 : O << " * 2.0";
1308 138388 : break;
1309 138388 : case 2:
1310 : O << " * 4.0";
1311 46719 : break;
1312 : case 3:
1313 46719 : O << " / 2.0";
1314 46719 : break;
1315 971 : }
1316 971 : }
1317 971 :
1318 723 : void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1319 723 : raw_ostream &O) {
1320 723 : printOperand(MI, OpNo, O);
1321 115 : O << ", ";
1322 115 : printOperand(MI, OpNo + 1, O);
1323 115 : }
1324 176 :
1325 176 : void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1326 176 : raw_ostream &O) {
1327 30 : if (OpNo >= MI->getNumOperands()) {
1328 30 : O << "/*Missing OP" << OpNo << "*/";
1329 30 : return;
1330 : }
1331 :
1332 : const MCOperand &Op = MI->getOperand(OpNo);
1333 46719 : if (Op.isReg()) {
1334 : switch (Op.getReg()) {
1335 46719 : // This is the default predicate state, so we don't need to print it.
1336 : case R600::PRED_SEL_OFF:
1337 46719 : break;
1338 46719 :
1339 : default:
1340 1104 : O << getRegisterName(Op.getReg());
1341 : break;
1342 1104 : }
1343 1104 : } else if (Op.isImm()) {
1344 : O << Op.getImm();
1345 : } else if (Op.isFPImm()) {
1346 : // We special case 0.0 because otherwise it will be printed as an integer.
1347 : if (Op.getFPImm() == 0.0)
1348 : O << "0.0";
1349 : else {
1350 : O << Op.getFPImm();
1351 : }
1352 : } else if (Op.isExpr()) {
1353 1104 : const MCExpr *Exp = Op.getExpr();
1354 : Exp->print(O, &MAI);
1355 7678 : } else {
1356 : O << "/*INV_OP*/";
1357 7678 : }
1358 7678 : }
1359 3316 :
1360 3316 : void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1361 3316 : raw_ostream &O) {
1362 3316 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1363 6632 : }
1364 :
1365 7678 : void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1366 : raw_ostream &O) {
1367 50192 : unsigned Sel = MI->getOperand(OpNo).getImm();
1368 : switch (Sel) {
1369 50192 : case 0:
1370 50192 : O << 'X';
1371 : break;
1372 27590 : case 1:
1373 : O << 'Y';
1374 : break;
1375 : case 2:
1376 27590 : O << 'Z';
1377 27577 : break;
1378 55154 : case 3:
1379 : O << 'W';
1380 27590 : break;
1381 26 : case 4:
1382 : O << '0';
1383 27590 : break;
1384 : case 5:
1385 90989 : O << '1';
1386 : break;
1387 90989 : case 7:
1388 90989 : O << '_';
1389 : break;
1390 39454 : default:
1391 : break;
1392 39454 : }
1393 : }
1394 0 :
1395 0 : void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1396 0 : raw_ostream &O) {
1397 0 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1398 0 : }
1399 0 :
1400 0 : void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1401 0 : raw_ostream &O) {
1402 0 : AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1403 : }
1404 39454 :
1405 : void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1406 1705 : raw_ostream &O) {
1407 : const MCOperand &Op = MI->getOperand(OpNo);
1408 1705 : if (Op.getImm() == 0) {
1409 1705 : O << " (MASKED)";
1410 1705 : }
1411 1705 : }
1412 :
1413 226308 : #include "R600GenAsmWriter.inc"
|