xref: /freebsd/contrib/llvm-project/clang/utils/TableGen/SveEmitter.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1 //===- SveEmitter.cpp - Generate arm_sve.h for use with clang -*- C++ -*-===//
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 arm_sve.h, which includes
10 // a declaration and definition of each function specified by the ARM C/C++
11 // Language Extensions (ACLE).
12 //
13 // For details, visit:
14 //  https://developer.arm.com/architectures/system-architectures/software-standards/acle
15 //
16 // Each SVE instruction is implemented in terms of 1 or more functions which
17 // are suffixed with the element type of the input vectors.  Functions may be
18 // implemented in terms of generic vector operations such as +, *, -, etc. or
19 // by calling a __builtin_-prefixed function which will be handled by clang's
20 // CodeGen library.
21 //
22 // See also the documentation in include/clang/Basic/arm_sve.td.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 #include "llvm/ADT/ArrayRef.h"
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/ADT/StringMap.h"
30 #include "llvm/TableGen/Error.h"
31 #include "llvm/TableGen/Record.h"
32 #include <array>
33 #include <cctype>
34 #include <set>
35 #include <sstream>
36 #include <string>
37 #include <tuple>
38 
39 using namespace llvm;
40 
41 enum ClassKind {
42   ClassNone,
43   ClassS,     // signed/unsigned, e.g., "_s8", "_u8" suffix
44   ClassG,     // Overloaded name without type suffix
45 };
46 
47 enum class ACLEKind { SVE, SME };
48 
49 using TypeSpec = std::string;
50 
51 namespace {
52 
53 class ImmCheck {
54   unsigned Arg;
55   unsigned Kind;
56   unsigned ElementSizeInBits;
57 
58 public:
59   ImmCheck(unsigned Arg, unsigned Kind, unsigned ElementSizeInBits = 0)
60       : Arg(Arg), Kind(Kind), ElementSizeInBits(ElementSizeInBits) {}
61   ImmCheck(const ImmCheck &Other) = default;
62   ~ImmCheck() = default;
63 
64   unsigned getArg() const { return Arg; }
65   unsigned getKind() const { return Kind; }
66   unsigned getElementSizeInBits() const { return ElementSizeInBits; }
67 };
68 
69 class SVEType {
70   bool Float, Signed, Immediate, Void, Constant, Pointer, BFloat;
71   bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp,
72       Svcount;
73   unsigned Bitwidth, ElementBitwidth, NumVectors;
74 
75 public:
76   SVEType() : SVEType("", 'v') {}
77 
78   SVEType(StringRef TS, char CharMod, unsigned NumVectors = 1)
79       : Float(false), Signed(true), Immediate(false), Void(false),
80         Constant(false), Pointer(false), BFloat(false), DefaultType(false),
81         IsScalable(true), Predicate(false), PredicatePattern(false),
82         PrefetchOp(false), Svcount(false), Bitwidth(128), ElementBitwidth(~0U),
83         NumVectors(NumVectors) {
84     if (!TS.empty())
85       applyTypespec(TS);
86     applyModifier(CharMod);
87   }
88 
89   SVEType(const SVEType &Base, unsigned NumV) : SVEType(Base) {
90     NumVectors = NumV;
91   }
92 
93   bool isPointer() const { return Pointer; }
94   bool isVoidPointer() const { return Pointer && Void; }
95   bool isSigned() const { return Signed; }
96   bool isImmediate() const { return Immediate; }
97   bool isScalar() const { return NumVectors == 0; }
98   bool isVector() const { return NumVectors > 0; }
99   bool isScalableVector() const { return isVector() && IsScalable; }
100   bool isFixedLengthVector() const { return isVector() && !IsScalable; }
101   bool isChar() const { return ElementBitwidth == 8; }
102   bool isVoid() const { return Void & !Pointer; }
103   bool isDefault() const { return DefaultType; }
104   bool isFloat() const { return Float && !BFloat; }
105   bool isBFloat() const { return BFloat && !Float; }
106   bool isFloatingPoint() const { return Float || BFloat; }
107   bool isInteger() const {
108     return !isFloatingPoint() && !Predicate && !Svcount;
109   }
110   bool isScalarPredicate() const {
111     return !isFloatingPoint() && Predicate && NumVectors == 0;
112   }
113   bool isPredicateVector() const { return Predicate; }
114   bool isPredicatePattern() const { return PredicatePattern; }
115   bool isPrefetchOp() const { return PrefetchOp; }
116   bool isSvcount() const { return Svcount; }
117   bool isConstant() const { return Constant; }
118   unsigned getElementSizeInBits() const { return ElementBitwidth; }
119   unsigned getNumVectors() const { return NumVectors; }
120 
121   unsigned getNumElements() const {
122     assert(ElementBitwidth != ~0U);
123     return Bitwidth / ElementBitwidth;
124   }
125   unsigned getSizeInBits() const {
126     return Bitwidth;
127   }
128 
129   /// Return the string representation of a type, which is an encoded
130   /// string for passing to the BUILTIN() macro in Builtins.def.
131   std::string builtin_str() const;
132 
133   /// Return the C/C++ string representation of a type for use in the
134   /// arm_sve.h header file.
135   std::string str() const;
136 
137 private:
138   /// Creates the type based on the typespec string in TS.
139   void applyTypespec(StringRef TS);
140 
141   /// Applies a prototype modifier to the type.
142   void applyModifier(char Mod);
143 };
144 
145 class SVEEmitter;
146 
147 /// The main grunt class. This represents an instantiation of an intrinsic with
148 /// a particular typespec and prototype.
149 class Intrinsic {
150   /// The unmangled name.
151   std::string Name;
152 
153   /// The name of the corresponding LLVM IR intrinsic.
154   std::string LLVMName;
155 
156   /// Intrinsic prototype.
157   std::string Proto;
158 
159   /// The base type spec for this intrinsic.
160   TypeSpec BaseTypeSpec;
161 
162   /// The base class kind. Most intrinsics use ClassS, which has full type
163   /// info for integers (_s32/_u32), or ClassG which is used for overloaded
164   /// intrinsics.
165   ClassKind Class;
166 
167   /// The architectural #ifdef guard.
168   std::string Guard;
169 
170   // The merge suffix such as _m, _x or _z.
171   std::string MergeSuffix;
172 
173   /// The types of return value [0] and parameters [1..].
174   std::vector<SVEType> Types;
175 
176   /// The "base type", which is VarType('d', BaseTypeSpec).
177   SVEType BaseType;
178 
179   uint64_t Flags;
180 
181   SmallVector<ImmCheck, 2> ImmChecks;
182 
183 public:
184   Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
185             StringRef MergeSuffix, uint64_t MemoryElementTy, StringRef LLVMName,
186             uint64_t Flags, ArrayRef<ImmCheck> ImmChecks, TypeSpec BT,
187             ClassKind Class, SVEEmitter &Emitter, StringRef Guard);
188 
189   ~Intrinsic()=default;
190 
191   std::string getName() const { return Name; }
192   std::string getLLVMName() const { return LLVMName; }
193   std::string getProto() const { return Proto; }
194   TypeSpec getBaseTypeSpec() const { return BaseTypeSpec; }
195   SVEType getBaseType() const { return BaseType; }
196 
197   StringRef getGuard() const { return Guard; }
198   ClassKind getClassKind() const { return Class; }
199 
200   SVEType getReturnType() const { return Types[0]; }
201   ArrayRef<SVEType> getTypes() const { return Types; }
202   SVEType getParamType(unsigned I) const { return Types[I + 1]; }
203   unsigned getNumParams() const {
204     return Proto.size() - (2 * llvm::count(Proto, '.')) - 1;
205   }
206 
207   uint64_t getFlags() const { return Flags; }
208   bool isFlagSet(uint64_t Flag) const { return Flags & Flag;}
209 
210   ArrayRef<ImmCheck> getImmChecks() const { return ImmChecks; }
211 
212   /// Return the type string for a BUILTIN() macro in Builtins.def.
213   std::string getBuiltinTypeStr();
214 
215   /// Return the name, mangled with type information. The name is mangled for
216   /// ClassS, so will add type suffixes such as _u32/_s32.
217   std::string getMangledName() const { return mangleName(ClassS); }
218 
219   /// As above, but mangles the LLVM name instead.
220   std::string getMangledLLVMName() const { return mangleLLVMName(); }
221 
222   /// Returns true if the intrinsic is overloaded, in that it should also generate
223   /// a short form without the type-specifiers, e.g. 'svld1(..)' instead of
224   /// 'svld1_u32(..)'.
225   static bool isOverloadedIntrinsic(StringRef Name) {
226     auto BrOpen = Name.find('[');
227     auto BrClose = Name.find(']');
228     return BrOpen != std::string::npos && BrClose != std::string::npos;
229   }
230 
231   /// Return true if the intrinsic takes a splat operand.
232   bool hasSplat() const {
233     // These prototype modifiers are described in arm_sve.td.
234     return Proto.find_first_of("ajfrKLR@") != std::string::npos;
235   }
236 
237   /// Return the parameter index of the splat operand.
238   unsigned getSplatIdx() const {
239     unsigned I = 1, Param = 0;
240     for (; I < Proto.size(); ++I, ++Param) {
241       if (Proto[I] == 'a' || Proto[I] == 'j' || Proto[I] == 'f' ||
242           Proto[I] == 'r' || Proto[I] == 'K' || Proto[I] == 'L' ||
243           Proto[I] == 'R' || Proto[I] == '@')
244         break;
245 
246       // Multivector modifier can be skipped
247       if (Proto[I] == '.')
248         I += 2;
249     }
250     assert(I != Proto.size() && "Prototype has no splat operand");
251     return Param;
252   }
253 
254   /// Emits the intrinsic declaration to the ostream.
255   void emitIntrinsic(raw_ostream &OS, SVEEmitter &Emitter, ACLEKind Kind) const;
256 
257 private:
258   std::string getMergeSuffix() const { return MergeSuffix; }
259   std::string mangleName(ClassKind LocalCK) const;
260   std::string mangleLLVMName() const;
261   std::string replaceTemplatedArgs(std::string Name, TypeSpec TS,
262                                    std::string Proto) const;
263 };
264 
265 class SVEEmitter {
266 private:
267   // The reinterpret builtins are generated separately because they
268   // need the cross product of all types (121 functions in total),
269   // which is inconvenient to specify in the arm_sve.td file or
270   // generate in CGBuiltin.cpp.
271   struct ReinterpretTypeInfo {
272     SVEType BaseType;
273     const char *Suffix;
274   };
275 
276   static const std::array<ReinterpretTypeInfo, 12> Reinterprets;
277 
278   RecordKeeper &Records;
279   llvm::StringMap<uint64_t> EltTypes;
280   llvm::StringMap<uint64_t> MemEltTypes;
281   llvm::StringMap<uint64_t> FlagTypes;
282   llvm::StringMap<uint64_t> MergeTypes;
283   llvm::StringMap<uint64_t> ImmCheckTypes;
284 
285 public:
286   SVEEmitter(RecordKeeper &R) : Records(R) {
287     for (auto *RV : Records.getAllDerivedDefinitions("EltType"))
288       EltTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
289     for (auto *RV : Records.getAllDerivedDefinitions("MemEltType"))
290       MemEltTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
291     for (auto *RV : Records.getAllDerivedDefinitions("FlagType"))
292       FlagTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
293     for (auto *RV : Records.getAllDerivedDefinitions("MergeType"))
294       MergeTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
295     for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType"))
296       ImmCheckTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
297   }
298 
299   /// Returns the enum value for the immcheck type
300   unsigned getEnumValueForImmCheck(StringRef C) const {
301     auto It = ImmCheckTypes.find(C);
302     if (It != ImmCheckTypes.end())
303       return It->getValue();
304     llvm_unreachable("Unsupported imm check");
305   }
306 
307   /// Returns the enum value for the flag type
308   uint64_t getEnumValueForFlag(StringRef C) const {
309     auto Res = FlagTypes.find(C);
310     if (Res != FlagTypes.end())
311       return Res->getValue();
312     llvm_unreachable("Unsupported flag");
313   }
314 
315   // Returns the SVETypeFlags for a given value and mask.
316   uint64_t encodeFlag(uint64_t V, StringRef MaskName) const {
317     auto It = FlagTypes.find(MaskName);
318     if (It != FlagTypes.end()) {
319       uint64_t Mask = It->getValue();
320       unsigned Shift = llvm::countr_zero(Mask);
321       assert(Shift < 64 && "Mask value produced an invalid shift value");
322       return (V << Shift) & Mask;
323     }
324     llvm_unreachable("Unsupported flag");
325   }
326 
327   // Returns the SVETypeFlags for the given element type.
328   uint64_t encodeEltType(StringRef EltName) {
329     auto It = EltTypes.find(EltName);
330     if (It != EltTypes.end())
331       return encodeFlag(It->getValue(), "EltTypeMask");
332     llvm_unreachable("Unsupported EltType");
333   }
334 
335   // Returns the SVETypeFlags for the given memory element type.
336   uint64_t encodeMemoryElementType(uint64_t MT) {
337     return encodeFlag(MT, "MemEltTypeMask");
338   }
339 
340   // Returns the SVETypeFlags for the given merge type.
341   uint64_t encodeMergeType(uint64_t MT) {
342     return encodeFlag(MT, "MergeTypeMask");
343   }
344 
345   // Returns the SVETypeFlags for the given splat operand.
346   unsigned encodeSplatOperand(unsigned SplatIdx) {
347     assert(SplatIdx < 7 && "SplatIdx out of encodable range");
348     return encodeFlag(SplatIdx + 1, "SplatOperandMask");
349   }
350 
351   // Returns the SVETypeFlags value for the given SVEType.
352   uint64_t encodeTypeFlags(const SVEType &T);
353 
354   /// Emit arm_sve.h.
355   void createHeader(raw_ostream &o);
356 
357   // Emits core intrinsics in both arm_sme.h and arm_sve.h
358   void createCoreHeaderIntrinsics(raw_ostream &o, SVEEmitter &Emitter,
359                                   ACLEKind Kind);
360 
361   /// Emit all the __builtin prototypes and code needed by Sema.
362   void createBuiltins(raw_ostream &o);
363 
364   /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
365   void createCodeGenMap(raw_ostream &o);
366 
367   /// Emit all the range checks for the immediates.
368   void createRangeChecks(raw_ostream &o);
369 
370   /// Create the SVETypeFlags used in CGBuiltins
371   void createTypeFlags(raw_ostream &o);
372 
373   /// Emit arm_sme.h.
374   void createSMEHeader(raw_ostream &o);
375 
376   /// Emit all the SME __builtin prototypes and code needed by Sema.
377   void createSMEBuiltins(raw_ostream &o);
378 
379   /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
380   void createSMECodeGenMap(raw_ostream &o);
381 
382   /// Create a table for a builtin's requirement for PSTATE.SM.
383   void createStreamingAttrs(raw_ostream &o, ACLEKind Kind);
384 
385   /// Emit all the range checks for the immediates.
386   void createSMERangeChecks(raw_ostream &o);
387 
388   /// Create a table for a builtin's requirement for PSTATE.ZA.
389   void createBuiltinZAState(raw_ostream &OS);
390 
391   /// Create intrinsic and add it to \p Out
392   void createIntrinsic(Record *R,
393                        SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out);
394 };
395 
396 const std::array<SVEEmitter::ReinterpretTypeInfo, 12> SVEEmitter::Reinterprets =
397     {{{SVEType("c", 'd'), "s8"},
398       {SVEType("Uc", 'd'), "u8"},
399       {SVEType("s", 'd'), "s16"},
400       {SVEType("Us", 'd'), "u16"},
401       {SVEType("i", 'd'), "s32"},
402       {SVEType("Ui", 'd'), "u32"},
403       {SVEType("l", 'd'), "s64"},
404       {SVEType("Ul", 'd'), "u64"},
405       {SVEType("h", 'd'), "f16"},
406       {SVEType("b", 'd'), "bf16"},
407       {SVEType("f", 'd'), "f32"},
408       {SVEType("d", 'd'), "f64"}}};
409 
410 } // end anonymous namespace
411 
412 
413 //===----------------------------------------------------------------------===//
414 // Type implementation
415 //===----------------------------------------------------------------------===//
416 
417 std::string SVEType::builtin_str() const {
418   std::string S;
419   if (isVoid())
420     return "v";
421 
422   if (isScalarPredicate())
423     return "b";
424 
425   if (isSvcount())
426     return "Qa";
427 
428   if (isVoidPointer())
429     S += "v";
430   else if (!isFloatingPoint())
431     switch (ElementBitwidth) {
432     case 1: S += "b"; break;
433     case 8: S += "c"; break;
434     case 16: S += "s"; break;
435     case 32: S += "i"; break;
436     case 64: S += "Wi"; break;
437     case 128: S += "LLLi"; break;
438     default: llvm_unreachable("Unhandled case!");
439     }
440   else if (isFloat())
441     switch (ElementBitwidth) {
442     case 16: S += "h"; break;
443     case 32: S += "f"; break;
444     case 64: S += "d"; break;
445     default: llvm_unreachable("Unhandled case!");
446     }
447   else if (isBFloat()) {
448     assert(ElementBitwidth == 16 && "Not a valid BFloat.");
449     S += "y";
450   }
451 
452   if (!isFloatingPoint()) {
453     if ((isChar() || isPointer()) && !isVoidPointer()) {
454       // Make chars and typed pointers explicitly signed.
455       if (Signed)
456         S = "S" + S;
457       else if (!Signed)
458         S = "U" + S;
459     } else if (!isVoidPointer() && !Signed) {
460       S = "U" + S;
461     }
462   }
463 
464   // Constant indices are "int", but have the "constant expression" modifier.
465   if (isImmediate()) {
466     assert(!isFloat() && "fp immediates are not supported");
467     S = "I" + S;
468   }
469 
470   if (isScalar()) {
471     if (Constant) S += "C";
472     if (Pointer) S += "*";
473     return S;
474   }
475 
476   if (isFixedLengthVector())
477     return "V" + utostr(getNumElements() * NumVectors) + S;
478   return "q" + utostr(getNumElements() * NumVectors) + S;
479 }
480 
481 std::string SVEType::str() const {
482   if (isPredicatePattern())
483     return "enum svpattern";
484 
485   if (isPrefetchOp())
486     return "enum svprfop";
487 
488   std::string S;
489   if (Void)
490     S += "void";
491   else {
492     if (isScalableVector() || isSvcount())
493       S += "sv";
494     if (!Signed && !isFloatingPoint())
495       S += "u";
496 
497     if (Float)
498       S += "float";
499     else if (isSvcount())
500       S += "count";
501     else if (isScalarPredicate() || isPredicateVector())
502       S += "bool";
503     else if (isBFloat())
504       S += "bfloat";
505     else
506       S += "int";
507 
508     if (!isScalarPredicate() && !isPredicateVector() && !isSvcount())
509       S += utostr(ElementBitwidth);
510     if (isFixedLengthVector())
511       S += "x" + utostr(getNumElements());
512     if (NumVectors > 1)
513       S += "x" + utostr(NumVectors);
514     if (!isScalarPredicate())
515       S += "_t";
516   }
517 
518   if (Constant)
519     S += " const";
520   if (Pointer)
521     S += " *";
522 
523   return S;
524 }
525 
526 void SVEType::applyTypespec(StringRef TS) {
527   for (char I : TS) {
528     switch (I) {
529     case 'Q':
530       Svcount = true;
531       break;
532     case 'P':
533       Predicate = true;
534       break;
535     case 'U':
536       Signed = false;
537       break;
538     case 'c':
539       ElementBitwidth = 8;
540       break;
541     case 's':
542       ElementBitwidth = 16;
543       break;
544     case 'i':
545       ElementBitwidth = 32;
546       break;
547     case 'l':
548       ElementBitwidth = 64;
549       break;
550     case 'q':
551       ElementBitwidth = 128;
552       break;
553     case 'h':
554       Float = true;
555       ElementBitwidth = 16;
556       break;
557     case 'f':
558       Float = true;
559       ElementBitwidth = 32;
560       break;
561     case 'd':
562       Float = true;
563       ElementBitwidth = 64;
564       break;
565     case 'b':
566       BFloat = true;
567       Float = false;
568       ElementBitwidth = 16;
569       break;
570     default:
571       llvm_unreachable("Unhandled type code!");
572     }
573   }
574   assert(ElementBitwidth != ~0U && "Bad element bitwidth!");
575 }
576 
577 void SVEType::applyModifier(char Mod) {
578   switch (Mod) {
579   case 'v':
580     Void = true;
581     break;
582   case 'd':
583     DefaultType = true;
584     break;
585   case 'c':
586     Constant = true;
587     [[fallthrough]];
588   case 'p':
589     Pointer = true;
590     Bitwidth = ElementBitwidth;
591     NumVectors = 0;
592     break;
593   case 'e':
594     Signed = false;
595     ElementBitwidth /= 2;
596     break;
597   case 'h':
598     ElementBitwidth /= 2;
599     break;
600   case 'q':
601     ElementBitwidth /= 4;
602     break;
603   case 'b':
604     Signed = false;
605     Float = false;
606     BFloat = false;
607     ElementBitwidth /= 4;
608     break;
609   case 'o':
610     ElementBitwidth *= 4;
611     break;
612   case 'P':
613     Signed = true;
614     Float = false;
615     BFloat = false;
616     Predicate = true;
617     Svcount = false;
618     Bitwidth = 16;
619     ElementBitwidth = 1;
620     break;
621   case '{':
622     IsScalable = false;
623     Bitwidth = 128;
624     NumVectors = 1;
625     break;
626   case 's':
627   case 'a':
628     Bitwidth = ElementBitwidth;
629     NumVectors = 0;
630     break;
631   case 'R':
632     ElementBitwidth /= 2;
633     NumVectors = 0;
634     break;
635   case 'r':
636     ElementBitwidth /= 4;
637     NumVectors = 0;
638     break;
639   case '@':
640     Signed = false;
641     Float = false;
642     BFloat = false;
643     ElementBitwidth /= 4;
644     NumVectors = 0;
645     break;
646   case 'K':
647     Signed = true;
648     Float = false;
649     BFloat = false;
650     Bitwidth = ElementBitwidth;
651     NumVectors = 0;
652     break;
653   case 'L':
654     Signed = false;
655     Float = false;
656     BFloat = false;
657     Bitwidth = ElementBitwidth;
658     NumVectors = 0;
659     break;
660   case 'u':
661     Predicate = false;
662     Svcount = false;
663     Signed = false;
664     Float = false;
665     BFloat = false;
666     break;
667   case 'x':
668     Predicate = false;
669     Svcount = false;
670     Signed = true;
671     Float = false;
672     BFloat = false;
673     break;
674   case 'i':
675     Predicate = false;
676     Svcount = false;
677     Float = false;
678     BFloat = false;
679     ElementBitwidth = Bitwidth = 64;
680     NumVectors = 0;
681     Signed = false;
682     Immediate = true;
683     break;
684   case 'I':
685     Predicate = false;
686     Svcount = false;
687     Float = false;
688     BFloat = false;
689     ElementBitwidth = Bitwidth = 32;
690     NumVectors = 0;
691     Signed = true;
692     Immediate = true;
693     PredicatePattern = true;
694     break;
695   case 'J':
696     Predicate = false;
697     Svcount = false;
698     Float = false;
699     BFloat = false;
700     ElementBitwidth = Bitwidth = 32;
701     NumVectors = 0;
702     Signed = true;
703     Immediate = true;
704     PrefetchOp = true;
705     break;
706   case 'k':
707     Predicate = false;
708     Svcount = false;
709     Signed = true;
710     Float = false;
711     BFloat = false;
712     ElementBitwidth = Bitwidth = 32;
713     NumVectors = 0;
714     break;
715   case 'l':
716     Predicate = false;
717     Svcount = false;
718     Signed = true;
719     Float = false;
720     BFloat = false;
721     ElementBitwidth = Bitwidth = 64;
722     NumVectors = 0;
723     break;
724   case 'm':
725     Predicate = false;
726     Svcount = false;
727     Signed = false;
728     Float = false;
729     BFloat = false;
730     ElementBitwidth = Bitwidth = 32;
731     NumVectors = 0;
732     break;
733   case 'n':
734     Predicate = false;
735     Svcount = false;
736     Signed = false;
737     Float = false;
738     BFloat = false;
739     ElementBitwidth = Bitwidth = 64;
740     NumVectors = 0;
741     break;
742   case 'w':
743     ElementBitwidth = 64;
744     break;
745   case 'j':
746     ElementBitwidth = Bitwidth = 64;
747     NumVectors = 0;
748     break;
749   case 'f':
750     Signed = false;
751     ElementBitwidth = Bitwidth = 64;
752     NumVectors = 0;
753     break;
754   case 'g':
755     Signed = false;
756     Float = false;
757     BFloat = false;
758     ElementBitwidth = 64;
759     break;
760   case '[':
761     Signed = false;
762     Float = false;
763     BFloat = false;
764     ElementBitwidth = 8;
765     break;
766   case 't':
767     Signed = true;
768     Float = false;
769     BFloat = false;
770     ElementBitwidth = 32;
771     break;
772   case 'z':
773     Signed = false;
774     Float = false;
775     BFloat = false;
776     ElementBitwidth = 32;
777     break;
778   case 'O':
779     Predicate = false;
780     Svcount = false;
781     Float = true;
782     ElementBitwidth = 16;
783     break;
784   case 'M':
785     Predicate = false;
786     Svcount = false;
787     Float = true;
788     BFloat = false;
789     ElementBitwidth = 32;
790     break;
791   case 'N':
792     Predicate = false;
793     Svcount = false;
794     Float = true;
795     ElementBitwidth = 64;
796     break;
797   case 'Q':
798     Constant = true;
799     Pointer = true;
800     Void = true;
801     NumVectors = 0;
802     break;
803   case 'S':
804     Constant = true;
805     Pointer = true;
806     ElementBitwidth = Bitwidth = 8;
807     NumVectors = 0;
808     Signed = true;
809     break;
810   case 'W':
811     Constant = true;
812     Pointer = true;
813     ElementBitwidth = Bitwidth = 8;
814     NumVectors = 0;
815     Signed = false;
816     break;
817   case 'T':
818     Constant = true;
819     Pointer = true;
820     ElementBitwidth = Bitwidth = 16;
821     NumVectors = 0;
822     Signed = true;
823     break;
824   case 'X':
825     Constant = true;
826     Pointer = true;
827     ElementBitwidth = Bitwidth = 16;
828     NumVectors = 0;
829     Signed = false;
830     break;
831   case 'Y':
832     Constant = true;
833     Pointer = true;
834     ElementBitwidth = Bitwidth = 32;
835     NumVectors = 0;
836     Signed = false;
837     break;
838   case 'U':
839     Constant = true;
840     Pointer = true;
841     ElementBitwidth = Bitwidth = 32;
842     NumVectors = 0;
843     Signed = true;
844     break;
845   case '%':
846     Pointer = true;
847     Void = true;
848     NumVectors = 0;
849     break;
850   case 'A':
851     Pointer = true;
852     ElementBitwidth = Bitwidth = 8;
853     NumVectors = 0;
854     Signed = true;
855     break;
856   case 'B':
857     Pointer = true;
858     ElementBitwidth = Bitwidth = 16;
859     NumVectors = 0;
860     Signed = true;
861     break;
862   case 'C':
863     Pointer = true;
864     ElementBitwidth = Bitwidth = 32;
865     NumVectors = 0;
866     Signed = true;
867     break;
868   case 'D':
869     Pointer = true;
870     ElementBitwidth = Bitwidth = 64;
871     NumVectors = 0;
872     Signed = true;
873     break;
874   case 'E':
875     Pointer = true;
876     ElementBitwidth = Bitwidth = 8;
877     NumVectors = 0;
878     Signed = false;
879     break;
880   case 'F':
881     Pointer = true;
882     ElementBitwidth = Bitwidth = 16;
883     NumVectors = 0;
884     Signed = false;
885     break;
886   case 'G':
887     Pointer = true;
888     ElementBitwidth = Bitwidth = 32;
889     NumVectors = 0;
890     Signed = false;
891     break;
892   case '$':
893     Predicate = false;
894     Svcount = false;
895     Float = false;
896     BFloat = true;
897     ElementBitwidth = 16;
898     break;
899   case '}':
900     Predicate = false;
901     Signed = true;
902     Svcount = true;
903     NumVectors = 0;
904     Float = false;
905     BFloat = false;
906     break;
907   case '.':
908     llvm_unreachable(". is never a type in itself");
909     break;
910   default:
911     llvm_unreachable("Unhandled character!");
912   }
913 }
914 
915 /// Returns the modifier and number of vectors for the given operand \p Op.
916 std::pair<char, unsigned> getProtoModifier(StringRef Proto, unsigned Op) {
917   for (unsigned P = 0; !Proto.empty(); ++P) {
918     unsigned NumVectors = 1;
919     unsigned CharsToSkip = 1;
920     char Mod = Proto[0];
921     if (Mod == '2' || Mod == '3' || Mod == '4') {
922       NumVectors = Mod - '0';
923       Mod = 'd';
924       if (Proto.size() > 1 && Proto[1] == '.') {
925         Mod = Proto[2];
926         CharsToSkip = 3;
927       }
928     }
929 
930     if (P == Op)
931       return {Mod, NumVectors};
932 
933     Proto = Proto.drop_front(CharsToSkip);
934   }
935   llvm_unreachable("Unexpected Op");
936 }
937 
938 //===----------------------------------------------------------------------===//
939 // Intrinsic implementation
940 //===----------------------------------------------------------------------===//
941 
942 Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
943                      StringRef MergeSuffix, uint64_t MemoryElementTy,
944                      StringRef LLVMName, uint64_t Flags,
945                      ArrayRef<ImmCheck> Checks, TypeSpec BT, ClassKind Class,
946                      SVEEmitter &Emitter, StringRef Guard)
947     : Name(Name.str()), LLVMName(LLVMName), Proto(Proto.str()),
948       BaseTypeSpec(BT), Class(Class), Guard(Guard.str()),
949       MergeSuffix(MergeSuffix.str()), BaseType(BT, 'd'), Flags(Flags),
950       ImmChecks(Checks.begin(), Checks.end()) {
951   // Types[0] is the return value.
952   for (unsigned I = 0; I < (getNumParams() + 1); ++I) {
953     char Mod;
954     unsigned NumVectors;
955     std::tie(Mod, NumVectors) = getProtoModifier(Proto, I);
956     SVEType T(BaseTypeSpec, Mod, NumVectors);
957     Types.push_back(T);
958 
959     // Add range checks for immediates
960     if (I > 0) {
961       if (T.isPredicatePattern())
962         ImmChecks.emplace_back(
963             I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_31"));
964       else if (T.isPrefetchOp())
965         ImmChecks.emplace_back(
966             I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_13"));
967     }
968   }
969 
970   // Set flags based on properties
971   this->Flags |= Emitter.encodeTypeFlags(BaseType);
972   this->Flags |= Emitter.encodeMemoryElementType(MemoryElementTy);
973   this->Flags |= Emitter.encodeMergeType(MergeTy);
974   if (hasSplat())
975     this->Flags |= Emitter.encodeSplatOperand(getSplatIdx());
976 }
977 
978 std::string Intrinsic::getBuiltinTypeStr() {
979   std::string S = getReturnType().builtin_str();
980   for (unsigned I = 0; I < getNumParams(); ++I)
981     S += getParamType(I).builtin_str();
982 
983   return S;
984 }
985 
986 std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
987                                             std::string Proto) const {
988   std::string Ret = Name;
989   while (Ret.find('{') != std::string::npos) {
990     size_t Pos = Ret.find('{');
991     size_t End = Ret.find('}');
992     unsigned NumChars = End - Pos + 1;
993     assert(NumChars == 3 && "Unexpected template argument");
994 
995     SVEType T;
996     char C = Ret[Pos+1];
997     switch(C) {
998     default:
999       llvm_unreachable("Unknown predication specifier");
1000     case 'd':
1001       T = SVEType(TS, 'd');
1002       break;
1003     case '0':
1004     case '1':
1005     case '2':
1006     case '3':
1007       T = SVEType(TS, Proto[C - '0']);
1008       break;
1009     }
1010 
1011     // Replace templated arg with the right suffix (e.g. u32)
1012     std::string TypeCode;
1013     if (T.isInteger())
1014       TypeCode = T.isSigned() ? 's' : 'u';
1015     else if (T.isSvcount())
1016       TypeCode = 'c';
1017     else if (T.isPredicateVector())
1018       TypeCode = 'b';
1019     else if (T.isBFloat())
1020       TypeCode = "bf";
1021     else
1022       TypeCode = 'f';
1023     Ret.replace(Pos, NumChars, TypeCode + utostr(T.getElementSizeInBits()));
1024   }
1025 
1026   return Ret;
1027 }
1028 
1029 std::string Intrinsic::mangleLLVMName() const {
1030   std::string S = getLLVMName();
1031 
1032   // Replace all {d} like expressions with e.g. 'u32'
1033   return replaceTemplatedArgs(S, getBaseTypeSpec(), getProto());
1034 }
1035 
1036 std::string Intrinsic::mangleName(ClassKind LocalCK) const {
1037   std::string S = getName();
1038 
1039   if (LocalCK == ClassG) {
1040     // Remove the square brackets and everything in between.
1041     while (S.find('[') != std::string::npos) {
1042       auto Start = S.find('[');
1043       auto End = S.find(']');
1044       S.erase(Start, (End-Start)+1);
1045     }
1046   } else {
1047     // Remove the square brackets.
1048     while (S.find('[') != std::string::npos) {
1049       auto BrPos = S.find('[');
1050       if (BrPos != std::string::npos)
1051         S.erase(BrPos, 1);
1052       BrPos = S.find(']');
1053       if (BrPos != std::string::npos)
1054         S.erase(BrPos, 1);
1055     }
1056   }
1057 
1058   // Replace all {d} like expressions with e.g. 'u32'
1059   return replaceTemplatedArgs(S, getBaseTypeSpec(), getProto()) +
1060          getMergeSuffix();
1061 }
1062 
1063 void Intrinsic::emitIntrinsic(raw_ostream &OS, SVEEmitter &Emitter,
1064                               ACLEKind Kind) const {
1065   bool IsOverloaded = getClassKind() == ClassG && getProto().size() > 1;
1066 
1067   std::string FullName = mangleName(ClassS);
1068   std::string ProtoName = mangleName(getClassKind());
1069   std::string SMEAttrs = "";
1070 
1071   if (Flags & Emitter.getEnumValueForFlag("IsStreaming"))
1072     SMEAttrs += ", arm_streaming";
1073   if (Flags & Emitter.getEnumValueForFlag("IsStreamingCompatible"))
1074     SMEAttrs += ", arm_streaming_compatible";
1075   if (Flags & Emitter.getEnumValueForFlag("IsSharedZA"))
1076     SMEAttrs += ", arm_shared_za";
1077   if (Flags & Emitter.getEnumValueForFlag("IsPreservesZA"))
1078     SMEAttrs += ", arm_preserves_za";
1079 
1080   OS << (IsOverloaded ? "__aio " : "__ai ")
1081      << "__attribute__((__clang_arm_builtin_alias(";
1082 
1083   switch (Kind) {
1084   case ACLEKind::SME:
1085     OS << "__builtin_sme_" << FullName << ")";
1086     break;
1087   case ACLEKind::SVE:
1088     OS << "__builtin_sve_" << FullName << ")";
1089     break;
1090   }
1091 
1092   if (!SMEAttrs.empty())
1093     OS << SMEAttrs;
1094   OS << "))\n";
1095 
1096   OS << getTypes()[0].str() << " " << ProtoName << "(";
1097   for (unsigned I = 0; I < getTypes().size() - 1; ++I) {
1098     if (I != 0)
1099       OS << ", ";
1100     OS << getTypes()[I + 1].str();
1101   }
1102   OS << ");\n";
1103 }
1104 
1105 //===----------------------------------------------------------------------===//
1106 // SVEEmitter implementation
1107 //===----------------------------------------------------------------------===//
1108 uint64_t SVEEmitter::encodeTypeFlags(const SVEType &T) {
1109   if (T.isFloat()) {
1110     switch (T.getElementSizeInBits()) {
1111     case 16:
1112       return encodeEltType("EltTyFloat16");
1113     case 32:
1114       return encodeEltType("EltTyFloat32");
1115     case 64:
1116       return encodeEltType("EltTyFloat64");
1117     default:
1118       llvm_unreachable("Unhandled float element bitwidth!");
1119     }
1120   }
1121 
1122   if (T.isBFloat()) {
1123     assert(T.getElementSizeInBits() == 16 && "Not a valid BFloat.");
1124     return encodeEltType("EltTyBFloat16");
1125   }
1126 
1127   if (T.isPredicateVector() || T.isSvcount()) {
1128     switch (T.getElementSizeInBits()) {
1129     case 8:
1130       return encodeEltType("EltTyBool8");
1131     case 16:
1132       return encodeEltType("EltTyBool16");
1133     case 32:
1134       return encodeEltType("EltTyBool32");
1135     case 64:
1136       return encodeEltType("EltTyBool64");
1137     default:
1138       llvm_unreachable("Unhandled predicate element bitwidth!");
1139     }
1140   }
1141 
1142   switch (T.getElementSizeInBits()) {
1143   case 8:
1144     return encodeEltType("EltTyInt8");
1145   case 16:
1146     return encodeEltType("EltTyInt16");
1147   case 32:
1148     return encodeEltType("EltTyInt32");
1149   case 64:
1150     return encodeEltType("EltTyInt64");
1151   case 128:
1152     return encodeEltType("EltTyInt128");
1153   default:
1154     llvm_unreachable("Unhandled integer element bitwidth!");
1155   }
1156 }
1157 
1158 void SVEEmitter::createIntrinsic(
1159     Record *R, SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out) {
1160   StringRef Name = R->getValueAsString("Name");
1161   StringRef Proto = R->getValueAsString("Prototype");
1162   StringRef Types = R->getValueAsString("Types");
1163   StringRef Guard = R->getValueAsString("TargetGuard");
1164   StringRef LLVMName = R->getValueAsString("LLVMIntrinsic");
1165   uint64_t Merge = R->getValueAsInt("Merge");
1166   StringRef MergeSuffix = R->getValueAsString("MergeSuffix");
1167   uint64_t MemEltType = R->getValueAsInt("MemEltType");
1168   std::vector<Record*> FlagsList = R->getValueAsListOfDefs("Flags");
1169   std::vector<Record*> ImmCheckList = R->getValueAsListOfDefs("ImmChecks");
1170 
1171   int64_t Flags = 0;
1172   for (auto FlagRec : FlagsList)
1173     Flags |= FlagRec->getValueAsInt("Value");
1174 
1175   // Create a dummy TypeSpec for non-overloaded builtins.
1176   if (Types.empty()) {
1177     assert((Flags & getEnumValueForFlag("IsOverloadNone")) &&
1178            "Expect TypeSpec for overloaded builtin!");
1179     Types = "i";
1180   }
1181 
1182   // Extract type specs from string
1183   SmallVector<TypeSpec, 8> TypeSpecs;
1184   TypeSpec Acc;
1185   for (char I : Types) {
1186     Acc.push_back(I);
1187     if (islower(I)) {
1188       TypeSpecs.push_back(TypeSpec(Acc));
1189       Acc.clear();
1190     }
1191   }
1192 
1193   // Remove duplicate type specs.
1194   llvm::sort(TypeSpecs);
1195   TypeSpecs.erase(std::unique(TypeSpecs.begin(), TypeSpecs.end()),
1196                   TypeSpecs.end());
1197 
1198   // Create an Intrinsic for each type spec.
1199   for (auto TS : TypeSpecs) {
1200     // Collate a list of range/option checks for the immediates.
1201     SmallVector<ImmCheck, 2> ImmChecks;
1202     for (auto *R : ImmCheckList) {
1203       int64_t Arg = R->getValueAsInt("Arg");
1204       int64_t EltSizeArg = R->getValueAsInt("EltSizeArg");
1205       int64_t Kind = R->getValueAsDef("Kind")->getValueAsInt("Value");
1206       assert(Arg >= 0 && Kind >= 0 && "Arg and Kind must be nonnegative");
1207 
1208       unsigned ElementSizeInBits = 0;
1209       char Mod;
1210       unsigned NumVectors;
1211       std::tie(Mod, NumVectors) = getProtoModifier(Proto, EltSizeArg + 1);
1212       if (EltSizeArg >= 0)
1213         ElementSizeInBits = SVEType(TS, Mod, NumVectors).getElementSizeInBits();
1214       ImmChecks.push_back(ImmCheck(Arg, Kind, ElementSizeInBits));
1215     }
1216 
1217     Out.push_back(std::make_unique<Intrinsic>(
1218         Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags, ImmChecks,
1219         TS, ClassS, *this, Guard));
1220 
1221     // Also generate the short-form (e.g. svadd_m) for the given type-spec.
1222     if (Intrinsic::isOverloadedIntrinsic(Name))
1223       Out.push_back(std::make_unique<Intrinsic>(
1224           Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags,
1225           ImmChecks, TS, ClassG, *this, Guard));
1226   }
1227 }
1228 
1229 void SVEEmitter::createCoreHeaderIntrinsics(raw_ostream &OS,
1230                                             SVEEmitter &Emitter,
1231                                             ACLEKind Kind) {
1232   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1233   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1234   for (auto *R : RV)
1235     createIntrinsic(R, Defs);
1236 
1237   // Sort intrinsics in header file by following order/priority:
1238   // - Architectural guard (i.e. does it require SVE2 or SVE2_AES)
1239   // - Class (is intrinsic overloaded or not)
1240   // - Intrinsic name
1241   std::stable_sort(Defs.begin(), Defs.end(),
1242                    [](const std::unique_ptr<Intrinsic> &A,
1243                       const std::unique_ptr<Intrinsic> &B) {
1244                      auto ToTuple = [](const std::unique_ptr<Intrinsic> &I) {
1245                        return std::make_tuple(I->getGuard(),
1246                                               (unsigned)I->getClassKind(),
1247                                               I->getName());
1248                      };
1249                      return ToTuple(A) < ToTuple(B);
1250                    });
1251 
1252   // Actually emit the intrinsic declarations.
1253   for (auto &I : Defs)
1254     I->emitIntrinsic(OS, Emitter, Kind);
1255 }
1256 
1257 void SVEEmitter::createHeader(raw_ostream &OS) {
1258   OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
1259         "-----------------------------------===\n"
1260         " *\n"
1261         " *\n"
1262         " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
1263         "Exceptions.\n"
1264         " * See https://llvm.org/LICENSE.txt for license information.\n"
1265         " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
1266         " *\n"
1267         " *===-----------------------------------------------------------------"
1268         "------===\n"
1269         " */\n\n";
1270 
1271   OS << "#ifndef __ARM_SVE_H\n";
1272   OS << "#define __ARM_SVE_H\n\n";
1273 
1274   OS << "#if !defined(__LITTLE_ENDIAN__)\n";
1275   OS << "#error \"Big endian is currently not supported for arm_sve.h\"\n";
1276   OS << "#endif\n";
1277 
1278   OS << "#include <stdint.h>\n\n";
1279   OS << "#ifdef  __cplusplus\n";
1280   OS << "extern \"C\" {\n";
1281   OS << "#else\n";
1282   OS << "#include <stdbool.h>\n";
1283   OS << "#endif\n\n";
1284 
1285   OS << "typedef __fp16 float16_t;\n";
1286   OS << "typedef float float32_t;\n";
1287   OS << "typedef double float64_t;\n";
1288 
1289   OS << "typedef __SVInt8_t svint8_t;\n";
1290   OS << "typedef __SVInt16_t svint16_t;\n";
1291   OS << "typedef __SVInt32_t svint32_t;\n";
1292   OS << "typedef __SVInt64_t svint64_t;\n";
1293   OS << "typedef __SVUint8_t svuint8_t;\n";
1294   OS << "typedef __SVUint16_t svuint16_t;\n";
1295   OS << "typedef __SVUint32_t svuint32_t;\n";
1296   OS << "typedef __SVUint64_t svuint64_t;\n";
1297   OS << "typedef __SVFloat16_t svfloat16_t;\n\n";
1298 
1299   OS << "typedef __SVBfloat16_t svbfloat16_t;\n";
1300 
1301   OS << "#include <arm_bf16.h>\n";
1302   OS << "#include <arm_vector_types.h>\n";
1303 
1304   OS << "typedef __SVFloat32_t svfloat32_t;\n";
1305   OS << "typedef __SVFloat64_t svfloat64_t;\n";
1306   OS << "typedef __clang_svint8x2_t svint8x2_t;\n";
1307   OS << "typedef __clang_svint16x2_t svint16x2_t;\n";
1308   OS << "typedef __clang_svint32x2_t svint32x2_t;\n";
1309   OS << "typedef __clang_svint64x2_t svint64x2_t;\n";
1310   OS << "typedef __clang_svuint8x2_t svuint8x2_t;\n";
1311   OS << "typedef __clang_svuint16x2_t svuint16x2_t;\n";
1312   OS << "typedef __clang_svuint32x2_t svuint32x2_t;\n";
1313   OS << "typedef __clang_svuint64x2_t svuint64x2_t;\n";
1314   OS << "typedef __clang_svfloat16x2_t svfloat16x2_t;\n";
1315   OS << "typedef __clang_svfloat32x2_t svfloat32x2_t;\n";
1316   OS << "typedef __clang_svfloat64x2_t svfloat64x2_t;\n";
1317   OS << "typedef __clang_svint8x3_t svint8x3_t;\n";
1318   OS << "typedef __clang_svint16x3_t svint16x3_t;\n";
1319   OS << "typedef __clang_svint32x3_t svint32x3_t;\n";
1320   OS << "typedef __clang_svint64x3_t svint64x3_t;\n";
1321   OS << "typedef __clang_svuint8x3_t svuint8x3_t;\n";
1322   OS << "typedef __clang_svuint16x3_t svuint16x3_t;\n";
1323   OS << "typedef __clang_svuint32x3_t svuint32x3_t;\n";
1324   OS << "typedef __clang_svuint64x3_t svuint64x3_t;\n";
1325   OS << "typedef __clang_svfloat16x3_t svfloat16x3_t;\n";
1326   OS << "typedef __clang_svfloat32x3_t svfloat32x3_t;\n";
1327   OS << "typedef __clang_svfloat64x3_t svfloat64x3_t;\n";
1328   OS << "typedef __clang_svint8x4_t svint8x4_t;\n";
1329   OS << "typedef __clang_svint16x4_t svint16x4_t;\n";
1330   OS << "typedef __clang_svint32x4_t svint32x4_t;\n";
1331   OS << "typedef __clang_svint64x4_t svint64x4_t;\n";
1332   OS << "typedef __clang_svuint8x4_t svuint8x4_t;\n";
1333   OS << "typedef __clang_svuint16x4_t svuint16x4_t;\n";
1334   OS << "typedef __clang_svuint32x4_t svuint32x4_t;\n";
1335   OS << "typedef __clang_svuint64x4_t svuint64x4_t;\n";
1336   OS << "typedef __clang_svfloat16x4_t svfloat16x4_t;\n";
1337   OS << "typedef __clang_svfloat32x4_t svfloat32x4_t;\n";
1338   OS << "typedef __clang_svfloat64x4_t svfloat64x4_t;\n";
1339   OS << "typedef __SVBool_t  svbool_t;\n";
1340   OS << "typedef __clang_svboolx2_t  svboolx2_t;\n";
1341   OS << "typedef __clang_svboolx4_t  svboolx4_t;\n\n";
1342 
1343   OS << "typedef __clang_svbfloat16x2_t svbfloat16x2_t;\n";
1344   OS << "typedef __clang_svbfloat16x3_t svbfloat16x3_t;\n";
1345   OS << "typedef __clang_svbfloat16x4_t svbfloat16x4_t;\n";
1346 
1347   OS << "typedef __SVCount_t svcount_t;\n\n";
1348 
1349   OS << "enum svpattern\n";
1350   OS << "{\n";
1351   OS << "  SV_POW2 = 0,\n";
1352   OS << "  SV_VL1 = 1,\n";
1353   OS << "  SV_VL2 = 2,\n";
1354   OS << "  SV_VL3 = 3,\n";
1355   OS << "  SV_VL4 = 4,\n";
1356   OS << "  SV_VL5 = 5,\n";
1357   OS << "  SV_VL6 = 6,\n";
1358   OS << "  SV_VL7 = 7,\n";
1359   OS << "  SV_VL8 = 8,\n";
1360   OS << "  SV_VL16 = 9,\n";
1361   OS << "  SV_VL32 = 10,\n";
1362   OS << "  SV_VL64 = 11,\n";
1363   OS << "  SV_VL128 = 12,\n";
1364   OS << "  SV_VL256 = 13,\n";
1365   OS << "  SV_MUL4 = 29,\n";
1366   OS << "  SV_MUL3 = 30,\n";
1367   OS << "  SV_ALL = 31\n";
1368   OS << "};\n\n";
1369 
1370   OS << "enum svprfop\n";
1371   OS << "{\n";
1372   OS << "  SV_PLDL1KEEP = 0,\n";
1373   OS << "  SV_PLDL1STRM = 1,\n";
1374   OS << "  SV_PLDL2KEEP = 2,\n";
1375   OS << "  SV_PLDL2STRM = 3,\n";
1376   OS << "  SV_PLDL3KEEP = 4,\n";
1377   OS << "  SV_PLDL3STRM = 5,\n";
1378   OS << "  SV_PSTL1KEEP = 8,\n";
1379   OS << "  SV_PSTL1STRM = 9,\n";
1380   OS << "  SV_PSTL2KEEP = 10,\n";
1381   OS << "  SV_PSTL2STRM = 11,\n";
1382   OS << "  SV_PSTL3KEEP = 12,\n";
1383   OS << "  SV_PSTL3STRM = 13\n";
1384   OS << "};\n\n";
1385 
1386   OS << "/* Function attributes */\n";
1387   OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
1388         "__nodebug__))\n\n";
1389   OS << "#define __aio static __inline__ __attribute__((__always_inline__, "
1390         "__nodebug__, __overloadable__))\n\n";
1391 
1392   // Add reinterpret functions.
1393   for (auto [N, Suffix] :
1394        std::initializer_list<std::pair<unsigned, const char *>>{
1395            {1, ""}, {2, "_x2"}, {3, "_x3"}, {4, "_x4"}}) {
1396     for (auto ShortForm : {false, true})
1397       for (const ReinterpretTypeInfo &To : Reinterprets) {
1398         SVEType ToV(To.BaseType, N);
1399         for (const ReinterpretTypeInfo &From : Reinterprets) {
1400           SVEType FromV(From.BaseType, N);
1401           if (ShortForm) {
1402             OS << "__aio __attribute__((target(\"sve\"))) " << ToV.str()
1403                << " svreinterpret_" << To.Suffix;
1404             OS << "(" << FromV.str() << " op) __arm_streaming_compatible {\n";
1405             OS << "  return __builtin_sve_reinterpret_" << To.Suffix << "_"
1406                << From.Suffix << Suffix << "(op);\n";
1407             OS << "}\n\n";
1408           } else
1409             OS << "#define svreinterpret_" << To.Suffix << "_" << From.Suffix
1410                << Suffix << "(...) __builtin_sve_reinterpret_" << To.Suffix
1411                << "_" << From.Suffix << Suffix << "(__VA_ARGS__)\n";
1412         }
1413       }
1414   }
1415 
1416   createCoreHeaderIntrinsics(OS, *this, ACLEKind::SVE);
1417 
1418   OS << "#define svcvtnt_bf16_x      svcvtnt_bf16_m\n";
1419   OS << "#define svcvtnt_bf16_f32_x  svcvtnt_bf16_f32_m\n";
1420 
1421   OS << "#define svcvtnt_f16_x      svcvtnt_f16_m\n";
1422   OS << "#define svcvtnt_f16_f32_x  svcvtnt_f16_f32_m\n";
1423   OS << "#define svcvtnt_f32_x      svcvtnt_f32_m\n";
1424   OS << "#define svcvtnt_f32_f64_x  svcvtnt_f32_f64_m\n\n";
1425 
1426   OS << "#define svcvtxnt_f32_x     svcvtxnt_f32_m\n";
1427   OS << "#define svcvtxnt_f32_f64_x svcvtxnt_f32_f64_m\n\n";
1428 
1429   OS << "#ifdef __cplusplus\n";
1430   OS << "} // extern \"C\"\n";
1431   OS << "#endif\n\n";
1432   OS << "#undef __ai\n\n";
1433   OS << "#undef __aio\n\n";
1434   OS << "#endif /* __ARM_SVE_H */\n";
1435 }
1436 
1437 void SVEEmitter::createBuiltins(raw_ostream &OS) {
1438   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1439   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1440   for (auto *R : RV)
1441     createIntrinsic(R, Defs);
1442 
1443   // The mappings must be sorted based on BuiltinID.
1444   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1445                       const std::unique_ptr<Intrinsic> &B) {
1446     return A->getMangledName() < B->getMangledName();
1447   });
1448 
1449   OS << "#ifdef GET_SVE_BUILTINS\n";
1450   for (auto &Def : Defs) {
1451     // Only create BUILTINs for non-overloaded intrinsics, as overloaded
1452     // declarations only live in the header file.
1453     if (Def->getClassKind() != ClassG)
1454       OS << "TARGET_BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \""
1455          << Def->getBuiltinTypeStr() << "\", \"n\", \"" << Def->getGuard()
1456          << "\")\n";
1457   }
1458 
1459   // Add reinterpret functions.
1460   for (auto [N, Suffix] :
1461        std::initializer_list<std::pair<unsigned, const char *>>{
1462            {1, ""}, {2, "_x2"}, {3, "_x3"}, {4, "_x4"}}) {
1463     for (const ReinterpretTypeInfo &To : Reinterprets) {
1464       SVEType ToV(To.BaseType, N);
1465       for (const ReinterpretTypeInfo &From : Reinterprets) {
1466         SVEType FromV(From.BaseType, N);
1467         OS << "TARGET_BUILTIN(__builtin_sve_reinterpret_" << To.Suffix << "_"
1468            << From.Suffix << Suffix << +", \"" << ToV.builtin_str()
1469            << FromV.builtin_str() << "\", \"n\", \"sve\")\n";
1470       }
1471     }
1472   }
1473 
1474   OS << "#endif\n\n";
1475 }
1476 
1477 void SVEEmitter::createCodeGenMap(raw_ostream &OS) {
1478   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1479   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1480   for (auto *R : RV)
1481     createIntrinsic(R, Defs);
1482 
1483   // The mappings must be sorted based on BuiltinID.
1484   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1485                       const std::unique_ptr<Intrinsic> &B) {
1486     return A->getMangledName() < B->getMangledName();
1487   });
1488 
1489   OS << "#ifdef GET_SVE_LLVM_INTRINSIC_MAP\n";
1490   for (auto &Def : Defs) {
1491     // Builtins only exist for non-overloaded intrinsics, overloaded
1492     // declarations only live in the header file.
1493     if (Def->getClassKind() == ClassG)
1494       continue;
1495 
1496     uint64_t Flags = Def->getFlags();
1497     auto FlagString = std::to_string(Flags);
1498 
1499     std::string LLVMName = Def->getMangledLLVMName();
1500     std::string Builtin = Def->getMangledName();
1501     if (!LLVMName.empty())
1502       OS << "SVEMAP1(" << Builtin << ", " << LLVMName << ", " << FlagString
1503          << "),\n";
1504     else
1505       OS << "SVEMAP2(" << Builtin << ", " << FlagString << "),\n";
1506   }
1507   OS << "#endif\n\n";
1508 }
1509 
1510 void SVEEmitter::createRangeChecks(raw_ostream &OS) {
1511   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1512   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1513   for (auto *R : RV)
1514     createIntrinsic(R, Defs);
1515 
1516   // The mappings must be sorted based on BuiltinID.
1517   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1518                       const std::unique_ptr<Intrinsic> &B) {
1519     return A->getMangledName() < B->getMangledName();
1520   });
1521 
1522 
1523   OS << "#ifdef GET_SVE_IMMEDIATE_CHECK\n";
1524 
1525   // Ensure these are only emitted once.
1526   std::set<std::string> Emitted;
1527 
1528   for (auto &Def : Defs) {
1529     if (Emitted.find(Def->getMangledName()) != Emitted.end() ||
1530         Def->getImmChecks().empty())
1531       continue;
1532 
1533     OS << "case SVE::BI__builtin_sve_" << Def->getMangledName() << ":\n";
1534     for (auto &Check : Def->getImmChecks())
1535       OS << "ImmChecks.push_back(std::make_tuple(" << Check.getArg() << ", "
1536          << Check.getKind() << ", " << Check.getElementSizeInBits() << "));\n";
1537     OS << "  break;\n";
1538 
1539     Emitted.insert(Def->getMangledName());
1540   }
1541 
1542   OS << "#endif\n\n";
1543 }
1544 
1545 /// Create the SVETypeFlags used in CGBuiltins
1546 void SVEEmitter::createTypeFlags(raw_ostream &OS) {
1547   OS << "#ifdef LLVM_GET_SVE_TYPEFLAGS\n";
1548   for (auto &KV : FlagTypes)
1549     OS << "const uint64_t " << KV.getKey() << " = " << KV.getValue() << ";\n";
1550   OS << "#endif\n\n";
1551 
1552   OS << "#ifdef LLVM_GET_SVE_ELTTYPES\n";
1553   for (auto &KV : EltTypes)
1554     OS << "  " << KV.getKey() << " = " << KV.getValue() << ",\n";
1555   OS << "#endif\n\n";
1556 
1557   OS << "#ifdef LLVM_GET_SVE_MEMELTTYPES\n";
1558   for (auto &KV : MemEltTypes)
1559     OS << "  " << KV.getKey() << " = " << KV.getValue() << ",\n";
1560   OS << "#endif\n\n";
1561 
1562   OS << "#ifdef LLVM_GET_SVE_MERGETYPES\n";
1563   for (auto &KV : MergeTypes)
1564     OS << "  " << KV.getKey() << " = " << KV.getValue() << ",\n";
1565   OS << "#endif\n\n";
1566 
1567   OS << "#ifdef LLVM_GET_SVE_IMMCHECKTYPES\n";
1568   for (auto &KV : ImmCheckTypes)
1569     OS << "  " << KV.getKey() << " = " << KV.getValue() << ",\n";
1570   OS << "#endif\n\n";
1571 }
1572 
1573 void SVEEmitter::createSMEHeader(raw_ostream &OS) {
1574   OS << "/*===---- arm_sme_draft_spec_subject_to_change.h - ARM SME intrinsics "
1575         "------===\n"
1576         " *\n"
1577         " *\n"
1578         " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
1579         "Exceptions.\n"
1580         " * See https://llvm.org/LICENSE.txt for license information.\n"
1581         " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
1582         " *\n"
1583         " *===-----------------------------------------------------------------"
1584         "------===\n"
1585         " */\n\n";
1586 
1587   OS << "#ifndef __ARM_SME_H\n";
1588   OS << "#define __ARM_SME_H\n\n";
1589 
1590   OS << "#if !defined(__LITTLE_ENDIAN__)\n";
1591   OS << "#error \"Big endian is currently not supported for arm_sme_draft_spec_subject_to_change.h\"\n";
1592   OS << "#endif\n";
1593 
1594   OS << "#include <arm_sve.h>\n\n";
1595 
1596   OS << "/* Function attributes */\n";
1597   OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
1598         "__nodebug__))\n\n";
1599   OS << "#define __aio static __inline__ __attribute__((__always_inline__, "
1600         "__nodebug__, __overloadable__))\n\n";
1601 
1602   OS << "#ifdef  __cplusplus\n";
1603   OS << "extern \"C\" {\n";
1604   OS << "#endif\n\n";
1605 
1606   OS << "void __arm_za_disable(void) __arm_streaming_compatible;\n\n";
1607 
1608   OS << "__ai bool __arm_has_sme(void) __arm_streaming_compatible {\n";
1609   OS << "  uint64_t x0, x1;\n";
1610   OS << "  __builtin_arm_get_sme_state(&x0, &x1);\n";
1611   OS << "  return x0 & (1ULL << 63);\n";
1612   OS << "}\n\n";
1613 
1614   OS << "__ai bool __arm_in_streaming_mode(void) __arm_streaming_compatible "
1615         "{\n";
1616   OS << "  uint64_t x0, x1;\n";
1617   OS << "  __builtin_arm_get_sme_state(&x0, &x1);\n";
1618   OS << "  return x0 & 1;\n";
1619   OS << "}\n\n";
1620 
1621   OS << "__ai __attribute__((target(\"sme\"))) void svundef_za(void) "
1622         "__arm_streaming_compatible __arm_shared_za "
1623         "{ }\n\n";
1624 
1625   createCoreHeaderIntrinsics(OS, *this, ACLEKind::SME);
1626 
1627   OS << "#ifdef __cplusplus\n";
1628   OS << "} // extern \"C\"\n";
1629   OS << "#endif\n\n";
1630   OS << "#undef __ai\n\n";
1631   OS << "#endif /* __ARM_SME_H */\n";
1632 }
1633 
1634 void SVEEmitter::createSMEBuiltins(raw_ostream &OS) {
1635   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1636   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1637   for (auto *R : RV) {
1638     createIntrinsic(R, Defs);
1639   }
1640 
1641   // The mappings must be sorted based on BuiltinID.
1642   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1643                       const std::unique_ptr<Intrinsic> &B) {
1644     return A->getMangledName() < B->getMangledName();
1645   });
1646 
1647   OS << "#ifdef GET_SME_BUILTINS\n";
1648   for (auto &Def : Defs) {
1649     // Only create BUILTINs for non-overloaded intrinsics, as overloaded
1650     // declarations only live in the header file.
1651     if (Def->getClassKind() != ClassG)
1652       OS << "TARGET_BUILTIN(__builtin_sme_" << Def->getMangledName() << ", \""
1653          << Def->getBuiltinTypeStr() << "\", \"n\", \"" << Def->getGuard()
1654          << "\")\n";
1655   }
1656 
1657   OS << "#endif\n\n";
1658 }
1659 
1660 void SVEEmitter::createSMECodeGenMap(raw_ostream &OS) {
1661   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1662   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1663   for (auto *R : RV) {
1664     createIntrinsic(R, Defs);
1665   }
1666 
1667   // The mappings must be sorted based on BuiltinID.
1668   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1669                       const std::unique_ptr<Intrinsic> &B) {
1670     return A->getMangledName() < B->getMangledName();
1671   });
1672 
1673   OS << "#ifdef GET_SME_LLVM_INTRINSIC_MAP\n";
1674   for (auto &Def : Defs) {
1675     // Builtins only exist for non-overloaded intrinsics, overloaded
1676     // declarations only live in the header file.
1677     if (Def->getClassKind() == ClassG)
1678       continue;
1679 
1680     uint64_t Flags = Def->getFlags();
1681     auto FlagString = std::to_string(Flags);
1682 
1683     std::string LLVMName = Def->getLLVMName();
1684     std::string Builtin = Def->getMangledName();
1685     if (!LLVMName.empty())
1686       OS << "SMEMAP1(" << Builtin << ", " << LLVMName << ", " << FlagString
1687          << "),\n";
1688     else
1689       OS << "SMEMAP2(" << Builtin << ", " << FlagString << "),\n";
1690   }
1691   OS << "#endif\n\n";
1692 }
1693 
1694 void SVEEmitter::createSMERangeChecks(raw_ostream &OS) {
1695   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1696   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1697   for (auto *R : RV) {
1698     createIntrinsic(R, Defs);
1699   }
1700 
1701   // The mappings must be sorted based on BuiltinID.
1702   llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
1703                       const std::unique_ptr<Intrinsic> &B) {
1704     return A->getMangledName() < B->getMangledName();
1705   });
1706 
1707 
1708   OS << "#ifdef GET_SME_IMMEDIATE_CHECK\n";
1709 
1710   // Ensure these are only emitted once.
1711   std::set<std::string> Emitted;
1712 
1713   for (auto &Def : Defs) {
1714     if (Emitted.find(Def->getMangledName()) != Emitted.end() ||
1715         Def->getImmChecks().empty())
1716       continue;
1717 
1718     OS << "case SME::BI__builtin_sme_" << Def->getMangledName() << ":\n";
1719     for (auto &Check : Def->getImmChecks())
1720       OS << "ImmChecks.push_back(std::make_tuple(" << Check.getArg() << ", "
1721          << Check.getKind() << ", " << Check.getElementSizeInBits() << "));\n";
1722     OS << "  break;\n";
1723 
1724     Emitted.insert(Def->getMangledName());
1725   }
1726 
1727   OS << "#endif\n\n";
1728 }
1729 
1730 void SVEEmitter::createBuiltinZAState(raw_ostream &OS) {
1731   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1732   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1733   for (auto *R : RV)
1734     createIntrinsic(R, Defs);
1735 
1736   std::map<bool, std::set<std::string>> DefsZAState;
1737 
1738   uint64_t IsSharedZAFlag = getEnumValueForFlag("IsSharedZA");
1739   for (auto &Def : Defs) {
1740     bool HasZAState = Def->isFlagSet(IsSharedZAFlag);
1741     DefsZAState[HasZAState].insert(Def->getMangledName());
1742   }
1743 
1744   OS << "#ifdef GET_SME_BUILTIN_HAS_ZA_STATE\n";
1745 
1746   for (auto HasZA : {true, false}) {
1747     auto Names = DefsZAState[HasZA];
1748     for (auto Name : Names)
1749       OS << "case SME::BI__builtin_sme_" << Name << ":\n";
1750     OS << "  return " << (HasZA ? "true" : "false") << ";\n";
1751   }
1752   OS << "#endif\n\n";
1753 }
1754 
1755 void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) {
1756   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
1757   SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
1758   for (auto *R : RV)
1759     createIntrinsic(R, Defs);
1760 
1761   StringRef ExtensionKind;
1762   switch (Kind) {
1763   case ACLEKind::SME:
1764     ExtensionKind = "SME";
1765     break;
1766   case ACLEKind::SVE:
1767     ExtensionKind = "SVE";
1768     break;
1769   }
1770 
1771   OS << "#ifdef GET_" << ExtensionKind << "_STREAMING_ATTRS\n";
1772 
1773   llvm::StringMap<std::set<std::string>> StreamingMap;
1774 
1775   uint64_t IsStreamingFlag = getEnumValueForFlag("IsStreaming");
1776   uint64_t IsStreamingOrSVE2p1Flag = getEnumValueForFlag("IsStreamingOrSVE2p1");
1777   uint64_t IsStreamingCompatibleFlag =
1778       getEnumValueForFlag("IsStreamingCompatible");
1779   for (auto &Def : Defs) {
1780     if (Def->isFlagSet(IsStreamingFlag))
1781       StreamingMap["ArmStreaming"].insert(Def->getMangledName());
1782     else if (Def->isFlagSet(IsStreamingOrSVE2p1Flag))
1783       StreamingMap["ArmStreamingOrSVE2p1"].insert(Def->getMangledName());
1784     else if (Def->isFlagSet(IsStreamingCompatibleFlag))
1785       StreamingMap["ArmStreamingCompatible"].insert(Def->getMangledName());
1786     else
1787       StreamingMap["ArmNonStreaming"].insert(Def->getMangledName());
1788   }
1789 
1790   for (auto BuiltinType : StreamingMap.keys()) {
1791     for (auto Name : StreamingMap[BuiltinType]) {
1792       OS << "case " << ExtensionKind << "::BI__builtin_"
1793          << ExtensionKind.lower() << "_";
1794       OS << Name << ":\n";
1795     }
1796     OS << "  BuiltinType = " << BuiltinType << ";\n";
1797     OS << "  break;\n";
1798   }
1799 
1800   OS << "#endif\n\n";
1801 }
1802 
1803 namespace clang {
1804 void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
1805   SVEEmitter(Records).createHeader(OS);
1806 }
1807 
1808 void EmitSveBuiltins(RecordKeeper &Records, raw_ostream &OS) {
1809   SVEEmitter(Records).createBuiltins(OS);
1810 }
1811 
1812 void EmitSveBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
1813   SVEEmitter(Records).createCodeGenMap(OS);
1814 }
1815 
1816 void EmitSveRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
1817   SVEEmitter(Records).createRangeChecks(OS);
1818 }
1819 
1820 void EmitSveTypeFlags(RecordKeeper &Records, raw_ostream &OS) {
1821   SVEEmitter(Records).createTypeFlags(OS);
1822 }
1823 
1824 void EmitSveStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) {
1825   SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SVE);
1826 }
1827 
1828 void EmitSmeHeader(RecordKeeper &Records, raw_ostream &OS) {
1829   SVEEmitter(Records).createSMEHeader(OS);
1830 }
1831 
1832 void EmitSmeBuiltins(RecordKeeper &Records, raw_ostream &OS) {
1833   SVEEmitter(Records).createSMEBuiltins(OS);
1834 }
1835 
1836 void EmitSmeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
1837   SVEEmitter(Records).createSMECodeGenMap(OS);
1838 }
1839 
1840 void EmitSmeRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
1841   SVEEmitter(Records).createSMERangeChecks(OS);
1842 }
1843 
1844 void EmitSmeStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) {
1845   SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SME);
1846 }
1847 
1848 void EmitSmeBuiltinZAState(RecordKeeper &Records, raw_ostream &OS) {
1849   SVEEmitter(Records).createBuiltinZAState(OS);
1850 }
1851 } // End namespace clang
1852