Line data Source code
1 : /* Data structure definitions for a generic GCC target.
2 : Copyright (C) 2001-2026 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 : /* Values for bitint_info::extended below. */
72 :
73 : enum bitint_ext { bitint_ext_undef, bitint_ext_partial, bitint_ext_full };
74 :
75 : /* Target properties of _BitInt(N) type. _BitInt(N) is to be represented
76 : as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode))
77 : limbs, ordered from least significant to most significant if !big_endian,
78 : otherwise from most significant to least significant. If extended is
79 : bitint_ext_undef, the bits above or equal to N are undefined when stored in
80 : a register or memory, if extended is bitint_ext_full, they are zero or sign
81 : extended depending on if it is unsigned _BitInt(N) or
82 : _BitInt(N) / signed _BitInt(N), if extended is bitint_ext_partial, then bits
83 : above or equal to N and below
84 : M = CEIL (N, GET_MODE_PRECISION (limb_mode)) * GET_MODE_PRECISION (limb_mode)
85 : are zero or sign extended as specified above and bits above or equal to M
86 : are undefined.
87 : limb_mode is either the same as abi_limb_mode, or some narrower mode
88 : in which _BitInt lowering should actually perform operations in and
89 : what libgcc _BitInt helpers should use.
90 : E.g. abi_limb_mode could be TImode which is something some processor
91 : specific ABI would specify to use, but it would be desirable to handle
92 : it as an array of DImode instead for efficiency.
93 : Note, abi_limb_mode can be different from limb_mode only if big_endian
94 : matches WORDS_BIG_ENDIAN. */
95 :
96 : struct bitint_info {
97 : machine_mode abi_limb_mode, limb_mode;
98 : bool big_endian;
99 : enum bitint_ext extended;
100 : };
101 :
102 : /* Types of memory operation understood by the "by_pieces" infrastructure.
103 : Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and
104 : internally by the functions in expr.cc. */
105 :
106 : enum by_pieces_operation
107 : {
108 : CLEAR_BY_PIECES,
109 : MOVE_BY_PIECES,
110 : SET_BY_PIECES,
111 : STORE_BY_PIECES,
112 : COMPARE_BY_PIECES
113 : };
114 :
115 : extern unsigned HOST_WIDE_INT by_pieces_ninsns (unsigned HOST_WIDE_INT,
116 : unsigned int,
117 : unsigned int,
118 : by_pieces_operation);
119 :
120 : /* An example implementation for ELF targets. Defined in varasm.cc */
121 : extern void elf_record_gcc_switches (const char *);
122 :
123 : /* Some places still assume that all pointer or address modes are the
124 : standard Pmode and ptr_mode. These optimizations become invalid if
125 : the target actually supports multiple different modes. For now,
126 : we disable such optimizations on such targets, using this function. */
127 : extern bool target_default_pointer_address_modes_p (void);
128 :
129 : /* For hooks which use the MOVE_RATIO macro, this gives the legacy default
130 : behavior. */
131 : extern unsigned int get_move_ratio (bool);
132 :
133 : struct stdarg_info;
134 : struct spec_info_def;
135 : struct hard_reg_set_container;
136 : struct cgraph_node;
137 : struct cgraph_simd_clone;
138 :
139 : /* The struct used by the secondary_reload target hook. */
140 : struct secondary_reload_info
141 : {
142 : /* icode is actually an enum insn_code, but we don't want to force every
143 : file that includes target.h to include optabs.h . */
144 : int icode;
145 : int extra_cost; /* Cost for using (a) scratch register(s) to be taken
146 : into account by copy_cost. */
147 : /* The next two members are for the use of the backward
148 : compatibility hook. */
149 : struct secondary_reload_info *prev_sri;
150 : int t_icode; /* Actually an enum insn_code - see above. */
151 : };
152 :
153 : /* This is defined in sched-int.h . */
154 : struct _dep;
155 :
156 : /* This is defined in ddg.h . */
157 : struct ddg;
158 :
159 : /* This is defined in cfgloop.h . */
160 : class loop;
161 :
162 : /* This is defined in ifcvt.h. */
163 : struct noce_if_info;
164 :
165 : /* This is defined in tree-ssa-alias.h. */
166 : class ao_ref;
167 :
168 : /* This is defined in tree-vectorizer.h. */
169 : class _stmt_vec_info;
170 :
171 : /* This is defined in calls.h. */
172 : class function_arg_info;
173 :
174 : /* This is defined in function-abi.h. */
175 : class predefined_function_abi;
176 :
177 : /* This is defined in avoid-store-forwarding.h. */
178 : struct store_fwd_info;
179 :
180 : /* These are defined in tree-vect-stmts.cc. */
181 : extern bool stmt_in_inner_loop_p (class vec_info *, class _stmt_vec_info *);
182 :
183 : /* Assembler instructions for creating various kinds of integer object. */
184 :
185 : struct asm_int_op
186 : {
187 : const char *hi;
188 : const char *psi;
189 : const char *si;
190 : const char *pdi;
191 : const char *di;
192 : const char *pti;
193 : const char *ti;
194 : };
195 :
196 : /* Types of costs for vectorizer cost model. */
197 : enum vect_cost_for_stmt
198 : {
199 : scalar_stmt,
200 : scalar_load,
201 : scalar_store,
202 : vector_stmt,
203 : vector_load,
204 : vector_gather_load,
205 : unaligned_load,
206 : unaligned_store,
207 : vector_store,
208 : vector_scatter_store,
209 : vec_to_scalar,
210 : scalar_to_vec,
211 : cond_branch_not_taken,
212 : cond_branch_taken,
213 : vec_perm,
214 : vec_promote_demote,
215 : vec_construct,
216 : vec_deconstruct
217 : };
218 :
219 : /* Separate locations for which the vectorizer cost model should
220 : track costs. */
221 : enum vect_cost_model_location {
222 : vect_prologue = 0,
223 : vect_body = 1,
224 : vect_epilogue = 2
225 : };
226 :
227 : class vec_perm_indices;
228 :
229 : /* The type to use for lists of vector sizes. */
230 : typedef vec<machine_mode> vector_modes;
231 :
232 : /* Same, but can be used to construct local lists that are
233 : automatically freed. */
234 : typedef auto_vec<machine_mode, 8> auto_vector_modes;
235 :
236 : /* First argument of targetm.omp.device_kind_arch_isa. */
237 : enum omp_device_kind_arch_isa {
238 : omp_device_kind,
239 : omp_device_arch,
240 : omp_device_isa
241 : };
242 :
243 : /* Flags returned by TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES:
244 :
245 : VECT_COMPARE_COSTS
246 : Tells the loop vectorizer to try all the provided modes and
247 : pick the one with the lowest cost. By default the vectorizer
248 : will choose the first mode that works. */
249 : const unsigned int VECT_COMPARE_COSTS = 1U << 0;
250 :
251 : /* The contexts in which the use of a type T can be checked by
252 : TARGET_VERIFY_TYPE_CONTEXT. */
253 : enum type_context_kind {
254 : /* Directly measuring the size of T. */
255 : TCTX_SIZEOF,
256 :
257 : /* Directly measuring the alignment of T. */
258 : TCTX_ALIGNOF,
259 :
260 : /* Creating objects of type T with static storage duration. */
261 : TCTX_STATIC_STORAGE,
262 :
263 : /* Creating objects of type T with thread-local storage duration. */
264 : TCTX_THREAD_STORAGE,
265 :
266 : /* Creating a field of type T. */
267 : TCTX_FIELD,
268 :
269 : /* Creating an array with elements of type T. */
270 : TCTX_ARRAY_ELEMENT,
271 :
272 : /* Adding to or subtracting from a pointer to T, or computing the
273 : difference between two pointers when one of them is a pointer to T. */
274 : TCTX_POINTER_ARITH,
275 :
276 : /* Dynamically allocating objects of type T. */
277 : TCTX_ALLOCATION,
278 :
279 : /* Dynamically deallocating objects of type T. */
280 : TCTX_DEALLOCATION,
281 :
282 : /* Throwing or catching an object of type T. */
283 : TCTX_EXCEPTIONS,
284 :
285 : /* Capturing objects of type T by value in a closure. */
286 : TCTX_CAPTURE_BY_COPY,
287 :
288 : /* Objects of type T appearing in OpenMP map clause. */
289 : TCTX_OMP_MAP,
290 :
291 : /* Objects of type T appearing in OpenMP target region
292 : without explicit map. */
293 : TCTX_OMP_MAP_IMP_REF,
294 :
295 : /* Objects of type T appearing in OpenMP private clause. */
296 : TCTX_OMP_PRIVATE,
297 :
298 : /* Objects of type T appearing in OpenMP firstprivate clause. */
299 : TCTX_OMP_FIRSTPRIVATE,
300 :
301 : /* Objects of type T appearing in OpenMP device clauses. */
302 : TCTX_OMP_DEVICE_ADDR
303 :
304 : };
305 :
306 : enum poly_value_estimate_kind
307 : {
308 : POLY_VALUE_MIN,
309 : POLY_VALUE_MAX,
310 : POLY_VALUE_LIKELY
311 : };
312 :
313 : enum class spill_cost_type
314 : {
315 : SAVE,
316 : RESTORE
317 : };
318 :
319 : enum class frame_cost_type
320 : {
321 : ALLOCATION,
322 : DEALLOCATION
323 : };
324 :
325 : typedef void (*emit_support_tinfos_callback) (tree);
326 :
327 : extern bool verify_type_context (location_t, type_context_kind, const_tree,
328 : bool = false);
329 :
330 : /* The target structure. This holds all the backend hooks. */
331 : #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
332 : #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
333 : #define DEFHOOK_UNDOC DEFHOOK
334 : #define HOOKSTRUCT(FRAGMENT) FRAGMENT
335 :
336 : #include "target.def"
337 :
338 : extern struct gcc_target targetm;
339 :
340 : /* Return an estimate of the runtime value of X, for use in things
341 : like cost calculations or profiling frequencies. Note that this
342 : function should never be used in situations where the actual
343 : runtime value is needed for correctness, since the function only
344 : provides a rough guess. */
345 :
346 : inline HOST_WIDE_INT
347 28548 : estimated_poly_value (poly_int64 x,
348 : poly_value_estimate_kind kind = POLY_VALUE_LIKELY)
349 : {
350 28548 : if (NUM_POLY_INT_COEFFS == 1)
351 28548 : return x.coeffs[0];
352 : else
353 : return targetm.estimated_poly_value (x, kind);
354 : }
355 :
356 : /* Return true when MODE can be used to copy GET_MODE_BITSIZE bits
357 : unchanged. */
358 :
359 : inline bool
360 5441273 : mode_can_transfer_bits (machine_mode mode)
361 : {
362 5441273 : if (mode == BLKmode)
363 : return true;
364 9160218 : if (maybe_ne (GET_MODE_BITSIZE (mode),
365 9160218 : GET_MODE_UNIT_PRECISION (mode) * GET_MODE_NUNITS (mode)))
366 : return false;
367 4578281 : if (targetm.mode_can_transfer_bits)
368 4578281 : return targetm.mode_can_transfer_bits (mode);
369 : return true;
370 : }
371 :
372 : /* Return true if OpenMP context types. */
373 :
374 : inline bool
375 : omp_type_context (type_context_kind context)
376 : {
377 : switch (context)
378 : {
379 : case TCTX_OMP_MAP:
380 : case TCTX_OMP_MAP_IMP_REF:
381 : case TCTX_OMP_PRIVATE:
382 : case TCTX_OMP_FIRSTPRIVATE:
383 : case TCTX_OMP_DEVICE_ADDR:
384 : return true;
385 : default:
386 : return false;
387 : }
388 : }
389 :
390 : #ifdef GCC_TM_H
391 :
392 : #ifndef CUMULATIVE_ARGS_MAGIC
393 : #define CUMULATIVE_ARGS_MAGIC ((void *) &targetm.calls)
394 : #endif
395 :
396 : inline CUMULATIVE_ARGS *
397 85507247 : get_cumulative_args (cumulative_args_t arg)
398 : {
399 : #if CHECKING_P
400 85507247 : gcc_assert (arg.magic == CUMULATIVE_ARGS_MAGIC);
401 : #endif /* CHECKING_P */
402 85507247 : return (CUMULATIVE_ARGS *) arg.p;
403 : }
404 :
405 : inline cumulative_args_t
406 34953260 : pack_cumulative_args (CUMULATIVE_ARGS *arg)
407 : {
408 34953260 : cumulative_args_t ret;
409 :
410 : #if CHECKING_P
411 34953260 : ret.magic = CUMULATIVE_ARGS_MAGIC;
412 : #endif /* CHECKING_P */
413 34953260 : ret.p = (void *) arg;
414 34953260 : return ret;
415 : }
416 : #endif /* GCC_TM_H */
417 :
418 : #endif /* GCC_TARGET_H */
|