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