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/STLExtras.h"
27 #include "llvm/ADT/DenseMap.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/TableGen/Record.h"
31 #include "llvm/TableGen/Error.h"
32 #include <string>
33 #include <sstream>
34 #include <set>
35 #include <cctype>
36 
37 using namespace llvm;
38 
39 //===----------------------------------------------------------------------===//
40 // SVEEmitter
41 //===----------------------------------------------------------------------===//
42 
43 namespace {
44 
45 class SVEEmitter {
46 public:
47   // run - Emit arm_sve.h
48   void run(raw_ostream &o);
49 };
50 
51 } // end anonymous namespace
52 
53 
54 //===----------------------------------------------------------------------===//
55 // SVEEmitter implementation
56 //===----------------------------------------------------------------------===//
57 
58 void SVEEmitter::run(raw_ostream &OS) {
59   OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
60         "-----------------------------------===\n"
61         " *\n"
62         " *\n"
63         " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
64         "Exceptions.\n"
65         " * See https://llvm.org/LICENSE.txt for license information.\n"
66         " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
67         " *\n"
68         " *===-----------------------------------------------------------------"
69         "------===\n"
70         " */\n\n";
71 
72   OS << "#ifndef __ARM_SVE_H\n";
73   OS << "#define __ARM_SVE_H\n\n";
74 
75   OS << "#if !defined(__ARM_FEATURE_SVE)\n";
76   OS << "#error \"SVE support not enabled\"\n";
77   OS << "#else\n\n";
78 
79   OS << "#include <stdint.h>\n\n";
80   OS << "#ifndef  __cplusplus\n";
81   OS << "#include <stdbool.h>\n";
82   OS << "#endif\n\n";
83 
84   OS << "typedef __fp16 float16_t;\n";
85   OS << "typedef float float32_t;\n";
86   OS << "typedef double float64_t;\n";
87   OS << "typedef bool bool_t;\n\n";
88 
89   OS << "typedef __SVInt8_t svint8_t;\n";
90   OS << "typedef __SVInt16_t svint16_t;\n";
91   OS << "typedef __SVInt32_t svint32_t;\n";
92   OS << "typedef __SVInt64_t svint64_t;\n";
93   OS << "typedef __SVUint8_t svuint8_t;\n";
94   OS << "typedef __SVUint16_t svuint16_t;\n";
95   OS << "typedef __SVUint32_t svuint32_t;\n";
96   OS << "typedef __SVUint64_t svuint64_t;\n";
97   OS << "typedef __SVFloat16_t svfloat16_t;\n";
98   OS << "typedef __SVFloat32_t svfloat32_t;\n";
99   OS << "typedef __SVFloat64_t svfloat64_t;\n";
100   OS << "typedef __SVBool_t  svbool_t;\n\n";
101 
102   OS << "#define svld1_u8(...) __builtin_sve_svld1_u8(__VA_ARGS__)\n";
103   OS << "#define svld1_u16(...) __builtin_sve_svld1_u16(__VA_ARGS__)\n";
104   OS << "#define svld1_u32(...) __builtin_sve_svld1_u32(__VA_ARGS__)\n";
105   OS << "#define svld1_u64(...) __builtin_sve_svld1_u64(__VA_ARGS__)\n";
106   OS << "#define svld1_s8(...) __builtin_sve_svld1_s8(__VA_ARGS__)\n";
107   OS << "#define svld1_s16(...) __builtin_sve_svld1_s16(__VA_ARGS__)\n";
108   OS << "#define svld1_s32(...) __builtin_sve_svld1_s32(__VA_ARGS__)\n";
109   OS << "#define svld1_s64(...) __builtin_sve_svld1_s64(__VA_ARGS__)\n";
110   OS << "#define svld1_f16(...) __builtin_sve_svld1_f16(__VA_ARGS__)\n";
111   OS << "#define svld1_f32(...) __builtin_sve_svld1_f32(__VA_ARGS__)\n";
112   OS << "#define svld1_f64(...) __builtin_sve_svld1_f64(__VA_ARGS__)\n";
113 
114   OS << "#endif /*__ARM_FEATURE_SVE */\n";
115   OS << "#endif /* __ARM_SVE_H */\n";
116 }
117 
118 namespace clang {
119 void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
120   SVEEmitter().run(OS);
121 }
122 
123 } // End namespace clang
124