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