1 //===- RISCVVEmitter.cpp - Generate riscv_vector.h for use with clang -----===//
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 tablegen backend is responsible for emitting riscv_vector.h which
10 // includes a declaration and definition of each intrinsic functions specified
11 // in https://github.com/riscv/rvv-intrinsic-doc.
12 //
13 // See also the documentation in include/clang/Basic/riscv_vector.td.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringSet.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/TableGen/Error.h"
24 #include "llvm/TableGen/Record.h"
25 #include <numeric>
26 
27 using namespace llvm;
28 using BasicType = char;
29 using VScaleVal = Optional<unsigned>;
30 
31 namespace {
32 
33 // Exponential LMUL
34 struct LMULType {
35   int Log2LMUL;
36   LMULType(int Log2LMUL);
37   // Return the C/C++ string representation of LMUL
38   std::string str() const;
39   Optional<unsigned> getScale(unsigned ElementBitwidth) const;
40   void MulLog2LMUL(int Log2LMUL);
41   LMULType &operator*=(uint32_t RHS);
42 };
43 
44 // This class is compact representation of a valid and invalid RVVType.
45 class RVVType {
46   enum ScalarTypeKind : uint32_t {
47     Void,
48     Size_t,
49     Ptrdiff_t,
50     UnsignedLong,
51     SignedLong,
52     Boolean,
53     SignedInteger,
54     UnsignedInteger,
55     Float,
56     Invalid,
57   };
58   BasicType BT;
59   ScalarTypeKind ScalarType = Invalid;
60   LMULType LMUL;
61   bool IsPointer = false;
62   // IsConstant indices are "int", but have the constant expression.
63   bool IsImmediate = false;
64   // Const qualifier for pointer to const object or object of const type.
65   bool IsConstant = false;
66   unsigned ElementBitwidth = 0;
67   VScaleVal Scale = 0;
68   bool Valid;
69 
70   std::string BuiltinStr;
71   std::string ClangBuiltinStr;
72   std::string Str;
73   std::string ShortStr;
74 
75 public:
76   RVVType() : RVVType(BasicType(), 0, StringRef()) {}
77   RVVType(BasicType BT, int Log2LMUL, StringRef prototype);
78 
79   // Return the string representation of a type, which is an encoded string for
80   // passing to the BUILTIN() macro in Builtins.def.
81   const std::string &getBuiltinStr() const { return BuiltinStr; }
82 
83   // Return the clang builtin type for RVV vector type which are used in the
84   // riscv_vector.h header file.
85   const std::string &getClangBuiltinStr() const { return ClangBuiltinStr; }
86 
87   // Return the C/C++ string representation of a type for use in the
88   // riscv_vector.h header file.
89   const std::string &getTypeStr() const { return Str; }
90 
91   // Return the short name of a type for C/C++ name suffix.
92   const std::string &getShortStr() {
93     // Not all types are used in short name, so compute the short name by
94     // demanded.
95     if (ShortStr.empty())
96       initShortStr();
97     return ShortStr;
98   }
99 
100   bool isValid() const { return Valid; }
101   bool isScalar() const { return Scale.hasValue() && Scale.getValue() == 0; }
102   bool isVector() const { return Scale.hasValue() && Scale.getValue() != 0; }
103   bool isVector(unsigned Width) const {
104     return isVector() && ElementBitwidth == Width;
105   }
106   bool isFloat() const { return ScalarType == ScalarTypeKind::Float; }
107   bool isSignedInteger() const {
108     return ScalarType == ScalarTypeKind::SignedInteger;
109   }
110   bool isFloatVector(unsigned Width) const {
111     return isVector() && isFloat() && ElementBitwidth == Width;
112   }
113   bool isFloat(unsigned Width) const {
114     return isFloat() && ElementBitwidth == Width;
115   }
116 
117 private:
118   // Verify RVV vector type and set Valid.
119   bool verifyType() const;
120 
121   // Creates a type based on basic types of TypeRange
122   void applyBasicType();
123 
124   // Applies a prototype modifier to the current type. The result maybe an
125   // invalid type.
126   void applyModifier(StringRef prototype);
127 
128   // Compute and record a string for legal type.
129   void initBuiltinStr();
130   // Compute and record a builtin RVV vector type string.
131   void initClangBuiltinStr();
132   // Compute and record a type string for used in the header.
133   void initTypeStr();
134   // Compute and record a short name of a type for C/C++ name suffix.
135   void initShortStr();
136 };
137 
138 using RVVTypePtr = RVVType *;
139 using RVVTypes = std::vector<RVVTypePtr>;
140 using RISCVPredefinedMacroT = uint8_t;
141 
142 enum RISCVPredefinedMacro : RISCVPredefinedMacroT {
143   Basic = 0,
144   V = 1 << 1,
145   Zvfh = 1 << 2,
146   RV64 = 1 << 3,
147   VectorMaxELen64 = 1 << 4,
148   VectorMaxELenFp32 = 1 << 5,
149   VectorMaxELenFp64 = 1 << 6,
150 };
151 
152 enum PolicyScheme : uint8_t {
153   SchemeNone,
154   HasPassthruOperand,
155   HasPolicyOperand,
156 };
157 
158 // TODO refactor RVVIntrinsic class design after support all intrinsic
159 // combination. This represents an instantiation of an intrinsic with a
160 // particular type and prototype
161 class RVVIntrinsic {
162 
163 private:
164   std::string BuiltinName; // Builtin name
165   std::string Name;        // C intrinsic name.
166   std::string MangledName;
167   std::string IRName;
168   bool IsMasked;
169   bool HasVL;
170   PolicyScheme Scheme;
171   bool HasUnMaskedOverloaded;
172   bool HasBuiltinAlias;
173   std::string ManualCodegen;
174   RVVTypePtr OutputType; // Builtin output type
175   RVVTypes InputTypes;   // Builtin input types
176   // The types we use to obtain the specific LLVM intrinsic. They are index of
177   // InputTypes. -1 means the return type.
178   std::vector<int64_t> IntrinsicTypes;
179   RISCVPredefinedMacroT RISCVPredefinedMacros = 0;
180   unsigned NF = 1;
181 
182 public:
183   RVVIntrinsic(StringRef Name, StringRef Suffix, StringRef MangledName,
184                StringRef MangledSuffix, StringRef IRName, bool IsMasked,
185                bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme,
186                bool HasUnMaskedOverloaded, bool HasBuiltinAlias,
187                StringRef ManualCodegen, const RVVTypes &Types,
188                const std::vector<int64_t> &IntrinsicTypes,
189                const std::vector<StringRef> &RequiredFeatures, unsigned NF);
190   ~RVVIntrinsic() = default;
191 
192   StringRef getBuiltinName() const { return BuiltinName; }
193   StringRef getName() const { return Name; }
194   StringRef getMangledName() const { return MangledName; }
195   bool hasVL() const { return HasVL; }
196   bool hasPolicy() const { return Scheme != SchemeNone; }
197   bool hasPassthruOperand() const { return Scheme == HasPassthruOperand; }
198   bool hasPolicyOperand() const { return Scheme == HasPolicyOperand; }
199   bool hasUnMaskedOverloaded() const { return HasUnMaskedOverloaded; }
200   bool hasBuiltinAlias() const { return HasBuiltinAlias; }
201   bool hasManualCodegen() const { return !ManualCodegen.empty(); }
202   bool isMasked() const { return IsMasked; }
203   StringRef getIRName() const { return IRName; }
204   StringRef getManualCodegen() const { return ManualCodegen; }
205   PolicyScheme getPolicyScheme() const { return Scheme; }
206   RISCVPredefinedMacroT getRISCVPredefinedMacros() const {
207     return RISCVPredefinedMacros;
208   }
209   unsigned getNF() const { return NF; }
210   const std::vector<int64_t> &getIntrinsicTypes() const {
211     return IntrinsicTypes;
212   }
213 
214   // Return the type string for a BUILTIN() macro in Builtins.def.
215   std::string getBuiltinTypeStr() const;
216 
217   // Emit the code block for switch body in EmitRISCVBuiltinExpr, it should
218   // init the RVVIntrinsic ID and IntrinsicTypes.
219   void emitCodeGenSwitchBody(raw_ostream &o) const;
220 
221   // Emit the macros for mapping C/C++ intrinsic function to builtin functions.
222   void emitIntrinsicFuncDef(raw_ostream &o) const;
223 
224   // Emit the mangled function definition.
225   void emitMangledFuncDef(raw_ostream &o) const;
226 };
227 
228 class RVVEmitter {
229 private:
230   RecordKeeper &Records;
231   // Concat BasicType, LMUL and Proto as key
232   StringMap<RVVType> LegalTypes;
233   StringSet<> IllegalTypes;
234 
235 public:
236   RVVEmitter(RecordKeeper &R) : Records(R) {}
237 
238   /// Emit riscv_vector.h
239   void createHeader(raw_ostream &o);
240 
241   /// Emit all the __builtin prototypes and code needed by Sema.
242   void createBuiltins(raw_ostream &o);
243 
244   /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
245   void createCodeGen(raw_ostream &o);
246 
247   std::string getSuffixStr(char Type, int Log2LMUL, StringRef Prototypes);
248 
249 private:
250   /// Create all intrinsics and add them to \p Out
251   void createRVVIntrinsics(std::vector<std::unique_ptr<RVVIntrinsic>> &Out);
252   /// Print HeaderCode in RVVHeader Record to \p Out
253   void printHeaderCode(raw_ostream &OS);
254   /// Compute output and input types by applying different config (basic type
255   /// and LMUL with type transformers). It also record result of type in legal
256   /// or illegal set to avoid compute the  same config again. The result maybe
257   /// have illegal RVVType.
258   Optional<RVVTypes> computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
259                                   ArrayRef<std::string> PrototypeSeq);
260   Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL, StringRef Proto);
261 
262   /// Emit Acrh predecessor definitions and body, assume the element of Defs are
263   /// sorted by extension.
264   void emitArchMacroAndBody(
265       std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &o,
266       std::function<void(raw_ostream &, const RVVIntrinsic &)>);
267 
268   // Emit the architecture preprocessor definitions. Return true when emits
269   // non-empty string.
270   bool emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros,
271                                raw_ostream &o);
272   // Slice Prototypes string into sub prototype string and process each sub
273   // prototype string individually in the Handler.
274   void parsePrototypes(StringRef Prototypes,
275                        std::function<void(StringRef)> Handler);
276 };
277 
278 } // namespace
279 
280 //===----------------------------------------------------------------------===//
281 // Type implementation
282 //===----------------------------------------------------------------------===//
283 
284 LMULType::LMULType(int NewLog2LMUL) {
285   // Check Log2LMUL is -3, -2, -1, 0, 1, 2, 3
286   assert(NewLog2LMUL <= 3 && NewLog2LMUL >= -3 && "Bad LMUL number!");
287   Log2LMUL = NewLog2LMUL;
288 }
289 
290 std::string LMULType::str() const {
291   if (Log2LMUL < 0)
292     return "mf" + utostr(1ULL << (-Log2LMUL));
293   return "m" + utostr(1ULL << Log2LMUL);
294 }
295 
296 VScaleVal LMULType::getScale(unsigned ElementBitwidth) const {
297   int Log2ScaleResult = 0;
298   switch (ElementBitwidth) {
299   default:
300     break;
301   case 8:
302     Log2ScaleResult = Log2LMUL + 3;
303     break;
304   case 16:
305     Log2ScaleResult = Log2LMUL + 2;
306     break;
307   case 32:
308     Log2ScaleResult = Log2LMUL + 1;
309     break;
310   case 64:
311     Log2ScaleResult = Log2LMUL;
312     break;
313   }
314   // Illegal vscale result would be less than 1
315   if (Log2ScaleResult < 0)
316     return llvm::None;
317   return 1 << Log2ScaleResult;
318 }
319 
320 void LMULType::MulLog2LMUL(int log2LMUL) { Log2LMUL += log2LMUL; }
321 
322 LMULType &LMULType::operator*=(uint32_t RHS) {
323   assert(isPowerOf2_32(RHS));
324   this->Log2LMUL = this->Log2LMUL + Log2_32(RHS);
325   return *this;
326 }
327 
328 RVVType::RVVType(BasicType BT, int Log2LMUL, StringRef prototype)
329     : BT(BT), LMUL(LMULType(Log2LMUL)) {
330   applyBasicType();
331   applyModifier(prototype);
332   Valid = verifyType();
333   if (Valid) {
334     initBuiltinStr();
335     initTypeStr();
336     if (isVector()) {
337       initClangBuiltinStr();
338     }
339   }
340 }
341 
342 // clang-format off
343 // boolean type are encoded the ratio of n (SEW/LMUL)
344 // SEW/LMUL | 1         | 2         | 4         | 8        | 16        | 32        | 64
345 // c type   | vbool64_t | vbool32_t | vbool16_t | vbool8_t | vbool4_t  | vbool2_t  | vbool1_t
346 // IR type  | nxv1i1    | nxv2i1    | nxv4i1    | nxv8i1   | nxv16i1   | nxv32i1   | nxv64i1
347 
348 // type\lmul | 1/8    | 1/4      | 1/2     | 1       | 2        | 4        | 8
349 // --------  |------  | -------- | ------- | ------- | -------- | -------- | --------
350 // i64       | N/A    | N/A      | N/A     | nxv1i64 | nxv2i64  | nxv4i64  | nxv8i64
351 // i32       | N/A    | N/A      | nxv1i32 | nxv2i32 | nxv4i32  | nxv8i32  | nxv16i32
352 // i16       | N/A    | nxv1i16  | nxv2i16 | nxv4i16 | nxv8i16  | nxv16i16 | nxv32i16
353 // i8        | nxv1i8 | nxv2i8   | nxv4i8  | nxv8i8  | nxv16i8  | nxv32i8  | nxv64i8
354 // double    | N/A    | N/A      | N/A     | nxv1f64 | nxv2f64  | nxv4f64  | nxv8f64
355 // float     | N/A    | N/A      | nxv1f32 | nxv2f32 | nxv4f32  | nxv8f32  | nxv16f32
356 // half      | N/A    | nxv1f16  | nxv2f16 | nxv4f16 | nxv8f16  | nxv16f16 | nxv32f16
357 // clang-format on
358 
359 bool RVVType::verifyType() const {
360   if (ScalarType == Invalid)
361     return false;
362   if (isScalar())
363     return true;
364   if (!Scale.hasValue())
365     return false;
366   if (isFloat() && ElementBitwidth == 8)
367     return false;
368   unsigned V = Scale.getValue();
369   switch (ElementBitwidth) {
370   case 1:
371   case 8:
372     // Check Scale is 1,2,4,8,16,32,64
373     return (V <= 64 && isPowerOf2_32(V));
374   case 16:
375     // Check Scale is 1,2,4,8,16,32
376     return (V <= 32 && isPowerOf2_32(V));
377   case 32:
378     // Check Scale is 1,2,4,8,16
379     return (V <= 16 && isPowerOf2_32(V));
380   case 64:
381     // Check Scale is 1,2,4,8
382     return (V <= 8 && isPowerOf2_32(V));
383   }
384   return false;
385 }
386 
387 void RVVType::initBuiltinStr() {
388   assert(isValid() && "RVVType is invalid");
389   switch (ScalarType) {
390   case ScalarTypeKind::Void:
391     BuiltinStr = "v";
392     return;
393   case ScalarTypeKind::Size_t:
394     BuiltinStr = "z";
395     if (IsImmediate)
396       BuiltinStr = "I" + BuiltinStr;
397     if (IsPointer)
398       BuiltinStr += "*";
399     return;
400   case ScalarTypeKind::Ptrdiff_t:
401     BuiltinStr = "Y";
402     return;
403   case ScalarTypeKind::UnsignedLong:
404     BuiltinStr = "ULi";
405     return;
406   case ScalarTypeKind::SignedLong:
407     BuiltinStr = "Li";
408     return;
409   case ScalarTypeKind::Boolean:
410     assert(ElementBitwidth == 1);
411     BuiltinStr += "b";
412     break;
413   case ScalarTypeKind::SignedInteger:
414   case ScalarTypeKind::UnsignedInteger:
415     switch (ElementBitwidth) {
416     case 8:
417       BuiltinStr += "c";
418       break;
419     case 16:
420       BuiltinStr += "s";
421       break;
422     case 32:
423       BuiltinStr += "i";
424       break;
425     case 64:
426       BuiltinStr += "Wi";
427       break;
428     default:
429       llvm_unreachable("Unhandled ElementBitwidth!");
430     }
431     if (isSignedInteger())
432       BuiltinStr = "S" + BuiltinStr;
433     else
434       BuiltinStr = "U" + BuiltinStr;
435     break;
436   case ScalarTypeKind::Float:
437     switch (ElementBitwidth) {
438     case 16:
439       BuiltinStr += "x";
440       break;
441     case 32:
442       BuiltinStr += "f";
443       break;
444     case 64:
445       BuiltinStr += "d";
446       break;
447     default:
448       llvm_unreachable("Unhandled ElementBitwidth!");
449     }
450     break;
451   default:
452     llvm_unreachable("ScalarType is invalid!");
453   }
454   if (IsImmediate)
455     BuiltinStr = "I" + BuiltinStr;
456   if (isScalar()) {
457     if (IsConstant)
458       BuiltinStr += "C";
459     if (IsPointer)
460       BuiltinStr += "*";
461     return;
462   }
463   BuiltinStr = "q" + utostr(Scale.getValue()) + BuiltinStr;
464   // Pointer to vector types. Defined for segment load intrinsics.
465   // segment load intrinsics have pointer type arguments to store the loaded
466   // vector values.
467   if (IsPointer)
468     BuiltinStr += "*";
469 }
470 
471 void RVVType::initClangBuiltinStr() {
472   assert(isValid() && "RVVType is invalid");
473   assert(isVector() && "Handle Vector type only");
474 
475   ClangBuiltinStr = "__rvv_";
476   switch (ScalarType) {
477   case ScalarTypeKind::Boolean:
478     ClangBuiltinStr += "bool" + utostr(64 / Scale.getValue()) + "_t";
479     return;
480   case ScalarTypeKind::Float:
481     ClangBuiltinStr += "float";
482     break;
483   case ScalarTypeKind::SignedInteger:
484     ClangBuiltinStr += "int";
485     break;
486   case ScalarTypeKind::UnsignedInteger:
487     ClangBuiltinStr += "uint";
488     break;
489   default:
490     llvm_unreachable("ScalarTypeKind is invalid");
491   }
492   ClangBuiltinStr += utostr(ElementBitwidth) + LMUL.str() + "_t";
493 }
494 
495 void RVVType::initTypeStr() {
496   assert(isValid() && "RVVType is invalid");
497 
498   if (IsConstant)
499     Str += "const ";
500 
501   auto getTypeString = [&](StringRef TypeStr) {
502     if (isScalar())
503       return Twine(TypeStr + Twine(ElementBitwidth) + "_t").str();
504     return Twine("v" + TypeStr + Twine(ElementBitwidth) + LMUL.str() + "_t")
505         .str();
506   };
507 
508   switch (ScalarType) {
509   case ScalarTypeKind::Void:
510     Str = "void";
511     return;
512   case ScalarTypeKind::Size_t:
513     Str = "size_t";
514     if (IsPointer)
515       Str += " *";
516     return;
517   case ScalarTypeKind::Ptrdiff_t:
518     Str = "ptrdiff_t";
519     return;
520   case ScalarTypeKind::UnsignedLong:
521     Str = "unsigned long";
522     return;
523   case ScalarTypeKind::SignedLong:
524     Str = "long";
525     return;
526   case ScalarTypeKind::Boolean:
527     if (isScalar())
528       Str += "bool";
529     else
530       // Vector bool is special case, the formulate is
531       // `vbool<N>_t = MVT::nxv<64/N>i1` ex. vbool16_t = MVT::4i1
532       Str += "vbool" + utostr(64 / Scale.getValue()) + "_t";
533     break;
534   case ScalarTypeKind::Float:
535     if (isScalar()) {
536       if (ElementBitwidth == 64)
537         Str += "double";
538       else if (ElementBitwidth == 32)
539         Str += "float";
540       else if (ElementBitwidth == 16)
541         Str += "_Float16";
542       else
543         llvm_unreachable("Unhandled floating type.");
544     } else
545       Str += getTypeString("float");
546     break;
547   case ScalarTypeKind::SignedInteger:
548     Str += getTypeString("int");
549     break;
550   case ScalarTypeKind::UnsignedInteger:
551     Str += getTypeString("uint");
552     break;
553   default:
554     llvm_unreachable("ScalarType is invalid!");
555   }
556   if (IsPointer)
557     Str += " *";
558 }
559 
560 void RVVType::initShortStr() {
561   switch (ScalarType) {
562   case ScalarTypeKind::Boolean:
563     assert(isVector());
564     ShortStr = "b" + utostr(64 / Scale.getValue());
565     return;
566   case ScalarTypeKind::Float:
567     ShortStr = "f" + utostr(ElementBitwidth);
568     break;
569   case ScalarTypeKind::SignedInteger:
570     ShortStr = "i" + utostr(ElementBitwidth);
571     break;
572   case ScalarTypeKind::UnsignedInteger:
573     ShortStr = "u" + utostr(ElementBitwidth);
574     break;
575   default:
576     PrintFatalError("Unhandled case!");
577   }
578   if (isVector())
579     ShortStr += LMUL.str();
580 }
581 
582 void RVVType::applyBasicType() {
583   switch (BT) {
584   case 'c':
585     ElementBitwidth = 8;
586     ScalarType = ScalarTypeKind::SignedInteger;
587     break;
588   case 's':
589     ElementBitwidth = 16;
590     ScalarType = ScalarTypeKind::SignedInteger;
591     break;
592   case 'i':
593     ElementBitwidth = 32;
594     ScalarType = ScalarTypeKind::SignedInteger;
595     break;
596   case 'l':
597     ElementBitwidth = 64;
598     ScalarType = ScalarTypeKind::SignedInteger;
599     break;
600   case 'x':
601     ElementBitwidth = 16;
602     ScalarType = ScalarTypeKind::Float;
603     break;
604   case 'f':
605     ElementBitwidth = 32;
606     ScalarType = ScalarTypeKind::Float;
607     break;
608   case 'd':
609     ElementBitwidth = 64;
610     ScalarType = ScalarTypeKind::Float;
611     break;
612   default:
613     PrintFatalError("Unhandled type code!");
614   }
615   assert(ElementBitwidth != 0 && "Bad element bitwidth!");
616 }
617 
618 void RVVType::applyModifier(StringRef Transformer) {
619   if (Transformer.empty())
620     return;
621   // Handle primitive type transformer
622   auto PType = Transformer.back();
623   switch (PType) {
624   case 'e':
625     Scale = 0;
626     break;
627   case 'v':
628     Scale = LMUL.getScale(ElementBitwidth);
629     break;
630   case 'w':
631     ElementBitwidth *= 2;
632     LMUL *= 2;
633     Scale = LMUL.getScale(ElementBitwidth);
634     break;
635   case 'q':
636     ElementBitwidth *= 4;
637     LMUL *= 4;
638     Scale = LMUL.getScale(ElementBitwidth);
639     break;
640   case 'o':
641     ElementBitwidth *= 8;
642     LMUL *= 8;
643     Scale = LMUL.getScale(ElementBitwidth);
644     break;
645   case 'm':
646     ScalarType = ScalarTypeKind::Boolean;
647     Scale = LMUL.getScale(ElementBitwidth);
648     ElementBitwidth = 1;
649     break;
650   case '0':
651     ScalarType = ScalarTypeKind::Void;
652     break;
653   case 'z':
654     ScalarType = ScalarTypeKind::Size_t;
655     break;
656   case 't':
657     ScalarType = ScalarTypeKind::Ptrdiff_t;
658     break;
659   case 'u':
660     ScalarType = ScalarTypeKind::UnsignedLong;
661     break;
662   case 'l':
663     ScalarType = ScalarTypeKind::SignedLong;
664     break;
665   default:
666     PrintFatalError("Illegal primitive type transformers!");
667   }
668   Transformer = Transformer.drop_back();
669 
670   // Extract and compute complex type transformer. It can only appear one time.
671   if (Transformer.startswith("(")) {
672     size_t Idx = Transformer.find(')');
673     assert(Idx != StringRef::npos);
674     StringRef ComplexType = Transformer.slice(1, Idx);
675     Transformer = Transformer.drop_front(Idx + 1);
676     assert(!Transformer.contains('(') &&
677            "Only allow one complex type transformer");
678 
679     auto UpdateAndCheckComplexProto = [&]() {
680       Scale = LMUL.getScale(ElementBitwidth);
681       const StringRef VectorPrototypes("vwqom");
682       if (!VectorPrototypes.contains(PType))
683         PrintFatalError("Complex type transformer only supports vector type!");
684       if (Transformer.find_first_of("PCKWS") != StringRef::npos)
685         PrintFatalError(
686             "Illegal type transformer for Complex type transformer");
687     };
688     auto ComputeFixedLog2LMUL =
689         [&](StringRef Value,
690             std::function<bool(const int32_t &, const int32_t &)> Compare) {
691           int32_t Log2LMUL;
692           Value.getAsInteger(10, Log2LMUL);
693           if (!Compare(Log2LMUL, LMUL.Log2LMUL)) {
694             ScalarType = Invalid;
695             return false;
696           }
697           // Update new LMUL
698           LMUL = LMULType(Log2LMUL);
699           UpdateAndCheckComplexProto();
700           return true;
701         };
702     auto ComplexTT = ComplexType.split(":");
703     if (ComplexTT.first == "Log2EEW") {
704       uint32_t Log2EEW;
705       ComplexTT.second.getAsInteger(10, Log2EEW);
706       // update new elmul = (eew/sew) * lmul
707       LMUL.MulLog2LMUL(Log2EEW - Log2_32(ElementBitwidth));
708       // update new eew
709       ElementBitwidth = 1 << Log2EEW;
710       ScalarType = ScalarTypeKind::SignedInteger;
711       UpdateAndCheckComplexProto();
712     } else if (ComplexTT.first == "FixedSEW") {
713       uint32_t NewSEW;
714       ComplexTT.second.getAsInteger(10, NewSEW);
715       // Set invalid type if src and dst SEW are same.
716       if (ElementBitwidth == NewSEW) {
717         ScalarType = Invalid;
718         return;
719       }
720       // Update new SEW
721       ElementBitwidth = NewSEW;
722       UpdateAndCheckComplexProto();
723     } else if (ComplexTT.first == "LFixedLog2LMUL") {
724       // New LMUL should be larger than old
725       if (!ComputeFixedLog2LMUL(ComplexTT.second, std::greater<int32_t>()))
726         return;
727     } else if (ComplexTT.first == "SFixedLog2LMUL") {
728       // New LMUL should be smaller than old
729       if (!ComputeFixedLog2LMUL(ComplexTT.second, std::less<int32_t>()))
730         return;
731     } else {
732       PrintFatalError("Illegal complex type transformers!");
733     }
734   }
735 
736   // Compute the remain type transformers
737   for (char I : Transformer) {
738     switch (I) {
739     case 'P':
740       if (IsConstant)
741         PrintFatalError("'P' transformer cannot be used after 'C'");
742       if (IsPointer)
743         PrintFatalError("'P' transformer cannot be used twice");
744       IsPointer = true;
745       break;
746     case 'C':
747       if (IsConstant)
748         PrintFatalError("'C' transformer cannot be used twice");
749       IsConstant = true;
750       break;
751     case 'K':
752       IsImmediate = true;
753       break;
754     case 'U':
755       ScalarType = ScalarTypeKind::UnsignedInteger;
756       break;
757     case 'I':
758       ScalarType = ScalarTypeKind::SignedInteger;
759       break;
760     case 'F':
761       ScalarType = ScalarTypeKind::Float;
762       break;
763     case 'S':
764       LMUL = LMULType(0);
765       // Update ElementBitwidth need to update Scale too.
766       Scale = LMUL.getScale(ElementBitwidth);
767       break;
768     default:
769       PrintFatalError("Illegal non-primitive type transformer!");
770     }
771   }
772 }
773 
774 //===----------------------------------------------------------------------===//
775 // RVVIntrinsic implementation
776 //===----------------------------------------------------------------------===//
777 RVVIntrinsic::RVVIntrinsic(
778     StringRef NewName, StringRef Suffix, StringRef NewMangledName,
779     StringRef MangledSuffix, StringRef IRName, bool IsMasked,
780     bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme,
781     bool HasUnMaskedOverloaded, bool HasBuiltinAlias, StringRef ManualCodegen,
782     const RVVTypes &OutInTypes, const std::vector<int64_t> &NewIntrinsicTypes,
783     const std::vector<StringRef> &RequiredFeatures, unsigned NF)
784     : IRName(IRName), IsMasked(IsMasked), HasVL(HasVL), Scheme(Scheme),
785       HasUnMaskedOverloaded(HasUnMaskedOverloaded),
786       HasBuiltinAlias(HasBuiltinAlias), ManualCodegen(ManualCodegen.str()),
787       NF(NF) {
788 
789   // Init BuiltinName, Name and MangledName
790   BuiltinName = NewName.str();
791   Name = BuiltinName;
792   if (NewMangledName.empty())
793     MangledName = NewName.split("_").first.str();
794   else
795     MangledName = NewMangledName.str();
796   if (!Suffix.empty())
797     Name += "_" + Suffix.str();
798   if (!MangledSuffix.empty())
799     MangledName += "_" + MangledSuffix.str();
800   if (IsMasked) {
801     BuiltinName += "_m";
802     Name += "_m";
803   }
804 
805   // Init RISC-V extensions
806   for (const auto &T : OutInTypes) {
807     if (T->isFloatVector(16) || T->isFloat(16))
808       RISCVPredefinedMacros |= RISCVPredefinedMacro::Zvfh;
809     if (T->isFloatVector(32))
810       RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp32;
811     if (T->isFloatVector(64))
812       RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp64;
813     if (T->isVector(64))
814       RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELen64;
815   }
816   for (auto Feature : RequiredFeatures) {
817     if (Feature == "RV64")
818       RISCVPredefinedMacros |= RISCVPredefinedMacro::RV64;
819     // Note: Full multiply instruction (mulh, mulhu, mulhsu, smul) for EEW=64
820     // require V.
821     if (Feature == "FullMultiply" &&
822         (RISCVPredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64))
823       RISCVPredefinedMacros |= RISCVPredefinedMacro::V;
824   }
825 
826   // Init OutputType and InputTypes
827   OutputType = OutInTypes[0];
828   InputTypes.assign(OutInTypes.begin() + 1, OutInTypes.end());
829 
830   // IntrinsicTypes is unmasked TA version index. Need to update it
831   // if there is merge operand (It is always in first operand).
832   IntrinsicTypes = NewIntrinsicTypes;
833   if ((IsMasked && HasMaskedOffOperand) ||
834       (!IsMasked && hasPassthruOperand())) {
835     for (auto &I : IntrinsicTypes) {
836       if (I >= 0)
837         I += NF;
838     }
839   }
840 }
841 
842 std::string RVVIntrinsic::getBuiltinTypeStr() const {
843   std::string S;
844   S += OutputType->getBuiltinStr();
845   for (const auto &T : InputTypes) {
846     S += T->getBuiltinStr();
847   }
848   return S;
849 }
850 
851 void RVVIntrinsic::emitCodeGenSwitchBody(raw_ostream &OS) const {
852   if (!getIRName().empty())
853     OS << "  ID = Intrinsic::riscv_" + getIRName() + ";\n";
854   if (NF >= 2)
855     OS << "  NF = " + utostr(getNF()) + ";\n";
856   if (hasManualCodegen()) {
857     OS << ManualCodegen;
858     OS << "break;\n";
859     return;
860   }
861 
862   if (isMasked()) {
863     if (hasVL()) {
864       OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);\n";
865       if (hasPolicyOperand())
866         OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(),"
867               " TAIL_UNDISTURBED));\n";
868     } else {
869       OS << "  std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());\n";
870     }
871   } else {
872     if (hasPolicyOperand())
873       OS << "  Ops.push_back(ConstantInt::get(Ops.back()->getType(), "
874             "TAIL_UNDISTURBED));\n";
875     else if (hasPassthruOperand()) {
876       OS << "  Ops.push_back(llvm::UndefValue::get(ResultType));\n";
877       OS << "  std::rotate(Ops.rbegin(), Ops.rbegin() + 1,  Ops.rend());\n";
878     }
879   }
880 
881   OS << "  IntrinsicTypes = {";
882   ListSeparator LS;
883   for (const auto &Idx : IntrinsicTypes) {
884     if (Idx == -1)
885       OS << LS << "ResultType";
886     else
887       OS << LS << "Ops[" << Idx << "]->getType()";
888   }
889 
890   // VL could be i64 or i32, need to encode it in IntrinsicTypes. VL is
891   // always last operand.
892   if (hasVL())
893     OS << ", Ops.back()->getType()";
894   OS << "};\n";
895   OS << "  break;\n";
896 }
897 
898 void RVVIntrinsic::emitIntrinsicFuncDef(raw_ostream &OS) const {
899   OS << "__attribute__((__clang_builtin_alias__(";
900   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
901   OS << OutputType->getTypeStr() << " " << getName() << "(";
902   // Emit function arguments
903   if (!InputTypes.empty()) {
904     ListSeparator LS;
905     for (unsigned i = 0; i < InputTypes.size(); ++i)
906       OS << LS << InputTypes[i]->getTypeStr();
907   }
908   OS << ");\n";
909 }
910 
911 void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
912   OS << "__attribute__((__clang_builtin_alias__(";
913   OS << "__builtin_rvv_" << getBuiltinName() << ")))\n";
914   OS << OutputType->getTypeStr() << " " << getMangledName() << "(";
915   // Emit function arguments
916   if (!InputTypes.empty()) {
917     ListSeparator LS;
918     for (unsigned i = 0; i < InputTypes.size(); ++i)
919       OS << LS << InputTypes[i]->getTypeStr();
920   }
921   OS << ");\n";
922 }
923 
924 //===----------------------------------------------------------------------===//
925 // RVVEmitter implementation
926 //===----------------------------------------------------------------------===//
927 void RVVEmitter::createHeader(raw_ostream &OS) {
928 
929   OS << "/*===---- riscv_vector.h - RISC-V V-extension RVVIntrinsics "
930         "-------------------===\n"
931         " *\n"
932         " *\n"
933         " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
934         "Exceptions.\n"
935         " * See https://llvm.org/LICENSE.txt for license information.\n"
936         " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
937         " *\n"
938         " *===-----------------------------------------------------------------"
939         "------===\n"
940         " */\n\n";
941 
942   OS << "#ifndef __RISCV_VECTOR_H\n";
943   OS << "#define __RISCV_VECTOR_H\n\n";
944 
945   OS << "#include <stdint.h>\n";
946   OS << "#include <stddef.h>\n\n";
947 
948   OS << "#ifndef __riscv_vector\n";
949   OS << "#error \"Vector intrinsics require the vector extension.\"\n";
950   OS << "#endif\n\n";
951 
952   OS << "#ifdef __cplusplus\n";
953   OS << "extern \"C\" {\n";
954   OS << "#endif\n\n";
955 
956   printHeaderCode(OS);
957 
958   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
959   createRVVIntrinsics(Defs);
960 
961   auto printType = [&](auto T) {
962     OS << "typedef " << T->getClangBuiltinStr() << " " << T->getTypeStr()
963        << ";\n";
964   };
965 
966   constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3};
967   // Print RVV boolean types.
968   for (int Log2LMUL : Log2LMULs) {
969     auto T = computeType('c', Log2LMUL, "m");
970     if (T.hasValue())
971       printType(T.getValue());
972   }
973   // Print RVV int/float types.
974   for (char I : StringRef("csil")) {
975     for (int Log2LMUL : Log2LMULs) {
976       auto T = computeType(I, Log2LMUL, "v");
977       if (T.hasValue()) {
978         printType(T.getValue());
979         auto UT = computeType(I, Log2LMUL, "Uv");
980         printType(UT.getValue());
981       }
982     }
983   }
984   OS << "#if defined(__riscv_zvfh)\n";
985   for (int Log2LMUL : Log2LMULs) {
986     auto T = computeType('x', Log2LMUL, "v");
987     if (T.hasValue())
988       printType(T.getValue());
989   }
990   OS << "#endif\n";
991 
992   OS << "#if defined(__riscv_f)\n";
993   for (int Log2LMUL : Log2LMULs) {
994     auto T = computeType('f', Log2LMUL, "v");
995     if (T.hasValue())
996       printType(T.getValue());
997   }
998   OS << "#endif\n";
999 
1000   OS << "#if defined(__riscv_d)\n";
1001   for (int Log2LMUL : Log2LMULs) {
1002     auto T = computeType('d', Log2LMUL, "v");
1003     if (T.hasValue())
1004       printType(T.getValue());
1005   }
1006   OS << "#endif\n\n";
1007 
1008   // The same extension include in the same arch guard marco.
1009   llvm::stable_sort(Defs, [](const std::unique_ptr<RVVIntrinsic> &A,
1010                              const std::unique_ptr<RVVIntrinsic> &B) {
1011     return A->getRISCVPredefinedMacros() < B->getRISCVPredefinedMacros();
1012   });
1013 
1014   OS << "#define __rvv_ai static __inline__\n";
1015 
1016   // Print intrinsic functions with macro
1017   emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
1018     OS << "__rvv_ai ";
1019     Inst.emitIntrinsicFuncDef(OS);
1020   });
1021 
1022   OS << "#undef __rvv_ai\n\n";
1023 
1024   OS << "#define __riscv_v_intrinsic_overloading 1\n";
1025 
1026   // Print Overloaded APIs
1027   OS << "#define __rvv_aio static __inline__ "
1028         "__attribute__((__overloadable__))\n";
1029 
1030   emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
1031     if (!Inst.isMasked() && !Inst.hasUnMaskedOverloaded())
1032       return;
1033     OS << "__rvv_aio ";
1034     Inst.emitMangledFuncDef(OS);
1035   });
1036 
1037   OS << "#undef __rvv_aio\n";
1038 
1039   OS << "\n#ifdef __cplusplus\n";
1040   OS << "}\n";
1041   OS << "#endif // __cplusplus\n";
1042   OS << "#endif // __RISCV_VECTOR_H\n";
1043 }
1044 
1045 void RVVEmitter::createBuiltins(raw_ostream &OS) {
1046   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
1047   createRVVIntrinsics(Defs);
1048 
1049   // Map to keep track of which builtin names have already been emitted.
1050   StringMap<RVVIntrinsic *> BuiltinMap;
1051 
1052   OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n";
1053   OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, "
1054         "ATTRS, \"zve32x\")\n";
1055   OS << "#endif\n";
1056   for (auto &Def : Defs) {
1057     auto P =
1058         BuiltinMap.insert(std::make_pair(Def->getBuiltinName(), Def.get()));
1059     if (!P.second) {
1060       // Verf that this would have produced the same builtin definition.
1061       if (P.first->second->hasBuiltinAlias() != Def->hasBuiltinAlias())
1062         PrintFatalError("Builtin with same name has different hasAutoDef");
1063       else if (!Def->hasBuiltinAlias() &&
1064                P.first->second->getBuiltinTypeStr() != Def->getBuiltinTypeStr())
1065         PrintFatalError("Builtin with same name has different type string");
1066       continue;
1067     }
1068     OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getBuiltinName() << ",\"";
1069     if (!Def->hasBuiltinAlias())
1070       OS << Def->getBuiltinTypeStr();
1071     OS << "\", \"n\")\n";
1072   }
1073   OS << "#undef RISCVV_BUILTIN\n";
1074 }
1075 
1076 void RVVEmitter::createCodeGen(raw_ostream &OS) {
1077   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
1078   createRVVIntrinsics(Defs);
1079   // IR name could be empty, use the stable sort preserves the relative order.
1080   llvm::stable_sort(Defs, [](const std::unique_ptr<RVVIntrinsic> &A,
1081                              const std::unique_ptr<RVVIntrinsic> &B) {
1082     return A->getIRName() < B->getIRName();
1083   });
1084 
1085   // Map to keep track of which builtin names have already been emitted.
1086   StringMap<RVVIntrinsic *> BuiltinMap;
1087 
1088   // Print switch body when the ir name or ManualCodegen changes from previous
1089   // iteration.
1090   RVVIntrinsic *PrevDef = Defs.begin()->get();
1091   for (auto &Def : Defs) {
1092     StringRef CurIRName = Def->getIRName();
1093     if (CurIRName != PrevDef->getIRName() ||
1094         (Def->getManualCodegen() != PrevDef->getManualCodegen())) {
1095       PrevDef->emitCodeGenSwitchBody(OS);
1096     }
1097     PrevDef = Def.get();
1098 
1099     auto P =
1100         BuiltinMap.insert(std::make_pair(Def->getBuiltinName(), Def.get()));
1101     if (P.second) {
1102       OS << "case RISCVVector::BI__builtin_rvv_" << Def->getBuiltinName()
1103          << ":\n";
1104       continue;
1105     }
1106 
1107     if (P.first->second->getIRName() != Def->getIRName())
1108       PrintFatalError("Builtin with same name has different IRName");
1109     else if (P.first->second->getManualCodegen() != Def->getManualCodegen())
1110       PrintFatalError("Builtin with same name has different ManualCodegen");
1111     else if (P.first->second->getNF() != Def->getNF())
1112       PrintFatalError("Builtin with same name has different NF");
1113     else if (P.first->second->isMasked() != Def->isMasked())
1114       PrintFatalError("Builtin with same name has different isMasked");
1115     else if (P.first->second->hasVL() != Def->hasVL())
1116       PrintFatalError("Builtin with same name has different hasVL");
1117     else if (P.first->second->getPolicyScheme() != Def->getPolicyScheme())
1118       PrintFatalError("Builtin with same name has different getPolicyScheme");
1119     else if (P.first->second->getIntrinsicTypes() != Def->getIntrinsicTypes())
1120       PrintFatalError("Builtin with same name has different IntrinsicTypes");
1121   }
1122   Defs.back()->emitCodeGenSwitchBody(OS);
1123   OS << "\n";
1124 }
1125 
1126 void RVVEmitter::parsePrototypes(StringRef Prototypes,
1127                                  std::function<void(StringRef)> Handler) {
1128   const StringRef Primaries("evwqom0ztul");
1129   while (!Prototypes.empty()) {
1130     size_t Idx = 0;
1131     // Skip over complex prototype because it could contain primitive type
1132     // character.
1133     if (Prototypes[0] == '(')
1134       Idx = Prototypes.find_first_of(')');
1135     Idx = Prototypes.find_first_of(Primaries, Idx);
1136     assert(Idx != StringRef::npos);
1137     Handler(Prototypes.slice(0, Idx + 1));
1138     Prototypes = Prototypes.drop_front(Idx + 1);
1139   }
1140 }
1141 
1142 std::string RVVEmitter::getSuffixStr(char Type, int Log2LMUL,
1143                                      StringRef Prototypes) {
1144   SmallVector<std::string> SuffixStrs;
1145   parsePrototypes(Prototypes, [&](StringRef Proto) {
1146     auto T = computeType(Type, Log2LMUL, Proto);
1147     SuffixStrs.push_back(T.getValue()->getShortStr());
1148   });
1149   return join(SuffixStrs, "_");
1150 }
1151 
1152 void RVVEmitter::createRVVIntrinsics(
1153     std::vector<std::unique_ptr<RVVIntrinsic>> &Out) {
1154   std::vector<Record *> RV = Records.getAllDerivedDefinitions("RVVBuiltin");
1155   for (auto *R : RV) {
1156     StringRef Name = R->getValueAsString("Name");
1157     StringRef SuffixProto = R->getValueAsString("Suffix");
1158     StringRef MangledName = R->getValueAsString("MangledName");
1159     StringRef MangledSuffixProto = R->getValueAsString("MangledSuffix");
1160     StringRef Prototypes = R->getValueAsString("Prototype");
1161     StringRef TypeRange = R->getValueAsString("TypeRange");
1162     bool HasMasked = R->getValueAsBit("HasMasked");
1163     bool HasMaskedOffOperand = R->getValueAsBit("HasMaskedOffOperand");
1164     bool HasVL = R->getValueAsBit("HasVL");
1165     Record *MaskedPolicyRecord = R->getValueAsDef("MaskedPolicy");
1166     PolicyScheme MaskedPolicy =
1167         static_cast<PolicyScheme>(MaskedPolicyRecord->getValueAsInt("Value"));
1168     Record *UnMaskedPolicyRecord = R->getValueAsDef("UnMaskedPolicy");
1169     PolicyScheme UnMaskedPolicy =
1170         static_cast<PolicyScheme>(UnMaskedPolicyRecord->getValueAsInt("Value"));
1171     bool HasUnMaskedOverloaded = R->getValueAsBit("HasUnMaskedOverloaded");
1172     std::vector<int64_t> Log2LMULList = R->getValueAsListOfInts("Log2LMUL");
1173     bool HasBuiltinAlias = R->getValueAsBit("HasBuiltinAlias");
1174     StringRef ManualCodegen = R->getValueAsString("ManualCodegen");
1175     StringRef MaskedManualCodegen = R->getValueAsString("MaskedManualCodegen");
1176     std::vector<int64_t> IntrinsicTypes =
1177         R->getValueAsListOfInts("IntrinsicTypes");
1178     std::vector<StringRef> RequiredFeatures =
1179         R->getValueAsListOfStrings("RequiredFeatures");
1180     StringRef IRName = R->getValueAsString("IRName");
1181     StringRef MaskedIRName = R->getValueAsString("MaskedIRName");
1182     unsigned NF = R->getValueAsInt("NF");
1183 
1184     // Parse prototype and create a list of primitive type with transformers
1185     // (operand) in ProtoSeq. ProtoSeq[0] is output operand.
1186     SmallVector<std::string> ProtoSeq;
1187     parsePrototypes(Prototypes, [&ProtoSeq](StringRef Proto) {
1188       ProtoSeq.push_back(Proto.str());
1189     });
1190 
1191     // Compute Builtin types
1192     SmallVector<std::string> ProtoMaskSeq = ProtoSeq;
1193     if (HasMasked) {
1194       // If HasMaskedOffOperand, insert result type as first input operand.
1195       if (HasMaskedOffOperand) {
1196         if (NF == 1) {
1197           ProtoMaskSeq.insert(ProtoMaskSeq.begin() + 1, ProtoSeq[0]);
1198         } else {
1199           // Convert
1200           // (void, op0 address, op1 address, ...)
1201           // to
1202           // (void, op0 address, op1 address, ..., maskedoff0, maskedoff1, ...)
1203           for (unsigned I = 0; I < NF; ++I)
1204             ProtoMaskSeq.insert(
1205                 ProtoMaskSeq.begin() + NF + 1,
1206                 ProtoSeq[1].substr(1)); // Use substr(1) to skip '*'
1207         }
1208       }
1209       if (HasMaskedOffOperand && NF > 1) {
1210         // Convert
1211         // (void, op0 address, op1 address, ..., maskedoff0, maskedoff1, ...)
1212         // to
1213         // (void, op0 address, op1 address, ..., mask, maskedoff0, maskedoff1,
1214         // ...)
1215         ProtoMaskSeq.insert(ProtoMaskSeq.begin() + NF + 1, "m");
1216       } else {
1217         // If HasMasked, insert 'm' as first input operand.
1218         ProtoMaskSeq.insert(ProtoMaskSeq.begin() + 1, "m");
1219       }
1220     }
1221     // If HasVL, append 'z' to last operand
1222     if (HasVL) {
1223       ProtoSeq.push_back("z");
1224       ProtoMaskSeq.push_back("z");
1225     }
1226 
1227     // Create Intrinsics for each type and LMUL.
1228     for (char I : TypeRange) {
1229       for (int Log2LMUL : Log2LMULList) {
1230         Optional<RVVTypes> Types = computeTypes(I, Log2LMUL, NF, ProtoSeq);
1231         // Ignored to create new intrinsic if there are any illegal types.
1232         if (!Types.hasValue())
1233           continue;
1234 
1235         auto SuffixStr = getSuffixStr(I, Log2LMUL, SuffixProto);
1236         auto MangledSuffixStr = getSuffixStr(I, Log2LMUL, MangledSuffixProto);
1237         // Create a unmasked intrinsic
1238         Out.push_back(std::make_unique<RVVIntrinsic>(
1239             Name, SuffixStr, MangledName, MangledSuffixStr, IRName,
1240             /*IsMasked=*/false, /*HasMaskedOffOperand=*/false, HasVL,
1241             UnMaskedPolicy, HasUnMaskedOverloaded, HasBuiltinAlias,
1242             ManualCodegen, Types.getValue(), IntrinsicTypes, RequiredFeatures,
1243             NF));
1244         if (HasMasked) {
1245           // Create a masked intrinsic
1246           Optional<RVVTypes> MaskTypes =
1247               computeTypes(I, Log2LMUL, NF, ProtoMaskSeq);
1248           Out.push_back(std::make_unique<RVVIntrinsic>(
1249               Name, SuffixStr, MangledName, MangledSuffixStr, MaskedIRName,
1250               /*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicy,
1251               HasUnMaskedOverloaded, HasBuiltinAlias, MaskedManualCodegen,
1252               MaskTypes.getValue(), IntrinsicTypes, RequiredFeatures, NF));
1253         }
1254       } // end for Log2LMULList
1255     }   // end for TypeRange
1256   }
1257 }
1258 
1259 void RVVEmitter::printHeaderCode(raw_ostream &OS) {
1260   std::vector<Record *> RVVHeaders =
1261       Records.getAllDerivedDefinitions("RVVHeader");
1262   for (auto *R : RVVHeaders) {
1263     StringRef HeaderCodeStr = R->getValueAsString("HeaderCode");
1264     OS << HeaderCodeStr.str();
1265   }
1266 }
1267 
1268 Optional<RVVTypes>
1269 RVVEmitter::computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
1270                          ArrayRef<std::string> PrototypeSeq) {
1271   // LMUL x NF must be less than or equal to 8.
1272   if ((Log2LMUL >= 1) && (1 << Log2LMUL) * NF > 8)
1273     return llvm::None;
1274 
1275   RVVTypes Types;
1276   for (const std::string &Proto : PrototypeSeq) {
1277     auto T = computeType(BT, Log2LMUL, Proto);
1278     if (!T.hasValue())
1279       return llvm::None;
1280     // Record legal type index
1281     Types.push_back(T.getValue());
1282   }
1283   return Types;
1284 }
1285 
1286 Optional<RVVTypePtr> RVVEmitter::computeType(BasicType BT, int Log2LMUL,
1287                                              StringRef Proto) {
1288   std::string Idx = Twine(Twine(BT) + Twine(Log2LMUL) + Proto).str();
1289   // Search first
1290   auto It = LegalTypes.find(Idx);
1291   if (It != LegalTypes.end())
1292     return &(It->second);
1293   if (IllegalTypes.count(Idx))
1294     return llvm::None;
1295   // Compute type and record the result.
1296   RVVType T(BT, Log2LMUL, Proto);
1297   if (T.isValid()) {
1298     // Record legal type index and value.
1299     LegalTypes.insert({Idx, T});
1300     return &(LegalTypes[Idx]);
1301   }
1302   // Record illegal type index.
1303   IllegalTypes.insert(Idx);
1304   return llvm::None;
1305 }
1306 
1307 void RVVEmitter::emitArchMacroAndBody(
1308     std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &OS,
1309     std::function<void(raw_ostream &, const RVVIntrinsic &)> PrintBody) {
1310   RISCVPredefinedMacroT PrevMacros =
1311       (*Defs.begin())->getRISCVPredefinedMacros();
1312   bool NeedEndif = emitMacroRestrictionStr(PrevMacros, OS);
1313   for (auto &Def : Defs) {
1314     RISCVPredefinedMacroT CurMacros = Def->getRISCVPredefinedMacros();
1315     if (CurMacros != PrevMacros) {
1316       if (NeedEndif)
1317         OS << "#endif\n\n";
1318       NeedEndif = emitMacroRestrictionStr(CurMacros, OS);
1319       PrevMacros = CurMacros;
1320     }
1321     if (Def->hasBuiltinAlias())
1322       PrintBody(OS, *Def);
1323   }
1324   if (NeedEndif)
1325     OS << "#endif\n\n";
1326 }
1327 
1328 bool RVVEmitter::emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros,
1329                                          raw_ostream &OS) {
1330   if (PredefinedMacros == RISCVPredefinedMacro::Basic)
1331     return false;
1332   OS << "#if ";
1333   ListSeparator LS(" && ");
1334   if (PredefinedMacros & RISCVPredefinedMacro::V)
1335     OS << LS << "defined(__riscv_v)";
1336   if (PredefinedMacros & RISCVPredefinedMacro::Zvfh)
1337     OS << LS << "defined(__riscv_zvfh)";
1338   if (PredefinedMacros & RISCVPredefinedMacro::RV64)
1339     OS << LS << "(__riscv_xlen == 64)";
1340   if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64)
1341     OS << LS << "(__riscv_v_elen >= 64)";
1342   if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp32)
1343     OS << LS << "(__riscv_v_elen_fp >= 32)";
1344   if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp64)
1345     OS << LS << "(__riscv_v_elen_fp >= 64)";
1346   OS << "\n";
1347   return true;
1348 }
1349 
1350 namespace clang {
1351 void EmitRVVHeader(RecordKeeper &Records, raw_ostream &OS) {
1352   RVVEmitter(Records).createHeader(OS);
1353 }
1354 
1355 void EmitRVVBuiltins(RecordKeeper &Records, raw_ostream &OS) {
1356   RVVEmitter(Records).createBuiltins(OS);
1357 }
1358 
1359 void EmitRVVBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
1360   RVVEmitter(Records).createCodeGen(OS);
1361 }
1362 
1363 } // End namespace clang
1364