LLVM 20.0.0git
AMDGPUInstPrinter.cpp
Go to the documentation of this file.
1//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// \file
8//===----------------------------------------------------------------------===//
9
10#include "AMDGPUInstPrinter.h"
12#include "SIDefines.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCInstrDesc.h"
18#include "llvm/MC/MCInstrInfo.h"
23
24using namespace llvm;
25using namespace llvm::AMDGPU;
26
28 // FIXME: The current implementation of
29 // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
30 // as an integer or we provide a name which represents a physical register.
31 // For CFI instructions we really want to emit a name for the DWARF register
32 // instead, because there may be multiple DWARF registers corresponding to a
33 // single physical register. One case where this problem manifests is with
34 // wave32/wave64 where using the physical register name is ambiguous: if we
35 // write e.g. `.cfi_undefined v0` we lose information about the wavefront
36 // size which we need to encode the register in the final DWARF. Ideally we
37 // would extend MC to support parsing DWARF register names so we could do
38 // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
39 // non-pretty DWARF register names in assembly text.
40 OS << Reg.id();
41}
42
44 StringRef Annot, const MCSubtargetInfo &STI,
45 raw_ostream &OS) {
47 printAnnotation(OS, Annot);
48}
49
50void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
51 const MCSubtargetInfo &STI,
52 raw_ostream &O) {
53 const MCOperand &Op = MI->getOperand(OpNo);
54 if (Op.isExpr()) {
55 Op.getExpr()->print(O, &MAI);
56 return;
57 }
58
59 // It's possible to end up with a 32-bit literal used with a 16-bit operand
60 // with ignored high bits. Print as 32-bit anyway in that case.
61 int64_t Imm = Op.getImm();
62 if (isInt<16>(Imm) || isUInt<16>(Imm))
63 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
64 else
65 printU32ImmOperand(MI, OpNo, STI, O);
66}
67
68void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
69 raw_ostream &O) {
70 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
71}
72
73void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
74 const MCSubtargetInfo &STI,
75 raw_ostream &O) {
76 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
77}
78
79void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
80 raw_ostream &O, StringRef BitName) {
81 if (MI->getOperand(OpNo).getImm()) {
82 O << ' ' << BitName;
83 }
84}
85
86void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
87 const MCSubtargetInfo &STI,
88 raw_ostream &O) {
89 uint32_t Imm = MI->getOperand(OpNo).getImm();
90 if (Imm != 0) {
91 O << " offset:";
92
93 // GFX12 uses a 24-bit signed offset for VBUFFER.
94 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
95 bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);
96 if (AMDGPU::isGFX12(STI) && IsVBuffer)
97 O << formatDec(SignExtend32<24>(Imm));
98 else
99 printU16ImmDecOperand(MI, OpNo, O);
100 }
101}
102
103void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
104 const MCSubtargetInfo &STI,
105 raw_ostream &O) {
106 uint32_t Imm = MI->getOperand(OpNo).getImm();
107 if (Imm != 0) {
108 O << " offset:";
109
110 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
111 bool AllowNegative = (Desc.TSFlags & (SIInstrFlags::FlatGlobal |
113 AMDGPU::isGFX12(STI);
114
115 if (AllowNegative) // Signed offset
117 else // Unsigned offset
118 printU16ImmDecOperand(MI, OpNo, O);
119 }
120}
121
122void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
123 const MCSubtargetInfo &STI,
124 raw_ostream &O) {
125 printU32ImmOperand(MI, OpNo, STI, O);
126}
127
128void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
129 const MCSubtargetInfo &STI,
130 raw_ostream &O) {
131 O << formatHex(MI->getOperand(OpNo).getImm());
132}
133
134void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
135 const MCSubtargetInfo &STI,
136 raw_ostream &O) {
137 printU32ImmOperand(MI, OpNo, STI, O);
138}
139
140void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
141 const MCSubtargetInfo &STI, raw_ostream &O) {
142 auto Imm = MI->getOperand(OpNo).getImm();
143
144 if (AMDGPU::isGFX12Plus(STI)) {
145 const int64_t TH = Imm & CPol::TH;
146 const int64_t Scope = Imm & CPol::SCOPE;
147
148 printTH(MI, TH, Scope, O);
149 printScope(Scope, O);
150
151 return;
152 }
153
154 if (Imm & CPol::GLC)
155 O << ((AMDGPU::isGFX940(STI) &&
156 !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
157 : " glc");
158 if (Imm & CPol::SLC)
159 O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
160 if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
161 O << " dlc";
162 if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
163 O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
164 if (Imm & ~CPol::ALL)
165 O << " /* unexpected cache policy bit */";
166}
167
168void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,
169 raw_ostream &O) {
170 // For th = 0 do not print this field
171 if (TH == 0)
172 return;
173
174 const unsigned Opcode = MI->getOpcode();
175 const MCInstrDesc &TID = MII.get(Opcode);
176 bool IsStore = TID.mayStore();
177 bool IsAtomic =
179
180 O << " th:";
181
182 if (IsAtomic) {
183 O << "TH_ATOMIC_";
185 if (Scope >= AMDGPU::CPol::SCOPE_DEV)
186 O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");
187 else
188 O << formatHex(TH);
189 } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)
190 O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");
191 else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)
192 O << "RETURN";
193 else
194 O << formatHex(TH);
195 } else {
196 if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)
197 O << formatHex(TH);
198 else {
199 // This will default to printing load variants when neither MayStore nor
200 // MayLoad flag is present which is the case with instructions like
201 // image_get_resinfo.
202 O << (IsStore ? "TH_STORE_" : "TH_LOAD_");
203 switch (TH) {
205 O << "NT";
206 break;
208 O << "HT";
209 break;
210 case AMDGPU::CPol::TH_BYPASS: // or LU or RT_WB
211 O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"
212 : (IsStore ? "RT_WB" : "LU"));
213 break;
215 O << "NT_RT";
216 break;
218 O << "RT_NT";
219 break;
221 O << "NT_HT";
222 break;
224 O << "NT_WB";
225 break;
226 default:
227 llvm_unreachable("unexpected th value");
228 }
229 }
230 }
231}
232
233void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {
234 if (Scope == CPol::SCOPE_CU)
235 return;
236
237 O << " scope:";
238
239 if (Scope == CPol::SCOPE_SE)
240 O << "SCOPE_SE";
241 else if (Scope == CPol::SCOPE_DEV)
242 O << "SCOPE_DEV";
243 else if (Scope == CPol::SCOPE_SYS)
244 O << "SCOPE_SYS";
245 else
246 llvm_unreachable("unexpected scope policy value");
247
248 return;
249}
250
251void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
252 const MCSubtargetInfo &STI, raw_ostream &O) {
253 unsigned Dim = MI->getOperand(OpNo).getImm();
254 O << " dim:SQ_RSRC_IMG_";
255
257 if (DimInfo)
258 O << DimInfo->AsmSuffix;
259 else
260 O << Dim;
261}
262
263void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
264 const MCSubtargetInfo &STI, raw_ostream &O) {
265 if (STI.hasFeature(AMDGPU::FeatureR128A16))
266 printNamedBit(MI, OpNo, O, "a16");
267 else
268 printNamedBit(MI, OpNo, O, "r128");
269}
270
271void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
272 const MCSubtargetInfo &STI,
273 raw_ostream &O) {
274}
275
276void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
277 const MCSubtargetInfo &STI,
278 raw_ostream &O) {
279 using namespace llvm::AMDGPU::MTBUFFormat;
280
281 int OpNo =
282 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
283 assert(OpNo != -1);
284
285 unsigned Val = MI->getOperand(OpNo).getImm();
286 if (AMDGPU::isGFX10Plus(STI)) {
287 if (Val == UFMT_DEFAULT)
288 return;
289 if (isValidUnifiedFormat(Val, STI)) {
290 O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
291 } else {
292 O << " format:" << Val;
293 }
294 } else {
295 if (Val == DFMT_NFMT_DEFAULT)
296 return;
297 if (isValidDfmtNfmt(Val, STI)) {
298 unsigned Dfmt;
299 unsigned Nfmt;
300 decodeDfmtNfmt(Val, Dfmt, Nfmt);
301 O << " format:[";
302 if (Dfmt != DFMT_DEFAULT) {
303 O << getDfmtName(Dfmt);
304 if (Nfmt != NFMT_DEFAULT) {
305 O << ',';
306 }
307 }
308 if (Nfmt != NFMT_DEFAULT) {
309 O << getNfmtName(Nfmt, STI);
310 }
311 O << ']';
312 } else {
313 O << " format:" << Val;
314 }
315 }
316}
317
319 const MCRegisterInfo &MRI) {
320#if !defined(NDEBUG)
321 switch (RegNo) {
322 case AMDGPU::FP_REG:
323 case AMDGPU::SP_REG:
324 case AMDGPU::PRIVATE_RSRC_REG:
325 llvm_unreachable("pseudo-register should not ever be emitted");
326 default:
327 break;
328 }
329#endif
330
331 O << getRegisterName(RegNo);
332}
333
334void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
335 const MCSubtargetInfo &STI, raw_ostream &O) {
336 auto Opcode = MI->getOpcode();
337 auto Flags = MII.get(Opcode).TSFlags;
338 if (OpNo == 0) {
339 if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
340 O << "_e64_dpp";
341 else if (Flags & SIInstrFlags::VOP3) {
342 if (!getVOP3IsSingle(Opcode))
343 O << "_e64";
344 } else if (Flags & SIInstrFlags::DPP)
345 O << "_dpp";
346 else if (Flags & SIInstrFlags::SDWA)
347 O << "_sdwa";
348 else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
349 ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
350 O << "_e32";
351 O << " ";
352 }
353
354 printRegularOperand(MI, OpNo, STI, O);
355
356 // Print default vcc/vcc_lo operand.
357 switch (Opcode) {
358 default: break;
359
360 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
361 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
362 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
363 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
364 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
365 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
366 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
367 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
368 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
369 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
370 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
371 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
372 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
373 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
374 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
375 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
376 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
377 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
378 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
379 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
380 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
381 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
382 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
383 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
384 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
385 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
386 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
387 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
388 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
389 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
390 printDefaultVccOperand(false, STI, O);
391 break;
392 }
393}
394
395void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
396 const MCSubtargetInfo &STI, raw_ostream &O) {
397 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
398 O << " ";
399 else
400 O << "_e32 ";
401
402 printRegularOperand(MI, OpNo, STI, O);
403}
404
405void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
406 const MCSubtargetInfo &STI,
407 raw_ostream &O) {
408 int32_t SImm = static_cast<int32_t>(Imm);
409 if (isInlinableIntLiteral(SImm)) {
410 O << SImm;
411 return;
412 }
413
414 if (printImmediateFloat32(Imm, STI, O))
415 return;
416
417 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
418}
419
420static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI,
421 raw_ostream &O) {
422 if (Imm == 0x3C00)
423 O << "1.0";
424 else if (Imm == 0xBC00)
425 O << "-1.0";
426 else if (Imm == 0x3800)
427 O << "0.5";
428 else if (Imm == 0xB800)
429 O << "-0.5";
430 else if (Imm == 0x4000)
431 O << "2.0";
432 else if (Imm == 0xC000)
433 O << "-2.0";
434 else if (Imm == 0x4400)
435 O << "4.0";
436 else if (Imm == 0xC400)
437 O << "-4.0";
438 else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
439 O << "0.15915494";
440 else
441 return false;
442
443 return true;
444}
445
447 raw_ostream &O) {
448 if (Imm == 0x3F80)
449 O << "1.0";
450 else if (Imm == 0xBF80)
451 O << "-1.0";
452 else if (Imm == 0x3F00)
453 O << "0.5";
454 else if (Imm == 0xBF00)
455 O << "-0.5";
456 else if (Imm == 0x4000)
457 O << "2.0";
458 else if (Imm == 0xC000)
459 O << "-2.0";
460 else if (Imm == 0x4080)
461 O << "4.0";
462 else if (Imm == 0xC080)
463 O << "-4.0";
464 else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
465 O << "0.15915494";
466 else
467 return false;
468
469 return true;
470}
471
472void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,
473 const MCSubtargetInfo &STI,
474 raw_ostream &O) {
475 int16_t SImm = static_cast<int16_t>(Imm);
476 if (isInlinableIntLiteral(SImm)) {
477 O << SImm;
478 return;
479 }
480
481 if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
482 return;
483
484 O << formatHex(static_cast<uint64_t>(Imm));
485}
486
487void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,
488 const MCSubtargetInfo &STI,
489 raw_ostream &O) {
490 int16_t SImm = static_cast<int16_t>(Imm);
491 if (isInlinableIntLiteral(SImm)) {
492 O << SImm;
493 return;
494 }
495
496 uint16_t HImm = static_cast<uint16_t>(Imm);
497 if (printImmediateFP16(HImm, STI, O))
498 return;
499
500 uint64_t Imm16 = static_cast<uint16_t>(Imm);
501 O << formatHex(Imm16);
502}
503
504void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,
505 const MCSubtargetInfo &STI,
506 raw_ostream &O) {
507 int32_t SImm = static_cast<int32_t>(Imm);
508 if (isInlinableIntLiteral(SImm)) {
509 O << SImm;
510 return;
511 }
512
513 switch (OpType) {
517 if (printImmediateFloat32(Imm, STI, O))
518 return;
519 break;
523 if (isUInt<16>(Imm) &&
524 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
525 return;
526 break;
530 if (isUInt<16>(Imm) &&
531 printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
532 return;
533 break;
534 default:
535 llvm_unreachable("bad operand type");
536 }
537
538 O << formatHex(static_cast<uint64_t>(Imm));
539}
540
541bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,
542 const MCSubtargetInfo &STI,
543 raw_ostream &O) {
544 if (Imm == llvm::bit_cast<uint32_t>(0.0f))
545 O << "0.0";
546 else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
547 O << "1.0";
548 else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
549 O << "-1.0";
550 else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
551 O << "0.5";
552 else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
553 O << "-0.5";
554 else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
555 O << "2.0";
556 else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
557 O << "-2.0";
558 else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
559 O << "4.0";
560 else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
561 O << "-4.0";
562 else if (Imm == 0x3e22f983 &&
563 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
564 O << "0.15915494";
565 else
566 return false;
567
568 return true;
569}
570
571void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
572 const MCSubtargetInfo &STI,
573 raw_ostream &O) {
574 int32_t SImm = static_cast<int32_t>(Imm);
575 if (isInlinableIntLiteral(SImm)) {
576 O << SImm;
577 return;
578 }
579
580 if (printImmediateFloat32(Imm, STI, O))
581 return;
582
583 O << formatHex(static_cast<uint64_t>(Imm));
584}
585
586void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
587 const MCSubtargetInfo &STI,
588 raw_ostream &O, bool IsFP) {
589 int64_t SImm = static_cast<int64_t>(Imm);
590 if (SImm >= -16 && SImm <= 64) {
591 O << SImm;
592 return;
593 }
594
595 if (Imm == llvm::bit_cast<uint64_t>(0.0))
596 O << "0.0";
597 else if (Imm == llvm::bit_cast<uint64_t>(1.0))
598 O << "1.0";
599 else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
600 O << "-1.0";
601 else if (Imm == llvm::bit_cast<uint64_t>(0.5))
602 O << "0.5";
603 else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
604 O << "-0.5";
605 else if (Imm == llvm::bit_cast<uint64_t>(2.0))
606 O << "2.0";
607 else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
608 O << "-2.0";
609 else if (Imm == llvm::bit_cast<uint64_t>(4.0))
610 O << "4.0";
611 else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
612 O << "-4.0";
613 else if (Imm == 0x3fc45f306dc9c882 &&
614 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
615 O << "0.15915494309189532";
616 else if (IsFP) {
618 O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
619 } else {
620 assert(isUInt<32>(Imm) || isInt<32>(Imm));
621
622 // In rare situations, we will have a 32-bit literal in a 64-bit
623 // operand. This is technically allowed for the encoding of s_mov_b64.
624 O << formatHex(static_cast<uint64_t>(Imm));
625 }
626}
627
628void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
629 const MCSubtargetInfo &STI,
630 raw_ostream &O) {
631 unsigned Imm = MI->getOperand(OpNo).getImm();
632 if (!Imm)
633 return;
634
635 if (AMDGPU::isGFX940(STI)) {
636 switch (MI->getOpcode()) {
637 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
638 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
639 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
640 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
641 O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
642 << ((Imm >> 2) & 1) << ']';
643 return;
644 }
645 }
646
647 O << " blgp:" << Imm;
648}
649
650void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
651 const MCSubtargetInfo &STI,
652 raw_ostream &O) {
653 if (!FirstOperand)
654 O << ", ";
655 printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize64)
656 ? AMDGPU::VCC
657 : AMDGPU::VCC_LO,
658 O, MRI);
659 if (FirstOperand)
660 O << ", ";
661}
662
663bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
664 unsigned OpNo) const {
665 return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
666 (Desc.TSFlags & SIInstrFlags::VOPC) &&
667 !isVOPCAsmOnly(Desc.getOpcode()) &&
668 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
669 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
670}
671
672// Print default vcc/vcc_lo operand of VOPC.
673void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
674 const MCSubtargetInfo &STI,
675 raw_ostream &O) {
676 unsigned Opc = MI->getOpcode();
677 const MCInstrDesc &Desc = MII.get(Opc);
678 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
679 // 0, 1 and 2 are the first printed operands in different cases
680 // If there are printed modifiers, printOperandAndFPInputMods or
681 // printOperandAndIntInputMods will be called instead
682 if ((OpNo == 0 ||
683 (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
684 (Desc.TSFlags & SIInstrFlags::VOPC) && !isVOPCAsmOnly(Desc.getOpcode()) &&
685 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
686 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
687 printDefaultVccOperand(true, STI, O);
688
689 printRegularOperand(MI, OpNo, STI, O);
690}
691
692// Print operands after vcc or modifier handling.
693void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
694 const MCSubtargetInfo &STI,
695 raw_ostream &O) {
696 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
697
698 if (OpNo >= MI->getNumOperands()) {
699 O << "/*Missing OP" << OpNo << "*/";
700 return;
701 }
702
703 const MCOperand &Op = MI->getOperand(OpNo);
704 if (Op.isReg()) {
705 printRegOperand(Op.getReg(), O, MRI);
706
707 // Check if operand register class contains register used.
708 // Intention: print disassembler message when invalid code is decoded,
709 // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
710 int RCID = Desc.operands()[OpNo].RegClass;
711 if (RCID != -1) {
712 const MCRegisterClass RC = MRI.getRegClass(RCID);
713 auto Reg = mc2PseudoReg(Op.getReg());
714 if (!RC.contains(Reg) && !isInlineValue(Reg)) {
715 O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
716 << "\' register class*/";
717 }
718 }
719 } else if (Op.isImm()) {
720 const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
721 switch (OpTy) {
735 printImmediate32(Op.getImm(), STI, O);
736 break;
739 printImmediate64(Op.getImm(), STI, O, false);
740 break;
744 printImmediate64(Op.getImm(), STI, O, true);
745 break;
749 printImmediateInt16(Op.getImm(), STI, O);
750 break;
755 printImmediateF16(Op.getImm(), STI, O);
756 break;
761 printImmediateBF16(Op.getImm(), STI, O);
762 break;
772 printImmediateV216(Op.getImm(), OpTy, STI, O);
773 break;
776 O << formatDec(Op.getImm());
777 break;
779 // Disassembler does not fail when operand should not allow immediate
780 // operands but decodes them into 32bit immediate operand.
781 printImmediate32(Op.getImm(), STI, O);
782 O << "/*Invalid immediate*/";
783 break;
784 default:
785 // We hit this for the immediate instruction bits that don't yet have a
786 // custom printer.
787 llvm_unreachable("unexpected immediate operand type");
788 }
789 } else if (Op.isDFPImm()) {
790 double Value = bit_cast<double>(Op.getDFPImm());
791 // We special case 0.0 because otherwise it will be printed as an integer.
792 if (Value == 0.0)
793 O << "0.0";
794 else {
795 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
796 int RCID = Desc.operands()[OpNo].RegClass;
797 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
798 if (RCBits == 32)
799 printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
800 else if (RCBits == 64)
801 printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
802 else
803 llvm_unreachable("Invalid register class size");
804 }
805 } else if (Op.isExpr()) {
806 const MCExpr *Exp = Op.getExpr();
807 Exp->print(O, &MAI);
808 } else {
809 O << "/*INV_OP*/";
810 }
811
812 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
813 switch (MI->getOpcode()) {
814 default: break;
815
816 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
817 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
818 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
819 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
820 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
821 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
822 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
823 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
824 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
825 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
826 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
827 case AMDGPU::V_CNDMASK_B32_e32_gfx11:
828 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
829 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
830 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
831 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
832 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
833 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
834 case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
835 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
836 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
837 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
838 case AMDGPU::V_CNDMASK_B32_e32_gfx12:
839 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
840 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
841 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
842 case AMDGPU::V_CNDMASK_B32_dpp_gfx12:
843 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
844 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
845 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
846 case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:
847 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
848 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
849 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
850
851 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
852 case AMDGPU::V_CNDMASK_B32_e32_vi:
853 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
854 AMDGPU::OpName::src1))
855 printDefaultVccOperand(OpNo == 0, STI, O);
856 break;
857 }
858
859 if (Desc.TSFlags & SIInstrFlags::MTBUF) {
860 int SOffsetIdx =
861 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
862 assert(SOffsetIdx != -1);
863 if ((int)OpNo == SOffsetIdx)
864 printSymbolicFormat(MI, STI, O);
865 }
866}
867
868void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
869 unsigned OpNo,
870 const MCSubtargetInfo &STI,
871 raw_ostream &O) {
872 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
873 if (needsImpliedVcc(Desc, OpNo))
874 printDefaultVccOperand(true, STI, O);
875
876 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
877
878 // Use 'neg(...)' instead of '-' to avoid ambiguity.
879 // This is important for integer literals because
880 // -1 is not the same value as neg(1).
881 bool NegMnemo = false;
882
883 if (InputModifiers & SISrcMods::NEG) {
884 if (OpNo + 1 < MI->getNumOperands() &&
885 (InputModifiers & SISrcMods::ABS) == 0) {
886 const MCOperand &Op = MI->getOperand(OpNo + 1);
887 NegMnemo = Op.isImm() || Op.isDFPImm();
888 }
889 if (NegMnemo) {
890 O << "neg(";
891 } else {
892 O << '-';
893 }
894 }
895
896 if (InputModifiers & SISrcMods::ABS)
897 O << '|';
898 printRegularOperand(MI, OpNo + 1, STI, O);
899 if (InputModifiers & SISrcMods::ABS)
900 O << '|';
901
902 if (NegMnemo) {
903 O << ')';
904 }
905
906 // Print default vcc/vcc_lo operand of VOP2b.
907 switch (MI->getOpcode()) {
908 default:
909 break;
910
911 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
912 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
913 case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
914 if ((int)OpNo + 1 ==
915 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
916 printDefaultVccOperand(OpNo == 0, STI, O);
917 break;
918 }
919}
920
921void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
922 unsigned OpNo,
923 const MCSubtargetInfo &STI,
924 raw_ostream &O) {
925 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
926 if (needsImpliedVcc(Desc, OpNo))
927 printDefaultVccOperand(true, STI, O);
928
929 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
930 if (InputModifiers & SISrcMods::SEXT)
931 O << "sext(";
932 printRegularOperand(MI, OpNo + 1, STI, O);
933 if (InputModifiers & SISrcMods::SEXT)
934 O << ')';
935
936 // Print default vcc/vcc_lo operand of VOP2b.
937 switch (MI->getOpcode()) {
938 default: break;
939
940 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
941 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
942 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
943 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
944 AMDGPU::OpName::src1))
945 printDefaultVccOperand(OpNo == 0, STI, O);
946 break;
947 }
948}
949
950void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
951 const MCSubtargetInfo &STI,
952 raw_ostream &O) {
953 if (!AMDGPU::isGFX10Plus(STI))
954 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
955
956 unsigned Imm = MI->getOperand(OpNo).getImm();
957 O << "dpp8:[" << formatDec(Imm & 0x7);
958 for (size_t i = 1; i < 8; ++i) {
959 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
960 }
961 O << ']';
962}
963
964void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
965 const MCSubtargetInfo &STI,
966 raw_ostream &O) {
967 using namespace AMDGPU::DPP;
968
969 unsigned Imm = MI->getOperand(OpNo).getImm();
970 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
971
973 O << " /* DP ALU dpp only supports row_newbcast */";
974 return;
975 }
976 if (Imm <= DppCtrl::QUAD_PERM_LAST) {
977 O << "quad_perm:[";
978 O << formatDec(Imm & 0x3) << ',';
979 O << formatDec((Imm & 0xc) >> 2) << ',';
980 O << formatDec((Imm & 0x30) >> 4) << ',';
981 O << formatDec((Imm & 0xc0) >> 6) << ']';
982 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
983 (Imm <= DppCtrl::ROW_SHL_LAST)) {
984 O << "row_shl:" << formatDec(Imm - DppCtrl::ROW_SHL0);
985 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
986 (Imm <= DppCtrl::ROW_SHR_LAST)) {
987 O << "row_shr:" << formatDec(Imm - DppCtrl::ROW_SHR0);
988 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
989 (Imm <= DppCtrl::ROW_ROR_LAST)) {
990 O << "row_ror:" << formatDec(Imm - DppCtrl::ROW_ROR0);
991 } else if (Imm == DppCtrl::WAVE_SHL1) {
992 if (AMDGPU::isGFX10Plus(STI)) {
993 O << "/* wave_shl is not supported starting from GFX10 */";
994 return;
995 }
996 O << "wave_shl:1";
997 } else if (Imm == DppCtrl::WAVE_ROL1) {
998 if (AMDGPU::isGFX10Plus(STI)) {
999 O << "/* wave_rol is not supported starting from GFX10 */";
1000 return;
1001 }
1002 O << "wave_rol:1";
1003 } else if (Imm == DppCtrl::WAVE_SHR1) {
1004 if (AMDGPU::isGFX10Plus(STI)) {
1005 O << "/* wave_shr is not supported starting from GFX10 */";
1006 return;
1007 }
1008 O << "wave_shr:1";
1009 } else if (Imm == DppCtrl::WAVE_ROR1) {
1010 if (AMDGPU::isGFX10Plus(STI)) {
1011 O << "/* wave_ror is not supported starting from GFX10 */";
1012 return;
1013 }
1014 O << "wave_ror:1";
1015 } else if (Imm == DppCtrl::ROW_MIRROR) {
1016 O << "row_mirror";
1017 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
1018 O << "row_half_mirror";
1019 } else if (Imm == DppCtrl::BCAST15) {
1020 if (AMDGPU::isGFX10Plus(STI)) {
1021 O << "/* row_bcast is not supported starting from GFX10 */";
1022 return;
1023 }
1024 O << "row_bcast:15";
1025 } else if (Imm == DppCtrl::BCAST31) {
1026 if (AMDGPU::isGFX10Plus(STI)) {
1027 O << "/* row_bcast is not supported starting from GFX10 */";
1028 return;
1029 }
1030 O << "row_bcast:31";
1031 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
1032 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
1033 if (AMDGPU::isGFX90A(STI)) {
1034 O << "row_newbcast:";
1035 } else if (AMDGPU::isGFX10Plus(STI)) {
1036 O << "row_share:";
1037 } else {
1038 O << " /* row_newbcast/row_share is not supported on ASICs earlier "
1039 "than GFX90A/GFX10 */";
1040 return;
1041 }
1042 O << formatDec(Imm - DppCtrl::ROW_SHARE_FIRST);
1043 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
1044 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
1045 if (!AMDGPU::isGFX10Plus(STI)) {
1046 O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
1047 return;
1048 }
1049 O << "row_xmask:" << formatDec(Imm - DppCtrl::ROW_XMASK_FIRST);
1050 } else {
1051 O << "/* Invalid dpp_ctrl value */";
1052 }
1053}
1054
1055void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
1056 const MCSubtargetInfo &STI,
1057 raw_ostream &O) {
1058 unsigned Imm = MI->getOperand(OpNo).getImm();
1059 if (Imm) {
1060 O << " bound_ctrl:1";
1061 }
1062}
1063
1064void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
1065 const MCSubtargetInfo &STI, raw_ostream &O) {
1066 using namespace llvm::AMDGPU::DPP;
1067 unsigned Imm = MI->getOperand(OpNo).getImm();
1068 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1069 O << " fi:1";
1070 }
1071}
1072
1073void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1074 raw_ostream &O) {
1075 using namespace llvm::AMDGPU::SDWA;
1076
1077 unsigned Imm = MI->getOperand(OpNo).getImm();
1078 switch (Imm) {
1079 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1080 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1081 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1082 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1083 case SdwaSel::WORD_0: O << "WORD_0"; break;
1084 case SdwaSel::WORD_1: O << "WORD_1"; break;
1085 case SdwaSel::DWORD: O << "DWORD"; break;
1086 default: llvm_unreachable("Invalid SDWA data select operand");
1087 }
1088}
1089
1090void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1091 const MCSubtargetInfo &STI,
1092 raw_ostream &O) {
1093 O << "dst_sel:";
1094 printSDWASel(MI, OpNo, O);
1095}
1096
1097void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1098 const MCSubtargetInfo &STI,
1099 raw_ostream &O) {
1100 O << "src0_sel:";
1101 printSDWASel(MI, OpNo, O);
1102}
1103
1104void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1105 const MCSubtargetInfo &STI,
1106 raw_ostream &O) {
1107 O << "src1_sel:";
1108 printSDWASel(MI, OpNo, O);
1109}
1110
1111void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1112 const MCSubtargetInfo &STI,
1113 raw_ostream &O) {
1114 using namespace llvm::AMDGPU::SDWA;
1115
1116 O << "dst_unused:";
1117 unsigned Imm = MI->getOperand(OpNo).getImm();
1118 switch (Imm) {
1119 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1120 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1121 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1122 default: llvm_unreachable("Invalid SDWA dest_unused operand");
1123 }
1124}
1125
1126void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1127 const MCSubtargetInfo &STI, raw_ostream &O,
1128 unsigned N) {
1129 unsigned Opc = MI->getOpcode();
1130 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1131 unsigned En = MI->getOperand(EnIdx).getImm();
1132
1133 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1134
1135 // If compr is set, print as src0, src0, src1, src1
1136 if (MI->getOperand(ComprIdx).getImm())
1137 OpNo = OpNo - N + N / 2;
1138
1139 if (En & (1 << N))
1140 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
1141 else
1142 O << "off";
1143}
1144
1145void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1146 const MCSubtargetInfo &STI,
1147 raw_ostream &O) {
1148 printExpSrcN(MI, OpNo, STI, O, 0);
1149}
1150
1151void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1152 const MCSubtargetInfo &STI,
1153 raw_ostream &O) {
1154 printExpSrcN(MI, OpNo, STI, O, 1);
1155}
1156
1157void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1158 const MCSubtargetInfo &STI,
1159 raw_ostream &O) {
1160 printExpSrcN(MI, OpNo, STI, O, 2);
1161}
1162
1163void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1164 const MCSubtargetInfo &STI,
1165 raw_ostream &O) {
1166 printExpSrcN(MI, OpNo, STI, O, 3);
1167}
1168
1169void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1170 const MCSubtargetInfo &STI,
1171 raw_ostream &O) {
1172 using namespace llvm::AMDGPU::Exp;
1173
1174 // This is really a 6 bit field.
1175 unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1176
1177 int Index;
1178 StringRef TgtName;
1179 if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1180 O << ' ' << TgtName;
1181 if (Index >= 0)
1182 O << Index;
1183 } else {
1184 O << " invalid_target_" << Id;
1185 }
1186}
1187
1188static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1189 bool IsPacked, bool HasDstSel) {
1190 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1191
1192 for (int I = 0; I < NumOps; ++I) {
1193 if (!!(Ops[I] & Mod) != DefaultValue)
1194 return false;
1195 }
1196
1197 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1198 return false;
1199
1200 return true;
1201}
1202
1203void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1205 unsigned Mod,
1206 raw_ostream &O) {
1207 unsigned Opc = MI->getOpcode();
1208 int NumOps = 0;
1209 int Ops[3];
1210
1211 std::pair<int, int> MOps[] = {
1212 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},
1213 {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},
1214 {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};
1215 int DefaultValue = (Mod == SISrcMods::OP_SEL_1);
1216
1217 for (auto [SrcMod, Src] : MOps) {
1218 if (!AMDGPU::hasNamedOperand(Opc, Src))
1219 break;
1220
1221 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);
1222 Ops[NumOps++] =
1223 (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;
1224 }
1225
1226 // Print three values of neg/opsel for wmma instructions (prints 0 when there
1227 // is no src_modifier operand instead of not printing anything).
1228 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsSWMMAC ||
1229 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsWMMA) {
1230 NumOps = 0;
1231 int DefaultValue = Mod == SISrcMods::OP_SEL_1;
1232 for (int OpName :
1233 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
1234 AMDGPU::OpName::src2_modifiers}) {
1236 if (Idx != -1)
1237 Ops[NumOps++] = MI->getOperand(Idx).getImm();
1238 else
1239 Ops[NumOps++] = DefaultValue;
1240 }
1241 }
1242
1243 const bool HasDstSel =
1244 NumOps > 0 &&
1246 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
1247
1248 const bool IsPacked =
1249 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
1250
1251 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1252 return;
1253
1254 O << Name;
1255 for (int I = 0; I < NumOps; ++I) {
1256 if (I != 0)
1257 O << ',';
1258
1259 O << !!(Ops[I] & Mod);
1260 }
1261
1262 if (HasDstSel) {
1263 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1264 }
1265
1266 O << ']';
1267}
1268
1269void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1270 const MCSubtargetInfo &STI,
1271 raw_ostream &O) {
1272 unsigned Opc = MI->getOpcode();
1273 if (isCvt_F32_Fp8_Bf8_e64(Opc)) {
1274 auto SrcMod =
1275 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1276 unsigned Mod = MI->getOperand(SrcMod).getImm();
1277 unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);
1278 unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);
1279 if (Index0 || Index1)
1280 O << " op_sel:[" << Index0 << ',' << Index1 << ']';
1281 return;
1282 }
1283 if (isPermlane16(Opc)) {
1284 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1285 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1286 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1287 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1288 if (FI || BC)
1289 O << " op_sel:[" << FI << ',' << BC << ']';
1290 return;
1291 }
1292
1293 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1294}
1295
1296void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1297 const MCSubtargetInfo &STI,
1298 raw_ostream &O) {
1299 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1300}
1301
1302void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1303 const MCSubtargetInfo &STI,
1304 raw_ostream &O) {
1305 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1306}
1307
1308void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1309 const MCSubtargetInfo &STI,
1310 raw_ostream &O) {
1311 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1312}
1313
1314void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,
1315 const MCSubtargetInfo &STI,
1316 raw_ostream &O) {
1317 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1318 if (Imm == 0)
1319 return;
1320
1321 O << " index_key:" << Imm;
1322}
1323
1324void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,
1325 const MCSubtargetInfo &STI,
1326 raw_ostream &O) {
1327 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1328 if (Imm == 0)
1329 return;
1330
1331 O << " index_key:" << Imm;
1332}
1333
1334void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1335 const MCSubtargetInfo &STI,
1336 raw_ostream &O) {
1337 unsigned Imm = MI->getOperand(OpNum).getImm();
1338 switch (Imm) {
1339 case 0:
1340 O << "p10";
1341 break;
1342 case 1:
1343 O << "p20";
1344 break;
1345 case 2:
1346 O << "p0";
1347 break;
1348 default:
1349 O << "invalid_param_" << Imm;
1350 }
1351}
1352
1353void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1354 const MCSubtargetInfo &STI,
1355 raw_ostream &O) {
1356 unsigned Attr = MI->getOperand(OpNum).getImm();
1357 O << "attr" << Attr;
1358}
1359
1360void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1361 const MCSubtargetInfo &STI,
1362 raw_ostream &O) {
1363 unsigned Chan = MI->getOperand(OpNum).getImm();
1364 O << '.' << "xyzw"[Chan & 0x3];
1365}
1366
1367void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,
1368 const MCSubtargetInfo &STI,
1369 raw_ostream &O) {
1370 using namespace llvm::AMDGPU::VGPRIndexMode;
1371 unsigned Val = MI->getOperand(OpNo).getImm();
1372
1373 if ((Val & ~ENABLE_MASK) != 0) {
1374 O << formatHex(static_cast<uint64_t>(Val));
1375 } else {
1376 O << "gpr_idx(";
1377 bool NeedComma = false;
1378 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1379 if (Val & (1 << ModeId)) {
1380 if (NeedComma)
1381 O << ',';
1382 O << IdSymbolic[ModeId];
1383 NeedComma = true;
1384 }
1385 }
1386 O << ')';
1387 }
1388}
1389
1390void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1391 const MCSubtargetInfo &STI,
1392 raw_ostream &O) {
1393 printRegularOperand(MI, OpNo, STI, O);
1394 O << ", ";
1395 printRegularOperand(MI, OpNo + 1, STI, O);
1396}
1397
1398void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1399 raw_ostream &O, StringRef Asm,
1401 const MCOperand &Op = MI->getOperand(OpNo);
1402 assert(Op.isImm());
1403 if (Op.getImm() == 1) {
1404 O << Asm;
1405 } else {
1406 O << Default;
1407 }
1408}
1409
1410void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1411 raw_ostream &O, char Asm) {
1412 const MCOperand &Op = MI->getOperand(OpNo);
1413 assert(Op.isImm());
1414 if (Op.getImm() == 1)
1415 O << Asm;
1416}
1417
1418void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1419 const MCSubtargetInfo &STI,
1420 raw_ostream &O) {
1421 int Imm = MI->getOperand(OpNo).getImm();
1422 if (Imm == SIOutMods::MUL2)
1423 O << " mul:2";
1424 else if (Imm == SIOutMods::MUL4)
1425 O << " mul:4";
1426 else if (Imm == SIOutMods::DIV2)
1427 O << " div:2";
1428}
1429
1430void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1431 const MCSubtargetInfo &STI,
1432 raw_ostream &O) {
1433 using namespace llvm::AMDGPU::SendMsg;
1434
1435 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1436
1437 uint16_t MsgId;
1438 uint16_t OpId;
1440 decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
1441
1442 StringRef MsgName = getMsgName(MsgId, STI);
1443
1444 if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1445 isValidMsgStream(MsgId, OpId, StreamId, STI)) {
1446 O << "sendmsg(" << MsgName;
1447 if (msgRequiresOp(MsgId, STI)) {
1448 O << ", " << getMsgOpName(MsgId, OpId, STI);
1449 if (msgSupportsStream(MsgId, OpId, STI)) {
1450 O << ", " << StreamId;
1451 }
1452 }
1453 O << ')';
1454 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1455 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1456 } else {
1457 O << Imm16; // Unknown imm16 code.
1458 }
1459}
1460
1461static void printSwizzleBitmask(const uint16_t AndMask,
1462 const uint16_t OrMask,
1463 const uint16_t XorMask,
1464 raw_ostream &O) {
1465 using namespace llvm::AMDGPU::Swizzle;
1466
1467 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1468 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1469
1470 O << "\"";
1471
1472 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1473 uint16_t p0 = Probe0 & Mask;
1474 uint16_t p1 = Probe1 & Mask;
1475
1476 if (p0 == p1) {
1477 if (p0 == 0) {
1478 O << "0";
1479 } else {
1480 O << "1";
1481 }
1482 } else {
1483 if (p0 == 0) {
1484 O << "p";
1485 } else {
1486 O << "i";
1487 }
1488 }
1489 }
1490
1491 O << "\"";
1492}
1493
1494void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1495 const MCSubtargetInfo &STI,
1496 raw_ostream &O) {
1497 using namespace llvm::AMDGPU::Swizzle;
1498
1499 uint16_t Imm = MI->getOperand(OpNo).getImm();
1500 if (Imm == 0) {
1501 return;
1502 }
1503
1504 O << " offset:";
1505
1506 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1507
1508 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1509 for (unsigned I = 0; I < LANE_NUM; ++I) {
1510 O << ",";
1511 O << formatDec(Imm & LANE_MASK);
1512 Imm >>= LANE_SHIFT;
1513 }
1514 O << ")";
1515
1516 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1517
1518 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1519 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1520 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1521
1522 if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
1523
1524 O << "swizzle(" << IdSymbolic[ID_SWAP];
1525 O << ",";
1526 O << formatDec(XorMask);
1527 O << ")";
1528
1529 } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
1530 isPowerOf2_64(XorMask + 1)) {
1531
1532 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1533 O << ",";
1534 O << formatDec(XorMask + 1);
1535 O << ")";
1536
1537 } else {
1538
1539 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1540 if (GroupSize > 1 &&
1541 isPowerOf2_64(GroupSize) &&
1542 OrMask < GroupSize &&
1543 XorMask == 0) {
1544
1545 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1546 O << ",";
1547 O << formatDec(GroupSize);
1548 O << ",";
1549 O << formatDec(OrMask);
1550 O << ")";
1551
1552 } else {
1553 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1554 O << ",";
1555 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1556 O << ")";
1557 }
1558 }
1559 } else {
1560 printU16ImmDecOperand(MI, OpNo, O);
1561 }
1562}
1563
1564void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,
1565 const MCSubtargetInfo &STI,
1566 raw_ostream &O) {
1568
1569 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1570 unsigned Vmcnt, Expcnt, Lgkmcnt;
1571 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1572
1573 bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1574 bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1575 bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1576 bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1577
1578 bool NeedSpace = false;
1579
1580 if (!IsDefaultVmcnt || PrintAll) {
1581 O << "vmcnt(" << Vmcnt << ')';
1582 NeedSpace = true;
1583 }
1584
1585 if (!IsDefaultExpcnt || PrintAll) {
1586 if (NeedSpace)
1587 O << ' ';
1588 O << "expcnt(" << Expcnt << ')';
1589 NeedSpace = true;
1590 }
1591
1592 if (!IsDefaultLgkmcnt || PrintAll) {
1593 if (NeedSpace)
1594 O << ' ';
1595 O << "lgkmcnt(" << Lgkmcnt << ')';
1596 }
1597}
1598
1599void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
1600 const MCSubtargetInfo &STI,
1601 raw_ostream &O) {
1602 using namespace llvm::AMDGPU::DepCtr;
1603
1604 uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
1605
1606 bool HasNonDefaultVal = false;
1607 if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
1608 int Id = 0;
1610 unsigned Val;
1611 bool IsDefault;
1612 bool NeedSpace = false;
1613 while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
1614 if (!IsDefault || !HasNonDefaultVal) {
1615 if (NeedSpace)
1616 O << ' ';
1617 O << Name << '(' << Val << ')';
1618 NeedSpace = true;
1619 }
1620 }
1621 } else {
1622 O << formatHex(Imm16);
1623 }
1624}
1625
1627 const MCSubtargetInfo &STI,
1628 raw_ostream &O) {
1629 const char *BadInstId = "/* invalid instid value */";
1630 static const std::array<const char *, 12> InstIds = {
1631 "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",
1632 "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",
1633 "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1634 "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};
1635
1636 const char *BadInstSkip = "/* invalid instskip value */";
1637 static const std::array<const char *, 6> InstSkips = {
1638 "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1639
1640 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1641 const char *Prefix = "";
1642
1643 unsigned Value = SImm16 & 0xF;
1644 if (Value) {
1645 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1646 O << Prefix << "instid0(" << Name << ')';
1647 Prefix = " | ";
1648 }
1649
1650 Value = (SImm16 >> 4) & 7;
1651 if (Value) {
1652 const char *Name =
1653 Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1654 O << Prefix << "instskip(" << Name << ')';
1655 Prefix = " | ";
1656 }
1657
1658 Value = (SImm16 >> 7) & 0xF;
1659 if (Value) {
1660 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1661 O << Prefix << "instid1(" << Name << ')';
1662 Prefix = " | ";
1663 }
1664
1665 if (!*Prefix)
1666 O << "0";
1667}
1668
1669void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1670 const MCSubtargetInfo &STI, raw_ostream &O) {
1671 using namespace llvm::AMDGPU::Hwreg;
1672 unsigned Val = MI->getOperand(OpNo).getImm();
1673 auto [Id, Offset, Width] = HwregEncoding::decode(Val);
1674 StringRef HwRegName = getHwreg(Id, STI);
1675
1676 O << "hwreg(";
1677 if (!HwRegName.empty()) {
1678 O << HwRegName;
1679 } else {
1680 O << Id;
1681 }
1682 if (Width != HwregSize::Default || Offset != HwregOffset::Default)
1683 O << ", " << Offset << ", " << Width;
1684 O << ')';
1685}
1686
1687void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1688 const MCSubtargetInfo &STI,
1689 raw_ostream &O) {
1690 uint16_t Imm = MI->getOperand(OpNo).getImm();
1691 if (Imm == 0) {
1692 return;
1693 }
1694
1695 O << ' ' << formatDec(Imm);
1696}
1697
1698void AMDGPUInstPrinter::printNamedInt(const MCInst *MI, unsigned OpNo,
1699 const MCSubtargetInfo &STI,
1700 raw_ostream &O, StringRef Prefix,
1701 bool PrintInHex, bool AlwaysPrint) {
1702 int64_t V = MI->getOperand(OpNo).getImm();
1703 if (AlwaysPrint || V != 0)
1704 O << ' ' << Prefix << ':' << (PrintInHex ? formatHex(V) : formatDec(V));
1705}
1706
1707#include "AMDGPUGenAsmWriter.inc"
unsigned const MachineRegisterInfo * MRI
static void printSwizzleBitmask(const uint16_t AndMask, const uint16_t OrMask, const uint16_t XorMask, raw_ostream &O)
static bool printImmediateBFloat16(uint32_t Imm, const MCSubtargetInfo &STI, raw_ostream &O)
static bool allOpsDefaultValue(const int *Ops, int NumOps, int Mod, bool IsPacked, bool HasDstSel)
static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI, raw_ostream &O)
Provides AMDGPU specific target descriptions.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
void printSwizzle(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printEndpgm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getRegisterName(MCRegister Reg)
static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O, StringRef Asm, StringRef Default="")
void printDepCtr(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printHwreg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printSendMsg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &OS, MCRegister Reg) const override
Print the assembler register name.
static void printRegOperand(unsigned RegNo, raw_ostream &O, const MCRegisterInfo &MRI)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printSWaitCnt(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printOModSI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printSDelayALU(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
This class represents an Operation in the Expression.
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
Definition: MCInstPrinter.h:52
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:53
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:444
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
MCRegisterClass - Base class of TargetRegisterClass.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const char * getRegClassName(const MCRegisterClass *Class) const
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
StringRef getCPU() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
bool getTgtName(unsigned Id, StringRef &Name, int &Index)
bool isValidUnifiedFormat(unsigned Id, const MCSubtargetInfo &STI)
StringRef getUnifiedFormatName(unsigned Id, const MCSubtargetInfo &STI)
bool isValidDfmtNfmt(unsigned Id, const MCSubtargetInfo &STI)
StringRef getDfmtName(unsigned Id)
StringRef getNfmtName(unsigned Id, const MCSubtargetInfo &STI)
void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt)
const char *const IdSymbolic[]
void decodeWaitcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt)
Decodes Vmcnt, Expcnt and Lgkmcnt from given Waitcnt for given isa Version, and writes decoded values...
bool isVOPCAsmOnly(unsigned Opc)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
bool isGFX12Plus(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
bool isSI(const MCSubtargetInfo &STI)
bool getVOP3IsSingle(unsigned Opc)
bool getVOP1IsSingle(unsigned Opc)
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned getVmcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
unsigned getLgkmcntBitMask(const IsaVersion &Version)
unsigned getExpcntBitMask(const IsaVersion &Version)
bool isInlineValue(unsigned Reg)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_REG_IMM_INT64
Definition: SIDefines.h:201
@ OPERAND_REG_IMM_V2FP16
Definition: SIDefines.h:211
@ OPERAND_REG_INLINE_C_V2INT32
Definition: SIDefines.h:227
@ OPERAND_REG_INLINE_C_FP64
Definition: SIDefines.h:223
@ OPERAND_REG_INLINE_C_BF16
Definition: SIDefines.h:220
@ OPERAND_REG_INLINE_C_V2BF16
Definition: SIDefines.h:225
@ OPERAND_REG_IMM_V2INT16
Definition: SIDefines.h:212
@ OPERAND_REG_IMM_BF16
Definition: SIDefines.h:205
@ OPERAND_REG_INLINE_AC_V2FP16
Definition: SIDefines.h:246
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
Definition: SIDefines.h:200
@ OPERAND_REG_IMM_V2BF16
Definition: SIDefines.h:210
@ OPERAND_REG_IMM_BF16_DEFERRED
Definition: SIDefines.h:207
@ OPERAND_REG_IMM_FP16
Definition: SIDefines.h:206
@ OPERAND_REG_INLINE_C_INT64
Definition: SIDefines.h:219
@ OPERAND_REG_INLINE_AC_BF16
Definition: SIDefines.h:240
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition: SIDefines.h:217
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
Definition: SIDefines.h:238
@ OPERAND_REG_IMM_FP64
Definition: SIDefines.h:204
@ OPERAND_REG_INLINE_C_V2FP16
Definition: SIDefines.h:226
@ OPERAND_REG_INLINE_AC_V2INT16
Definition: SIDefines.h:244
@ OPERAND_REG_INLINE_AC_FP16
Definition: SIDefines.h:241
@ OPERAND_REG_INLINE_AC_INT32
Definition: SIDefines.h:239
@ OPERAND_REG_INLINE_AC_FP32
Definition: SIDefines.h:242
@ OPERAND_REG_INLINE_AC_V2BF16
Definition: SIDefines.h:245
@ OPERAND_REG_IMM_V2INT32
Definition: SIDefines.h:213
@ OPERAND_REG_IMM_FP32
Definition: SIDefines.h:203
@ OPERAND_REG_INLINE_C_FP32
Definition: SIDefines.h:222
@ OPERAND_REG_INLINE_C_INT32
Definition: SIDefines.h:218
@ OPERAND_REG_INLINE_C_V2INT16
Definition: SIDefines.h:224
@ OPERAND_REG_IMM_V2FP32
Definition: SIDefines.h:214
@ OPERAND_REG_INLINE_AC_FP64
Definition: SIDefines.h:243
@ OPERAND_REG_INLINE_C_FP16
Definition: SIDefines.h:221
@ OPERAND_REG_IMM_INT16
Definition: SIDefines.h:202
@ OPERAND_REG_INLINE_C_V2FP32
Definition: SIDefines.h:228
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
Definition: SIDefines.h:231
@ OPERAND_REG_IMM_FP32_DEFERRED
Definition: SIDefines.h:209
@ OPERAND_REG_IMM_FP16_DEFERRED
Definition: SIDefines.h:208
bool isCvt_F32_Fp8_Bf8_e64(unsigned Opc)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isCI(const MCSubtargetInfo &STI)
bool getVOP2IsSingle(unsigned Opc)
bool isPermlane16(unsigned Opc)
@ OPERAND_REGISTER
Definition: MCInstrDesc.h:61
@ OPERAND_IMMEDIATE
Definition: MCInstrDesc.h:60
@ OPERAND_UNKNOWN
Definition: MCInstrDesc.h:59
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition: bit.h:385
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:296
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:154
@ Mod
The access may modify the value stored in memory.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Definition: MathExtras.h:563
@ Default
The result values are uniform if and only if all operands are uniform.
#define N
Instruction set architecture version.
Definition: TargetParser.h:127
Description of the encoding of one expression Op.