Sander de Smalen | 5087ace | 2020-03-15 14:29:45 +0000 | [diff] [blame] | 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 { |
Sander de Smalen | 5087ace | 2020-03-15 14:29:45 +0000 | [diff] [blame] | 46 | public: |
Sander de Smalen | 5087ace | 2020-03-15 14:29:45 +0000 | [diff] [blame] | 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) { |
Benjamin Kramer | 5cc9dea | 2020-03-15 16:51:22 +0100 | [diff] [blame^] | 120 | SVEEmitter().run(OS); |
Sander de Smalen | 5087ace | 2020-03-15 14:29:45 +0000 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | } // End namespace clang |