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   assert(isVector() && "only handle vector type");
532   switch (ScalarType) {
533   case ScalarTypeKind::Boolean:
534     ShortStr = "b" + utostr(64 / Scale.getValue());
535     break;
536   case ScalarTypeKind::Float:
537     ShortStr = "f" + utostr(ElementBitwidth) + LMUL.str();
538     break;
539   case ScalarTypeKind::SignedInteger:
540     ShortStr = "i" + utostr(ElementBitwidth) + LMUL.str();
541     break;
542   case ScalarTypeKind::UnsignedInteger:
543     ShortStr = "u" + utostr(ElementBitwidth) + LMUL.str();
544     break;
545   default:
546     llvm_unreachable("Unhandled case!");
547   }
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 ComplexTT = ComplexType.split(":");
657     if (ComplexTT.first == "Log2EEW") {
658       uint32_t Log2EEW;
659       ComplexTT.second.getAsInteger(10, Log2EEW);
660       // update new elmul = (eew/sew) * lmul
661       LMUL.MulLog2LMUL(Log2EEW - Log2_32(ElementBitwidth));
662       // update new eew
663       ElementBitwidth = 1 << Log2EEW;
664       ScalarType = ScalarTypeKind::SignedInteger;
665       UpdateAndCheckComplexProto();
666     } else {
667       PrintFatalError("Illegal complex type transformers!");
668     }
669   }
670 
671   // Compute the remain type transformers
672   for (char I : Transformer) {
673     switch (I) {
674     case 'P':
675       if (IsConstant)
676         PrintFatalError("'P' transformer cannot be used after 'C'");
677       if (IsPointer)
678         PrintFatalError("'P' transformer cannot be used twice");
679       IsPointer = true;
680       break;
681     case 'C':
682       if (IsConstant)
683         PrintFatalError("'C' transformer cannot be used twice");
684       IsConstant = true;
685       break;
686     case 'K':
687       IsImmediate = true;
688       break;
689     case 'U':
690       ScalarType = ScalarTypeKind::UnsignedInteger;
691       break;
692     case 'I':
693       ScalarType = ScalarTypeKind::SignedInteger;
694       break;
695     case 'F':
696       ScalarType = ScalarTypeKind::Float;
697       break;
698     case 'S':
699       LMUL = LMULType(0);
700       // Update ElementBitwidth need to update Scale too.
701       Scale = LMUL.getScale(ElementBitwidth);
702       break;
703     default:
704       PrintFatalError("Illegal non-primitive type transformer!");
705     }
706   }
707 }
708 
709 //===----------------------------------------------------------------------===//
710 // RVVIntrinsic implementation
711 //===----------------------------------------------------------------------===//
712 RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix,
713                            StringRef NewMangledName, StringRef IRName,
714                            bool HasSideEffects, bool IsMask,
715                            bool HasMaskedOffOperand, bool HasVL,
716                            bool HasNoMaskedOverloaded, bool HasAutoDef,
717                            StringRef ManualCodegen, const RVVTypes &OutInTypes,
718                            const std::vector<int64_t> &NewIntrinsicTypes,
719                            const std::vector<int64_t> &PermuteOperands)
720     : IRName(IRName), HasSideEffects(HasSideEffects), IsMask(IsMask),
721       HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL),
722       HasNoMaskedOverloaded(HasNoMaskedOverloaded), HasAutoDef(HasAutoDef),
723       ManualCodegen(ManualCodegen.str()) {
724 
725   // Init Name and MangledName
726   Name = NewName.str();
727   if (NewMangledName.empty())
728     MangledName = NewName.split("_").first.str();
729   else
730     MangledName = NewMangledName.str();
731   if (!Suffix.empty())
732     Name += "_" + Suffix.str();
733   if (IsMask) {
734     Name += "_m";
735   }
736   // Init RISC-V extensions
737   for (const auto &T : OutInTypes) {
738     if (T->isFloatVector(16))
739       RISCVExtensions |= RISCVExtension::Zfh;
740     else if (T->isFloatVector(32))
741       RISCVExtensions |= RISCVExtension::F;
742     else if (T->isFloatVector(64))
743       RISCVExtensions |= RISCVExtension::D;
744   }
745 
746   // Init OutputType and InputTypes
747   OutputType = OutInTypes[0];
748   InputTypes.assign(OutInTypes.begin() + 1, OutInTypes.end());
749   CTypeOrder.resize(InputTypes.size());
750   std::iota(CTypeOrder.begin(), CTypeOrder.end(), 0);
751   // Update default order if we need permutate.
752   if (!PermuteOperands.empty()) {
753     // PermuteOperands is nonmasked version index. Update index when there is
754     // maskedoff operand which is always in first operand.
755 
756     unsigned Skew = HasMaskedOffOperand ? 1 : 0;
757     for (unsigned i = 0; i < PermuteOperands.size(); ++i) {
758       if (i != PermuteOperands[i])
759         CTypeOrder[i] = PermuteOperands[i] + Skew;
760     }
761     // Verify the result of CTypeOrder has legal value.
762     if (*std::max_element(CTypeOrder.begin(), CTypeOrder.end()) >=
763         CTypeOrder.size())
764       PrintFatalError(
765           "The index of PermuteOperand is bigger than the operand number");
766     SmallSet<unsigned, 8> Seen;
767     for (auto Idx : CTypeOrder) {
768       if (!Seen.insert(Idx).second)
769         PrintFatalError(
770             "The different element in PermuteOperand could not be equal");
771     }
772   }
773 
774   if (IsMask) {
775     if (HasVL)
776       // Builtin type order: op0, op1, ..., mask, vl
777       // C type order: mask, op0, op1, ..., vl
778       std::rotate(CTypeOrder.begin(), CTypeOrder.end() - 2,
779                   CTypeOrder.end() - 1);
780     else
781       // Builtin type order: op0, op1, ..., mask
782       // C type order: mask, op0, op1, ...,
783       std::rotate(CTypeOrder.begin(), CTypeOrder.end() - 1, CTypeOrder.end());
784   }
785 
786   // IntrinsicTypes is nonmasked version index. Need to update it
787   // if there is maskedoff operand (It is always in first operand).
788   IntrinsicTypes = NewIntrinsicTypes;
789   if (IsMask && HasMaskedOffOperand) {
790     for (auto &I : IntrinsicTypes) {
791       if (I >= 0)
792         I += 1;
793     }
794   }
795 }
796 
797 std::string RVVIntrinsic::getBuiltinTypeStr() const {
798   std::string S;
799   S += OutputType->getBuiltinStr();
800   for (const auto &T : InputTypes) {
801     S += T->getBuiltinStr();
802   }
803   return S;
804 }
805 
806 void RVVIntrinsic::emitCodeGenSwitchBody(raw_ostream &OS) const {
807 
808   OS << "  ID = Intrinsic::riscv_" + getIRName() + ";\n";
809   if (hasManualCodegen()) {
810     OS << ManualCodegen;
811     OS << "break;\n";
812     return;
813   }
814   OS << "  IntrinsicTypes = {";
815   ListSeparator LS;
816   for (const auto &Idx : IntrinsicTypes) {
817     if (Idx == -1)
818       OS << LS << "ResultType";
819     else
820       OS << LS << "Ops[" << Idx << "]->getType()";
821   }
822 
823   // VL could be i64 or i32, need to encode it in IntrinsicTypes. VL is
824   // always last operand.
825   if (hasVL())
826     OS << ", Ops[" << getNumOperand() - 1 << "]->getType()";
827   OS << "};\n";
828   OS << "  break;\n";
829 }
830 
831 void RVVIntrinsic::emitIntrinsicMacro(raw_ostream &OS) const {
832   OS << "#define " << getName() << "(";
833   if (getNumOperand() > 0) {
834     ListSeparator LS;
835     for (const auto &I : CTypeOrder)
836       OS << LS << "op" << I;
837   }
838   OS << ") \\\n";
839   OS << "__builtin_rvv_" << getName() << "(";
840   if (getNumOperand() > 0) {
841     ListSeparator LS;
842     for (unsigned i = 0; i < InputTypes.size(); ++i)
843       OS << LS << "(" << InputTypes[i]->getTypeStr() << ")(op" << i << ")";
844   }
845   OS << ")\n";
846 }
847 
848 void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
849   OS << OutputType->getTypeStr() << " " << getMangledName() << "(";
850   // Emit function arguments
851   if (getNumOperand() > 0) {
852     ListSeparator LS;
853     for (unsigned i = 0; i < CTypeOrder.size(); ++i)
854       OS << LS << InputTypes[CTypeOrder[i]]->getTypeStr() << " op" << i;
855   }
856   OS << "){\n";
857   OS << "  return " << getName() << "(";
858   // Emit parameter variables
859   if (getNumOperand() > 0) {
860     ListSeparator LS;
861     for (unsigned i = 0; i < CTypeOrder.size(); ++i)
862       OS << LS << "op" << i;
863   }
864   OS << ");\n";
865   OS << "}\n\n";
866 }
867 
868 //===----------------------------------------------------------------------===//
869 // RVVEmitter implementation
870 //===----------------------------------------------------------------------===//
871 void RVVEmitter::createHeader(raw_ostream &OS) {
872 
873   OS << "/*===---- riscv_vector.h - RISC-V V-extension RVVIntrinsics "
874         "-------------------===\n"
875         " *\n"
876         " *\n"
877         " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
878         "Exceptions.\n"
879         " * See https://llvm.org/LICENSE.txt for license information.\n"
880         " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
881         " *\n"
882         " *===-----------------------------------------------------------------"
883         "------===\n"
884         " */\n\n";
885 
886   OS << "#ifndef __RISCV_VECTOR_H\n";
887   OS << "#define __RISCV_VECTOR_H\n\n";
888 
889   OS << "#include <stdint.h>\n";
890   OS << "#include <stddef.h>\n\n";
891 
892   OS << "#ifndef __riscv_vector\n";
893   OS << "#error \"Vector intrinsics require the vector extension.\"\n";
894   OS << "#endif\n\n";
895 
896   OS << "#ifdef __cplusplus\n";
897   OS << "extern \"C\" {\n";
898   OS << "#endif\n\n";
899 
900   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
901   createRVVIntrinsics(Defs);
902 
903   // Print header code
904   if (!HeaderCode.empty()) {
905     OS << HeaderCode;
906   }
907 
908   auto printType = [&](auto T) {
909     OS << "typedef " << T->getClangBuiltinStr() << " " << T->getTypeStr()
910        << ";\n";
911   };
912 
913   constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3};
914   // Print RVV boolean types.
915   for (int Log2LMUL : Log2LMULs) {
916     auto T = computeType('c', Log2LMUL, "m");
917     if (T.hasValue())
918       printType(T.getValue());
919   }
920   // Print RVV int/float types.
921   for (char I : StringRef("csil")) {
922     for (int Log2LMUL : Log2LMULs) {
923       auto T = computeType(I, Log2LMUL, "v");
924       if (T.hasValue()) {
925         printType(T.getValue());
926         auto UT = computeType(I, Log2LMUL, "Uv");
927         printType(UT.getValue());
928       }
929     }
930   }
931   OS << "#if defined(__riscv_zfh)\n";
932   for (int Log2LMUL : Log2LMULs) {
933     auto T = computeType('h', Log2LMUL, "v");
934     if (T.hasValue())
935       printType(T.getValue());
936   }
937   OS << "#endif\n";
938 
939   OS << "#if defined(__riscv_f)\n";
940   for (int Log2LMUL : Log2LMULs) {
941     auto T = computeType('f', Log2LMUL, "v");
942     if (T.hasValue())
943       printType(T.getValue());
944   }
945   OS << "#endif\n";
946 
947   OS << "#if defined(__riscv_d)\n";
948   for (int Log2LMUL : Log2LMULs) {
949     auto T = computeType('d', Log2LMUL, "v");
950     if (T.hasValue())
951       printType(T.getValue());
952   }
953   OS << "#endif\n\n";
954 
955   // The same extension include in the same arch guard marco.
956   std::stable_sort(Defs.begin(), Defs.end(),
957                    [](const std::unique_ptr<RVVIntrinsic> &A,
958                       const std::unique_ptr<RVVIntrinsic> &B) {
959                      return A->getRISCVExtensions() < B->getRISCVExtensions();
960                    });
961 
962   // Print intrinsic functions with macro
963   emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
964     Inst.emitIntrinsicMacro(OS);
965   });
966 
967   OS << "#define __riscv_v_intrinsic_overloading 1\n";
968 
969   // Print Overloaded APIs
970   OS << "#define __rvv_overloaded static inline "
971         "__attribute__((__always_inline__, __nodebug__, __overloadable__))\n";
972 
973   emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
974     if (!Inst.isMask() && !Inst.hasNoMaskedOverloaded())
975       return;
976     OS << "__rvv_overloaded ";
977     Inst.emitMangledFuncDef(OS);
978   });
979 
980   OS << "\n#ifdef __cplusplus\n";
981   OS << "}\n";
982   OS << "#endif // __riscv_vector\n";
983   OS << "#endif // __RISCV_VECTOR_H\n";
984 }
985 
986 void RVVEmitter::createBuiltins(raw_ostream &OS) {
987   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
988   createRVVIntrinsics(Defs);
989 
990   OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n";
991   OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, "
992         "ATTRS, \"experimental-v\")\n";
993   OS << "#endif\n";
994   for (auto &Def : Defs) {
995     OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getName() << ",\""
996        << Def->getBuiltinTypeStr() << "\", ";
997     if (!Def->hasSideEffects())
998       OS << "\"n\")\n";
999     else
1000       OS << "\"\")\n";
1001   }
1002   OS << "#undef RISCVV_BUILTIN\n";
1003 }
1004 
1005 void RVVEmitter::createCodeGen(raw_ostream &OS) {
1006   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
1007   createRVVIntrinsics(Defs);
1008 
1009   // The same intrinsic IR name has the same switch body.
1010   std::stable_sort(Defs.begin(), Defs.end(),
1011                    [](const std::unique_ptr<RVVIntrinsic> &A,
1012                       const std::unique_ptr<RVVIntrinsic> &B) {
1013                      return A->getIRName() < B->getIRName();
1014                    });
1015   // Print switch body when the ir name changes from previous iteration.
1016   RVVIntrinsic *PrevDef = Defs.begin()->get();
1017   for (auto &Def : Defs) {
1018     StringRef CurIRName = Def->getIRName();
1019     if (CurIRName != PrevDef->getIRName()) {
1020       PrevDef->emitCodeGenSwitchBody(OS);
1021     }
1022     PrevDef = Def.get();
1023     OS << "case RISCV::BI__builtin_rvv_" << Def->getName() << ":\n";
1024   }
1025   Defs.back()->emitCodeGenSwitchBody(OS);
1026   OS << "\n";
1027 }
1028 
1029 void RVVEmitter::parsePrototypes(StringRef Prototypes,
1030                                  std::function<void(StringRef)> Handler) {
1031   const StringRef Primaries("evwqom0ztul");
1032   while (!Prototypes.empty()) {
1033     size_t Idx = 0;
1034     // Skip over complex prototype because it could contain primitive type
1035     // character.
1036     if (Prototypes[0] == '(')
1037       Idx = Prototypes.find_first_of(')');
1038     Idx = Prototypes.find_first_of(Primaries, Idx);
1039     assert(Idx != StringRef::npos);
1040     Handler(Prototypes.slice(0, Idx + 1));
1041     Prototypes = Prototypes.drop_front(Idx + 1);
1042   }
1043 }
1044 
1045 std::string RVVEmitter::getSuffixStr(char Type, int Log2LMUL,
1046                                      StringRef Prototypes) {
1047   SmallVector<std::string> SuffixStrs;
1048   parsePrototypes(Prototypes, [&](StringRef Proto) {
1049     auto T = computeType(Type, Log2LMUL, Proto);
1050     SuffixStrs.push_back(T.getValue()->getShortStr());
1051   });
1052   return join(SuffixStrs, "_");
1053 }
1054 
1055 void RVVEmitter::createRVVIntrinsics(
1056     std::vector<std::unique_ptr<RVVIntrinsic>> &Out) {
1057   std::vector<Record *> RV = Records.getAllDerivedDefinitions("RVVBuiltin");
1058   for (auto *R : RV) {
1059     StringRef Name = R->getValueAsString("Name");
1060     StringRef SuffixProto = R->getValueAsString("Suffix");
1061     StringRef MangledName = R->getValueAsString("MangledName");
1062     StringRef Prototypes = R->getValueAsString("Prototype");
1063     StringRef TypeRange = R->getValueAsString("TypeRange");
1064     bool HasMask = R->getValueAsBit("HasMask");
1065     bool HasMaskedOffOperand = R->getValueAsBit("HasMaskedOffOperand");
1066     bool HasVL = R->getValueAsBit("HasVL");
1067     bool HasNoMaskedOverloaded = R->getValueAsBit("HasNoMaskedOverloaded");
1068     bool HasSideEffects = R->getValueAsBit("HasSideEffects");
1069     std::vector<int64_t> Log2LMULList = R->getValueAsListOfInts("Log2LMUL");
1070     StringRef ManualCodegen = R->getValueAsString("ManualCodegen");
1071     StringRef ManualCodegenMask = R->getValueAsString("ManualCodegenMask");
1072     std::vector<int64_t> IntrinsicTypes =
1073         R->getValueAsListOfInts("IntrinsicTypes");
1074     std::vector<int64_t> PermuteOperands =
1075         R->getValueAsListOfInts("PermuteOperands");
1076     StringRef IRName = R->getValueAsString("IRName");
1077     StringRef IRNameMask = R->getValueAsString("IRNameMask");
1078 
1079     StringRef HeaderCodeStr = R->getValueAsString("HeaderCode");
1080     bool HasAutoDef = HeaderCodeStr.empty();
1081     if (!HeaderCodeStr.empty()) {
1082       HeaderCode += HeaderCodeStr.str();
1083     }
1084     // Parse prototype and create a list of primitive type with transformers
1085     // (operand) in ProtoSeq. ProtoSeq[0] is output operand.
1086     SmallVector<std::string> ProtoSeq;
1087     parsePrototypes(Prototypes, [&ProtoSeq](StringRef Proto) {
1088       ProtoSeq.push_back(Proto.str());
1089     });
1090 
1091     // Compute Builtin types
1092     SmallVector<std::string> ProtoMaskSeq = ProtoSeq;
1093     if (HasMask) {
1094       // If HasMask, append 'm' to last operand.
1095       ProtoMaskSeq.push_back("m");
1096       // If HasMaskedOffOperand, insert result type as first input operand.
1097       if (HasMaskedOffOperand)
1098         ProtoMaskSeq.insert(ProtoMaskSeq.begin() + 1, ProtoSeq[0]);
1099     }
1100     // If HasVL, append 'z' to last operand
1101     if (HasVL) {
1102       ProtoSeq.push_back("z");
1103       ProtoMaskSeq.push_back("z");
1104     }
1105 
1106     // Create Intrinsics for each type and LMUL.
1107     for (char I : TypeRange) {
1108       for (int Log2LMUL : Log2LMULList) {
1109         Optional<RVVTypes> Types = computeTypes(I, Log2LMUL, ProtoSeq);
1110         // Ignored to create new intrinsic if there are any illegal types.
1111         if (!Types.hasValue())
1112           continue;
1113 
1114         auto SuffixStr = getSuffixStr(I, Log2LMUL, SuffixProto);
1115         // Create a non-mask intrinsic
1116         Out.push_back(std::make_unique<RVVIntrinsic>(
1117             Name, SuffixStr, MangledName, IRName, HasSideEffects,
1118             /*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL,
1119             HasNoMaskedOverloaded, HasAutoDef, ManualCodegen, Types.getValue(),
1120             IntrinsicTypes, PermuteOperands));
1121         if (HasMask) {
1122           // Create a mask intrinsic
1123           Optional<RVVTypes> MaskTypes =
1124               computeTypes(I, Log2LMUL, ProtoMaskSeq);
1125           Out.push_back(std::make_unique<RVVIntrinsic>(
1126               Name, SuffixStr, MangledName, IRNameMask, HasSideEffects,
1127               /*IsMask=*/true, HasMaskedOffOperand, HasVL,
1128               HasNoMaskedOverloaded, HasAutoDef, ManualCodegenMask,
1129               MaskTypes.getValue(), IntrinsicTypes, PermuteOperands));
1130         }
1131       } // end for Log2LMULList
1132     }   // end for TypeRange
1133   }
1134 }
1135 
1136 Optional<RVVTypes>
1137 RVVEmitter::computeTypes(BasicType BT, int Log2LMUL,
1138                          ArrayRef<std::string> PrototypeSeq) {
1139   RVVTypes Types;
1140   for (const std::string &Proto : PrototypeSeq) {
1141     auto T = computeType(BT, Log2LMUL, Proto);
1142     if (!T.hasValue())
1143       return llvm::None;
1144     // Record legal type index
1145     Types.push_back(T.getValue());
1146   }
1147   return Types;
1148 }
1149 
1150 Optional<RVVTypePtr> RVVEmitter::computeType(BasicType BT, int Log2LMUL,
1151                                              StringRef Proto) {
1152   std::string Idx = Twine(Twine(BT) + Twine(Log2LMUL) + Proto).str();
1153   // Search first
1154   auto It = LegalTypes.find(Idx);
1155   if (It != LegalTypes.end())
1156     return &(It->second);
1157   if (IllegalTypes.count(Idx))
1158     return llvm::None;
1159   // Compute type and record the result.
1160   RVVType T(BT, Log2LMUL, Proto);
1161   if (T.isValid()) {
1162     // Record legal type index and value.
1163     LegalTypes.insert({Idx, T});
1164     return &(LegalTypes[Idx]);
1165   }
1166   // Record illegal type index.
1167   IllegalTypes.insert(Idx);
1168   return llvm::None;
1169 }
1170 
1171 void RVVEmitter::emitArchMacroAndBody(
1172     std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &OS,
1173     std::function<void(raw_ostream &, const RVVIntrinsic &)> PrintBody) {
1174   uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions();
1175   bool NeedEndif = emitExtDefStr(PrevExt, OS);
1176   for (auto &Def : Defs) {
1177     uint8_t CurExt = Def->getRISCVExtensions();
1178     if (CurExt != PrevExt) {
1179       if (NeedEndif)
1180         OS << "#endif\n\n";
1181       NeedEndif = emitExtDefStr(CurExt, OS);
1182       PrevExt = CurExt;
1183     }
1184     if (Def->hasAutoDef())
1185       PrintBody(OS, *Def);
1186   }
1187   if (NeedEndif)
1188     OS << "#endif\n\n";
1189 }
1190 
1191 bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) {
1192   if (Extents == RISCVExtension::Basic)
1193     return false;
1194   OS << "#if ";
1195   ListSeparator LS(" && ");
1196   if (Extents & RISCVExtension::F)
1197     OS << LS << "defined(__riscv_f)";
1198   if (Extents & RISCVExtension::D)
1199     OS << LS << "defined(__riscv_d)";
1200   if (Extents & RISCVExtension::Zfh)
1201     OS << LS << "defined(__riscv_zfh)";
1202   OS << "\n";
1203   return true;
1204 }
1205 
1206 namespace clang {
1207 void EmitRVVHeader(RecordKeeper &Records, raw_ostream &OS) {
1208   RVVEmitter(Records).createHeader(OS);
1209 }
1210 
1211 void EmitRVVBuiltins(RecordKeeper &Records, raw_ostream &OS) {
1212   RVVEmitter(Records).createBuiltins(OS);
1213 }
1214 
1215 void EmitRVVBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
1216   RVVEmitter(Records).createCodeGen(OS);
1217 }
1218 
1219 } // End namespace clang
1220