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