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 : };
217 :
218 : /* Separate locations for which the vectorizer cost model should
219 : track costs. */
220 : enum vect_cost_model_location {
221 : vect_prologue = 0,
222 : vect_body = 1,
223 : vect_epilogue = 2
224 : };
225 :
226 : class vec_perm_indices;
227 :
228 : /* The type to use for lists of vector sizes. */
229 : typedef vec<machine_mode> vector_modes;
230 :
231 : /* Same, but can be used to construct local lists that are
232 : automatically freed. */
233 : typedef auto_vec<machine_mode, 8> auto_vector_modes;
234 :
235 : /* First argument of targetm.omp.device_kind_arch_isa. */
236 : enum omp_device_kind_arch_isa {
237 : omp_device_kind,
238 : omp_device_arch,
239 : omp_device_isa
240 : };
241 :
242 : /* Flags returned by TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES:
243 :
244 : VECT_COMPARE_COSTS
245 : Tells the loop vectorizer to try all the provided modes and
246 : pick the one with the lowest cost. By default the vectorizer
247 : will choose the first mode that works. */
248 : const unsigned int VECT_COMPARE_COSTS = 1U << 0;
249 :
250 : /* The contexts in which the use of a type T can be checked by
251 : TARGET_VERIFY_TYPE_CONTEXT. */
252 : enum type_context_kind {
253 : /* Directly measuring the size of T. */
254 : TCTX_SIZEOF,
255 :
256 : /* Directly measuring the alignment of T. */
257 : TCTX_ALIGNOF,
258 :
259 : /* Creating objects of type T with static storage duration. */
260 : TCTX_STATIC_STORAGE,
261 :
262 : /* Creating objects of type T with thread-local storage duration. */
263 : TCTX_THREAD_STORAGE,
264 :
265 : /* Creating a field of type T. */
266 : TCTX_FIELD,
267 :
268 : /* Creating an array with elements of type T. */
269 : TCTX_ARRAY_ELEMENT,
270 :
271 : /* Adding to or subtracting from a pointer to T, or computing the
272 : difference between two pointers when one of them is a pointer to T. */
273 : TCTX_POINTER_ARITH,
274 :
275 : /* Dynamically allocating objects of type T. */
276 : TCTX_ALLOCATION,
277 :
278 : /* Dynamically deallocating objects of type T. */
279 : TCTX_DEALLOCATION,
280 :
281 : /* Throwing or catching an object of type T. */
282 : TCTX_EXCEPTIONS,
283 :
284 : /* Capturing objects of type T by value in a closure. */
285 : TCTX_CAPTURE_BY_COPY,
286 :
287 : /* Objects of type T appearing in OpenMP map clause. */
288 : TCTX_OMP_MAP,
289 :
290 : /* Objects of type T appearing in OpenMP target region
291 : without explicit map. */
292 : TCTX_OMP_MAP_IMP_REF,
293 :
294 : /* Objects of type T appearing in OpenMP private clause. */
295 : TCTX_OMP_PRIVATE,
296 :
297 : /* Objects of type T appearing in OpenMP firstprivate clause. */
298 : TCTX_OMP_FIRSTPRIVATE,
299 :
300 : /* Objects of type T appearing in OpenMP device clauses. */
301 : TCTX_OMP_DEVICE_ADDR
302 :
303 : };
304 :
305 : enum poly_value_estimate_kind
306 : {
307 : POLY_VALUE_MIN,
308 : POLY_VALUE_MAX,
309 : POLY_VALUE_LIKELY
310 : };
311 :
312 : enum class spill_cost_type
313 : {
314 : SAVE,
315 : RESTORE
316 : };
317 :
318 : enum class frame_cost_type
319 : {
320 : ALLOCATION,
321 : DEALLOCATION
322 : };
323 :
324 : typedef void (*emit_support_tinfos_callback) (tree);
325 :
326 : extern bool verify_type_context (location_t, type_context_kind, const_tree,
327 : bool = false);
328 :
329 : /* The target structure. This holds all the backend hooks. */
330 : #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
331 : #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
332 : #define DEFHOOK_UNDOC DEFHOOK
333 : #define HOOKSTRUCT(FRAGMENT) FRAGMENT
334 :
335 : #include "target.def"
336 :
337 : extern struct gcc_target targetm;
338 :
339 : /* Return an estimate of the runtime value of X, for use in things
340 : like cost calculations or profiling frequencies. Note that this
341 : function should never be used in situations where the actual
342 : runtime value is needed for correctness, since the function only
343 : provides a rough guess. */
344 :
345 : inline HOST_WIDE_INT
346 28019 : estimated_poly_value (poly_int64 x,
347 : poly_value_estimate_kind kind = POLY_VALUE_LIKELY)
348 : {
349 28019 : if (NUM_POLY_INT_COEFFS == 1)
350 28019 : return x.coeffs[0];
351 : else
352 : return targetm.estimated_poly_value (x, kind);
353 : }
354 :
355 : /* Return true when MODE can be used to copy GET_MODE_BITSIZE bits
356 : unchanged. */
357 :
358 : inline bool
359 5400794 : mode_can_transfer_bits (machine_mode mode)
360 : {
361 5400794 : if (mode == BLKmode)
362 : return true;
363 9097820 : if (maybe_ne (GET_MODE_BITSIZE (mode),
364 9097820 : GET_MODE_UNIT_PRECISION (mode) * GET_MODE_NUNITS (mode)))
365 : return false;
366 4547143 : if (targetm.mode_can_transfer_bits)
367 4547143 : return targetm.mode_can_transfer_bits (mode);
368 : return true;
369 : }
370 :
371 : /* Return true if OpenMP context types. */
372 :
373 : inline bool
374 : omp_type_context (type_context_kind context)
375 : {
376 : switch (context)
377 : {
378 : case TCTX_OMP_MAP:
379 : case TCTX_OMP_MAP_IMP_REF:
380 : case TCTX_OMP_PRIVATE:
381 : case TCTX_OMP_FIRSTPRIVATE:
382 : case TCTX_OMP_DEVICE_ADDR:
383 : return true;
384 : default:
385 : return false;
386 : }
387 : }
388 :
389 : #ifdef GCC_TM_H
390 :
391 : #ifndef CUMULATIVE_ARGS_MAGIC
392 : #define CUMULATIVE_ARGS_MAGIC ((void *) &targetm.calls)
393 : #endif
394 :
395 : inline CUMULATIVE_ARGS *
396 85649805 : get_cumulative_args (cumulative_args_t arg)
397 : {
398 : #if CHECKING_P
399 85649805 : gcc_assert (arg.magic == CUMULATIVE_ARGS_MAGIC);
400 : #endif /* CHECKING_P */
401 85649805 : return (CUMULATIVE_ARGS *) arg.p;
402 : }
403 :
404 : inline cumulative_args_t
405 35082525 : pack_cumulative_args (CUMULATIVE_ARGS *arg)
406 : {
407 35082525 : cumulative_args_t ret;
408 :
409 : #if CHECKING_P
410 35082525 : ret.magic = CUMULATIVE_ARGS_MAGIC;
411 : #endif /* CHECKING_P */
412 35082525 : ret.p = (void *) arg;
413 35082525 : return ret;
414 : }
415 : #endif /* GCC_TM_H */
416 :
417 : #endif /* GCC_TARGET_H */
|