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