1 | /* Data structure definitions for a generic GCC target. |
2 | Copyright (C) 2001-2024 Free Software Foundation, Inc. |
3 | |
4 | This program is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU General Public License as published by the |
6 | Free Software Foundation; either version 3, or (at your option) any |
7 | later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; see the file COPYING3. If not see |
16 | <http://www.gnu.org/licenses/>. |
17 | |
18 | In other words, you are welcome to use, share and improve this program. |
19 | You are forbidden to forbid anyone else to use, share and improve |
20 | what you give them. Help stamp out software-hoarding! */ |
21 | |
22 | |
23 | /* This file contains a data structure that describes a GCC target. |
24 | At present it is incomplete, but in future it should grow to |
25 | contain most or all target machine and target O/S specific |
26 | information. |
27 | |
28 | This structure has its initializer declared in target-def.h in the |
29 | form of large macro TARGET_INITIALIZER that expands to many smaller |
30 | macros. |
31 | |
32 | The smaller macros each initialize one component of the structure, |
33 | and each has a default. Each target should have a file that |
34 | includes target.h and target-def.h, and overrides any inappropriate |
35 | defaults by undefining the relevant macro and defining a suitable |
36 | replacement. That file should then contain the definition of |
37 | "targetm" like so: |
38 | |
39 | struct gcc_target targetm = TARGET_INITIALIZER; |
40 | |
41 | Doing things this way allows us to bring together everything that |
42 | defines a GCC target. By supplying a default that is appropriate |
43 | to most targets, we can easily add new items without needing to |
44 | edit dozens of target configuration files. It should also allow us |
45 | to gradually reduce the amount of conditional compilation that is |
46 | scattered throughout GCC. */ |
47 | |
48 | #ifndef GCC_TARGET_H |
49 | #define GCC_TARGET_H |
50 | |
51 | #include "insn-codes.h" |
52 | #include "tm.h" |
53 | #include "hard-reg-set.h" |
54 | |
55 | #if CHECKING_P |
56 | |
57 | struct cumulative_args_t { void *magic; void *p; }; |
58 | |
59 | #else /* !CHECKING_P */ |
60 | |
61 | /* When using a GCC build compiler, we could use |
62 | __attribute__((transparent_union)) to get cumulative_args_t function |
63 | arguments passed like scalars where the ABI would mandate a less |
64 | efficient way of argument passing otherwise. However, that would come |
65 | at the cost of less type-safe !CHECKING_P compilation. */ |
66 | |
67 | union cumulative_args_t { void *p; }; |
68 | |
69 | #endif /* !CHECKING_P */ |
70 | |
71 | /* Target properties of _BitInt(N) type. _BitInt(N) is to be represented |
72 | as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode)) |
73 | limbs, ordered from least significant to most significant if !big_endian, |
74 | otherwise from most significant to least significant. If extended is |
75 | false, the bits above or equal to N are undefined when stored in a register |
76 | or memory, otherwise they are zero or sign extended depending on if |
77 | it is unsigned _BitInt(N) or _BitInt(N) / signed _BitInt(N). |
78 | limb_mode is either the same as abi_limb_mode, or some narrower mode |
79 | in which _BitInt lowering should actually perform operations in and |
80 | what libgcc _BitInt helpers should use. |
81 | E.g. abi_limb_mode could be TImode which is something some processor |
82 | specific ABI would specify to use, but it would be desirable to handle |
83 | it as an array of DImode instead for efficiency. |
84 | Note, abi_limb_mode can be different from limb_mode only if big_endian |
85 | matches WORDS_BIG_ENDIAN. */ |
86 | |
87 | struct bitint_info { |
88 | machine_mode abi_limb_mode, limb_mode; |
89 | bool big_endian; |
90 | bool extended; |
91 | }; |
92 | |
93 | /* Types of memory operation understood by the "by_pieces" infrastructure. |
94 | Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and |
95 | internally by the functions in expr.cc. */ |
96 | |
97 | enum by_pieces_operation |
98 | { |
99 | CLEAR_BY_PIECES, |
100 | MOVE_BY_PIECES, |
101 | SET_BY_PIECES, |
102 | STORE_BY_PIECES, |
103 | COMPARE_BY_PIECES |
104 | }; |
105 | |
106 | extern unsigned HOST_WIDE_INT by_pieces_ninsns (unsigned HOST_WIDE_INT, |
107 | unsigned int, |
108 | unsigned int, |
109 | by_pieces_operation); |
110 | |
111 | /* An example implementation for ELF targets. Defined in varasm.cc */ |
112 | extern void elf_record_gcc_switches (const char *); |
113 | |
114 | /* Some places still assume that all pointer or address modes are the |
115 | standard Pmode and ptr_mode. These optimizations become invalid if |
116 | the target actually supports multiple different modes. For now, |
117 | we disable such optimizations on such targets, using this function. */ |
118 | extern bool target_default_pointer_address_modes_p (void); |
119 | |
120 | /* For hooks which use the MOVE_RATIO macro, this gives the legacy default |
121 | behavior. */ |
122 | extern unsigned int get_move_ratio (bool); |
123 | |
124 | struct stdarg_info; |
125 | struct spec_info_def; |
126 | struct hard_reg_set_container; |
127 | struct cgraph_node; |
128 | struct cgraph_simd_clone; |
129 | |
130 | /* The struct used by the secondary_reload target hook. */ |
131 | struct secondary_reload_info |
132 | { |
133 | /* icode is actually an enum insn_code, but we don't want to force every |
134 | file that includes target.h to include optabs.h . */ |
135 | int icode; |
136 | int ; /* Cost for using (a) scratch register(s) to be taken |
137 | into account by copy_cost. */ |
138 | /* The next two members are for the use of the backward |
139 | compatibility hook. */ |
140 | struct secondary_reload_info *prev_sri; |
141 | int t_icode; /* Actually an enum insn_code - see above. */ |
142 | }; |
143 | |
144 | /* This is defined in sched-int.h . */ |
145 | struct _dep; |
146 | |
147 | /* This is defined in ddg.h . */ |
148 | struct ddg; |
149 | |
150 | /* This is defined in cfgloop.h . */ |
151 | class loop; |
152 | |
153 | /* This is defined in ifcvt.h. */ |
154 | struct noce_if_info; |
155 | |
156 | /* This is defined in tree-ssa-alias.h. */ |
157 | class ao_ref; |
158 | |
159 | /* This is defined in tree-vectorizer.h. */ |
160 | class _stmt_vec_info; |
161 | |
162 | /* This is defined in calls.h. */ |
163 | class function_arg_info; |
164 | |
165 | /* This is defined in function-abi.h. */ |
166 | class predefined_function_abi; |
167 | |
168 | /* These are defined in tree-vect-stmts.cc. */ |
169 | extern tree stmt_vectype (class _stmt_vec_info *); |
170 | extern bool stmt_in_inner_loop_p (class vec_info *, class _stmt_vec_info *); |
171 | |
172 | /* Assembler instructions for creating various kinds of integer object. */ |
173 | |
174 | struct asm_int_op |
175 | { |
176 | const char *hi; |
177 | const char *psi; |
178 | const char *si; |
179 | const char *pdi; |
180 | const char *di; |
181 | const char *pti; |
182 | const char *ti; |
183 | }; |
184 | |
185 | /* Types of costs for vectorizer cost model. */ |
186 | enum vect_cost_for_stmt |
187 | { |
188 | scalar_stmt, |
189 | scalar_load, |
190 | scalar_store, |
191 | vector_stmt, |
192 | vector_load, |
193 | vector_gather_load, |
194 | unaligned_load, |
195 | unaligned_store, |
196 | vector_store, |
197 | vector_scatter_store, |
198 | vec_to_scalar, |
199 | scalar_to_vec, |
200 | cond_branch_not_taken, |
201 | cond_branch_taken, |
202 | vec_perm, |
203 | vec_promote_demote, |
204 | vec_construct |
205 | }; |
206 | |
207 | /* Separate locations for which the vectorizer cost model should |
208 | track costs. */ |
209 | enum vect_cost_model_location { |
210 | vect_prologue = 0, |
211 | vect_body = 1, |
212 | vect_epilogue = 2 |
213 | }; |
214 | |
215 | class vec_perm_indices; |
216 | |
217 | /* The type to use for lists of vector sizes. */ |
218 | typedef vec<machine_mode> vector_modes; |
219 | |
220 | /* Same, but can be used to construct local lists that are |
221 | automatically freed. */ |
222 | typedef auto_vec<machine_mode, 8> auto_vector_modes; |
223 | |
224 | /* First argument of targetm.omp.device_kind_arch_isa. */ |
225 | enum omp_device_kind_arch_isa { |
226 | omp_device_kind, |
227 | omp_device_arch, |
228 | omp_device_isa |
229 | }; |
230 | |
231 | /* Flags returned by TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES: |
232 | |
233 | VECT_COMPARE_COSTS |
234 | Tells the loop vectorizer to try all the provided modes and |
235 | pick the one with the lowest cost. By default the vectorizer |
236 | will choose the first mode that works. */ |
237 | const unsigned int VECT_COMPARE_COSTS = 1U << 0; |
238 | |
239 | /* The contexts in which the use of a type T can be checked by |
240 | TARGET_VERIFY_TYPE_CONTEXT. */ |
241 | enum type_context_kind { |
242 | /* Directly measuring the size of T. */ |
243 | TCTX_SIZEOF, |
244 | |
245 | /* Directly measuring the alignment of T. */ |
246 | TCTX_ALIGNOF, |
247 | |
248 | /* Creating objects of type T with static storage duration. */ |
249 | TCTX_STATIC_STORAGE, |
250 | |
251 | /* Creating objects of type T with thread-local storage duration. */ |
252 | TCTX_THREAD_STORAGE, |
253 | |
254 | /* Creating a field of type T. */ |
255 | TCTX_FIELD, |
256 | |
257 | /* Creating an array with elements of type T. */ |
258 | TCTX_ARRAY_ELEMENT, |
259 | |
260 | /* Adding to or subtracting from a pointer to T, or computing the |
261 | difference between two pointers when one of them is a pointer to T. */ |
262 | TCTX_POINTER_ARITH, |
263 | |
264 | /* Dynamically allocating objects of type T. */ |
265 | TCTX_ALLOCATION, |
266 | |
267 | /* Dynamically deallocating objects of type T. */ |
268 | TCTX_DEALLOCATION, |
269 | |
270 | /* Throwing or catching an object of type T. */ |
271 | TCTX_EXCEPTIONS, |
272 | |
273 | /* Capturing objects of type T by value in a closure. */ |
274 | TCTX_CAPTURE_BY_COPY |
275 | }; |
276 | |
277 | enum poly_value_estimate_kind |
278 | { |
279 | POLY_VALUE_MIN, |
280 | POLY_VALUE_MAX, |
281 | POLY_VALUE_LIKELY |
282 | }; |
283 | |
284 | typedef void (*emit_support_tinfos_callback) (tree); |
285 | |
286 | extern bool verify_type_context (location_t, type_context_kind, const_tree, |
287 | bool = false); |
288 | |
289 | /* The target structure. This holds all the backend hooks. */ |
290 | #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; |
291 | #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; |
292 | #define DEFHOOK_UNDOC DEFHOOK |
293 | #define HOOKSTRUCT(FRAGMENT) FRAGMENT |
294 | |
295 | #include "target.def" |
296 | |
297 | extern struct gcc_target targetm; |
298 | |
299 | /* Return an estimate of the runtime value of X, for use in things |
300 | like cost calculations or profiling frequencies. Note that this |
301 | function should never be used in situations where the actual |
302 | runtime value is needed for correctness, since the function only |
303 | provides a rough guess. */ |
304 | |
305 | inline HOST_WIDE_INT |
306 | estimated_poly_value (poly_int64 x, |
307 | poly_value_estimate_kind kind = POLY_VALUE_LIKELY) |
308 | { |
309 | if (NUM_POLY_INT_COEFFS == 1) |
310 | return x.coeffs[0]; |
311 | else |
312 | return targetm.estimated_poly_value (x, kind); |
313 | } |
314 | |
315 | #ifdef GCC_TM_H |
316 | |
317 | #ifndef CUMULATIVE_ARGS_MAGIC |
318 | #define CUMULATIVE_ARGS_MAGIC ((void *) &targetm.calls) |
319 | #endif |
320 | |
321 | inline CUMULATIVE_ARGS * |
322 | get_cumulative_args (cumulative_args_t arg) |
323 | { |
324 | #if CHECKING_P |
325 | gcc_assert (arg.magic == CUMULATIVE_ARGS_MAGIC); |
326 | #endif /* CHECKING_P */ |
327 | return (CUMULATIVE_ARGS *) arg.p; |
328 | } |
329 | |
330 | inline cumulative_args_t |
331 | pack_cumulative_args (CUMULATIVE_ARGS *arg) |
332 | { |
333 | cumulative_args_t ret; |
334 | |
335 | #if CHECKING_P |
336 | ret.magic = CUMULATIVE_ARGS_MAGIC; |
337 | #endif /* CHECKING_P */ |
338 | ret.p = (void *) arg; |
339 | return ret; |
340 | } |
341 | #endif /* GCC_TM_H */ |
342 | |
343 | #endif /* GCC_TARGET_H */ |
344 | |