1//===----------------------------------------------------------------------===//
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//===----------------------------------------------------------------------===//
8//
9// This file implements functions associated with NVVM Intrinsics.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/IR/NVVMIntrinsicUtils.h"
14#include "llvm/ADT/StringRef.h"
15
16using namespace llvm;
17using namespace nvvm;
18
19void nvvm::printEvictPolicyType(raw_ostream &OS, const Constant *ImmArgVal) {
20 const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal);
21 if (!CI ||
22 CI->getZExtValue() > static_cast<uint64_t>(EvictPolicyType::EVICT_LAST)) {
23 OS << "Unsupported evict policy";
24 return;
25 }
26 OS << getEvictPolicyName(Policy: static_cast<EvictPolicyType>(CI->getZExtValue()));
27}
28
29void nvvm::printTMAReductionOp(raw_ostream &OS, const Constant *ImmArgVal) {
30 const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal);
31 if (!CI || CI->getZExtValue() > static_cast<uint64_t>(TMAReductionOp::XOR))
32 llvm_unreachable(
33 "printTMAReductionOp called with invalid value for immediate argument");
34
35 OS << getTMATensorReductionOpName(
36 Op: static_cast<TMAReductionOp>(CI->getZExtValue()));
37}
38
39void nvvm::printTcgen05MMAKind(raw_ostream &OS, const Constant *ImmArgVal) {
40 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
41 uint64_t Val = CI->getZExtValue();
42 switch (static_cast<Tcgen05MMAKind>(Val)) {
43 case Tcgen05MMAKind::F16:
44 OS << "f16";
45 return;
46 case Tcgen05MMAKind::TF32:
47 OS << "tf32";
48 return;
49 case Tcgen05MMAKind::F8F6F4:
50 OS << "f8f6f4";
51 return;
52 case Tcgen05MMAKind::I8:
53 OS << "i8";
54 return;
55 case Tcgen05MMAKind::TI16:
56 OS << "ti16";
57 return;
58 }
59 }
60}
61
62void nvvm::printTcgen05CollectorUsageOp(raw_ostream &OS,
63 const Constant *ImmArgVal) {
64 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
65 uint64_t Val = CI->getZExtValue();
66 switch (static_cast<Tcgen05CollectorUsageOp>(Val)) {
67 case Tcgen05CollectorUsageOp::DISCARD:
68 OS << "discard";
69 return;
70 case Tcgen05CollectorUsageOp::LASTUSE:
71 OS << "lastuse";
72 return;
73 case Tcgen05CollectorUsageOp::FILL:
74 OS << "fill";
75 return;
76 case Tcgen05CollectorUsageOp::USE:
77 OS << "use";
78 return;
79 }
80 }
81}
82
83void nvvm::printTcgen05MMACollectorBBuffer(raw_ostream &OS,
84 const Constant *ImmArgVal) {
85 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
86 uint64_t Val = CI->getZExtValue();
87 switch (static_cast<Tcgen05MMACollectorBBuffer>(Val)) {
88 case Tcgen05MMACollectorBBuffer::B0:
89 OS << "b0";
90 return;
91 case Tcgen05MMACollectorBBuffer::B1:
92 OS << "b1";
93 return;
94 case Tcgen05MMACollectorBBuffer::B2:
95 OS << "b2";
96 return;
97 case Tcgen05MMACollectorBBuffer::B3:
98 OS << "b3";
99 return;
100 }
101 }
102}
103
104void nvvm::printTensormapElemType(raw_ostream &OS, const Constant *ImmArgVal) {
105 static constexpr StringRef TensormapElemTypes[] = {
106 "u8", "u16", "u32", "s32", "u64", "s64",
107 "f16", "f32", "f32.ftz", "f64", "bf16", "tf32",
108 "tf32.ftz", "b4x16", "b4x16_p64", "b6x16_p32"};
109 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
110 uint64_t Val = CI->getZExtValue();
111 if (Val <= static_cast<uint64_t>(nvvm::TensormapElemType::B6x16_p32)) {
112 OS << TensormapElemTypes[Val];
113 return;
114 }
115 }
116}
117
118void nvvm::printTensormapInterleaveLayout(raw_ostream &OS,
119 const Constant *ImmArgVal) {
120 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
121 uint64_t Val = CI->getZExtValue();
122 switch (static_cast<TensormapInterleaveLayout>(Val)) {
123 case TensormapInterleaveLayout::NO_INTERLEAVE:
124 OS << "No interleave";
125 return;
126 case TensormapInterleaveLayout::INTERLEAVE_16B:
127 OS << "16B interleave";
128 return;
129 case TensormapInterleaveLayout::INTERLEAVE_32B:
130 OS << "32B interleave";
131 return;
132 }
133 }
134}
135
136void nvvm::printTensormapSwizzleMode(raw_ostream &OS,
137 const Constant *ImmArgVal) {
138 static constexpr StringRef TensormapSwizzleModes[] = {
139 "No swizzling", "32B swizzling", "64B swizzling", "128B swizzling",
140 "96B swizzling"};
141 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
142 uint64_t Val = CI->getZExtValue();
143 if (Val <= static_cast<uint64_t>(nvvm::TensormapSwizzleMode::SWIZZLE_96B)) {
144 OS << TensormapSwizzleModes[Val];
145 return;
146 }
147 }
148}
149
150void nvvm::printTensormapSwizzleAtomicity(raw_ostream &OS,
151 const Constant *ImmArgVal) {
152 static constexpr StringRef TensormapSwizzleAtomicities[] = {
153 "16B", "32B", "32B + 8B flip", "64B"};
154 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
155 uint64_t Val = CI->getZExtValue();
156 if (Val <= static_cast<uint64_t>(
157 nvvm::TensormapSwizzleAtomicity::SWIZZLE_ATOMICITY_64B)) {
158 OS << TensormapSwizzleAtomicities[Val];
159 return;
160 }
161 }
162}
163
164void nvvm::printTensormapFillMode(raw_ostream &OS, const Constant *ImmArgVal) {
165 if (const auto *CI = dyn_cast<ConstantInt>(Val: ImmArgVal)) {
166 uint64_t Val = CI->getZExtValue();
167 OS << (Val == static_cast<uint64_t>(TensormapFillMode::ZERO_FILL)
168 ? "Zero fill"
169 : "OOB-NaN fill");
170 return;
171 }
172}
173