LLVM 24.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"
16#include "llvm/MC/MCAsmInfo.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCInstrDesc.h"
20#include "llvm/MC/MCInstrInfo.h"
24
25using namespace llvm;
26using namespace llvm::AMDGPU;
27
29 // FIXME: The current implementation of
30 // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
31 // as an integer or we provide a name which represents a physical register.
32 // For CFI instructions we really want to emit a name for the DWARF register
33 // instead, because there may be multiple DWARF registers corresponding to a
34 // single physical register. One case where this problem manifests is with
35 // wave32/wave64 where using the physical register name is ambiguous: if we
36 // write e.g. `.cfi_undefined v0` we lose information about the wavefront
37 // size which we need to encode the register in the final DWARF. Ideally we
38 // would extend MC to support parsing DWARF register names so we could do
39 // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
40 // non-pretty DWARF register names in assembly text.
41 OS << Reg.id();
42}
43
45 StringRef Annot, const MCSubtargetInfo &STI,
46 raw_ostream &OS) {
47 printInstruction(MI, Address, STI, OS);
48 printAnnotation(OS, Annot);
49}
50
51void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
52 const MCSubtargetInfo &STI,
53 raw_ostream &O) {
54 const MCOperand &Op = MI->getOperand(OpNo);
55 if (Op.isExpr()) {
56 MAI.printExpr(O, *Op.getExpr());
57 return;
58 }
59
60 // It's possible to end up with a 32-bit literal used with a 16-bit operand
61 // with ignored high bits. Print as 32-bit anyway in that case.
62 int64_t Imm = Op.getImm();
63 if (isInt<16>(Imm) || isUInt<16>(Imm))
64 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
65 else
66 printU32ImmOperand(MI, OpNo, STI, O);
67}
68
69void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
70 raw_ostream &O) {
71 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
72}
73
74void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
75 const MCSubtargetInfo &STI,
76 raw_ostream &O) {
77 const MCOperand &Op = MI->getOperand(OpNo);
78 if (Op.isExpr()) {
79 MAI.printExpr(O, *Op.getExpr());
80 return;
81 }
82
83 O << formatHex(Op.getImm() & 0xffffffff);
84}
85
86void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
87 const MCSubtargetInfo &STI,
88 raw_ostream &O) {
89 // KIMM64
90 const MCOperand &Op = MI->getOperand(OpNo);
91 if (Op.isExpr()) {
92 MAI.printExpr(O, *Op.getExpr());
93 return;
94 }
95
96 printLiteral64(Op.getImm(), O, /*IsFP=*/true);
97}
98
99void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
100 raw_ostream &O, StringRef BitName) {
101 if (MI->getOperand(OpNo).getImm()) {
102 O << ' ' << BitName;
103 }
104}
105
106void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
107 const MCSubtargetInfo &STI,
108 raw_ostream &O) {
109 uint32_t Imm = MI->getOperand(OpNo).getImm();
110 if (Imm != 0) {
111 O << " offset:";
112
113 // GFX12+ uses a 24-bit signed offset for VBUFFER.
114 bool IsVBuffer = SIInstrFlags::isBuffer(MII, *MI);
115 if (IsVBuffer && AMDGPU::isGFX12Plus(STI))
116 O << formatDec(SignExtend32<24>(Imm));
117 else
118 printU16ImmDecOperand(MI, OpNo, O);
119 }
120}
121
122void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
123 const MCSubtargetInfo &STI,
124 raw_ostream &O) {
125 uint32_t Imm = MI->getOperand(OpNo).getImm();
126 if (Imm != 0) {
127 O << " offset:";
128
129 bool AllowNegative = SIInstrFlags::isSegmentSpecificFLAT(MII, *MI) ||
130 STI.hasFeature(AMDGPU::FeatureFlatSignedOffset);
131
132 if (AllowNegative) // Signed offset
134 else // Unsigned offset
135 printU16ImmDecOperand(MI, OpNo, O);
136 }
137}
138
139void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
140 const MCSubtargetInfo &STI,
141 raw_ostream &O) {
142 printU32ImmOperand(MI, OpNo, STI, O);
143}
144
145void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
146 const MCSubtargetInfo &STI,
147 raw_ostream &O) {
148 O << formatHex(MI->getOperand(OpNo).getImm());
149}
150
151void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
152 const MCSubtargetInfo &STI,
153 raw_ostream &O) {
154 printU32ImmOperand(MI, OpNo, STI, O);
155}
156
157void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
158 const MCSubtargetInfo &STI, raw_ostream &O) {
159 auto Imm = MI->getOperand(OpNo).getImm();
160
161 if (AMDGPU::isGFX12Plus(STI)) {
162 const int64_t TH = Imm & CPol::TH;
163 const int64_t Scope = Imm & CPol::SCOPE;
164
165 if (Imm & CPol::SCAL)
166 O << " scale_offset";
167
168 printTH(MI, TH, Scope, O);
169 printScope(Scope, O);
170
171 if (Imm & CPol::NV)
172 O << " nv";
173
174 if (STI.hasFeature(AMDGPU::FeatureCacheFillSize)) {
175 const int64_t CFS = Imm & CPol::CFS;
176 printCFS(CFS, O);
177 }
178
179 return;
180 }
181
182 if (Imm & CPol::GLC)
183 O << ((AMDGPU::isGFX940(STI) && !SIInstrFlags::isSMRD(MII, *MI)) ? " sc0"
184 : " glc");
185 if (Imm & CPol::SLC)
186 O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
187 if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
188 O << " dlc";
189 if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
190 O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
191 if (Imm & ~CPol::ALL_pregfx12)
192 O << " /* unexpected cache policy bit */";
193}
194
195void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,
196 raw_ostream &O) {
197 // For th = 0 do not print this field
198 if (TH == 0)
199 return;
200
201 const unsigned Opcode = MI->getOpcode();
202 const MCInstrDesc &TID = MII.get(Opcode);
203 unsigned THType = AMDGPU::getTemporalHintType(TID);
204 bool IsStore = (THType == AMDGPU::CPol::TH_TYPE_STORE);
205
206 O << " th:";
207
208 if (THType == AMDGPU::CPol::TH_TYPE_ATOMIC) {
209 O << "TH_ATOMIC_";
211 if (Scope >= AMDGPU::CPol::SCOPE_DEV)
212 O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");
213 else
214 O << formatHex(TH);
215 } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)
216 O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");
217 else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)
218 O << "RETURN";
219 else
220 O << formatHex(TH);
221 } else {
222 if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)
223 O << formatHex(TH);
224 else {
225 O << (IsStore ? "TH_STORE_" : "TH_LOAD_");
226 switch (TH) {
228 O << "NT";
229 break;
231 O << "HT";
232 break;
233 case AMDGPU::CPol::TH_BYPASS: // or LU or WB
234 O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"
235 : (IsStore ? "WB" : "LU"));
236 break;
238 O << "NT_RT";
239 break;
241 O << "RT_NT";
242 break;
244 O << "NT_HT";
245 break;
247 O << "NT_WB";
248 break;
249 default:
250 llvm_unreachable("unexpected th value");
251 }
252 }
253 }
254}
255
256void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {
257 if (Scope == CPol::SCOPE_CU)
258 return;
259
260 O << " scope:";
261
262 if (Scope == CPol::SCOPE_SE)
263 O << "SCOPE_SE";
264 else if (Scope == CPol::SCOPE_DEV)
265 O << "SCOPE_DEV";
266 else if (Scope == CPol::SCOPE_SYS)
267 O << "SCOPE_SYS";
268 else
269 llvm_unreachable("unexpected scope policy value");
270}
271
272void AMDGPUInstPrinter::printCFS(int64_t CFS, raw_ostream &O) {
273 if (CFS == CPol::CFS_256B)
274 return;
275
276 O << " cfs:";
277
278 switch (CFS) {
279 case CPol::CFS_128B:
280 O << "CFS_128B";
281 break;
282 case CPol::CFS_64B:
283 O << "CFS_64B";
284 break;
285 case CPol::CFS_32B:
286 O << "CFS_32B";
287 break;
288 default:
289 llvm_unreachable("unexpected cache fill size value");
290 }
291}
292
293void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
294 const MCSubtargetInfo &STI, raw_ostream &O) {
295 unsigned Dim = MI->getOperand(OpNo).getImm();
296 O << " dim:SQ_RSRC_IMG_";
297
298 const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
299 if (DimInfo)
301 else
302 O << Dim;
303}
304
305void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
306 const MCSubtargetInfo &STI, raw_ostream &O) {
307 if (STI.hasFeature(AMDGPU::FeatureR128A16))
308 printNamedBit(MI, OpNo, O, "a16");
309 else
310 printNamedBit(MI, OpNo, O, "r128");
311}
312
313void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
314 const MCSubtargetInfo &STI,
315 raw_ostream &O) {
316}
317
318void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
319 const MCSubtargetInfo &STI,
320 raw_ostream &O) {
321 using namespace llvm::AMDGPU::MTBUFFormat;
322
323 int OpNo =
324 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
325 assert(OpNo != -1);
326
327 unsigned Val = MI->getOperand(OpNo).getImm();
328 if (AMDGPU::isGFX10Plus(STI)) {
329 if (Val == UFMT_DEFAULT)
330 return;
331 if (isValidUnifiedFormat(Val, STI)) {
332 O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
333 } else {
334 O << " format:" << Val;
335 }
336 } else {
337 if (Val == DFMT_NFMT_DEFAULT)
338 return;
339 if (isValidDfmtNfmt(Val, STI)) {
340 unsigned Dfmt;
341 unsigned Nfmt;
342 decodeDfmtNfmt(Val, Dfmt, Nfmt);
343 O << " format:[";
344 if (Dfmt != DFMT_DEFAULT) {
345 O << getDfmtName(Dfmt);
346 if (Nfmt != NFMT_DEFAULT) {
347 O << ',';
348 }
349 }
350 if (Nfmt != NFMT_DEFAULT) {
351 O << getNfmtName(Nfmt, STI);
352 }
353 O << ']';
354 } else {
355 O << " format:" << Val;
356 }
357 }
358}
359
360// \returns a low 256 vgpr representing a high vgpr \p Reg [v256..v1023] or
361// \p Reg itself otherwise.
363 unsigned Enc = MRI.getEncodingValue(Reg);
364 unsigned Idx = Enc & AMDGPU::HWEncoding::REG_IDX_MASK;
365 if (Idx < 0x100)
366 return Reg;
367
368 unsigned RegNo = Idx % 0x100;
370 if (RC->getID() == AMDGPU::VGPR_16RegClassID) {
371 // This class has 2048 registers with interleaved lo16 and hi16.
372 RegNo *= 2;
374 ++RegNo;
375 }
376
377 return RC->getRegister(RegNo);
378}
379
380// Restore MSBs of a VGPR above 255 from the MCInstrAnalysis.
382 const MCInstrDesc &Desc,
383 const MCRegisterInfo &MRI,
384 const AMDGPUMCInstrAnalysis &MIA) {
385 unsigned VgprMSBs = MIA.getVgprMSBs();
386 if (!VgprMSBs)
387 return Reg;
388
389 unsigned Enc = MRI.getEncodingValue(Reg);
390 if (!(Enc & AMDGPU::HWEncoding::IS_VGPR))
391 return Reg;
392
394 if (!Ops.first)
395 return Reg;
396 unsigned Opc = Desc.getOpcode();
397 unsigned I;
398 for (I = 0; I < 4; ++I) {
399 if (Ops.first[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
400 (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.first[I]) == OpNo)
401 break;
402 if (Ops.second && Ops.second[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
403 (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.second[I]) == OpNo)
404 break;
405 }
406 if (I == 4)
407 return Reg;
408 unsigned OpMSBs = (VgprMSBs >> (I * 2)) & 3;
409 if (!OpMSBs)
410 return Reg;
411 if (MCRegister NewReg = AMDGPU::getVGPRWithMSBs(Reg, OpMSBs, MRI))
412 return NewReg;
413 return Reg;
414}
415
416void AMDGPUInstPrinter::printRsrcReg(const MCInst *MI, unsigned OpNo,
417 const MCSubtargetInfo &STI,
418 raw_ostream &O) {
419 MCRegister Reg = MI->getOperand(OpNo).getReg();
420 bool IsIndexReg = AMDGPU::isRsrcIndexReg(Reg, MRI);
421 if (IsIndexReg)
422 O << "rsrcidx(";
423 printRegOperand(Reg, MI->getOpcode(), OpNo, O, MRI);
424 if (IsIndexReg)
425 O << ')';
426}
427
429 const MCRegisterInfo &MRI) {
430#if !defined(NDEBUG)
431 switch (Reg.id()) {
432 case AMDGPU::FP_REG:
433 case AMDGPU::SP_REG:
434 case AMDGPU::PRIVATE_RSRC_REG:
435 llvm_unreachable("pseudo-register should not ever be emitted");
436 default:
437 break;
438 }
439#endif
440
441 MCRegister PrintReg = getRegForPrinting(Reg, MRI);
442 O << getRegisterName(PrintReg);
443
444 if (PrintReg != Reg)
445 O << " /*" << getRegisterName(Reg) << "*/";
446}
447
449 unsigned OpNo, raw_ostream &O,
450 const MCRegisterInfo &MRI) {
451 if (MIA)
452 Reg = getRegFromMIA(Reg, OpNo, MII.get(Opc), MRI,
453 *static_cast<const AMDGPUMCInstrAnalysis *>(MIA));
454 printRegOperand(Reg, O, MRI);
455}
456
457void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
458 const MCSubtargetInfo &STI, raw_ostream &O) {
459 auto Opcode = MI->getOpcode();
460 if (OpNo == 0) {
462 O << "_e64_dpp";
463 else if (SIInstrFlags::isVOP3(MII, *MI)) {
464 if (!getVOP3IsSingle(Opcode))
465 O << "_e64";
466 } else if (SIInstrFlags::isDPP(MII, *MI))
467 O << "_dpp";
468 else if (SIInstrFlags::isSDWA(MII, *MI))
469 O << "_sdwa";
470 else if ((SIInstrFlags::isVOP1(MII, *MI) && !getVOP1IsSingle(Opcode)) ||
472 O << "_e32";
473 O << " ";
474 }
475
476 printRegularOperand(MI, OpNo, STI, O);
477
478 // Print default vcc/vcc_lo operand.
479 switch (Opcode) {
480 default: break;
481
482 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
483 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
484 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
485 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
486 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
487 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
488 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
489 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
490 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
491 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
492 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
493 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
494 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
495 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
496 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
497 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
498 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
499 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
500 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
501 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
502 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
503 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
504 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
505 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
506 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
507 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
508 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
509 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
510 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
511 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
512 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx13:
513 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx13:
514 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx13:
515 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx13:
516 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx13:
517 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx13:
518 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx13:
519 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx13:
520 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx13:
521 printDefaultVccOperand(false, STI, O);
522 break;
523 }
524}
525
526void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
527 const MCSubtargetInfo &STI, raw_ostream &O) {
528 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
529 O << " ";
530 else
531 O << "_e32 ";
532
533 printRegularOperand(MI, OpNo, STI, O);
534}
535
536void AMDGPUInstPrinter::printAVLdSt32Align2RegOp(const MCInst *MI,
537 unsigned OpNo,
538 const MCSubtargetInfo &STI,
539 raw_ostream &O) {
540 MCRegister Reg = MI->getOperand(OpNo).getReg();
541
542 // On targets with an even alignment requirement
543 if (MCRegister SubReg = MRI.getSubReg(Reg, AMDGPU::sub0))
544 Reg = SubReg;
546}
547
548void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
549 const MCSubtargetInfo &STI,
550 raw_ostream &O) {
551 int32_t SImm = static_cast<int32_t>(Imm);
552 if (isInlinableIntLiteral(SImm)) {
553 O << SImm;
554 return;
555 }
556
557 if (printImmediateFloat32(Imm, STI, O))
558 return;
559
560 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
561}
562
564 raw_ostream &O) {
565 if (Imm == 0x3C00)
566 O << "1.0";
567 else if (Imm == 0xBC00)
568 O << "-1.0";
569 else if (Imm == 0x3800)
570 O << "0.5";
571 else if (Imm == 0xB800)
572 O << "-0.5";
573 else if (Imm == 0x4000)
574 O << "2.0";
575 else if (Imm == 0xC000)
576 O << "-2.0";
577 else if (Imm == 0x4400)
578 O << "4.0";
579 else if (Imm == 0xC400)
580 O << "-4.0";
581 else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
582 O << "0.15915494";
583 else
584 return false;
585
586 return true;
587}
588
590 raw_ostream &O) {
591 if (Imm == 0x3F80)
592 O << "1.0";
593 else if (Imm == 0xBF80)
594 O << "-1.0";
595 else if (Imm == 0x3F00)
596 O << "0.5";
597 else if (Imm == 0xBF00)
598 O << "-0.5";
599 else if (Imm == 0x4000)
600 O << "2.0";
601 else if (Imm == 0xC000)
602 O << "-2.0";
603 else if (Imm == 0x4080)
604 O << "4.0";
605 else if (Imm == 0xC080)
606 O << "-4.0";
607 else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
608 O << "0.15915494";
609 else
610 return false;
611
612 return true;
613}
614
615void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,
616 const MCSubtargetInfo &STI,
617 raw_ostream &O) {
618 int16_t SImm = static_cast<int16_t>(Imm);
619 if (isInlinableIntLiteral(SImm)) {
620 O << SImm;
621 return;
622 }
623
624 if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
625 return;
626
627 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
628}
629
630void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,
631 const MCSubtargetInfo &STI,
632 raw_ostream &O) {
633 int16_t SImm = static_cast<int16_t>(Imm);
634 if (isInlinableIntLiteral(SImm)) {
635 O << SImm;
636 return;
637 }
638
639 uint16_t HImm = static_cast<uint16_t>(Imm);
640 if (printImmediateFP16(HImm, STI, O))
641 return;
642
643 uint64_t Imm16 = static_cast<uint16_t>(Imm);
644 O << formatHex(Imm16);
645}
646
647void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,
648 const MCSubtargetInfo &STI,
649 raw_ostream &O) {
650 int32_t SImm = static_cast<int32_t>(Imm);
651 if (isInlinableIntLiteral(SImm)) {
652 O << SImm;
653 return;
654 }
655
656 switch (OpType) {
659 if (printImmediateFloat32(Imm, STI, O))
660 return;
661 break;
664 if (isUInt<16>(Imm) &&
665 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
666 return;
667 break;
669 if (AMDGPU::isGFX11Plus(STI)) {
670 // For GFX11+, the inline constant is duplicated to both channels, so we
671 // need to check if the low and high 16 bits are the same, and then if
672 // they can be printed as inline constant values.
673 uint16_t Lo16 = static_cast<uint16_t>(Imm & 0xFFFF);
674 uint16_t Hi16 = static_cast<uint16_t>((Imm >> 16) & 0xFFFF);
675 if (Lo16 == Hi16 &&
676 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
677 return;
678 } else {
679 // For pre-GFX11, the inline constant is in the low 16 bits, so we need
680 // to check if it can be printed as inline constant value.
681 if (isUInt<16>(Imm) &&
682 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
683 return;
684 }
685 break;
686 }
689 if (isUInt<16>(Imm) &&
690 printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
691 return;
692 break;
694 break;
695 default:
696 llvm_unreachable("bad operand type");
697 }
698
699 O << formatHex(static_cast<uint64_t>(Imm));
700}
701
702bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,
703 const MCSubtargetInfo &STI,
704 raw_ostream &O) {
705 if (Imm == llvm::bit_cast<uint32_t>(0.0f))
706 O << "0.0";
707 else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
708 O << "1.0";
709 else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
710 O << "-1.0";
711 else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
712 O << "0.5";
713 else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
714 O << "-0.5";
715 else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
716 O << "2.0";
717 else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
718 O << "-2.0";
719 else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
720 O << "4.0";
721 else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
722 O << "-4.0";
723 else if (Imm == 0x3e22f983 &&
724 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
725 O << "0.15915494";
726 else
727 return false;
728
729 return true;
730}
731
732void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
733 const MCSubtargetInfo &STI,
734 raw_ostream &O) {
735 int32_t SImm = static_cast<int32_t>(Imm);
736 if (isInlinableIntLiteral(SImm)) {
737 O << SImm;
738 return;
739 }
740
741 if (printImmediateFloat32(Imm, STI, O))
742 return;
743
744 O << formatHex(static_cast<uint64_t>(Imm));
745}
746
747void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
748 const MCSubtargetInfo &STI,
749 raw_ostream &O, bool IsFP) {
750 int64_t SImm = static_cast<int64_t>(Imm);
751 if (SImm >= -16 && SImm <= 64) {
752 O << SImm;
753 return;
754 }
755
756 if (Imm == llvm::bit_cast<uint64_t>(0.0))
757 O << "0.0";
758 else if (Imm == llvm::bit_cast<uint64_t>(1.0))
759 O << "1.0";
760 else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
761 O << "-1.0";
762 else if (Imm == llvm::bit_cast<uint64_t>(0.5))
763 O << "0.5";
764 else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
765 O << "-0.5";
766 else if (Imm == llvm::bit_cast<uint64_t>(2.0))
767 O << "2.0";
768 else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
769 O << "-2.0";
770 else if (Imm == llvm::bit_cast<uint64_t>(4.0))
771 O << "4.0";
772 else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
773 O << "-4.0";
774 else if (Imm == 0x3fc45f306dc9c882 &&
775 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
776 O << "0.15915494309189532";
777 else
778 printLiteral64(Imm, O, IsFP);
779}
780
781void AMDGPUInstPrinter::printLiteral64(uint64_t Imm, raw_ostream &O,
782 bool IsFP) {
783 if (IsFP && Lo_32(Imm) == 0)
784 O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
785 else
786 O << formatHex(Imm);
787}
788
789void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
790 const MCSubtargetInfo &STI,
791 raw_ostream &O) {
792 unsigned Imm = MI->getOperand(OpNo).getImm();
793 if (!Imm)
794 return;
795
796 if (AMDGPU::isGFX940(STI)) {
797 switch (MI->getOpcode()) {
798 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
799 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
800 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
801 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
802 O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
803 << ((Imm >> 2) & 1) << ']';
804 return;
805 }
806 }
807
808 O << " blgp:" << Imm;
809}
810
811void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
812 const MCSubtargetInfo &STI,
813 raw_ostream &O) {
814 if (!FirstOperand)
815 O << ", ";
816 printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize32)
817 ? AMDGPU::VCC_LO
818 : AMDGPU::VCC,
819 O, MRI);
820 if (FirstOperand)
821 O << ", ";
822}
823
824bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
825 unsigned OpNo) const {
826 return OpNo == 0 && SIInstrFlags::isDPP(Desc) && SIInstrFlags::isVOPC(Desc) &&
827 !isVOPCAsmOnly(Desc.getOpcode()) &&
828 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
829 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
830}
831
832// Print default vcc/vcc_lo operand of VOPC.
833void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
834 const MCSubtargetInfo &STI,
835 raw_ostream &O) {
836 unsigned Opc = MI->getOpcode();
837 const MCInstrDesc &Desc = MII.get(Opc);
838 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
839 // 0, 1 and 2 are the first printed operands in different cases
840 // If there are printed modifiers, printOperandAndFPInputMods or
841 // printOperandAndIntInputMods will be called instead
842 if ((OpNo == 0 || (OpNo == 1 && SIInstrFlags::isDPP(Desc) && ModIdx != -1)) &&
843 SIInstrFlags::isVOPC(Desc) && !isVOPCAsmOnly(Desc.getOpcode()) &&
844 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
845 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
846 printDefaultVccOperand(true, STI, O);
847
848 printRegularOperand(MI, OpNo, STI, O);
849}
850
851// Print operands after vcc or modifier handling.
852void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
853 const MCSubtargetInfo &STI,
854 raw_ostream &O) {
855 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
856
857 if (OpNo >= MI->getNumOperands()) {
858 O << "/*Missing OP" << OpNo << "*/";
859 return;
860 }
861
862 const MCOperand &Op = MI->getOperand(OpNo);
863 if (Op.isReg()) {
864 printRegOperand(Op.getReg(), MI->getOpcode(), OpNo, O, MRI);
865
866 // Check if operand register class contains register used.
867 // Intention: print disassembler message when invalid code is decoded,
868 // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
869 const MCOperandInfo &OpInfo = Desc.operands()[OpNo];
870 if (OpInfo.RegClass != -1) {
871 int16_t RCID = MII.getOpRegClassID(
873 const MCRegisterClass &RC = MRI.getRegClass(RCID);
874 auto Reg = mc2PseudoReg(Op.getReg());
875 if (!RC.contains(Reg) && !isInlineValue(Reg)) {
876 bool IsWaveSizeOp = OpInfo.isLookupRegClassByHwMode() &&
877 (OpInfo.RegClass == AMDGPU::SReg_1 ||
878 OpInfo.RegClass == AMDGPU::SReg_1_XEXEC);
879 // Suppress this comment for a mismatched wavesize. Some users expect to
880 // be able to assemble and disassemble modules with mixed wavesizes, but
881 // we do not know the subtarget in different functions in MC.
882 //
883 // TODO: Should probably print it anyway, maybe a more specific version.
884 if (!IsWaveSizeOp) {
885 O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
886 << "\' register class*/";
887 }
888 }
889 }
890 } else if (Op.isImm()) {
891 const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
892 switch (OpTy) {
903 printImmediate32(Op.getImm(), STI, O);
904 break;
908 printImmediate64(Op.getImm(), STI, O, false);
909 break;
914 printImmediate64(Op.getImm(), STI, O, true);
915 break;
918 printImmediateInt16(Op.getImm(), STI, O);
919 break;
923 printImmediateF16(Op.getImm(), STI, O);
924 break;
927 printImmediateBF16(Op.getImm(), STI, O);
928 break;
937 printImmediateV216(Op.getImm(), OpTy, STI, O);
938 break;
941 O << formatDec(Op.getImm());
942 break;
944 // Disassembler does not fail when operand should not allow immediate
945 // operands but decodes them into 32bit immediate operand.
946 printImmediate32(Op.getImm(), STI, O);
947 O << "/*Invalid immediate*/";
948 break;
949 default:
950 // We hit this for the immediate instruction bits that don't yet have a
951 // custom printer.
952 llvm_unreachable("unexpected immediate operand type");
953 }
954 } else if (Op.isExpr()) {
955 const MCExpr *Exp = Op.getExpr();
956 MAI.printExpr(O, *Exp);
957 } else {
958 O << "/*INV_OP*/";
959 }
960
961 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
962 switch (MI->getOpcode()) {
963 default: break;
964
965 case AMDGPU::V_CNDMASK_B32_e32_gfx10:
966 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
967 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
968 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
969 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
970 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
971 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
972 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
973 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
974 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
975 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
976 case AMDGPU::V_CNDMASK_B32_e32_gfx11:
977 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
978 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
979 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
980 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
981 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
982 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
983 case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
984 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
985 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
986 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
987 case AMDGPU::V_CNDMASK_B32_e32_gfx12:
988 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
989 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
990 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
991 case AMDGPU::V_CNDMASK_B32_dpp_gfx12:
992 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
993 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
994 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
995 case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:
996 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
997 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
998 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
999 case AMDGPU::V_CNDMASK_B32_e32_gfx13:
1000 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx13:
1001 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx13:
1002 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx13:
1003 case AMDGPU::V_CNDMASK_B32_dpp_gfx13:
1004 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx13:
1005 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx13:
1006 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx13:
1007 case AMDGPU::V_CNDMASK_B32_dpp8_gfx13:
1008 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx13:
1009 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx13:
1010 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx13:
1011
1012 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
1013 case AMDGPU::V_CNDMASK_B32_e32_vi:
1014 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
1015 AMDGPU::OpName::src1))
1016 printDefaultVccOperand(OpNo == 0, STI, O);
1017 break;
1018 }
1019
1021 int SOffsetIdx =
1022 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
1023 assert(SOffsetIdx != -1);
1024 if ((int)OpNo == SOffsetIdx)
1025 printSymbolicFormat(MI, STI, O);
1026 }
1027}
1028
1029void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
1030 unsigned OpNo,
1031 const MCSubtargetInfo &STI,
1032 raw_ostream &O) {
1033 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1034 if (needsImpliedVcc(Desc, OpNo))
1035 printDefaultVccOperand(true, STI, O);
1036
1037 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
1038
1039 // Use 'neg(...)' instead of '-' to avoid ambiguity.
1040 // This is important for integer literals because
1041 // -1 is not the same value as neg(1).
1042 bool NegMnemo = false;
1043
1044 if (InputModifiers & SISrcMods::NEG) {
1045 if (OpNo + 1 < MI->getNumOperands() &&
1046 (InputModifiers & SISrcMods::ABS) == 0) {
1047 const MCOperand &Op = MI->getOperand(OpNo + 1);
1048 NegMnemo = Op.isImm();
1049 }
1050 if (NegMnemo) {
1051 O << "neg(";
1052 } else {
1053 O << '-';
1054 }
1055 }
1056
1057 if (InputModifiers & SISrcMods::ABS)
1058 O << '|';
1059 printRegularOperand(MI, OpNo + 1, STI, O);
1060 if (InputModifiers & SISrcMods::ABS)
1061 O << '|';
1062
1063 if (NegMnemo) {
1064 O << ')';
1065 }
1066
1067 // Print default vcc/vcc_lo operand of VOP2b.
1068 switch (MI->getOpcode()) {
1069 default:
1070 break;
1071
1072 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
1073 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
1074 case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
1075 if ((int)OpNo + 1 ==
1076 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
1077 printDefaultVccOperand(OpNo == 0, STI, O);
1078 break;
1079 }
1080}
1081
1082void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
1083 unsigned OpNo,
1084 const MCSubtargetInfo &STI,
1085 raw_ostream &O) {
1086 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1087 if (needsImpliedVcc(Desc, OpNo))
1088 printDefaultVccOperand(true, STI, O);
1089
1090 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
1091 if (InputModifiers & SISrcMods::SEXT)
1092 O << "sext(";
1093 printRegularOperand(MI, OpNo + 1, STI, O);
1094 if (InputModifiers & SISrcMods::SEXT)
1095 O << ')';
1096
1097 // Print default vcc/vcc_lo operand of VOP2b.
1098 switch (MI->getOpcode()) {
1099 default: break;
1100
1101 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
1102 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
1103 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
1104 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
1105 AMDGPU::OpName::src1))
1106 printDefaultVccOperand(OpNo == 0, STI, O);
1107 break;
1108 }
1109}
1110
1111void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
1112 const MCSubtargetInfo &STI,
1113 raw_ostream &O) {
1114 if (!AMDGPU::isGFX10Plus(STI))
1115 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
1116
1117 unsigned Imm = MI->getOperand(OpNo).getImm();
1118 O << "dpp8:[" << formatDec(Imm & 0x7);
1119 for (size_t i = 1; i < 8; ++i) {
1120 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
1121 }
1122 O << ']';
1123}
1124
1125void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
1126 const MCSubtargetInfo &STI,
1127 raw_ostream &O) {
1128 using namespace AMDGPU::DPP;
1129
1130 unsigned Imm = MI->getOperand(OpNo).getImm();
1131 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1132
1134 STI.hasFeature(AMDGPU::FeatureDPALU_DPP) &&
1135 AMDGPU::isDPALU_DPP(Desc, MII, STI)) {
1136 O << " /* DP ALU dpp only supports "
1137 << (isGFX12(STI) ? "row_share" : "row_newbcast") << " */";
1138 return;
1139 }
1140 if (Imm <= DppCtrl::QUAD_PERM_LAST) {
1141 O << "quad_perm:[";
1142 O << formatDec(Imm & 0x3) << ',';
1143 O << formatDec((Imm & 0xc) >> 2) << ',';
1144 O << formatDec((Imm & 0x30) >> 4) << ',';
1145 O << formatDec((Imm & 0xc0) >> 6) << ']';
1146 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
1147 (Imm <= DppCtrl::ROW_SHL_LAST)) {
1148 O << "row_shl:" << formatDec(Imm - DppCtrl::ROW_SHL0);
1149 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
1150 (Imm <= DppCtrl::ROW_SHR_LAST)) {
1151 O << "row_shr:" << formatDec(Imm - DppCtrl::ROW_SHR0);
1152 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
1153 (Imm <= DppCtrl::ROW_ROR_LAST)) {
1154 O << "row_ror:" << formatDec(Imm - DppCtrl::ROW_ROR0);
1155 } else if (Imm == DppCtrl::WAVE_SHL1) {
1156 if (AMDGPU::isGFX10Plus(STI)) {
1157 O << "/* wave_shl is not supported starting from GFX10 */";
1158 return;
1159 }
1160 O << "wave_shl:1";
1161 } else if (Imm == DppCtrl::WAVE_ROL1) {
1162 if (AMDGPU::isGFX10Plus(STI)) {
1163 O << "/* wave_rol is not supported starting from GFX10 */";
1164 return;
1165 }
1166 O << "wave_rol:1";
1167 } else if (Imm == DppCtrl::WAVE_SHR1) {
1168 if (AMDGPU::isGFX10Plus(STI)) {
1169 O << "/* wave_shr is not supported starting from GFX10 */";
1170 return;
1171 }
1172 O << "wave_shr:1";
1173 } else if (Imm == DppCtrl::WAVE_ROR1) {
1174 if (AMDGPU::isGFX10Plus(STI)) {
1175 O << "/* wave_ror is not supported starting from GFX10 */";
1176 return;
1177 }
1178 O << "wave_ror:1";
1179 } else if (Imm == DppCtrl::ROW_MIRROR) {
1180 O << "row_mirror";
1181 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
1182 O << "row_half_mirror";
1183 } else if (Imm == DppCtrl::BCAST15) {
1184 if (AMDGPU::isGFX10Plus(STI)) {
1185 O << "/* row_bcast is not supported starting from GFX10 */";
1186 return;
1187 }
1188 O << "row_bcast:15";
1189 } else if (Imm == DppCtrl::BCAST31) {
1190 if (AMDGPU::isGFX10Plus(STI)) {
1191 O << "/* row_bcast is not supported starting from GFX10 */";
1192 return;
1193 }
1194 O << "row_bcast:31";
1195 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
1196 (Imm <= DppCtrl::ROW_SHARE_LAST)) {
1197 if (AMDGPU::isGFX90A(STI)) {
1198 O << "row_newbcast:";
1199 } else if (AMDGPU::isGFX10Plus(STI)) {
1200 O << "row_share:";
1201 } else {
1202 O << " /* row_newbcast/row_share is not supported on ASICs earlier "
1203 "than GFX90A/GFX10 */";
1204 return;
1205 }
1206 O << formatDec(Imm - DppCtrl::ROW_SHARE_FIRST);
1207 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
1208 (Imm <= DppCtrl::ROW_XMASK_LAST)) {
1209 if (!AMDGPU::isGFX10Plus(STI)) {
1210 O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
1211 return;
1212 }
1213 O << "row_xmask:" << formatDec(Imm - DppCtrl::ROW_XMASK_FIRST);
1214 } else {
1215 O << "/* Invalid dpp_ctrl value */";
1216 }
1217}
1218
1219void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
1220 const MCSubtargetInfo &STI,
1221 raw_ostream &O) {
1222 unsigned Imm = MI->getOperand(OpNo).getImm();
1223 if (Imm) {
1224 O << " bound_ctrl:1";
1225 }
1226}
1227
1228void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
1229 const MCSubtargetInfo &STI, raw_ostream &O) {
1230 using namespace llvm::AMDGPU::DPP;
1231 unsigned Imm = MI->getOperand(OpNo).getImm();
1232 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1233 O << " fi:1";
1234 }
1235}
1236
1237void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1238 raw_ostream &O) {
1239 using namespace llvm::AMDGPU::SDWA;
1240
1241 unsigned Imm = MI->getOperand(OpNo).getImm();
1242 switch (Imm) {
1243 case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1244 case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1245 case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1246 case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1247 case SdwaSel::WORD_0: O << "WORD_0"; break;
1248 case SdwaSel::WORD_1: O << "WORD_1"; break;
1249 case SdwaSel::DWORD: O << "DWORD"; break;
1250 default: llvm_unreachable("Invalid SDWA data select operand");
1251 }
1252}
1253
1254void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1255 const MCSubtargetInfo &STI,
1256 raw_ostream &O) {
1257 O << "dst_sel:";
1258 printSDWASel(MI, OpNo, O);
1259}
1260
1261void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1262 const MCSubtargetInfo &STI,
1263 raw_ostream &O) {
1264 O << "src0_sel:";
1265 printSDWASel(MI, OpNo, O);
1266}
1267
1268void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1269 const MCSubtargetInfo &STI,
1270 raw_ostream &O) {
1271 O << "src1_sel:";
1272 printSDWASel(MI, OpNo, O);
1273}
1274
1275void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1276 const MCSubtargetInfo &STI,
1277 raw_ostream &O) {
1278 using namespace llvm::AMDGPU::SDWA;
1279
1280 O << "dst_unused:";
1281 unsigned Imm = MI->getOperand(OpNo).getImm();
1282 switch (Imm) {
1283 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1284 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1285 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1286 default: llvm_unreachable("Invalid SDWA dest_unused operand");
1287 }
1288}
1289
1290void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1291 const MCSubtargetInfo &STI, raw_ostream &O,
1292 unsigned N) {
1293 unsigned Opc = MI->getOpcode();
1294 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1295 unsigned En = MI->getOperand(EnIdx).getImm();
1296
1297 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1298
1299 // If compr is set, print as src0, src0, src1, src1
1300 if (MI->getOperand(ComprIdx).getImm())
1301 OpNo = OpNo - N + N / 2;
1302
1303 if (En & (1 << N))
1304 printRegOperand(MI->getOperand(OpNo).getReg(), Opc, OpNo, O, MRI);
1305 else
1306 O << "off";
1307}
1308
1309void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1310 const MCSubtargetInfo &STI,
1311 raw_ostream &O) {
1312 printExpSrcN(MI, OpNo, STI, O, 0);
1313}
1314
1315void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1316 const MCSubtargetInfo &STI,
1317 raw_ostream &O) {
1318 printExpSrcN(MI, OpNo, STI, O, 1);
1319}
1320
1321void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1322 const MCSubtargetInfo &STI,
1323 raw_ostream &O) {
1324 printExpSrcN(MI, OpNo, STI, O, 2);
1325}
1326
1327void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1328 const MCSubtargetInfo &STI,
1329 raw_ostream &O) {
1330 printExpSrcN(MI, OpNo, STI, O, 3);
1331}
1332
1333void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1334 const MCSubtargetInfo &STI,
1335 raw_ostream &O) {
1336 using namespace llvm::AMDGPU::Exp;
1337
1338 // This is really a 6 bit field.
1339 unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1340
1341 int Index;
1342 StringRef TgtName;
1343 if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1344 O << ' ' << TgtName;
1345 if (Index >= 0)
1346 O << Index;
1347 } else {
1348 O << " invalid_target_" << Id;
1349 }
1350}
1351
1352static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1353 bool IsPacked, bool HasDstSel) {
1354 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1355
1356 for (int I = 0; I < NumOps; ++I) {
1357 if (!!(Ops[I] & Mod) != DefaultValue)
1358 return false;
1359 }
1360
1361 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1362 return false;
1363
1364 return true;
1365}
1366
1367void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1368 StringRef Name,
1369 unsigned Mod,
1370 raw_ostream &O) {
1371 unsigned Opc = MI->getOpcode();
1372 int NumOps = 0;
1373 int Ops[3];
1374
1375 std::pair<AMDGPU::OpName, AMDGPU::OpName> MOps[] = {
1376 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},
1377 {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},
1378 {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};
1379 int DefaultValue = (Mod == SISrcMods::OP_SEL_1);
1380
1381 for (auto [SrcMod, Src] : MOps) {
1382 if (!AMDGPU::hasNamedOperand(Opc, Src))
1383 break;
1384
1385 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);
1386 Ops[NumOps++] =
1387 (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;
1388 }
1389
1390 // Some instructions, e.g. v_interp_p2_f16 in GFX9, have src0, src2, but no
1391 // src1.
1392 if (NumOps == 1 && AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src2) &&
1393 !AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1)) {
1394 Ops[NumOps++] = DefaultValue; // Set src1_modifiers to default.
1395 int Mod2Idx =
1396 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers);
1397 assert(Mod2Idx != -1);
1398 Ops[NumOps++] = MI->getOperand(Mod2Idx).getImm();
1399 }
1400
1401 const bool HasDst =
1402 (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst) != -1) ||
1403 (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst) != -1);
1404
1405 // Print three values of neg/opsel for wmma instructions (prints 0 when there
1406 // is no src_modifier operand instead of not printing anything).
1408 NumOps = 0;
1409 int DefaultValue = Mod == SISrcMods::OP_SEL_1;
1410 for (AMDGPU::OpName OpName :
1411 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
1412 AMDGPU::OpName::src2_modifiers}) {
1413 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1414 if (Idx != -1)
1415 Ops[NumOps++] = MI->getOperand(Idx).getImm();
1416 else
1417 Ops[NumOps++] = DefaultValue;
1418 }
1419 }
1420
1421 const bool HasDstSel = HasDst && NumOps > 0 && Mod == SISrcMods::OP_SEL_0 &&
1423
1424 const bool IsPacked = SIInstrFlags::isPacked(MII, *MI);
1425
1426 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1427 return;
1428
1429 O << Name;
1430 ListSeparator Sep(",");
1431 for (int I = 0; I < NumOps; ++I)
1432 O << Sep << !!(Ops[I] & Mod);
1433
1434 if (HasDstSel) {
1435 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1436 }
1437
1438 O << ']';
1439}
1440
1441void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1442 const MCSubtargetInfo &STI,
1443 raw_ostream &O) {
1444 unsigned Opc = MI->getOpcode();
1446 auto SrcMod =
1447 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1448 unsigned Mod = MI->getOperand(SrcMod).getImm();
1449 unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);
1450 unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);
1451 if (Index0 || Index1)
1452 O << " op_sel:[" << Index0 << ',' << Index1 << ']';
1453 return;
1454 }
1455 if (isPermlane16(Opc)) {
1456 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1457 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1458 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1459 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1460 if (FI || BC)
1461 O << " op_sel:[" << FI << ',' << BC << ']';
1462 return;
1463 }
1464
1465 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1466}
1467
1468void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1469 const MCSubtargetInfo &STI,
1470 raw_ostream &O) {
1471 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1472}
1473
1474void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1475 const MCSubtargetInfo &STI,
1476 raw_ostream &O) {
1477 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1478}
1479
1480void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1481 const MCSubtargetInfo &STI,
1482 raw_ostream &O) {
1483 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1484}
1485
1486void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,
1487 const MCSubtargetInfo &STI,
1488 raw_ostream &O) {
1489 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1490 if (Imm == 0)
1491 return;
1492
1493 O << " index_key:" << Imm;
1494}
1495
1496void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,
1497 const MCSubtargetInfo &STI,
1498 raw_ostream &O) {
1499 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1500 if (Imm == 0)
1501 return;
1502
1503 O << " index_key:" << Imm;
1504}
1505
1506void AMDGPUInstPrinter::printIndexKey32bit(const MCInst *MI, unsigned OpNo,
1507 const MCSubtargetInfo &STI,
1508 raw_ostream &O) {
1509 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1510 if (Imm == 0)
1511 return;
1512
1513 O << " index_key:" << Imm;
1514}
1515
1516void AMDGPUInstPrinter::printMatrixFMT(const MCInst *MI, unsigned OpNo,
1517 const MCSubtargetInfo &STI,
1518 raw_ostream &O, char AorB) {
1519 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1520 if (Imm == 0)
1521 return;
1522
1523 O << " matrix_" << AorB << "_fmt:";
1524 if (Imm < static_cast<int64_t>(std::size(WMMAMods::ModMatrixFmt)))
1526 else
1527 O << Imm;
1528}
1529
1530void AMDGPUInstPrinter::printMatrixAFMT(const MCInst *MI, unsigned OpNo,
1531 const MCSubtargetInfo &STI,
1532 raw_ostream &O) {
1533 printMatrixFMT(MI, OpNo, STI, O, 'a');
1534}
1535
1536void AMDGPUInstPrinter::printMatrixBFMT(const MCInst *MI, unsigned OpNo,
1537 const MCSubtargetInfo &STI,
1538 raw_ostream &O) {
1539 printMatrixFMT(MI, OpNo, STI, O, 'b');
1540}
1541
1542void AMDGPUInstPrinter::printMatrixScale(const MCInst *MI, unsigned OpNo,
1543 const MCSubtargetInfo &STI,
1544 raw_ostream &O, char AorB) {
1545 auto Imm = MI->getOperand(OpNo).getImm() & 1;
1546 if (Imm == 0)
1547 return;
1548
1549 O << " matrix_" << AorB << "_scale:";
1550 if (Imm < static_cast<int64_t>(std::size(WMMAMods::ModMatrixScale)))
1552 else
1553 O << Imm;
1554}
1555
1556void AMDGPUInstPrinter::printMatrixAScale(const MCInst *MI, unsigned OpNo,
1557 const MCSubtargetInfo &STI,
1558 raw_ostream &O) {
1559 printMatrixScale(MI, OpNo, STI, O, 'a');
1560}
1561
1562void AMDGPUInstPrinter::printMatrixBScale(const MCInst *MI, unsigned OpNo,
1563 const MCSubtargetInfo &STI,
1564 raw_ostream &O) {
1565 printMatrixScale(MI, OpNo, STI, O, 'b');
1566}
1567
1568void AMDGPUInstPrinter::printMatrixScaleFmt(const MCInst *MI, unsigned OpNo,
1569 const MCSubtargetInfo &STI,
1570 raw_ostream &O, char AorB) {
1571 auto Imm = MI->getOperand(OpNo).getImm() & 3;
1572 if (Imm == 0)
1573 return;
1574
1575 O << " matrix_" << AorB << "_scale_fmt:";
1576 if (Imm < static_cast<int64_t>(std::size(WMMAMods::ModMatrixScaleFmt)))
1578 else
1579 O << Imm;
1580}
1581
1582void AMDGPUInstPrinter::printMatrixAScaleFmt(const MCInst *MI, unsigned OpNo,
1583 const MCSubtargetInfo &STI,
1584 raw_ostream &O) {
1585 printMatrixScaleFmt(MI, OpNo, STI, O, 'a');
1586}
1587
1588void AMDGPUInstPrinter::printMatrixBScaleFmt(const MCInst *MI, unsigned OpNo,
1589 const MCSubtargetInfo &STI,
1590 raw_ostream &O) {
1591 printMatrixScaleFmt(MI, OpNo, STI, O, 'b');
1592}
1593
1594void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1595 const MCSubtargetInfo &STI,
1596 raw_ostream &O) {
1597 unsigned Imm = MI->getOperand(OpNum).getImm();
1598 switch (Imm) {
1599 case 0:
1600 O << "p10";
1601 break;
1602 case 1:
1603 O << "p20";
1604 break;
1605 case 2:
1606 O << "p0";
1607 break;
1608 default:
1609 O << "invalid_param_" << Imm;
1610 }
1611}
1612
1613void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1614 const MCSubtargetInfo &STI,
1615 raw_ostream &O) {
1616 unsigned Attr = MI->getOperand(OpNum).getImm();
1617 O << "attr" << Attr;
1618}
1619
1620void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1621 const MCSubtargetInfo &STI,
1622 raw_ostream &O) {
1623 unsigned Chan = MI->getOperand(OpNum).getImm();
1624 O << '.' << "xyzw"[Chan & 0x3];
1625}
1626
1627void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,
1628 const MCSubtargetInfo &STI,
1629 raw_ostream &O) {
1630 using namespace llvm::AMDGPU::VGPRIndexMode;
1631 unsigned Val = MI->getOperand(OpNo).getImm();
1632
1633 if ((Val & ~ENABLE_MASK) != 0) {
1634 O << formatHex(static_cast<uint64_t>(Val));
1635 } else {
1636 O << "gpr_idx(";
1637 ListSeparator Sep(",");
1638 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1639 if (Val & (1 << ModeId))
1640 O << Sep << IdSymbolic[ModeId];
1641 }
1642 O << ')';
1643 }
1644}
1645
1646void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1647 const MCSubtargetInfo &STI,
1648 raw_ostream &O) {
1649 printRegularOperand(MI, OpNo, STI, O);
1650 O << ", ";
1651 printRegularOperand(MI, OpNo + 1, STI, O);
1652}
1653
1654void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1655 raw_ostream &O, StringRef Asm,
1657 const MCOperand &Op = MI->getOperand(OpNo);
1658 assert(Op.isImm());
1659 if (Op.getImm() == 1) {
1660 O << Asm;
1661 } else {
1662 O << Default;
1663 }
1664}
1665
1666void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1667 raw_ostream &O, char Asm) {
1668 const MCOperand &Op = MI->getOperand(OpNo);
1669 assert(Op.isImm());
1670 if (Op.getImm() == 1)
1671 O << Asm;
1672}
1673
1674void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1675 const MCSubtargetInfo &STI,
1676 raw_ostream &O) {
1677 int Imm = MI->getOperand(OpNo).getImm();
1678 if (Imm == SIOutMods::MUL2)
1679 O << " mul:2";
1680 else if (Imm == SIOutMods::MUL4)
1681 O << " mul:4";
1682 else if (Imm == SIOutMods::DIV2)
1683 O << " div:2";
1684}
1685
1686void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1687 const MCSubtargetInfo &STI,
1688 raw_ostream &O) {
1689 using namespace llvm::AMDGPU::SendMsg;
1690
1691 const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1692
1693 uint16_t MsgId;
1694 uint16_t OpId;
1695 uint16_t StreamId;
1696 decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
1697
1698 StringRef MsgName = getMsgName(MsgId, STI);
1699
1700 if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1701 isValidMsgStream(MsgId, OpId, StreamId, STI)) {
1702 O << "sendmsg(" << MsgName;
1703 if (msgRequiresOp(MsgId, STI)) {
1704 O << ", " << getMsgOpName(MsgId, OpId, STI);
1705 if (msgSupportsStream(MsgId, OpId, STI)) {
1706 O << ", " << StreamId;
1707 }
1708 }
1709 O << ')';
1710 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1711 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1712 } else {
1713 O << Imm16; // Unknown imm16 code.
1714 }
1715}
1716
1718 const MCSubtargetInfo &STI,
1719 raw_ostream &O) {
1720 using namespace llvm::AMDGPU::WaitEvent;
1721 const uint16_t Imm16 = static_cast<uint16_t>(MI->getOperand(OpNo).getImm());
1722
1723 StringRef EventName = getWaitEventMaskName(Imm16, STI);
1724 if (EventName.empty())
1725 O << formatHex(static_cast<uint64_t>(Imm16));
1726 else
1727 O << EventName;
1728}
1729
1730static void printSwizzleBitmask(const uint16_t AndMask,
1731 const uint16_t OrMask,
1732 const uint16_t XorMask,
1733 raw_ostream &O) {
1734 using namespace llvm::AMDGPU::Swizzle;
1735
1736 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1737 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1738
1739 O << "\"";
1740
1741 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1742 uint16_t p0 = Probe0 & Mask;
1743 uint16_t p1 = Probe1 & Mask;
1744
1745 if (p0 == p1) {
1746 if (p0 == 0) {
1747 O << "0";
1748 } else {
1749 O << "1";
1750 }
1751 } else {
1752 if (p0 == 0) {
1753 O << "p";
1754 } else {
1755 O << "i";
1756 }
1757 }
1758 }
1759
1760 O << "\"";
1761}
1762
1763void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1764 const MCSubtargetInfo &STI,
1765 raw_ostream &O) {
1766 using namespace llvm::AMDGPU::Swizzle;
1767
1768 uint16_t Imm = MI->getOperand(OpNo).getImm();
1769 if (Imm == 0) {
1770 return;
1771 }
1772
1773 O << " offset:";
1774
1775 // Rotate and FFT modes
1776 if (Imm >= ROTATE_MODE_LO && AMDGPU::isGFX9Plus(STI)) {
1777 if (Imm >= FFT_MODE_LO) {
1778 O << "swizzle(" << IdSymbolic[ID_FFT] << ',' << (Imm & FFT_SWIZZLE_MASK)
1779 << ')';
1780 } else if (Imm >= ROTATE_MODE_LO) {
1781 O << "swizzle(" << IdSymbolic[ID_ROTATE] << ','
1782 << ((Imm >> ROTATE_DIR_SHIFT) & ROTATE_DIR_MASK) << ','
1783 << ((Imm >> ROTATE_SIZE_SHIFT) & ROTATE_SIZE_MASK) << ')';
1784 }
1785 return;
1786 }
1787
1788 // Basic mode
1790 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1791 for (unsigned I = 0; I < LANE_NUM; ++I) {
1792 O << ",";
1793 O << formatDec(Imm & LANE_MASK);
1794 Imm >>= LANE_SHIFT;
1795 }
1796 O << ")";
1797
1798 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1799
1800 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1801 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1802 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1803
1804 if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
1805
1806 O << "swizzle(" << IdSymbolic[ID_SWAP];
1807 O << ",";
1808 O << formatDec(XorMask);
1809 O << ")";
1810
1811 } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
1812 isPowerOf2_64(XorMask + 1)) {
1813
1814 O << "swizzle(" << IdSymbolic[ID_REVERSE];
1815 O << ",";
1816 O << formatDec(XorMask + 1);
1817 O << ")";
1818
1819 } else {
1820
1821 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1822 if (GroupSize > 1 &&
1823 isPowerOf2_64(GroupSize) &&
1824 OrMask < GroupSize &&
1825 XorMask == 0) {
1826
1827 O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1828 O << ",";
1829 O << formatDec(GroupSize);
1830 O << ",";
1831 O << formatDec(OrMask);
1832 O << ")";
1833
1834 } else {
1835 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1836 O << ",";
1837 printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1838 O << ")";
1839 }
1840 }
1841 } else {
1842 printU16ImmDecOperand(MI, OpNo, O);
1843 }
1844}
1845
1846void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,
1847 const MCSubtargetInfo &STI,
1848 raw_ostream &O) {
1850
1851 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1852 unsigned Vmcnt, Expcnt, Lgkmcnt;
1853 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1854
1855 bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1856 bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1857 bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1858 bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1859
1860 ListSeparator Sep(" ");
1861
1862 if (!IsDefaultVmcnt || PrintAll)
1863 O << Sep << "vmcnt(" << Vmcnt << ')';
1864
1865 if (!IsDefaultExpcnt || PrintAll)
1866 O << Sep << "expcnt(" << Expcnt << ')';
1867
1868 if (!IsDefaultLgkmcnt || PrintAll)
1869 O << Sep << "lgkmcnt(" << Lgkmcnt << ')';
1870}
1871
1872void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
1873 const MCSubtargetInfo &STI,
1874 raw_ostream &O) {
1875 using namespace llvm::AMDGPU::DepCtr;
1876
1877 uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
1878
1879 bool HasNonDefaultVal = false;
1880 if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
1881 int Id = 0;
1882 StringRef Name;
1883 unsigned Val;
1884 bool IsDefault;
1885 ListSeparator Sep(" ");
1886 while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
1887 if (!IsDefault || !HasNonDefaultVal)
1888 O << Sep << Name << '(' << Val << ')';
1889 }
1890 } else {
1891 O << formatHex(Imm16);
1892 }
1893}
1894
1896 const MCSubtargetInfo &STI,
1897 raw_ostream &O) {
1898 const char *BadInstId = "/* invalid instid value */";
1899 static const std::array<const char *, 12> InstIds = {
1900 "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",
1901 "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",
1902 "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1903 "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};
1904
1905 const char *BadInstSkip = "/* invalid instskip value */";
1906 static const std::array<const char *, 6> InstSkips = {
1907 "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1908
1909 unsigned SImm16 = MI->getOperand(OpNo).getImm();
1910 const char *Prefix = "";
1911
1912 unsigned Value = SImm16 & 0xF;
1913 if (Value) {
1914 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1915 O << Prefix << "instid0(" << Name << ')';
1916 Prefix = " | ";
1917 }
1918
1919 Value = (SImm16 >> 4) & 7;
1920 if (Value) {
1921 const char *Name =
1922 Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1923 O << Prefix << "instskip(" << Name << ')';
1924 Prefix = " | ";
1925 }
1926
1927 Value = (SImm16 >> 7) & 0xF;
1928 if (Value) {
1929 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1930 O << Prefix << "instid1(" << Name << ')';
1931 Prefix = " | ";
1932 }
1933
1934 if (!*Prefix)
1935 O << "0";
1936}
1937
1938void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1939 const MCSubtargetInfo &STI, raw_ostream &O) {
1940 using namespace llvm::AMDGPU::Hwreg;
1941 unsigned Val = MI->getOperand(OpNo).getImm();
1942 auto [Id, Offset, Width] = HwregEncoding::decode(Val);
1943 StringRef HwRegName = getHwreg(Id, STI);
1944
1945 O << "hwreg(";
1946 if (!HwRegName.empty()) {
1947 O << HwRegName;
1948 } else {
1949 O << Id;
1950 }
1952 O << ", " << Offset << ", " << Width;
1953 O << ')';
1954}
1955
1956void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1957 const MCSubtargetInfo &STI,
1958 raw_ostream &O) {
1959 uint16_t Imm = MI->getOperand(OpNo).getImm();
1960 if (Imm == 0) {
1961 return;
1962 }
1963
1964 O << ' ' << formatDec(Imm);
1965}
1966
1967void AMDGPUInstPrinter::printNamedInt(const MCInst *MI, unsigned OpNo,
1968 const MCSubtargetInfo &STI,
1969 raw_ostream &O, StringRef Prefix,
1970 bool PrintInHex, bool AlwaysPrint) {
1971 int64_t V = MI->getOperand(OpNo).getImm();
1972 if (AlwaysPrint || V != 0)
1973 O << ' ' << Prefix << ':' << (PrintInHex ? formatHex(V) : formatDec(V));
1974}
1975
1976void AMDGPUInstPrinter::printBitOp3(const MCInst *MI, unsigned OpNo,
1977 const MCSubtargetInfo &STI,
1978 raw_ostream &O) {
1979 uint8_t Imm = MI->getOperand(OpNo).getImm();
1980 if (!Imm)
1981 return;
1982
1983 O << " bitop3:";
1984 if (Imm <= 10)
1985 O << formatDec(Imm);
1986 else
1987 O << formatHex(static_cast<uint64_t>(Imm));
1988}
1989
1990#include "AMDGPUGenAsmWriter.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
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 MCRegister getRegForPrinting(MCRegister Reg, const MCRegisterInfo &MRI)
static MCRegister getRegFromMIA(MCRegister Reg, unsigned OpNo, const MCInstrDesc &Desc, const MCRegisterInfo &MRI, const AMDGPUMCInstrAnalysis &MIA)
static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI, raw_ostream &O)
Provides AMDGPU specific target descriptions.
IRTranslator LLVM IR MI
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
MachineRegisterInfo & MRI
This file contains some functions that are useful when dealing with strings.
void printSwizzle(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printWaitEvent(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)
static void printRegOperand(MCRegister Reg, raw_ostream &O, const MCRegisterInfo &MRI)
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
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)
A helper class to return the specified delimiter string after the first invocation of operator String...
void printExpr(raw_ostream &, const MCExpr &) const
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
const MCRegisterInfo & MRI
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
const MCInstrAnalysis * MIA
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Describe properties that are true of each instruction in the target description file.
bool isLookupRegClassByHwMode() const
Set if this operand is a value that requires the current hwmode to look up its register class.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition MCInstrDesc.h:94
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
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...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
StringRef getCPU() const
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool decodeDepCtr(unsigned Code, int &Id, StringRef &Name, unsigned &Val, bool &IsDefault, const MCSubtargetInfo &STI)
bool isSymbolicDepCtrEncoding(unsigned Code, bool &HasNonDefaultVal, const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
bool getTgtName(unsigned Id, StringRef &Name, int &Index)
StringRef getHwreg(uint64_t Encoding, const MCSubtargetInfo &STI)
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)
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
void decodeMsg(unsigned Val, uint16_t &MsgId, uint16_t &OpId, uint16_t &StreamId, const MCSubtargetInfo &STI)
StringRef getMsgName(uint64_t Encoding, const MCSubtargetInfo &STI)
Map from an encoding to the symbolic name for a msg_id immediate.
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
StringRef getMsgOpName(int64_t MsgId, uint64_t Encoding, const MCSubtargetInfo &STI)
Map from an encoding to the symbolic name for a sendmsg operation.
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
const char *const IdSymbolic[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
StringRef getWaitEventMaskName(uint64_t Encoding, const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
bool isVOPCAsmOnly(unsigned Opc)
unsigned getTemporalHintType(const MCInstrDesc TID)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool isGFX12Plus(const MCSubtargetInfo &STI)
const MCRegisterClass * getVGPRPhysRegClass(MCRegister Reg, const MCRegisterInfo &MRI)
bool isGFX940(const MCSubtargetInfo &STI)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
Waitcnt decodeWaitcnt(const IsaVersion &Version, unsigned Encoded)
bool getVOP3IsSingle(unsigned Opc)
bool getVOP1IsSingle(unsigned Opc)
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isGFX12(const MCSubtargetInfo &STI)
MCRegister getVGPRWithMSBs(MCRegister Reg, unsigned MSBs, const MCRegisterInfo &MRI)
If Reg is a low VGPR return a corresponding high VGPR with MSBs set.
unsigned getVmcntBitMask(const IsaVersion &Version)
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)
std::pair< const AMDGPU::OpName *, const AMDGPU::OpName * > getVGPRLoweringOperandTables(const MCInstrDesc &Desc)
unsigned getExpcntBitMask(const IsaVersion &Version)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_REG_IMM_V2FP64
Definition SIDefines.h:441
@ OPERAND_REG_IMM_INT64
Definition SIDefines.h:426
@ OPERAND_REG_IMM_V2FP16
Definition SIDefines.h:434
@ OPERAND_REG_INLINE_C_FP64
Definition SIDefines.h:450
@ OPERAND_REG_IMM_NOINLINE_FP16
Definition SIDefines.h:432
@ OPERAND_REG_INLINE_C_BF16
Definition SIDefines.h:447
@ OPERAND_REG_INLINE_C_V2BF16
Definition SIDefines.h:452
@ OPERAND_REG_IMM_V2INT64
Definition SIDefines.h:437
@ OPERAND_REG_IMM_V2INT16
Definition SIDefines.h:436
@ OPERAND_REG_IMM_BF16
Definition SIDefines.h:430
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
Definition SIDefines.h:425
@ OPERAND_REG_IMM_V2BF16
Definition SIDefines.h:433
@ OPERAND_REG_IMM_FP16
Definition SIDefines.h:431
@ OPERAND_REG_IMM_V2FP16_SPLAT
Definition SIDefines.h:435
@ OPERAND_REG_INLINE_C_INT64
Definition SIDefines.h:446
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition SIDefines.h:444
@ OPERAND_REG_IMM_NOINLINE_V2FP16
Definition SIDefines.h:438
@ OPERAND_REG_IMM_FP64
Definition SIDefines.h:429
@ OPERAND_REG_INLINE_C_V2FP16
Definition SIDefines.h:453
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
Definition SIDefines.h:464
@ OPERAND_REG_INLINE_AC_FP32
Definition SIDefines.h:465
@ OPERAND_REG_IMM_V2INT32
Definition SIDefines.h:439
@ OPERAND_REG_IMM_FP32
Definition SIDefines.h:428
@ OPERAND_REG_INLINE_C_FP32
Definition SIDefines.h:449
@ OPERAND_REG_INLINE_C_INT32
Definition SIDefines.h:445
@ OPERAND_REG_INLINE_C_V2INT16
Definition SIDefines.h:451
@ OPERAND_REG_IMM_V2FP32
Definition SIDefines.h:440
@ OPERAND_REG_INLINE_AC_FP64
Definition SIDefines.h:466
@ OPERAND_REG_INLINE_C_FP16
Definition SIDefines.h:448
@ OPERAND_REG_IMM_INT16
Definition SIDefines.h:427
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
Definition SIDefines.h:456
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool isRsrcIndexReg(MCRegister Reg, const MCRegisterInfo &MRI)
bool isCvt_F32_Fp8_Bf8_e64(unsigned Opc)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
bool isCI(const MCSubtargetInfo &STI)
bool getVOP2IsSingle(unsigned Opc)
LLVM_READONLY StringRef getMIMGDimInfoStr(StringTable::Offset)
bool isPermlane16(unsigned Opc)
@ OPERAND_IMMEDIATE
Definition MCInstrDesc.h:61
constexpr bool isVOPC(const T &...O)
Definition SIDefines.h:233
constexpr bool isVOP3(const T &...O)
Definition SIDefines.h:236
constexpr bool hasVOP3OpSel(const T &...O)
Definition SIDefines.h:319
constexpr bool isVOP1(const T &...O)
Definition SIDefines.h:227
constexpr bool isVOP2(const T &...O)
Definition SIDefines.h:230
constexpr bool isSWMMAC(const T &...O)
Definition SIDefines.h:376
constexpr bool isBuffer(const T &...O)
Definition SIDefines.h:264
constexpr bool isMTBUF(const T &...O)
Definition SIDefines.h:261
constexpr bool isSMRD(const T &...O)
Definition SIDefines.h:268
constexpr bool isWMMA(const T &...O)
Definition SIDefines.h:364
constexpr bool isSDWA(const T &...O)
Definition SIDefines.h:249
constexpr bool isPacked(const T &...O)
Definition SIDefines.h:337
constexpr bool isDPP(const T &...O)
Definition SIDefines.h:252
constexpr bool isSegmentSpecificFLAT(const T &...O)
Definition SIDefines.h:393
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
Op::Description Desc
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:156
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
To bit_cast(const From &from) noexcept
Definition bit.h:90
DWARFExpression::Operation Op
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:554
#define N
static std::tuple< typename Fields::ValueType... > decode(uint64_t Encoded)
Instruction set architecture version.
StringTable::Offset AsmSuffix