Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #ifndef RUST_BUILTINS_H
20 : #define RUST_BUILTINS_H
21 :
22 : #include "rust-system.h"
23 : #include "rust-tree.h"
24 : #include "langhooks.h"
25 : #include "tree.h"
26 : #include "selftest.h"
27 :
28 : namespace Rust {
29 : namespace Compile {
30 :
31 : // https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs
32 : // https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs
33 : // https://github.com/Rust-GCC/gccrs/issues/658
34 : //
35 : // let llvm_name = match name {
36 : // sym::sqrtf32 => "llvm.sqrt.f32",
37 : // sym::sqrtf64 => "llvm.sqrt.f64",
38 : // sym::powif32 => "llvm.powi.f32",
39 : // sym::powif64 => "llvm.powi.f64",
40 : // sym::sinf32 => "llvm.sin.f32",
41 : // sym::sinf64 => "llvm.sin.f64",
42 : // sym::cosf32 => "llvm.cos.f32",
43 : // sym::cosf64 => "llvm.cos.f64",
44 : // sym::powf32 => "llvm.pow.f32",
45 : // sym::powf64 => "llvm.pow.f64",
46 : // sym::expf32 => "llvm.exp.f32",
47 : // sym::expf64 => "llvm.exp.f64",
48 : // sym::exp2f32 => "llvm.exp2.f32",
49 : // sym::exp2f64 => "llvm.exp2.f64",
50 : // sym::logf32 => "llvm.log.f32",
51 : // sym::logf64 => "llvm.log.f64",
52 : // sym::log10f32 => "llvm.log10.f32",
53 : // sym::log10f64 => "llvm.log10.f64",
54 : // sym::log2f32 => "llvm.log2.f32",
55 : // sym::log2f64 => "llvm.log2.f64",
56 : // sym::fmaf32 => "llvm.fma.f32",
57 : // sym::fmaf64 => "llvm.fma.f64",
58 : // sym::fabsf32 => "llvm.fabs.f32",
59 : // sym::fabsf64 => "llvm.fabs.f64",
60 : // sym::minnumf32 => "llvm.minnum.f32",
61 : // sym::minnumf64 => "llvm.minnum.f64",
62 : // sym::maxnumf32 => "llvm.maxnum.f32",
63 : // sym::maxnumf64 => "llvm.maxnum.f64",
64 : // sym::copysignf32 => "llvm.copysign.f32",
65 : // sym::copysignf64 => "llvm.copysign.f64",
66 : // sym::floorf32 => "llvm.floor.f32",
67 : // sym::floorf64 => "llvm.floor.f64",
68 : // sym::ceilf32 => "llvm.ceil.f32",
69 : // sym::ceilf64 => "llvm.ceil.f64",
70 : // sym::truncf32 => "llvm.trunc.f32",
71 : // sym::truncf64 => "llvm.trunc.f64",
72 : // sym::rintf32 => "llvm.rint.f32",
73 : // sym::rintf64 => "llvm.rint.f64",
74 : // sym::nearbyintf32 => "llvm.nearbyint.f32",
75 : // sym::nearbyintf64 => "llvm.nearbyint.f64",
76 : // sym::roundf32 => "llvm.round.f32",
77 : // sym::roundf64 => "llvm.round.f64",
78 : // _ => return None,
79 : // };
80 : // Some(cx.get_intrinsic(&llvm_name))
81 :
82 : enum class LlvmBuiltinMappingResult
83 : {
84 : NOT_MAPPED,
85 : TARGET_UNAVAILABLE,
86 : RESOLVED,
87 : };
88 :
89 : enum class LlvmBuiltinAdapter
90 : {
91 : OUTPUT_POINTER_VALUE_STATUS,
92 : OUTPUT_POINTER_STATUS_VALUE,
93 : FORWARD_ARGUMENTS,
94 : };
95 :
96 217117 : struct LlvmBuiltinMapping
97 : {
98 : std::string gcc_name;
99 : LlvmBuiltinAdapter adapter;
100 : };
101 :
102 : class BuiltinsContext
103 : {
104 : public:
105 : static BuiltinsContext &get ();
106 :
107 : bool lookup_simple_builtin (const std::string &name, tree *builtin);
108 :
109 : LlvmBuiltinMappingResult
110 : map_llvm_to_gcc_builtin (const std::string &name, tree *resolved,
111 : LlvmBuiltinAdapter *adapter);
112 :
113 : void register_builtin (tree decl);
114 :
115 : private:
116 : enum Type
117 : {
118 : #define DEF_PRIMITIVE_TYPE(NAME, V) NAME,
119 : #define DEF_FUNCTION_TYPE_0(NAME, R) NAME,
120 : #define DEF_FUNCTION_TYPE_1(NAME, R, A1) NAME,
121 : #define DEF_FUNCTION_TYPE_2(NAME, R, A1, A2) NAME,
122 : #define DEF_FUNCTION_TYPE_3(NAME, R, A1, A2, A3) NAME,
123 : #define DEF_FUNCTION_TYPE_4(NAME, R, A1, A2, A3, A4) NAME,
124 : #define DEF_FUNCTION_TYPE_5(NAME, R, A1, A2, A3, A4, A5) NAME,
125 : #define DEF_FUNCTION_TYPE_6(NAME, R, A1, A2, A3, A4, A5, A6) NAME,
126 : #define DEF_FUNCTION_TYPE_7(NAME, R, A1, A2, A3, A4, A5, A6, A7) NAME,
127 : #define DEF_FUNCTION_TYPE_8(NAME, R, A1, A2, A3, A4, A5, A6, A7, A8) NAME,
128 : #define DEF_FUNCTION_TYPE_9(NAME, R, A1, A2, A3, A4, A5, A6, A7, A8, A9) NAME,
129 : #define DEF_FUNCTION_TYPE_10(NAME, R, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) \
130 : NAME,
131 : #define DEF_FUNCTION_TYPE_11(NAME, R, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, \
132 : A11) \
133 : NAME,
134 : #define DEF_FUNCTION_TYPE_VAR_0(NAME, R) NAME,
135 : #define DEF_FUNCTION_TYPE_VAR_1(NAME, R, A1) NAME,
136 : #define DEF_FUNCTION_TYPE_VAR_2(NAME, R, A1, A2) NAME,
137 : #define DEF_FUNCTION_TYPE_VAR_3(NAME, R, A1, A2, A3) NAME,
138 : #define DEF_FUNCTION_TYPE_VAR_4(NAME, R, A1, A2, A3, A4) NAME,
139 : #define DEF_FUNCTION_TYPE_VAR_5(NAME, R, A1, A2, A3, A4, A5) NAME,
140 : #define DEF_FUNCTION_TYPE_VAR_6(NAME, R, A1, A2, A3, A4, A5, A6) NAME,
141 : #define DEF_FUNCTION_TYPE_VAR_7(NAME, R, A1, A2, A3, A4, A5, A6, A7) NAME,
142 : #define DEF_FUNCTION_TYPE_VAR_11(NAME, R, A1, A2, A3, A4, A5, A6, A7, A8, A9, \
143 : A10, A11) \
144 : NAME,
145 : #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
146 :
147 : #include "builtin-types.def"
148 :
149 : #undef DEF_PRIMITIVE_TYPE
150 : #undef DEF_FUNCTION_TYPE_0
151 : #undef DEF_FUNCTION_TYPE_1
152 : #undef DEF_FUNCTION_TYPE_2
153 : #undef DEF_FUNCTION_TYPE_3
154 : #undef DEF_FUNCTION_TYPE_4
155 : #undef DEF_FUNCTION_TYPE_5
156 : #undef DEF_FUNCTION_TYPE_6
157 : #undef DEF_FUNCTION_TYPE_7
158 : #undef DEF_FUNCTION_TYPE_8
159 : #undef DEF_FUNCTION_TYPE_9
160 : #undef DEF_FUNCTION_TYPE_10
161 : #undef DEF_FUNCTION_TYPE_11
162 : #undef DEF_FUNCTION_TYPE_VAR_0
163 : #undef DEF_FUNCTION_TYPE_VAR_1
164 : #undef DEF_FUNCTION_TYPE_VAR_2
165 : #undef DEF_FUNCTION_TYPE_VAR_3
166 : #undef DEF_FUNCTION_TYPE_VAR_4
167 : #undef DEF_FUNCTION_TYPE_VAR_5
168 : #undef DEF_FUNCTION_TYPE_VAR_6
169 : #undef DEF_FUNCTION_TYPE_VAR_7
170 : #undef DEF_FUNCTION_TYPE_VAR_11
171 : #undef DEF_POINTER_TYPE
172 :
173 : BT_LAST,
174 : };
175 :
176 : enum Attr
177 : {
178 : #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
179 : #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
180 : #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
181 : #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
182 : #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
183 :
184 : #include "builtin-attrs.def"
185 :
186 : #undef DEF_ATTR_NULL_TREE
187 : #undef DEF_ATTR_INT
188 : #undef DEF_ATTR_STRING
189 : #undef DEF_ATTR_IDENT
190 : #undef DEF_ATTR_TREE_LIST
191 :
192 : ATTR_LAST,
193 : };
194 :
195 : enum class SetupState
196 : {
197 : UNINITIALIZED,
198 : INITIALIZING,
199 : READY,
200 : };
201 :
202 : SetupState setup_state;
203 :
204 : /**
205 : * All builtin types, as defined in `builtin-types.def`
206 : *
207 : * This array is filled by the `define_builtin_types` method, during the first
208 : * initialization of the `BuiltinsContext`
209 : */
210 : tree builtin_types[Type::BT_LAST + 1];
211 :
212 : /**
213 : * Similarly, this array contains all builtin attributes, as defined in
214 : * `builtin-attr.def`
215 : *
216 : * This array is filled by the `define_builtin_attributes` method, during the
217 : * first initialization of the `BuiltinsContext`
218 : */
219 : tree builtin_attributes[Attr::ATTR_LAST + 1];
220 :
221 : void define_function_type (Type def, Type ret, bool is_variadic, size_t n,
222 : ...);
223 : void define_builtin_types ();
224 : void define_builtin_attributes ();
225 : void define_builtins ();
226 :
227 : void register_rust_mappings ();
228 : void register_llvm_to_gcc_builtin ();
229 :
230 : BuiltinsContext ();
231 :
232 : void setup_overflow_fns ();
233 : void setup_math_fns ();
234 : void setup_atomic_fns ();
235 :
236 : void setup ();
237 :
238 : bool lookup_gcc_builtin (const std::string &name, tree *builtin);
239 :
240 : // A mapping of the GCC built-ins exposed to GCC Rust.
241 : std::map<std::string, tree> builtin_functions;
242 : std::map<std::string, std::string> rust_intrinsic_to_gcc_builtin;
243 : std::map<std::string, LlvmBuiltinMapping> llvm_to_gcc_builtin;
244 : };
245 :
246 : } // namespace Compile
247 : } // namespace Rust
248 :
249 : #endif // RUST_BUILTINS_H
|