SveEmitter.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  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. #include "llvm/ADT/STLExtras.h"
  26. #include "llvm/ADT/StringMap.h"
  27. #include "llvm/ADT/ArrayRef.h"
  28. #include "llvm/ADT/StringExtras.h"
  29. #include "llvm/TableGen/Record.h"
  30. #include "llvm/TableGen/Error.h"
  31. #include <string>
  32. #include <sstream>
  33. #include <set>
  34. #include <cctype>
  35. #include <tuple>
  36. using namespace llvm;
  37. enum ClassKind {
  38. ClassNone,
  39. ClassS, // signed/unsigned, e.g., "_s8", "_u8" suffix
  40. ClassG, // Overloaded name without type suffix
  41. };
  42. using TypeSpec = std::string;
  43. namespace {
  44. class ImmCheck {
  45. unsigned Arg;
  46. unsigned Kind;
  47. unsigned ElementSizeInBits;
  48. public:
  49. ImmCheck(unsigned Arg, unsigned Kind, unsigned ElementSizeInBits = 0)
  50. : Arg(Arg), Kind(Kind), ElementSizeInBits(ElementSizeInBits) {}
  51. ImmCheck(const ImmCheck &Other) = default;
  52. ~ImmCheck() = default;
  53. unsigned getArg() const { return Arg; }
  54. unsigned getKind() const { return Kind; }
  55. unsigned getElementSizeInBits() const { return ElementSizeInBits; }
  56. };
  57. class SVEType {
  58. TypeSpec TS;
  59. bool Float, Signed, Immediate, Void, Constant, Pointer, BFloat;
  60. bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp;
  61. unsigned Bitwidth, ElementBitwidth, NumVectors;
  62. public:
  63. SVEType() : SVEType(TypeSpec(), 'v') {}
  64. SVEType(TypeSpec TS, char CharMod)
  65. : TS(TS), Float(false), Signed(true), Immediate(false), Void(false),
  66. Constant(false), Pointer(false), BFloat(false), DefaultType(false),
  67. IsScalable(true), Predicate(false), PredicatePattern(false),
  68. PrefetchOp(false), Bitwidth(128), ElementBitwidth(~0U), NumVectors(1) {
  69. if (!TS.empty())
  70. applyTypespec();
  71. applyModifier(CharMod);
  72. }
  73. bool isPointer() const { return Pointer; }
  74. bool isVoidPointer() const { return Pointer && Void; }
  75. bool isSigned() const { return Signed; }
  76. bool isImmediate() const { return Immediate; }
  77. bool isScalar() const { return NumVectors == 0; }
  78. bool isVector() const { return NumVectors > 0; }
  79. bool isScalableVector() const { return isVector() && IsScalable; }
  80. bool isChar() const { return ElementBitwidth == 8; }
  81. bool isVoid() const { return Void & !Pointer; }
  82. bool isDefault() const { return DefaultType; }
  83. bool isFloat() const { return Float && !BFloat; }
  84. bool isBFloat() const { return BFloat && !Float; }
  85. bool isFloatingPoint() const { return Float || BFloat; }
  86. bool isInteger() const { return !isFloatingPoint() && !Predicate; }
  87. bool isScalarPredicate() const {
  88. return !isFloatingPoint() && Predicate && NumVectors == 0;
  89. }
  90. bool isPredicateVector() const { return Predicate; }
  91. bool isPredicatePattern() const { return PredicatePattern; }
  92. bool isPrefetchOp() const { return PrefetchOp; }
  93. bool isConstant() const { return Constant; }
  94. unsigned getElementSizeInBits() const { return ElementBitwidth; }
  95. unsigned getNumVectors() const { return NumVectors; }
  96. unsigned getNumElements() const {
  97. assert(ElementBitwidth != ~0U);
  98. return Bitwidth / ElementBitwidth;
  99. }
  100. unsigned getSizeInBits() const {
  101. return Bitwidth;
  102. }
  103. /// Return the string representation of a type, which is an encoded
  104. /// string for passing to the BUILTIN() macro in Builtins.def.
  105. std::string builtin_str() const;
  106. /// Return the C/C++ string representation of a type for use in the
  107. /// arm_sve.h header file.
  108. std::string str() const;
  109. private:
  110. /// Creates the type based on the typespec string in TS.
  111. void applyTypespec();
  112. /// Applies a prototype modifier to the type.
  113. void applyModifier(char Mod);
  114. };
  115. class SVEEmitter;
  116. /// The main grunt class. This represents an instantiation of an intrinsic with
  117. /// a particular typespec and prototype.
  118. class Intrinsic {
  119. /// The unmangled name.
  120. std::string Name;
  121. /// The name of the corresponding LLVM IR intrinsic.
  122. std::string LLVMName;
  123. /// Intrinsic prototype.
  124. std::string Proto;
  125. /// The base type spec for this intrinsic.
  126. TypeSpec BaseTypeSpec;
  127. /// The base class kind. Most intrinsics use ClassS, which has full type
  128. /// info for integers (_s32/_u32), or ClassG which is used for overloaded
  129. /// intrinsics.
  130. ClassKind Class;
  131. /// The architectural #ifdef guard.
  132. std::string Guard;
  133. // The merge suffix such as _m, _x or _z.
  134. std::string MergeSuffix;
  135. /// The types of return value [0] and parameters [1..].
  136. std::vector<SVEType> Types;
  137. /// The "base type", which is VarType('d', BaseTypeSpec).
  138. SVEType BaseType;
  139. uint64_t Flags;
  140. SmallVector<ImmCheck, 2> ImmChecks;
  141. public:
  142. Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
  143. StringRef MergeSuffix, uint64_t MemoryElementTy, StringRef LLVMName,
  144. uint64_t Flags, ArrayRef<ImmCheck> ImmChecks, TypeSpec BT,
  145. ClassKind Class, SVEEmitter &Emitter, StringRef Guard);
  146. ~Intrinsic()=default;
  147. std::string getName() const { return Name; }
  148. std::string getLLVMName() const { return LLVMName; }
  149. std::string getProto() const { return Proto; }
  150. TypeSpec getBaseTypeSpec() const { return BaseTypeSpec; }
  151. SVEType getBaseType() const { return BaseType; }
  152. StringRef getGuard() const { return Guard; }
  153. ClassKind getClassKind() const { return Class; }
  154. SVEType getReturnType() const { return Types[0]; }
  155. ArrayRef<SVEType> getTypes() const { return Types; }
  156. SVEType getParamType(unsigned I) const { return Types[I + 1]; }
  157. unsigned getNumParams() const { return Proto.size() - 1; }
  158. uint64_t getFlags() const { return Flags; }
  159. bool isFlagSet(uint64_t Flag) const { return Flags & Flag;}
  160. ArrayRef<ImmCheck> getImmChecks() const { return ImmChecks; }
  161. /// Return the type string for a BUILTIN() macro in Builtins.def.
  162. std::string getBuiltinTypeStr();
  163. /// Return the name, mangled with type information. The name is mangled for
  164. /// ClassS, so will add type suffixes such as _u32/_s32.
  165. std::string getMangledName() const { return mangleName(ClassS); }
  166. /// Returns true if the intrinsic is overloaded, in that it should also generate
  167. /// a short form without the type-specifiers, e.g. 'svld1(..)' instead of
  168. /// 'svld1_u32(..)'.
  169. static bool isOverloadedIntrinsic(StringRef Name) {
  170. auto BrOpen = Name.find('[');
  171. auto BrClose = Name.find(']');
  172. return BrOpen != std::string::npos && BrClose != std::string::npos;
  173. }
  174. /// Return true if the intrinsic takes a splat operand.
  175. bool hasSplat() const {
  176. // These prototype modifiers are described in arm_sve.td.
  177. return Proto.find_first_of("ajfrKLR@") != std::string::npos;
  178. }
  179. /// Return the parameter index of the splat operand.
  180. unsigned getSplatIdx() const {
  181. // These prototype modifiers are described in arm_sve.td.
  182. auto Idx = Proto.find_first_of("ajfrKLR@");
  183. assert(Idx != std::string::npos && Idx > 0 &&
  184. "Prototype has no splat operand");
  185. return Idx - 1;
  186. }
  187. /// Emits the intrinsic declaration to the ostream.
  188. void emitIntrinsic(raw_ostream &OS) const;
  189. private:
  190. std::string getMergeSuffix() const { return MergeSuffix; }
  191. std::string mangleName(ClassKind LocalCK) const;
  192. std::string replaceTemplatedArgs(std::string Name, TypeSpec TS,
  193. std::string Proto) const;
  194. };
  195. class SVEEmitter {
  196. private:
  197. // The reinterpret builtins are generated separately because they
  198. // need the cross product of all types (121 functions in total),
  199. // which is inconvenient to specify in the arm_sve.td file or
  200. // generate in CGBuiltin.cpp.
  201. struct ReinterpretTypeInfo {
  202. const char *Suffix;
  203. const char *Type;
  204. const char *BuiltinType;
  205. };
  206. SmallVector<ReinterpretTypeInfo, 12> Reinterprets = {
  207. {"s8", "svint8_t", "q16Sc"}, {"s16", "svint16_t", "q8Ss"},
  208. {"s32", "svint32_t", "q4Si"}, {"s64", "svint64_t", "q2SWi"},
  209. {"u8", "svuint8_t", "q16Uc"}, {"u16", "svuint16_t", "q8Us"},
  210. {"u32", "svuint32_t", "q4Ui"}, {"u64", "svuint64_t", "q2UWi"},
  211. {"f16", "svfloat16_t", "q8h"}, {"bf16", "svbfloat16_t", "q8y"},
  212. {"f32", "svfloat32_t", "q4f"}, {"f64", "svfloat64_t", "q2d"}};
  213. RecordKeeper &Records;
  214. llvm::StringMap<uint64_t> EltTypes;
  215. llvm::StringMap<uint64_t> MemEltTypes;
  216. llvm::StringMap<uint64_t> FlagTypes;
  217. llvm::StringMap<uint64_t> MergeTypes;
  218. llvm::StringMap<uint64_t> ImmCheckTypes;
  219. public:
  220. SVEEmitter(RecordKeeper &R) : Records(R) {
  221. for (auto *RV : Records.getAllDerivedDefinitions("EltType"))
  222. EltTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
  223. for (auto *RV : Records.getAllDerivedDefinitions("MemEltType"))
  224. MemEltTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
  225. for (auto *RV : Records.getAllDerivedDefinitions("FlagType"))
  226. FlagTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
  227. for (auto *RV : Records.getAllDerivedDefinitions("MergeType"))
  228. MergeTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
  229. for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType"))
  230. ImmCheckTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value");
  231. }
  232. /// Returns the enum value for the immcheck type
  233. unsigned getEnumValueForImmCheck(StringRef C) const {
  234. auto It = ImmCheckTypes.find(C);
  235. if (It != ImmCheckTypes.end())
  236. return It->getValue();
  237. llvm_unreachable("Unsupported imm check");
  238. }
  239. /// Returns the enum value for the flag type
  240. uint64_t getEnumValueForFlag(StringRef C) const {
  241. auto Res = FlagTypes.find(C);
  242. if (Res != FlagTypes.end())
  243. return Res->getValue();
  244. llvm_unreachable("Unsupported flag");
  245. }
  246. // Returns the SVETypeFlags for a given value and mask.
  247. uint64_t encodeFlag(uint64_t V, StringRef MaskName) const {
  248. auto It = FlagTypes.find(MaskName);
  249. if (It != FlagTypes.end()) {
  250. uint64_t Mask = It->getValue();
  251. unsigned Shift = llvm::countTrailingZeros(Mask);
  252. return (V << Shift) & Mask;
  253. }
  254. llvm_unreachable("Unsupported flag");
  255. }
  256. // Returns the SVETypeFlags for the given element type.
  257. uint64_t encodeEltType(StringRef EltName) {
  258. auto It = EltTypes.find(EltName);
  259. if (It != EltTypes.end())
  260. return encodeFlag(It->getValue(), "EltTypeMask");
  261. llvm_unreachable("Unsupported EltType");
  262. }
  263. // Returns the SVETypeFlags for the given memory element type.
  264. uint64_t encodeMemoryElementType(uint64_t MT) {
  265. return encodeFlag(MT, "MemEltTypeMask");
  266. }
  267. // Returns the SVETypeFlags for the given merge type.
  268. uint64_t encodeMergeType(uint64_t MT) {
  269. return encodeFlag(MT, "MergeTypeMask");
  270. }
  271. // Returns the SVETypeFlags for the given splat operand.
  272. unsigned encodeSplatOperand(unsigned SplatIdx) {
  273. assert(SplatIdx < 7 && "SplatIdx out of encodable range");
  274. return encodeFlag(SplatIdx + 1, "SplatOperandMask");
  275. }
  276. // Returns the SVETypeFlags value for the given SVEType.
  277. uint64_t encodeTypeFlags(const SVEType &T);
  278. /// Emit arm_sve.h.
  279. void createHeader(raw_ostream &o);
  280. /// Emit all the __builtin prototypes and code needed by Sema.
  281. void createBuiltins(raw_ostream &o);
  282. /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
  283. void createCodeGenMap(raw_ostream &o);
  284. /// Emit all the range checks for the immediates.
  285. void createRangeChecks(raw_ostream &o);
  286. /// Create the SVETypeFlags used in CGBuiltins
  287. void createTypeFlags(raw_ostream &o);
  288. /// Create intrinsic and add it to \p Out
  289. void createIntrinsic(Record *R, SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out);
  290. };
  291. } // end anonymous namespace
  292. //===----------------------------------------------------------------------===//
  293. // Type implementation
  294. //===----------------------------------------------------------------------===//
  295. std::string SVEType::builtin_str() const {
  296. std::string S;
  297. if (isVoid())
  298. return "v";
  299. if (isScalarPredicate())
  300. return "b";
  301. if (isVoidPointer())
  302. S += "v";
  303. else if (!isFloatingPoint())
  304. switch (ElementBitwidth) {
  305. case 1: S += "b"; break;
  306. case 8: S += "c"; break;
  307. case 16: S += "s"; break;
  308. case 32: S += "i"; break;
  309. case 64: S += "Wi"; break;
  310. case 128: S += "LLLi"; break;
  311. default: llvm_unreachable("Unhandled case!");
  312. }
  313. else if (isFloat())
  314. switch (ElementBitwidth) {
  315. case 16: S += "h"; break;
  316. case 32: S += "f"; break;
  317. case 64: S += "d"; break;
  318. default: llvm_unreachable("Unhandled case!");
  319. }
  320. else if (isBFloat()) {
  321. assert(ElementBitwidth == 16 && "Not a valid BFloat.");
  322. S += "y";
  323. }
  324. if (!isFloatingPoint()) {
  325. if ((isChar() || isPointer()) && !isVoidPointer()) {
  326. // Make chars and typed pointers explicitly signed.
  327. if (Signed)
  328. S = "S" + S;
  329. else if (!Signed)
  330. S = "U" + S;
  331. } else if (!isVoidPointer() && !Signed) {
  332. S = "U" + S;
  333. }
  334. }
  335. // Constant indices are "int", but have the "constant expression" modifier.
  336. if (isImmediate()) {
  337. assert(!isFloat() && "fp immediates are not supported");
  338. S = "I" + S;
  339. }
  340. if (isScalar()) {
  341. if (Constant) S += "C";
  342. if (Pointer) S += "*";
  343. return S;
  344. }
  345. assert(isScalableVector() && "Unsupported type");
  346. return "q" + utostr(getNumElements() * NumVectors) + S;
  347. }
  348. std::string SVEType::str() const {
  349. if (isPredicatePattern())
  350. return "enum svpattern";
  351. if (isPrefetchOp())
  352. return "enum svprfop";
  353. std::string S;
  354. if (Void)
  355. S += "void";
  356. else {
  357. if (isScalableVector())
  358. S += "sv";
  359. if (!Signed && !isFloatingPoint())
  360. S += "u";
  361. if (Float)
  362. S += "float";
  363. else if (isScalarPredicate() || isPredicateVector())
  364. S += "bool";
  365. else if (isBFloat())
  366. S += "bfloat";
  367. else
  368. S += "int";
  369. if (!isScalarPredicate() && !isPredicateVector())
  370. S += utostr(ElementBitwidth);
  371. if (!isScalableVector() && isVector())
  372. S += "x" + utostr(getNumElements());
  373. if (NumVectors > 1)
  374. S += "x" + utostr(NumVectors);
  375. if (!isScalarPredicate())
  376. S += "_t";
  377. }
  378. if (Constant)
  379. S += " const";
  380. if (Pointer)
  381. S += " *";
  382. return S;
  383. }
  384. void SVEType::applyTypespec() {
  385. for (char I : TS) {
  386. switch (I) {
  387. case 'P':
  388. Predicate = true;
  389. break;
  390. case 'U':
  391. Signed = false;
  392. break;
  393. case 'c':
  394. ElementBitwidth = 8;
  395. break;
  396. case 's':
  397. ElementBitwidth = 16;
  398. break;
  399. case 'i':
  400. ElementBitwidth = 32;
  401. break;
  402. case 'l':
  403. ElementBitwidth = 64;
  404. break;
  405. case 'h':
  406. Float = true;
  407. ElementBitwidth = 16;
  408. break;
  409. case 'f':
  410. Float = true;
  411. ElementBitwidth = 32;
  412. break;
  413. case 'd':
  414. Float = true;
  415. ElementBitwidth = 64;
  416. break;
  417. case 'b':
  418. BFloat = true;
  419. Float = false;
  420. ElementBitwidth = 16;
  421. break;
  422. default:
  423. llvm_unreachable("Unhandled type code!");
  424. }
  425. }
  426. assert(ElementBitwidth != ~0U && "Bad element bitwidth!");
  427. }
  428. void SVEType::applyModifier(char Mod) {
  429. switch (Mod) {
  430. case '2':
  431. NumVectors = 2;
  432. break;
  433. case '3':
  434. NumVectors = 3;
  435. break;
  436. case '4':
  437. NumVectors = 4;
  438. break;
  439. case 'v':
  440. Void = true;
  441. break;
  442. case 'd':
  443. DefaultType = true;
  444. break;
  445. case 'c':
  446. Constant = true;
  447. LLVM_FALLTHROUGH;
  448. case 'p':
  449. Pointer = true;
  450. Bitwidth = ElementBitwidth;
  451. NumVectors = 0;
  452. break;
  453. case 'e':
  454. Signed = false;
  455. ElementBitwidth /= 2;
  456. break;
  457. case 'h':
  458. ElementBitwidth /= 2;
  459. break;
  460. case 'q':
  461. ElementBitwidth /= 4;
  462. break;
  463. case 'b':
  464. Signed = false;
  465. Float = false;
  466. BFloat = false;
  467. ElementBitwidth /= 4;
  468. break;
  469. case 'o':
  470. ElementBitwidth *= 4;
  471. break;
  472. case 'P':
  473. Signed = true;
  474. Float = false;
  475. BFloat = false;
  476. Predicate = true;
  477. Bitwidth = 16;
  478. ElementBitwidth = 1;
  479. break;
  480. case 's':
  481. case 'a':
  482. Bitwidth = ElementBitwidth;
  483. NumVectors = 0;
  484. break;
  485. case 'R':
  486. ElementBitwidth /= 2;
  487. NumVectors = 0;
  488. break;
  489. case 'r':
  490. ElementBitwidth /= 4;
  491. NumVectors = 0;
  492. break;
  493. case '@':
  494. Signed = false;
  495. Float = false;
  496. BFloat = false;
  497. ElementBitwidth /= 4;
  498. NumVectors = 0;
  499. break;
  500. case 'K':
  501. Signed = true;
  502. Float = false;
  503. BFloat = false;
  504. Bitwidth = ElementBitwidth;
  505. NumVectors = 0;
  506. break;
  507. case 'L':
  508. Signed = false;
  509. Float = false;
  510. BFloat = false;
  511. Bitwidth = ElementBitwidth;
  512. NumVectors = 0;
  513. break;
  514. case 'u':
  515. Predicate = false;
  516. Signed = false;
  517. Float = false;
  518. BFloat = false;
  519. break;
  520. case 'x':
  521. Predicate = false;
  522. Signed = true;
  523. Float = false;
  524. BFloat = false;
  525. break;
  526. case 'i':
  527. Predicate = false;
  528. Float = false;
  529. BFloat = false;
  530. ElementBitwidth = Bitwidth = 64;
  531. NumVectors = 0;
  532. Signed = false;
  533. Immediate = true;
  534. break;
  535. case 'I':
  536. Predicate = false;
  537. Float = false;
  538. BFloat = false;
  539. ElementBitwidth = Bitwidth = 32;
  540. NumVectors = 0;
  541. Signed = true;
  542. Immediate = true;
  543. PredicatePattern = true;
  544. break;
  545. case 'J':
  546. Predicate = false;
  547. Float = false;
  548. BFloat = false;
  549. ElementBitwidth = Bitwidth = 32;
  550. NumVectors = 0;
  551. Signed = true;
  552. Immediate = true;
  553. PrefetchOp = true;
  554. break;
  555. case 'k':
  556. Predicate = false;
  557. Signed = true;
  558. Float = false;
  559. BFloat = false;
  560. ElementBitwidth = Bitwidth = 32;
  561. NumVectors = 0;
  562. break;
  563. case 'l':
  564. Predicate = false;
  565. Signed = true;
  566. Float = false;
  567. BFloat = false;
  568. ElementBitwidth = Bitwidth = 64;
  569. NumVectors = 0;
  570. break;
  571. case 'm':
  572. Predicate = false;
  573. Signed = false;
  574. Float = false;
  575. BFloat = false;
  576. ElementBitwidth = Bitwidth = 32;
  577. NumVectors = 0;
  578. break;
  579. case 'n':
  580. Predicate = false;
  581. Signed = false;
  582. Float = false;
  583. BFloat = false;
  584. ElementBitwidth = Bitwidth = 64;
  585. NumVectors = 0;
  586. break;
  587. case 'w':
  588. ElementBitwidth = 64;
  589. break;
  590. case 'j':
  591. ElementBitwidth = Bitwidth = 64;
  592. NumVectors = 0;
  593. break;
  594. case 'f':
  595. Signed = false;
  596. ElementBitwidth = Bitwidth = 64;
  597. NumVectors = 0;
  598. break;
  599. case 'g':
  600. Signed = false;
  601. Float = false;
  602. BFloat = false;
  603. ElementBitwidth = 64;
  604. break;
  605. case 't':
  606. Signed = true;
  607. Float = false;
  608. BFloat = false;
  609. ElementBitwidth = 32;
  610. break;
  611. case 'z':
  612. Signed = false;
  613. Float = false;
  614. BFloat = false;
  615. ElementBitwidth = 32;
  616. break;
  617. case 'O':
  618. Predicate = false;
  619. Float = true;
  620. ElementBitwidth = 16;
  621. break;
  622. case 'M':
  623. Predicate = false;
  624. Float = true;
  625. BFloat = false;
  626. ElementBitwidth = 32;
  627. break;
  628. case 'N':
  629. Predicate = false;
  630. Float = true;
  631. ElementBitwidth = 64;
  632. break;
  633. case 'Q':
  634. Constant = true;
  635. Pointer = true;
  636. Void = true;
  637. NumVectors = 0;
  638. break;
  639. case 'S':
  640. Constant = true;
  641. Pointer = true;
  642. ElementBitwidth = Bitwidth = 8;
  643. NumVectors = 0;
  644. Signed = true;
  645. break;
  646. case 'W':
  647. Constant = true;
  648. Pointer = true;
  649. ElementBitwidth = Bitwidth = 8;
  650. NumVectors = 0;
  651. Signed = false;
  652. break;
  653. case 'T':
  654. Constant = true;
  655. Pointer = true;
  656. ElementBitwidth = Bitwidth = 16;
  657. NumVectors = 0;
  658. Signed = true;
  659. break;
  660. case 'X':
  661. Constant = true;
  662. Pointer = true;
  663. ElementBitwidth = Bitwidth = 16;
  664. NumVectors = 0;
  665. Signed = false;
  666. break;
  667. case 'Y':
  668. Constant = true;
  669. Pointer = true;
  670. ElementBitwidth = Bitwidth = 32;
  671. NumVectors = 0;
  672. Signed = false;
  673. break;
  674. case 'U':
  675. Constant = true;
  676. Pointer = true;
  677. ElementBitwidth = Bitwidth = 32;
  678. NumVectors = 0;
  679. Signed = true;
  680. break;
  681. case 'A':
  682. Pointer = true;
  683. ElementBitwidth = Bitwidth = 8;
  684. NumVectors = 0;
  685. Signed = true;
  686. break;
  687. case 'B':
  688. Pointer = true;
  689. ElementBitwidth = Bitwidth = 16;
  690. NumVectors = 0;
  691. Signed = true;
  692. break;
  693. case 'C':
  694. Pointer = true;
  695. ElementBitwidth = Bitwidth = 32;
  696. NumVectors = 0;
  697. Signed = true;
  698. break;
  699. case 'D':
  700. Pointer = true;
  701. ElementBitwidth = Bitwidth = 64;
  702. NumVectors = 0;
  703. Signed = true;
  704. break;
  705. case 'E':
  706. Pointer = true;
  707. ElementBitwidth = Bitwidth = 8;
  708. NumVectors = 0;
  709. Signed = false;
  710. break;
  711. case 'F':
  712. Pointer = true;
  713. ElementBitwidth = Bitwidth = 16;
  714. NumVectors = 0;
  715. Signed = false;
  716. break;
  717. case 'G':
  718. Pointer = true;
  719. ElementBitwidth = Bitwidth = 32;
  720. NumVectors = 0;
  721. Signed = false;
  722. break;
  723. default:
  724. llvm_unreachable("Unhandled character!");
  725. }
  726. }
  727. //===----------------------------------------------------------------------===//
  728. // Intrinsic implementation
  729. //===----------------------------------------------------------------------===//
  730. Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
  731. StringRef MergeSuffix, uint64_t MemoryElementTy,
  732. StringRef LLVMName, uint64_t Flags,
  733. ArrayRef<ImmCheck> Checks, TypeSpec BT, ClassKind Class,
  734. SVEEmitter &Emitter, StringRef Guard)
  735. : Name(Name.str()), LLVMName(LLVMName), Proto(Proto.str()),
  736. BaseTypeSpec(BT), Class(Class), Guard(Guard.str()),
  737. MergeSuffix(MergeSuffix.str()), BaseType(BT, 'd'), Flags(Flags),
  738. ImmChecks(Checks.begin(), Checks.end()) {
  739. // Types[0] is the return value.
  740. for (unsigned I = 0; I < Proto.size(); ++I) {
  741. SVEType T(BaseTypeSpec, Proto[I]);
  742. Types.push_back(T);
  743. // Add range checks for immediates
  744. if (I > 0) {
  745. if (T.isPredicatePattern())
  746. ImmChecks.emplace_back(
  747. I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_31"));
  748. else if (T.isPrefetchOp())
  749. ImmChecks.emplace_back(
  750. I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_13"));
  751. }
  752. }
  753. // Set flags based on properties
  754. this->Flags |= Emitter.encodeTypeFlags(BaseType);
  755. this->Flags |= Emitter.encodeMemoryElementType(MemoryElementTy);
  756. this->Flags |= Emitter.encodeMergeType(MergeTy);
  757. if (hasSplat())
  758. this->Flags |= Emitter.encodeSplatOperand(getSplatIdx());
  759. }
  760. std::string Intrinsic::getBuiltinTypeStr() {
  761. std::string S = getReturnType().builtin_str();
  762. for (unsigned I = 0; I < getNumParams(); ++I)
  763. S += getParamType(I).builtin_str();
  764. return S;
  765. }
  766. std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
  767. std::string Proto) const {
  768. std::string Ret = Name;
  769. while (Ret.find('{') != std::string::npos) {
  770. size_t Pos = Ret.find('{');
  771. size_t End = Ret.find('}');
  772. unsigned NumChars = End - Pos + 1;
  773. assert(NumChars == 3 && "Unexpected template argument");
  774. SVEType T;
  775. char C = Ret[Pos+1];
  776. switch(C) {
  777. default:
  778. llvm_unreachable("Unknown predication specifier");
  779. case 'd':
  780. T = SVEType(TS, 'd');
  781. break;
  782. case '0':
  783. case '1':
  784. case '2':
  785. case '3':
  786. T = SVEType(TS, Proto[C - '0']);
  787. break;
  788. }
  789. // Replace templated arg with the right suffix (e.g. u32)
  790. std::string TypeCode;
  791. if (T.isInteger())
  792. TypeCode = T.isSigned() ? 's' : 'u';
  793. else if (T.isPredicateVector())
  794. TypeCode = 'b';
  795. else if (T.isBFloat())
  796. TypeCode = "bf";
  797. else
  798. TypeCode = 'f';
  799. Ret.replace(Pos, NumChars, TypeCode + utostr(T.getElementSizeInBits()));
  800. }
  801. return Ret;
  802. }
  803. std::string Intrinsic::mangleName(ClassKind LocalCK) const {
  804. std::string S = getName();
  805. if (LocalCK == ClassG) {
  806. // Remove the square brackets and everything in between.
  807. while (S.find('[') != std::string::npos) {
  808. auto Start = S.find('[');
  809. auto End = S.find(']');
  810. S.erase(Start, (End-Start)+1);
  811. }
  812. } else {
  813. // Remove the square brackets.
  814. while (S.find('[') != std::string::npos) {
  815. auto BrPos = S.find('[');
  816. if (BrPos != std::string::npos)
  817. S.erase(BrPos, 1);
  818. BrPos = S.find(']');
  819. if (BrPos != std::string::npos)
  820. S.erase(BrPos, 1);
  821. }
  822. }
  823. // Replace all {d} like expressions with e.g. 'u32'
  824. return replaceTemplatedArgs(S, getBaseTypeSpec(), getProto()) +
  825. getMergeSuffix();
  826. }
  827. void Intrinsic::emitIntrinsic(raw_ostream &OS) const {
  828. bool IsOverloaded = getClassKind() == ClassG && getProto().size() > 1;
  829. std::string FullName = mangleName(ClassS);
  830. std::string ProtoName = mangleName(getClassKind());
  831. OS << (IsOverloaded ? "__aio " : "__ai ")
  832. << "__attribute__((__clang_arm_builtin_alias("
  833. << "__builtin_sve_" << FullName << ")))\n";
  834. OS << getTypes()[0].str() << " " << ProtoName << "(";
  835. for (unsigned I = 0; I < getTypes().size() - 1; ++I) {
  836. if (I != 0)
  837. OS << ", ";
  838. OS << getTypes()[I + 1].str();
  839. }
  840. OS << ");\n";
  841. }
  842. //===----------------------------------------------------------------------===//
  843. // SVEEmitter implementation
  844. //===----------------------------------------------------------------------===//
  845. uint64_t SVEEmitter::encodeTypeFlags(const SVEType &T) {
  846. if (T.isFloat()) {
  847. switch (T.getElementSizeInBits()) {
  848. case 16:
  849. return encodeEltType("EltTyFloat16");
  850. case 32:
  851. return encodeEltType("EltTyFloat32");
  852. case 64:
  853. return encodeEltType("EltTyFloat64");
  854. default:
  855. llvm_unreachable("Unhandled float element bitwidth!");
  856. }
  857. }
  858. if (T.isBFloat()) {
  859. assert(T.getElementSizeInBits() == 16 && "Not a valid BFloat.");
  860. return encodeEltType("EltTyBFloat16");
  861. }
  862. if (T.isPredicateVector()) {
  863. switch (T.getElementSizeInBits()) {
  864. case 8:
  865. return encodeEltType("EltTyBool8");
  866. case 16:
  867. return encodeEltType("EltTyBool16");
  868. case 32:
  869. return encodeEltType("EltTyBool32");
  870. case 64:
  871. return encodeEltType("EltTyBool64");
  872. default:
  873. llvm_unreachable("Unhandled predicate element bitwidth!");
  874. }
  875. }
  876. switch (T.getElementSizeInBits()) {
  877. case 8:
  878. return encodeEltType("EltTyInt8");
  879. case 16:
  880. return encodeEltType("EltTyInt16");
  881. case 32:
  882. return encodeEltType("EltTyInt32");
  883. case 64:
  884. return encodeEltType("EltTyInt64");
  885. default:
  886. llvm_unreachable("Unhandled integer element bitwidth!");
  887. }
  888. }
  889. void SVEEmitter::createIntrinsic(
  890. Record *R, SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out) {
  891. StringRef Name = R->getValueAsString("Name");
  892. StringRef Proto = R->getValueAsString("Prototype");
  893. StringRef Types = R->getValueAsString("Types");
  894. StringRef Guard = R->getValueAsString("ArchGuard");
  895. StringRef LLVMName = R->getValueAsString("LLVMIntrinsic");
  896. uint64_t Merge = R->getValueAsInt("Merge");
  897. StringRef MergeSuffix = R->getValueAsString("MergeSuffix");
  898. uint64_t MemEltType = R->getValueAsInt("MemEltType");
  899. std::vector<Record*> FlagsList = R->getValueAsListOfDefs("Flags");
  900. std::vector<Record*> ImmCheckList = R->getValueAsListOfDefs("ImmChecks");
  901. int64_t Flags = 0;
  902. for (auto FlagRec : FlagsList)
  903. Flags |= FlagRec->getValueAsInt("Value");
  904. // Create a dummy TypeSpec for non-overloaded builtins.
  905. if (Types.empty()) {
  906. assert((Flags & getEnumValueForFlag("IsOverloadNone")) &&
  907. "Expect TypeSpec for overloaded builtin!");
  908. Types = "i";
  909. }
  910. // Extract type specs from string
  911. SmallVector<TypeSpec, 8> TypeSpecs;
  912. TypeSpec Acc;
  913. for (char I : Types) {
  914. Acc.push_back(I);
  915. if (islower(I)) {
  916. TypeSpecs.push_back(TypeSpec(Acc));
  917. Acc.clear();
  918. }
  919. }
  920. // Remove duplicate type specs.
  921. llvm::sort(TypeSpecs);
  922. TypeSpecs.erase(std::unique(TypeSpecs.begin(), TypeSpecs.end()),
  923. TypeSpecs.end());
  924. // Create an Intrinsic for each type spec.
  925. for (auto TS : TypeSpecs) {
  926. // Collate a list of range/option checks for the immediates.
  927. SmallVector<ImmCheck, 2> ImmChecks;
  928. for (auto *R : ImmCheckList) {
  929. int64_t Arg = R->getValueAsInt("Arg");
  930. int64_t EltSizeArg = R->getValueAsInt("EltSizeArg");
  931. int64_t Kind = R->getValueAsDef("Kind")->getValueAsInt("Value");
  932. assert(Arg >= 0 && Kind >= 0 && "Arg and Kind must be nonnegative");
  933. unsigned ElementSizeInBits = 0;
  934. if (EltSizeArg >= 0)
  935. ElementSizeInBits =
  936. SVEType(TS, Proto[EltSizeArg + /* offset by return arg */ 1])
  937. .getElementSizeInBits();
  938. ImmChecks.push_back(ImmCheck(Arg, Kind, ElementSizeInBits));
  939. }
  940. Out.push_back(std::make_unique<Intrinsic>(
  941. Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags, ImmChecks,
  942. TS, ClassS, *this, Guard));
  943. // Also generate the short-form (e.g. svadd_m) for the given type-spec.
  944. if (Intrinsic::isOverloadedIntrinsic(Name))
  945. Out.push_back(std::make_unique<Intrinsic>(
  946. Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags,
  947. ImmChecks, TS, ClassG, *this, Guard));
  948. }
  949. }
  950. void SVEEmitter::createHeader(raw_ostream &OS) {
  951. OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
  952. "-----------------------------------===\n"
  953. " *\n"
  954. " *\n"
  955. " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
  956. "Exceptions.\n"
  957. " * See https://llvm.org/LICENSE.txt for license information.\n"
  958. " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
  959. " *\n"
  960. " *===-----------------------------------------------------------------"
  961. "------===\n"
  962. " */\n\n";
  963. OS << "#ifndef __ARM_SVE_H\n";
  964. OS << "#define __ARM_SVE_H\n\n";
  965. OS << "#if !defined(__ARM_FEATURE_SVE)\n";
  966. OS << "#error \"SVE support not enabled\"\n";
  967. OS << "#else\n\n";
  968. OS << "#if !defined(__LITTLE_ENDIAN__)\n";
  969. OS << "#error \"Big endian is currently not supported for arm_sve.h\"\n";
  970. OS << "#endif\n";
  971. OS << "#include <stdint.h>\n\n";
  972. OS << "#ifdef __cplusplus\n";
  973. OS << "extern \"C\" {\n";
  974. OS << "#else\n";
  975. OS << "#include <stdbool.h>\n";
  976. OS << "#endif\n\n";
  977. OS << "typedef __fp16 float16_t;\n";
  978. OS << "typedef float float32_t;\n";
  979. OS << "typedef double float64_t;\n";
  980. OS << "typedef __SVInt8_t svint8_t;\n";
  981. OS << "typedef __SVInt16_t svint16_t;\n";
  982. OS << "typedef __SVInt32_t svint32_t;\n";
  983. OS << "typedef __SVInt64_t svint64_t;\n";
  984. OS << "typedef __SVUint8_t svuint8_t;\n";
  985. OS << "typedef __SVUint16_t svuint16_t;\n";
  986. OS << "typedef __SVUint32_t svuint32_t;\n";
  987. OS << "typedef __SVUint64_t svuint64_t;\n";
  988. OS << "typedef __SVFloat16_t svfloat16_t;\n\n";
  989. OS << "#if defined(__ARM_FEATURE_SVE_BF16) && "
  990. "!defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)\n";
  991. OS << "#error \"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC must be defined when "
  992. "__ARM_FEATURE_SVE_BF16 is defined\"\n";
  993. OS << "#endif\n\n";
  994. OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n";
  995. OS << "typedef __SVBFloat16_t svbfloat16_t;\n";
  996. OS << "#endif\n\n";
  997. OS << "#if defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)\n";
  998. OS << "#include <arm_bf16.h>\n";
  999. OS << "typedef __bf16 bfloat16_t;\n";
  1000. OS << "#endif\n\n";
  1001. OS << "typedef __SVFloat32_t svfloat32_t;\n";
  1002. OS << "typedef __SVFloat64_t svfloat64_t;\n";
  1003. OS << "typedef __clang_svint8x2_t svint8x2_t;\n";
  1004. OS << "typedef __clang_svint16x2_t svint16x2_t;\n";
  1005. OS << "typedef __clang_svint32x2_t svint32x2_t;\n";
  1006. OS << "typedef __clang_svint64x2_t svint64x2_t;\n";
  1007. OS << "typedef __clang_svuint8x2_t svuint8x2_t;\n";
  1008. OS << "typedef __clang_svuint16x2_t svuint16x2_t;\n";
  1009. OS << "typedef __clang_svuint32x2_t svuint32x2_t;\n";
  1010. OS << "typedef __clang_svuint64x2_t svuint64x2_t;\n";
  1011. OS << "typedef __clang_svfloat16x2_t svfloat16x2_t;\n";
  1012. OS << "typedef __clang_svfloat32x2_t svfloat32x2_t;\n";
  1013. OS << "typedef __clang_svfloat64x2_t svfloat64x2_t;\n";
  1014. OS << "typedef __clang_svint8x3_t svint8x3_t;\n";
  1015. OS << "typedef __clang_svint16x3_t svint16x3_t;\n";
  1016. OS << "typedef __clang_svint32x3_t svint32x3_t;\n";
  1017. OS << "typedef __clang_svint64x3_t svint64x3_t;\n";
  1018. OS << "typedef __clang_svuint8x3_t svuint8x3_t;\n";
  1019. OS << "typedef __clang_svuint16x3_t svuint16x3_t;\n";
  1020. OS << "typedef __clang_svuint32x3_t svuint32x3_t;\n";
  1021. OS << "typedef __clang_svuint64x3_t svuint64x3_t;\n";
  1022. OS << "typedef __clang_svfloat16x3_t svfloat16x3_t;\n";
  1023. OS << "typedef __clang_svfloat32x3_t svfloat32x3_t;\n";
  1024. OS << "typedef __clang_svfloat64x3_t svfloat64x3_t;\n";
  1025. OS << "typedef __clang_svint8x4_t svint8x4_t;\n";
  1026. OS << "typedef __clang_svint16x4_t svint16x4_t;\n";
  1027. OS << "typedef __clang_svint32x4_t svint32x4_t;\n";
  1028. OS << "typedef __clang_svint64x4_t svint64x4_t;\n";
  1029. OS << "typedef __clang_svuint8x4_t svuint8x4_t;\n";
  1030. OS << "typedef __clang_svuint16x4_t svuint16x4_t;\n";
  1031. OS << "typedef __clang_svuint32x4_t svuint32x4_t;\n";
  1032. OS << "typedef __clang_svuint64x4_t svuint64x4_t;\n";
  1033. OS << "typedef __clang_svfloat16x4_t svfloat16x4_t;\n";
  1034. OS << "typedef __clang_svfloat32x4_t svfloat32x4_t;\n";
  1035. OS << "typedef __clang_svfloat64x4_t svfloat64x4_t;\n";
  1036. OS << "typedef __SVBool_t svbool_t;\n\n";
  1037. OS << "#ifdef __ARM_FEATURE_SVE_BF16\n";
  1038. OS << "typedef __clang_svbfloat16x2_t svbfloat16x2_t;\n";
  1039. OS << "typedef __clang_svbfloat16x3_t svbfloat16x3_t;\n";
  1040. OS << "typedef __clang_svbfloat16x4_t svbfloat16x4_t;\n";
  1041. OS << "#endif\n";
  1042. OS << "enum svpattern\n";
  1043. OS << "{\n";
  1044. OS << " SV_POW2 = 0,\n";
  1045. OS << " SV_VL1 = 1,\n";
  1046. OS << " SV_VL2 = 2,\n";
  1047. OS << " SV_VL3 = 3,\n";
  1048. OS << " SV_VL4 = 4,\n";
  1049. OS << " SV_VL5 = 5,\n";
  1050. OS << " SV_VL6 = 6,\n";
  1051. OS << " SV_VL7 = 7,\n";
  1052. OS << " SV_VL8 = 8,\n";
  1053. OS << " SV_VL16 = 9,\n";
  1054. OS << " SV_VL32 = 10,\n";
  1055. OS << " SV_VL64 = 11,\n";
  1056. OS << " SV_VL128 = 12,\n";
  1057. OS << " SV_VL256 = 13,\n";
  1058. OS << " SV_MUL4 = 29,\n";
  1059. OS << " SV_MUL3 = 30,\n";
  1060. OS << " SV_ALL = 31\n";
  1061. OS << "};\n\n";
  1062. OS << "enum svprfop\n";
  1063. OS << "{\n";
  1064. OS << " SV_PLDL1KEEP = 0,\n";
  1065. OS << " SV_PLDL1STRM = 1,\n";
  1066. OS << " SV_PLDL2KEEP = 2,\n";
  1067. OS << " SV_PLDL2STRM = 3,\n";
  1068. OS << " SV_PLDL3KEEP = 4,\n";
  1069. OS << " SV_PLDL3STRM = 5,\n";
  1070. OS << " SV_PSTL1KEEP = 8,\n";
  1071. OS << " SV_PSTL1STRM = 9,\n";
  1072. OS << " SV_PSTL2KEEP = 10,\n";
  1073. OS << " SV_PSTL2STRM = 11,\n";
  1074. OS << " SV_PSTL3KEEP = 12,\n";
  1075. OS << " SV_PSTL3STRM = 13\n";
  1076. OS << "};\n\n";
  1077. OS << "/* Function attributes */\n";
  1078. OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
  1079. "__nodebug__))\n\n";
  1080. OS << "#define __aio static __inline__ __attribute__((__always_inline__, "
  1081. "__nodebug__, __overloadable__))\n\n";
  1082. // Add reinterpret functions.
  1083. for (auto ShortForm : { false, true } )
  1084. for (const ReinterpretTypeInfo &From : Reinterprets)
  1085. for (const ReinterpretTypeInfo &To : Reinterprets) {
  1086. const bool IsBFloat = StringRef(From.Suffix).equals("bf16") ||
  1087. StringRef(To.Suffix).equals("bf16");
  1088. if (IsBFloat)
  1089. OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n";
  1090. if (ShortForm) {
  1091. OS << "__aio " << From.Type << " svreinterpret_" << From.Suffix;
  1092. OS << "(" << To.Type << " op) {\n";
  1093. OS << " return __builtin_sve_reinterpret_" << From.Suffix << "_"
  1094. << To.Suffix << "(op);\n";
  1095. OS << "}\n\n";
  1096. } else
  1097. OS << "#define svreinterpret_" << From.Suffix << "_" << To.Suffix
  1098. << "(...) __builtin_sve_reinterpret_" << From.Suffix << "_"
  1099. << To.Suffix << "(__VA_ARGS__)\n";
  1100. if (IsBFloat)
  1101. OS << "#endif /* #if defined(__ARM_FEATURE_SVE_BF16) */\n";
  1102. }
  1103. SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
  1104. std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
  1105. for (auto *R : RV)
  1106. createIntrinsic(R, Defs);
  1107. // Sort intrinsics in header file by following order/priority:
  1108. // - Architectural guard (i.e. does it require SVE2 or SVE2_AES)
  1109. // - Class (is intrinsic overloaded or not)
  1110. // - Intrinsic name
  1111. std::stable_sort(
  1112. Defs.begin(), Defs.end(), [](const std::unique_ptr<Intrinsic> &A,
  1113. const std::unique_ptr<Intrinsic> &B) {
  1114. auto ToTuple = [](const std::unique_ptr<Intrinsic> &I) {
  1115. return std::make_tuple(I->getGuard(), (unsigned)I->getClassKind(), I->getName());
  1116. };
  1117. return ToTuple(A) < ToTuple(B);
  1118. });
  1119. StringRef InGuard = "";
  1120. for (auto &I : Defs) {
  1121. // Emit #endif/#if pair if needed.
  1122. if (I->getGuard() != InGuard) {
  1123. if (!InGuard.empty())
  1124. OS << "#endif //" << InGuard << "\n";
  1125. InGuard = I->getGuard();
  1126. if (!InGuard.empty())
  1127. OS << "\n#if " << InGuard << "\n";
  1128. }
  1129. // Actually emit the intrinsic declaration.
  1130. I->emitIntrinsic(OS);
  1131. }
  1132. if (!InGuard.empty())
  1133. OS << "#endif //" << InGuard << "\n";
  1134. OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n";
  1135. OS << "#define svcvtnt_bf16_x svcvtnt_bf16_m\n";
  1136. OS << "#define svcvtnt_bf16_f32_x svcvtnt_bf16_f32_m\n";
  1137. OS << "#endif /*__ARM_FEATURE_SVE_BF16 */\n\n";
  1138. OS << "#if defined(__ARM_FEATURE_SVE2)\n";
  1139. OS << "#define svcvtnt_f16_x svcvtnt_f16_m\n";
  1140. OS << "#define svcvtnt_f16_f32_x svcvtnt_f16_f32_m\n";
  1141. OS << "#define svcvtnt_f32_x svcvtnt_f32_m\n";
  1142. OS << "#define svcvtnt_f32_f64_x svcvtnt_f32_f64_m\n\n";
  1143. OS << "#define svcvtxnt_f32_x svcvtxnt_f32_m\n";
  1144. OS << "#define svcvtxnt_f32_f64_x svcvtxnt_f32_f64_m\n\n";
  1145. OS << "#endif /*__ARM_FEATURE_SVE2 */\n\n";
  1146. OS << "#ifdef __cplusplus\n";
  1147. OS << "} // extern \"C\"\n";
  1148. OS << "#endif\n\n";
  1149. OS << "#endif /*__ARM_FEATURE_SVE */\n\n";
  1150. OS << "#endif /* __ARM_SVE_H */\n";
  1151. }
  1152. void SVEEmitter::createBuiltins(raw_ostream &OS) {
  1153. std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
  1154. SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
  1155. for (auto *R : RV)
  1156. createIntrinsic(R, Defs);
  1157. // The mappings must be sorted based on BuiltinID.
  1158. llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
  1159. const std::unique_ptr<Intrinsic> &B) {
  1160. return A->getMangledName() < B->getMangledName();
  1161. });
  1162. OS << "#ifdef GET_SVE_BUILTINS\n";
  1163. for (auto &Def : Defs) {
  1164. // Only create BUILTINs for non-overloaded intrinsics, as overloaded
  1165. // declarations only live in the header file.
  1166. if (Def->getClassKind() != ClassG)
  1167. OS << "BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \""
  1168. << Def->getBuiltinTypeStr() << "\", \"n\")\n";
  1169. }
  1170. // Add reinterpret builtins
  1171. for (const ReinterpretTypeInfo &From : Reinterprets)
  1172. for (const ReinterpretTypeInfo &To : Reinterprets)
  1173. OS << "BUILTIN(__builtin_sve_reinterpret_" << From.Suffix << "_"
  1174. << To.Suffix << +", \"" << From.BuiltinType << To.BuiltinType
  1175. << "\", \"n\")\n";
  1176. OS << "#endif\n\n";
  1177. }
  1178. void SVEEmitter::createCodeGenMap(raw_ostream &OS) {
  1179. std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
  1180. SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
  1181. for (auto *R : RV)
  1182. createIntrinsic(R, Defs);
  1183. // The mappings must be sorted based on BuiltinID.
  1184. llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
  1185. const std::unique_ptr<Intrinsic> &B) {
  1186. return A->getMangledName() < B->getMangledName();
  1187. });
  1188. OS << "#ifdef GET_SVE_LLVM_INTRINSIC_MAP\n";
  1189. for (auto &Def : Defs) {
  1190. // Builtins only exist for non-overloaded intrinsics, overloaded
  1191. // declarations only live in the header file.
  1192. if (Def->getClassKind() == ClassG)
  1193. continue;
  1194. uint64_t Flags = Def->getFlags();
  1195. auto FlagString = std::to_string(Flags);
  1196. std::string LLVMName = Def->getLLVMName();
  1197. std::string Builtin = Def->getMangledName();
  1198. if (!LLVMName.empty())
  1199. OS << "SVEMAP1(" << Builtin << ", " << LLVMName << ", " << FlagString
  1200. << "),\n";
  1201. else
  1202. OS << "SVEMAP2(" << Builtin << ", " << FlagString << "),\n";
  1203. }
  1204. OS << "#endif\n\n";
  1205. }
  1206. void SVEEmitter::createRangeChecks(raw_ostream &OS) {
  1207. std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
  1208. SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
  1209. for (auto *R : RV)
  1210. createIntrinsic(R, Defs);
  1211. // The mappings must be sorted based on BuiltinID.
  1212. llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
  1213. const std::unique_ptr<Intrinsic> &B) {
  1214. return A->getMangledName() < B->getMangledName();
  1215. });
  1216. OS << "#ifdef GET_SVE_IMMEDIATE_CHECK\n";
  1217. // Ensure these are only emitted once.
  1218. std::set<std::string> Emitted;
  1219. for (auto &Def : Defs) {
  1220. if (Emitted.find(Def->getMangledName()) != Emitted.end() ||
  1221. Def->getImmChecks().empty())
  1222. continue;
  1223. OS << "case SVE::BI__builtin_sve_" << Def->getMangledName() << ":\n";
  1224. for (auto &Check : Def->getImmChecks())
  1225. OS << "ImmChecks.push_back(std::make_tuple(" << Check.getArg() << ", "
  1226. << Check.getKind() << ", " << Check.getElementSizeInBits() << "));\n";
  1227. OS << " break;\n";
  1228. Emitted.insert(Def->getMangledName());
  1229. }
  1230. OS << "#endif\n\n";
  1231. }
  1232. /// Create the SVETypeFlags used in CGBuiltins
  1233. void SVEEmitter::createTypeFlags(raw_ostream &OS) {
  1234. OS << "#ifdef LLVM_GET_SVE_TYPEFLAGS\n";
  1235. for (auto &KV : FlagTypes)
  1236. OS << "const uint64_t " << KV.getKey() << " = " << KV.getValue() << ";\n";
  1237. OS << "#endif\n\n";
  1238. OS << "#ifdef LLVM_GET_SVE_ELTTYPES\n";
  1239. for (auto &KV : EltTypes)
  1240. OS << " " << KV.getKey() << " = " << KV.getValue() << ",\n";
  1241. OS << "#endif\n\n";
  1242. OS << "#ifdef LLVM_GET_SVE_MEMELTTYPES\n";
  1243. for (auto &KV : MemEltTypes)
  1244. OS << " " << KV.getKey() << " = " << KV.getValue() << ",\n";
  1245. OS << "#endif\n\n";
  1246. OS << "#ifdef LLVM_GET_SVE_MERGETYPES\n";
  1247. for (auto &KV : MergeTypes)
  1248. OS << " " << KV.getKey() << " = " << KV.getValue() << ",\n";
  1249. OS << "#endif\n\n";
  1250. OS << "#ifdef LLVM_GET_SVE_IMMCHECKTYPES\n";
  1251. for (auto &KV : ImmCheckTypes)
  1252. OS << " " << KV.getKey() << " = " << KV.getValue() << ",\n";
  1253. OS << "#endif\n\n";
  1254. }
  1255. namespace clang {
  1256. void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
  1257. SVEEmitter(Records).createHeader(OS);
  1258. }
  1259. void EmitSveBuiltins(RecordKeeper &Records, raw_ostream &OS) {
  1260. SVEEmitter(Records).createBuiltins(OS);
  1261. }
  1262. void EmitSveBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
  1263. SVEEmitter(Records).createCodeGenMap(OS);
  1264. }
  1265. void EmitSveRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
  1266. SVEEmitter(Records).createRangeChecks(OS);
  1267. }
  1268. void EmitSveTypeFlags(RecordKeeper &Records, raw_ostream &OS) {
  1269. SVEEmitter(Records).createTypeFlags(OS);
  1270. }
  1271. } // End namespace clang