10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/StringExtras.h"
12#include "llvm/ADT/Twine.h"
13#include "llvm/Support/ErrorHandling.h"
14#include "llvm/Support/raw_ostream.h"
35 assert(NewLog2LMUL <= 3 && NewLog2LMUL >= -3 &&
"Bad LMUL number!");
41 return "mf" + utostr(1ULL << (-
Log2LMUL));
42 return "m" + utostr(1ULL <<
Log2LMUL);
46 int Log2ScaleResult = 0;
47 switch (ElementBitwidth) {
64 if (Log2ScaleResult < 0)
66 return 1 << Log2ScaleResult;
71RVVType::RVVType(
BasicType BT,
int Log2LMUL,
75 applyModifier(prototype);
81 initClangBuiltinStr();
104bool RVVType::verifyType()
const {
111 if (
isFloat() && ElementBitwidth == 8)
113 if (
isBFloat() && ElementBitwidth != 16)
115 if (IsTuple && (NF == 1 || NF > 8))
117 if (IsTuple && (1 << std::max(0, LMUL.Log2LMUL)) * NF > 8)
120 switch (ElementBitwidth) {
124 return (
V <= 64 && isPowerOf2_32(
V));
127 return (
V <= 32 && isPowerOf2_32(
V));
130 return (
V <= 16 && isPowerOf2_32(
V));
133 return (
V <= 8 && isPowerOf2_32(
V));
138void RVVType::initBuiltinStr() {
139 assert(
isValid() &&
"RVVType is invalid");
140 switch (ScalarType) {
147 BuiltinStr =
"I" + BuiltinStr;
161 assert(ElementBitwidth == 1);
166 switch (ElementBitwidth) {
180 llvm_unreachable(
"Unhandled ElementBitwidth!");
183 BuiltinStr =
"S" + BuiltinStr;
185 BuiltinStr =
"U" + BuiltinStr;
188 switch (ElementBitwidth) {
199 llvm_unreachable(
"Unhandled ElementBitwidth!");
212 llvm_unreachable(
"ScalarType is invalid!");
215 BuiltinStr =
"I" + BuiltinStr;
223 BuiltinStr =
"q" + utostr(*Scale) + BuiltinStr;
231 BuiltinStr =
"T" + utostr(NF) + BuiltinStr;
234void RVVType::initClangBuiltinStr() {
235 assert(
isValid() &&
"RVVType is invalid");
236 assert(
isVector() &&
"Handle Vector type only");
238 ClangBuiltinStr =
"__rvv_";
239 switch (ScalarType) {
241 ClangBuiltinStr +=
"bool" + utostr(64 / *Scale) +
"_t";
244 ClangBuiltinStr +=
"float";
247 ClangBuiltinStr +=
"bfloat";
250 ClangBuiltinStr +=
"int";
253 ClangBuiltinStr +=
"uint";
256 ClangBuiltinStr +=
"float8e4m3" + LMUL.str() +
"_t";
259 ClangBuiltinStr +=
"float8e5m2" + LMUL.str() +
"_t";
262 llvm_unreachable(
"ScalarTypeKind is invalid");
264 ClangBuiltinStr += utostr(ElementBitwidth) + LMUL.str() +
265 (IsTuple ?
"x" + utostr(NF) :
"") +
"_t";
268void RVVType::initTypeStr() {
269 assert(
isValid() &&
"RVVType is invalid");
276 return Twine(TypeStr + Twine(ElementBitwidth) +
"_t").str();
277 return Twine(
"v" + TypeStr + Twine(ElementBitwidth) + LMUL.str() +
278 (IsTuple ?
"x" + utostr(NF) :
"") +
"_t")
282 switch (ScalarType) {
295 Str =
"unsigned long";
306 Str +=
"vbool" + utostr(64 / *Scale) +
"_t";
310 if (ElementBitwidth == 64)
312 else if (ElementBitwidth == 32)
314 else if (ElementBitwidth == 16)
317 llvm_unreachable(
"Unhandled floating type.");
323 if (ElementBitwidth == 16)
326 llvm_unreachable(
"Unhandled floating type.");
337 Str +=
"vfloat8e4m3" + LMUL.str() +
"_t";
340 Str +=
"vfloat8e5m2" + LMUL.str() +
"_t";
343 llvm_unreachable(
"ScalarType is invalid!");
349void RVVType::initShortStr() {
350 switch (ScalarType) {
353 ShortStr =
"b" + utostr(64 / *Scale);
356 ShortStr =
"f" + utostr(ElementBitwidth);
359 ShortStr =
"bf" + utostr(ElementBitwidth);
362 ShortStr =
"i" + utostr(ElementBitwidth);
365 ShortStr =
"u" + utostr(ElementBitwidth);
374 llvm_unreachable(
"Unhandled case!");
377 ShortStr += LMUL.str();
379 ShortStr +=
"x" + utostr(NF);
383 assert(2 <= NF && NF <= 8 &&
"2 <= NF <= 8");
388void RVVType::applyBasicType() {
395 ElementBitwidth = 16;
399 ElementBitwidth = 32;
403 ElementBitwidth = 64;
407 ElementBitwidth = 16;
411 ElementBitwidth = 32;
415 ElementBitwidth = 64;
419 ElementBitwidth = 16;
431 llvm_unreachable(
"Unhandled type code!");
433 assert(ElementBitwidth != 0 &&
"Bad element bitwidth!");
436std::optional<PrototypeDescriptor>
438 llvm::StringRef PrototypeDescriptorStr) {
443 if (PrototypeDescriptorStr.empty())
447 auto PType = PrototypeDescriptorStr.back();
494 llvm_unreachable(
"Illegal primitive type transformers!");
497 PrototypeDescriptorStr = PrototypeDescriptorStr.drop_back();
500 if (PrototypeDescriptorStr.starts_with(
"(")) {
502 "VectorTypeModifier should only have one modifier");
503 size_t Idx = PrototypeDescriptorStr.find(
')');
504 assert(Idx != StringRef::npos);
505 StringRef
ComplexType = PrototypeDescriptorStr.slice(1, Idx);
506 PrototypeDescriptorStr = PrototypeDescriptorStr.drop_front(Idx + 1);
507 assert(!PrototypeDescriptorStr.contains(
'(') &&
508 "Only allow one vector type modifier");
511 if (ComplexTT.first ==
"Log2EEW") {
513 if (ComplexTT.second.getAsInteger(10, Log2EEW)) {
514 llvm_unreachable(
"Invalid Log2EEW value!");
531 llvm_unreachable(
"Invalid Log2EEW value, should be [3-6]");
534 }
else if (ComplexTT.first ==
"FixedSEW") {
536 if (ComplexTT.second.getAsInteger(10, NewSEW)) {
537 llvm_unreachable(
"Invalid FixedSEW value!");
554 llvm_unreachable(
"Invalid FixedSEW value, should be 8, 16, 32 or 64");
557 }
else if (ComplexTT.first ==
"LFixedLog2LMUL") {
559 if (ComplexTT.second.getAsInteger(10, Log2LMUL)) {
560 llvm_unreachable(
"Invalid LFixedLog2LMUL value!");
586 llvm_unreachable(
"Invalid LFixedLog2LMUL value, should be [-3, 3]");
589 }
else if (ComplexTT.first ==
"SFixedLog2LMUL") {
591 if (ComplexTT.second.getAsInteger(10, Log2LMUL)) {
592 llvm_unreachable(
"Invalid SFixedLog2LMUL value!");
618 llvm_unreachable(
"Invalid LFixedLog2LMUL value, should be [-3, 3]");
622 }
else if (ComplexTT.first ==
"SEFixedLog2LMUL") {
624 if (ComplexTT.second.getAsInteger(10, Log2LMUL)) {
625 llvm_unreachable(
"Invalid SEFixedLog2LMUL value!");
651 llvm_unreachable(
"Invalid LFixedLog2LMUL value, should be [-3, 3]");
654 }
else if (ComplexTT.first ==
"Tuple") {
656 if (ComplexTT.second.getAsInteger(10, NF)) {
657 llvm_unreachable(
"Invalid NF value!");
662 llvm_unreachable(
"Illegal complex type transformers!");
669 for (
char I : PrototypeDescriptorStr) {
673 llvm_unreachable(
"'P' transformer cannot be used after 'C'");
675 llvm_unreachable(
"'P' transformer cannot be used twice");
703 llvm_unreachable(
"Illegal non-primitive type transformer!");
718 Scale = LMUL.
getScale(ElementBitwidth);
736 ElementBitwidth = 32;
744 switch (
static_cast<VectorTypeModifier
>(Transformer.
VTM)) {
746 ElementBitwidth *= 2;
748 Scale = LMUL.
getScale(ElementBitwidth);
757 Scale = LMUL.
getScale(ElementBitwidth);
760 ElementBitwidth *= 4;
762 Scale = LMUL.
getScale(ElementBitwidth);
768 ElementBitwidth *= 8;
770 Scale = LMUL.
getScale(ElementBitwidth);
774 Scale = LMUL.
getScale(ElementBitwidth);
780 Scale = LMUL.
getScale(ElementBitwidth);
808 applyFixedLog2LMUL(-3, FixedLMULType::LargerThan);
811 applyFixedLog2LMUL(-2, FixedLMULType::LargerThan);
814 applyFixedLog2LMUL(-1, FixedLMULType::LargerThan);
817 applyFixedLog2LMUL(0, FixedLMULType::LargerThan);
820 applyFixedLog2LMUL(1, FixedLMULType::LargerThan);
823 applyFixedLog2LMUL(2, FixedLMULType::LargerThan);
826 applyFixedLog2LMUL(3, FixedLMULType::LargerThan);
829 applyFixedLog2LMUL(-3, FixedLMULType::SmallerThan);
832 applyFixedLog2LMUL(-2, FixedLMULType::SmallerThan);
835 applyFixedLog2LMUL(-1, FixedLMULType::SmallerThan);
838 applyFixedLog2LMUL(0, FixedLMULType::SmallerThan);
841 applyFixedLog2LMUL(1, FixedLMULType::SmallerThan);
844 applyFixedLog2LMUL(2, FixedLMULType::SmallerThan);
847 applyFixedLog2LMUL(3, FixedLMULType::SmallerThan);
850 applyFixedLog2LMUL(-3, FixedLMULType::SmallerOrEqual);
853 applyFixedLog2LMUL(-2, FixedLMULType::SmallerOrEqual);
856 applyFixedLog2LMUL(-1, FixedLMULType::SmallerOrEqual);
859 applyFixedLog2LMUL(0, FixedLMULType::SmallerOrEqual);
862 applyFixedLog2LMUL(1, FixedLMULType::SmallerOrEqual);
865 applyFixedLog2LMUL(2, FixedLMULType::SmallerOrEqual);
868 applyFixedLog2LMUL(3, FixedLMULType::SmallerOrEqual);
878 NF = 2 +
static_cast<uint8_t
>(Transformer.
VTM) -
890 for (
unsigned TypeModifierMaskShift = 0;
892 ++TypeModifierMaskShift) {
893 unsigned TypeModifierMask = 1 << TypeModifierMaskShift;
894 if ((
static_cast<unsigned>(Transformer.
TM) & TypeModifierMask) !=
923 Scale = LMUL.getScale(ElementBitwidth);
931 llvm_unreachable(
"AltFP8 modifier requires an OFP8 base type");
934 llvm_unreachable(
"Unknown type modifier mask!");
939void RVVType::applyLog2EEW(
unsigned Log2EEW) {
941 LMUL.MulLog2LMUL(Log2EEW - Log2_32(ElementBitwidth));
943 ElementBitwidth = 1 << Log2EEW;
945 Scale = LMUL.getScale(ElementBitwidth);
948void RVVType::applyFixedSEW(
unsigned NewSEW) {
950 if (ElementBitwidth == NewSEW) {
955 ElementBitwidth = NewSEW;
956 Scale = LMUL.getScale(ElementBitwidth);
959void RVVType::applyFixedLog2LMUL(
int Log2LMUL,
enum FixedLMULType
Type) {
961 case FixedLMULType::LargerThan:
962 if (Log2LMUL <= LMUL.Log2LMUL) {
967 case FixedLMULType::SmallerThan:
968 if (Log2LMUL >= LMUL.Log2LMUL) {
973 case FixedLMULType::SmallerOrEqual:
974 if (Log2LMUL > LMUL.Log2LMUL) {
982 LMUL = LMULType(Log2LMUL);
983 Scale = LMUL.getScale(ElementBitwidth);
986std::optional<RVVTypes>
1006 assert(Log2LMUL >= -3 && Log2LMUL <= 3);
1007 return (Log2LMUL + 3) | (
static_cast<uint64_t
>(BT) & 0xffff) << 8 |
1008 (
static_cast<uint64_t
>(Proto.
PT) << 24) |
1009 (
static_cast<uint64_t
>(Proto.
TM) << 32) |
1010 (
static_cast<uint64_t
>(Proto.
VTM) << 40);
1017 auto It = LegalTypes.find(Idx);
1018 if (It != LegalTypes.end())
1019 return &(It->second);
1021 if (IllegalTypes.count(Idx))
1022 return std::nullopt;
1028 std::pair<std::unordered_map<uint64_t, RVVType>::iterator,
bool>
1029 InsertResult = LegalTypes.insert({Idx,
T});
1030 return &(InsertResult.first->second);
1033 IllegalTypes.insert(Idx);
1034 return std::nullopt;
1041 StringRef NewName, StringRef Suffix, StringRef NewOverloadedName,
1042 StringRef OverloadedSuffix, StringRef IRName,
bool IsMasked,
1043 bool HasMaskedOffOperand,
bool HasVL,
PolicyScheme Scheme,
1044 bool SupportOverloading,
bool HasBuiltinAlias, StringRef ManualCodegen,
1045 const RVVTypes &OutInTypes,
const std::vector<int64_t> &NewIntrinsicTypes,
1046 unsigned NF,
bool HasSegInstSEW,
Policy NewPolicyAttrs,
1047 bool HasFRMRoundModeOp,
unsigned TWiden,
bool AltFmt)
1048 : IRName(IRName), IsMasked(IsMasked),
1049 HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), Scheme(Scheme),
1050 SupportOverloading(SupportOverloading), HasBuiltinAlias(HasBuiltinAlias),
1051 ManualCodegen(ManualCodegen.str()), NF(NF), HasSegInstSEW(HasSegInstSEW),
1052 PolicyAttrs(NewPolicyAttrs), TWiden(TWiden) {
1055 BuiltinName = NewName.str();
1057 if (NewOverloadedName.empty())
1058 OverloadedName = NewName.split(
"_").first.str();
1060 OverloadedName = NewOverloadedName.str();
1061 if (!Suffix.empty())
1062 Name +=
"_" + Suffix.str();
1063 if (!OverloadedSuffix.empty())
1064 OverloadedName +=
"_" + OverloadedSuffix.str();
1067 PolicyAttrs, HasFRMRoundModeOp, AltFmt);
1070 OutputType = OutInTypes[0];
1071 InputTypes.assign(OutInTypes.begin() + 1, OutInTypes.end());
1075 IntrinsicTypes = NewIntrinsicTypes;
1078 for (
auto &I : IntrinsicTypes) {
1087 S += OutputType->getBuiltinStr();
1088 for (
const auto &
T : InputTypes) {
1089 S +=
T->getBuiltinStr();
1098 for (
auto PD : PrototypeDescriptors) {
1100 SuffixStrs.push_back((*T)->getShortStr());
1102 return join(SuffixStrs,
"_");
1107 bool HasMaskedOffOperand,
bool MaskedPrototypeHasResultMask,
bool HasVL,
1114 if (HasMaskedOffOperand && !PolicyAttrs.isTAMAPolicy()) {
1116 NewPrototype.insert(NewPrototype.begin() + 1, NewPrototype[0]);
1117 }
else if (NF > 1) {
1123 NewPrototype.insert(NewPrototype.begin() + 1, MaskoffType);
1131 NewPrototype.insert(NewPrototype.begin() + NF + 1, NF, MaskoffType);
1135 if (HasMaskedOffOperand && NF > 1) {
1142 NewPrototype.insert(NewPrototype.begin() + 1,
1145 NewPrototype.insert(NewPrototype.begin() + NF + 1,
1148 if (MaskedPrototypeHasResultMask)
1149 NewPrototype.insert(
1150 NewPrototype.begin() + 1,
1154 NewPrototype.insert(NewPrototype.begin() + 1,
1159 if (PolicyAttrs.isTUPolicy() && HasPassthruOp)
1160 NewPrototype.insert(NewPrototype.begin(), NewPrototype[0]);
1161 }
else if (PolicyAttrs.isTUPolicy() && HasPassthruOp) {
1167 NewPrototype.insert(NewPrototype.begin(), MaskoffType);
1176 NewPrototype.insert(NewPrototype.begin() + NF + 1, NF, MaskoffType);
1185 return NewPrototype;
1194 bool HasMaskPolicy) {
1195 if (HasTailPolicy && HasMaskPolicy)
1202 if (HasTailPolicy && !HasMaskPolicy)
1205 if (!HasTailPolicy && HasMaskPolicy)
1208 llvm_unreachable(
"An RVV instruction should not be without both tail policy "
1214 std::string &BuiltinName,
1215 std::string &OverloadedName,
1217 bool HasFRMRoundModeOp,
bool AltFmt) {
1219 auto appendPolicySuffix = [&](
const std::string &suffix) {
1221 BuiltinName += suffix;
1222 OverloadedName += suffix;
1225 if (HasFRMRoundModeOp) {
1227 BuiltinName +=
"_rm";
1231 BuiltinName +=
"_alt";
1234 if (PolicyAttrs.isTUMUPolicy())
1235 appendPolicySuffix(
"_tumu");
1236 else if (PolicyAttrs.isTUMAPolicy())
1237 appendPolicySuffix(
"_tum");
1238 else if (PolicyAttrs.isTAMUPolicy())
1239 appendPolicySuffix(
"_mu");
1240 else if (PolicyAttrs.isTAMAPolicy()) {
1242 BuiltinName +=
"_m";
1244 llvm_unreachable(
"Unhandled policy condition");
1246 if (PolicyAttrs.isTUPolicy())
1247 appendPolicySuffix(
"_tu");
1248 else if (PolicyAttrs.isTAPolicy())
1251 llvm_unreachable(
"Unhandled policy condition");
1257 const StringRef Primaries(
"evwdqom0ztulf");
1258 while (!Prototypes.empty()) {
1262 if (Prototypes[0] ==
'(')
1263 Idx = Prototypes.find_first_of(
')');
1264 Idx = Prototypes.find_first_of(Primaries, Idx);
1265 assert(Idx != StringRef::npos);
1267 Prototypes.slice(0, Idx + 1));
1269 llvm_unreachable(
"Error during parsing prototype.");
1270 PrototypeDescriptors.push_back(*PD);
1271 Prototypes = Prototypes.drop_front(Idx + 1);
1273 return PrototypeDescriptors;
1276#define STRINGIFY(NAME) \
1294 OS <<
"/*Name=*/\"" <<
Record.Name <<
"\", ";
1295 if (
Record.OverloadedName ==
nullptr ||
1296 StringRef(
Record.OverloadedName).empty())
1297 OS <<
"/*OverloadedName=*/nullptr, ";
1299 OS <<
"/*OverloadedName=*/\"" <<
Record.OverloadedName <<
"\", ";
1300 OS <<
"/*RequiredExtensions=*/\"" <<
Record.RequiredExtensions <<
"\", ";
1301 OS <<
"/*PrototypeIndex=*/" <<
Record.PrototypeIndex <<
", ";
1302 OS <<
"/*SuffixIndex=*/" <<
Record.SuffixIndex <<
", ";
1303 OS <<
"/*OverloadedSuffixIndex=*/" <<
Record.OverloadedSuffixIndex <<
", ";
1304 OS <<
"/*PrototypeLength=*/" << (int)
Record.PrototypeLength <<
", ";
1305 OS <<
"/*SuffixLength=*/" << (int)
Record.SuffixLength <<
", ";
1306 OS <<
"/*OverloadedSuffixSize=*/" << (int)
Record.OverloadedSuffixSize <<
", ";
1307 OS <<
"/*TypeRangeMask=*/" << (int)
Record.TypeRangeMask <<
", ";
1308 OS <<
"/*Log2LMULMask=*/" << (int)
Record.Log2LMULMask <<
", ";
1309 OS <<
"/*NF=*/" << (int)
Record.NF <<
", ";
1310 OS <<
"/*HasMasked=*/" << (int)
Record.HasMasked <<
", ";
1311 OS <<
"/*HasVL=*/" << (int)
Record.HasVL <<
", ";
1312 OS <<
"/*HasMaskedOffOperand=*/" << (int)
Record.HasMaskedOffOperand <<
", ";
1313 OS <<
"/*HasTailPolicy=*/" << (int)
Record.HasTailPolicy <<
", ";
1314 OS <<
"/*HasMaskPolicy=*/" << (int)
Record.HasMaskPolicy <<
", ";
1315 OS <<
"/*HasFRMRoundModeOp=*/" << (int)
Record.HasFRMRoundModeOp <<
", ";
1316 OS <<
"/*MaskedPrototypeHasResultMask=*/"
1317 << (int)
Record.MaskedPrototypeHasResultMask <<
", ";
1318 OS <<
"/*AltFmt=*/" << (int)
Record.AltFmt <<
",";
1319 OS <<
"/*IsTuple=*/" << (int)
Record.IsTuple <<
", ";
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
llvm::MachO::Record Record
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
Complex values, per C99 6.2.5p11.
RVVIntrinsic(llvm::StringRef Name, llvm::StringRef Suffix, llvm::StringRef OverloadedName, llvm::StringRef OverloadedSuffix, llvm::StringRef IRName, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme, bool SupportOverloading, bool HasBuiltinAlias, llvm::StringRef ManualCodegen, const RVVTypes &Types, const std::vector< int64_t > &IntrinsicTypes, unsigned NF, bool HasSegInstSEW, Policy PolicyAttrs, bool HasFRMRoundModeOp, unsigned TWiden, bool AltFmt)
bool hasPassthruOperand() const
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool MaskedPrototypeHasResultMask, bool HasVL, unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs, bool IsTuple)
bool hasMaskedOffOperand() const
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &PolicyAttrs, bool HasFRMRoundModeOp, bool AltFmt)
static llvm::SmallVector< Policy > getSupportedUnMaskedPolicies()
std::string getBuiltinTypeStr() const
std::optional< RVVTypePtr > computeType(BasicType BT, int Log2LMUL, PrototypeDescriptor Proto)
std::optional< RVVTypes > computeTypes(BasicType BT, int Log2LMUL, unsigned NF, llvm::ArrayRef< PrototypeDescriptor > Prototype)
Compute output and input types by applying different config (basic type and LMUL with type transforme...
bool isSignedInteger() const
The base class of the type hierarchy.
std::optional< unsigned > VScaleVal
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, enum PolicyScheme PS)
llvm::SmallVector< PrototypeDescriptor > parsePrototypes(llvm::StringRef Prototypes)
std::vector< RVVTypePtr > RVVTypes
static uint64_t computeRVVTypeHashValue(BasicType BT, int Log2LMUL, PrototypeDescriptor Proto)
static VectorTypeModifier getTupleVTM(unsigned NF)
Top level wrappers for InstallAPI frontend operations.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
std::optional< unsigned > getScale(unsigned ElementBitwidth) const
void MulLog2LMUL(int Log2LMUL)
static std::optional< PrototypeDescriptor > parsePrototypeDescriptor(llvm::StringRef PrototypeStr)
static const PrototypeDescriptor VL
constexpr PrototypeDescriptor()=default
static const PrototypeDescriptor Mask
static const PrototypeDescriptor Vector