Line data Source code
1 : /* Default target hook functions.
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : /* The migration of target macros to target hooks works as follows:
21 :
22 : 1. Create a target hook that uses the existing target macros to
23 : implement the same functionality.
24 :
25 : 2. Convert all the MI files to use the hook instead of the macro.
26 :
27 : 3. Repeat for a majority of the remaining target macros. This will
28 : take some time.
29 :
30 : 4. Tell target maintainers to start migrating.
31 :
32 : 5. Eventually convert the backends to override the hook instead of
33 : defining the macros. This will take some time too.
34 :
35 : 6. TBD when, poison the macros. Unmigrated targets will break at
36 : this point.
37 :
38 : Note that we expect steps 1-3 to be done by the people that
39 : understand what the MI does with each macro, and step 5 to be done
40 : by the target maintainers for their respective targets.
41 :
42 : Note that steps 1 and 2 don't have to be done together, but no
43 : target can override the new hook until step 2 is complete for it.
44 :
45 : Once the macros are poisoned, we will revert to the old migration
46 : rules - migrate the macro, callers, and targets all at once. This
47 : comment can thus be removed at that point. */
48 :
49 : #include "config.h"
50 : #include "system.h"
51 : #include "coretypes.h"
52 : #include "target.h"
53 : #include "function.h"
54 : #include "rtl.h"
55 : #include "tree.h"
56 : #include "tree-ssa-alias.h"
57 : #include "gimple-expr.h"
58 : #include "memmodel.h"
59 : #include "backend.h"
60 : #include "emit-rtl.h"
61 : #include "df.h"
62 : #include "tm_p.h"
63 : #include "stringpool.h"
64 : #include "tree-vrp.h"
65 : #include "tree-ssanames.h"
66 : #include "profile-count.h"
67 : #include "optabs.h"
68 : #include "regs.h"
69 : #include "recog.h"
70 : #include "diagnostic-core.h"
71 : #include "fold-const.h"
72 : #include "stor-layout.h"
73 : #include "varasm.h"
74 : #include "flags.h"
75 : #include "explow.h"
76 : #include "expmed.h"
77 : #include "calls.h"
78 : #include "expr.h"
79 : #include "output.h"
80 : #include "common/common-target.h"
81 : #include "reload.h"
82 : #include "intl.h"
83 : #include "opts.h"
84 : #include "gimplify.h"
85 : #include "predict.h"
86 : #include "real.h"
87 : #include "langhooks.h"
88 : #include "sbitmap.h"
89 : #include "function-abi.h"
90 : #include "attribs.h"
91 : #include "asan.h"
92 : #include "emit-rtl.h"
93 : #include "gimple.h"
94 : #include "cfgloop.h"
95 : #include "tree-vectorizer.h"
96 : #include "options.h"
97 : #include "case-cfn-macros.h"
98 : #include "avoid-store-forwarding.h"
99 :
100 : bool
101 0 : default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
102 : rtx addr ATTRIBUTE_UNUSED,
103 : bool strict ATTRIBUTE_UNUSED,
104 : code_helper ATTRIBUTE_UNUSED)
105 : {
106 : #ifdef GO_IF_LEGITIMATE_ADDRESS
107 : /* Defer to the old implementation using a goto. */
108 : if (strict)
109 : return strict_memory_address_p (mode, addr);
110 : else
111 : return memory_address_p (mode, addr);
112 : #else
113 0 : gcc_unreachable ();
114 : #endif
115 : }
116 :
117 : void
118 26897 : default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
119 : {
120 : #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
121 26897 : ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
122 : #endif
123 26897 : }
124 :
125 : int
126 5818820 : default_unspec_may_trap_p (const_rtx x, unsigned flags)
127 : {
128 5818820 : int i;
129 :
130 : /* Any floating arithmetic may trap. */
131 5818820 : if ((SCALAR_FLOAT_MODE_P (GET_MODE (x)) && flag_trapping_math))
132 : return 1;
133 :
134 10063507 : for (i = 0; i < XVECLEN (x, 0); ++i)
135 : {
136 7339232 : if (may_trap_p_1 (XVECEXP (x, 0, i), flags))
137 : return 1;
138 : }
139 :
140 : return 0;
141 : }
142 :
143 : machine_mode
144 16027074 : default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
145 : machine_mode mode,
146 : int *punsignedp ATTRIBUTE_UNUSED,
147 : const_tree funtype ATTRIBUTE_UNUSED,
148 : int for_return ATTRIBUTE_UNUSED)
149 : {
150 16027074 : if (type != NULL_TREE && for_return == 2)
151 3662133 : return promote_mode (type, mode, punsignedp);
152 : return mode;
153 : }
154 :
155 : machine_mode
156 0 : default_promote_function_mode_always_promote (const_tree type,
157 : machine_mode mode,
158 : int *punsignedp,
159 : const_tree funtype ATTRIBUTE_UNUSED,
160 : int for_return ATTRIBUTE_UNUSED)
161 : {
162 0 : return promote_mode (type, mode, punsignedp);
163 : }
164 :
165 : /* Sign-extend signed 8/16-bit integer arguments to 32 bits and
166 : zero-extend unsigned 8/16-bit integer arguments to 32 bits. */
167 :
168 : machine_mode
169 0 : default_promote_function_mode_sign_extend (const_tree type,
170 : machine_mode mode,
171 : int *punsignedp,
172 : const_tree, int)
173 : {
174 0 : if (GET_MODE_CLASS (mode) == MODE_INT
175 0 : && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
176 0 : < GET_MODE_SIZE (SImode)))
177 : return SImode;
178 :
179 0 : return promote_mode (type, mode, punsignedp);
180 : }
181 :
182 : machine_mode
183 0 : default_cc_modes_compatible (machine_mode m1, machine_mode m2)
184 : {
185 0 : if (m1 == m2)
186 0 : return m1;
187 : return VOIDmode;
188 : }
189 :
190 : bool
191 0 : default_return_in_memory (const_tree type,
192 : const_tree fntype ATTRIBUTE_UNUSED)
193 : {
194 0 : return (TYPE_MODE (type) == BLKmode);
195 : }
196 :
197 : rtx
198 0 : default_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
199 : machine_mode mode ATTRIBUTE_UNUSED)
200 : {
201 0 : return x;
202 : }
203 :
204 : bool
205 0 : default_legitimize_address_displacement (rtx *, rtx *, poly_int64,
206 : machine_mode)
207 : {
208 0 : return false;
209 : }
210 :
211 : bool
212 0 : default_const_not_ok_for_debug_p (rtx x)
213 : {
214 0 : if (GET_CODE (x) == UNSPEC)
215 0 : return true;
216 : return false;
217 : }
218 :
219 : rtx
220 0 : default_expand_builtin_saveregs (void)
221 : {
222 0 : error ("%<__builtin_saveregs%> not supported by this target");
223 0 : return const0_rtx;
224 : }
225 :
226 : void
227 0 : default_setup_incoming_varargs (cumulative_args_t,
228 : const function_arg_info &, int *, int)
229 : {
230 0 : }
231 :
232 : /* The default implementation of TARGET_BUILTIN_SETJMP_FRAME_VALUE. */
233 :
234 : rtx
235 0 : default_builtin_setjmp_frame_value (void)
236 : {
237 0 : return virtual_stack_vars_rtx;
238 : }
239 :
240 : /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */
241 :
242 : bool
243 0 : hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t ca ATTRIBUTE_UNUSED)
244 : {
245 0 : return false;
246 : }
247 :
248 : bool
249 0 : default_pretend_outgoing_varargs_named (cumulative_args_t ca ATTRIBUTE_UNUSED)
250 : {
251 0 : return (targetm.calls.setup_incoming_varargs
252 0 : != default_setup_incoming_varargs);
253 : }
254 :
255 : scalar_int_mode
256 501899 : default_eh_return_filter_mode (void)
257 : {
258 501899 : return targetm.unwind_word_mode ();
259 : }
260 :
261 : scalar_int_mode
262 44848 : default_libgcc_cmp_return_mode (void)
263 : {
264 44848 : return word_mode;
265 : }
266 :
267 : scalar_int_mode
268 308 : default_libgcc_shift_count_mode (void)
269 : {
270 308 : return word_mode;
271 : }
272 :
273 : scalar_int_mode
274 743407 : default_unwind_word_mode (void)
275 : {
276 743407 : return word_mode;
277 : }
278 :
279 : /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */
280 :
281 : unsigned HOST_WIDE_INT
282 1 : default_shift_truncation_mask (machine_mode mode)
283 : {
284 1 : return SHIFT_COUNT_TRUNCATED ? GET_MODE_UNIT_BITSIZE (mode) - 1 : 0;
285 : }
286 :
287 : /* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. */
288 :
289 : unsigned int
290 209571 : default_min_divisions_for_recip_mul (machine_mode mode ATTRIBUTE_UNUSED)
291 : {
292 209571 : return have_insn_for (DIV, mode) ? 3 : 2;
293 : }
294 :
295 : /* The default implementation of TARGET_MODE_REP_EXTENDED. */
296 :
297 : int
298 22480995 : default_mode_rep_extended (scalar_int_mode, scalar_int_mode)
299 : {
300 22480995 : return UNKNOWN;
301 : }
302 :
303 : /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */
304 :
305 : bool
306 5855216 : hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t a ATTRIBUTE_UNUSED)
307 : {
308 5855216 : return true;
309 : }
310 :
311 : /* Return machine mode for non-standard suffix
312 : or VOIDmode if non-standard suffixes are unsupported. */
313 : machine_mode
314 0 : default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED)
315 : {
316 0 : return VOIDmode;
317 : }
318 :
319 : /* Return machine mode for a floating type which is indicated
320 : by the given enum tree_index. */
321 :
322 : machine_mode
323 3150548 : default_mode_for_floating_type (enum tree_index ti)
324 : {
325 3150548 : if (ti == TI_FLOAT_TYPE)
326 : return SFmode;
327 1555392 : gcc_assert (ti == TI_DOUBLE_TYPE || ti == TI_LONG_DOUBLE_TYPE);
328 : return DFmode;
329 : }
330 :
331 : /* The generic C++ ABI specifies this is a 64-bit value. */
332 : tree
333 4661 : default_cxx_guard_type (void)
334 : {
335 4661 : return long_long_integer_type_node;
336 : }
337 :
338 : /* Returns the size of the cookie to use when allocating an array
339 : whose elements have the indicated TYPE. Assumes that it is already
340 : known that a cookie is needed. */
341 :
342 : tree
343 83964 : default_cxx_get_cookie_size (tree type)
344 : {
345 83964 : tree cookie_size;
346 :
347 : /* We need to allocate an additional max (sizeof (size_t), alignof
348 : (true_type)) bytes. */
349 83964 : tree sizetype_size;
350 83964 : tree type_align;
351 :
352 83964 : sizetype_size = size_in_bytes (sizetype);
353 83964 : type_align = size_int (TYPE_ALIGN_UNIT (type));
354 83964 : if (tree_int_cst_lt (type_align, sizetype_size))
355 : cookie_size = sizetype_size;
356 : else
357 19678 : cookie_size = type_align;
358 :
359 83964 : return cookie_size;
360 : }
361 :
362 : /* Returns modified FUNCTION_TYPE for cdtor callabi. */
363 :
364 : tree
365 0 : default_cxx_adjust_cdtor_callabi_fntype (tree fntype)
366 : {
367 0 : return fntype;
368 : }
369 :
370 : /* Return true if a parameter must be passed by reference. This version
371 : of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */
372 :
373 : bool
374 0 : hook_pass_by_reference_must_pass_in_stack (cumulative_args_t,
375 : const function_arg_info &arg)
376 : {
377 0 : return targetm.calls.must_pass_in_stack (arg);
378 : }
379 :
380 : /* Return true if a parameter follows callee copies conventions. This
381 : version of the hook is true for all named arguments. */
382 :
383 : bool
384 0 : hook_callee_copies_named (cumulative_args_t, const function_arg_info &arg)
385 : {
386 0 : return arg.named;
387 : }
388 :
389 : /* Emit to STREAM the assembler syntax for insn operand X. */
390 :
391 : void
392 0 : default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
393 : int code ATTRIBUTE_UNUSED)
394 : {
395 : #ifdef PRINT_OPERAND
396 : PRINT_OPERAND (stream, x, code);
397 : #else
398 0 : gcc_unreachable ();
399 : #endif
400 : }
401 :
402 : /* Emit to STREAM the assembler syntax for an insn operand whose memory
403 : address is X. */
404 :
405 : void
406 0 : default_print_operand_address (FILE *stream ATTRIBUTE_UNUSED,
407 : machine_mode /*mode*/,
408 : rtx x ATTRIBUTE_UNUSED)
409 : {
410 : #ifdef PRINT_OPERAND_ADDRESS
411 : PRINT_OPERAND_ADDRESS (stream, x);
412 : #else
413 0 : gcc_unreachable ();
414 : #endif
415 : }
416 :
417 : /* Return true if CODE is a valid punctuation character for the
418 : `print_operand' hook. */
419 :
420 : bool
421 0 : default_print_operand_punct_valid_p (unsigned char code ATTRIBUTE_UNUSED)
422 : {
423 : #ifdef PRINT_OPERAND_PUNCT_VALID_P
424 : return PRINT_OPERAND_PUNCT_VALID_P (code);
425 : #else
426 0 : return false;
427 : #endif
428 : }
429 :
430 : /* The default implementation of TARGET_MANGLE_ASSEMBLER_NAME. */
431 : tree
432 545594 : default_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED)
433 : {
434 545594 : const char *skipped = name + (*name == '*' ? 1 : 0);
435 545594 : const char *stripped = targetm.strip_name_encoding (skipped);
436 545594 : if (*name != '*' && user_label_prefix[0])
437 0 : stripped = ACONCAT ((user_label_prefix, stripped, NULL));
438 545594 : return get_identifier (stripped);
439 : }
440 :
441 : /* The default implementation of TARGET_TRANSLATE_MODE_ATTRIBUTE. */
442 :
443 : machine_mode
444 54888 : default_translate_mode_attribute (machine_mode mode)
445 : {
446 54888 : return mode;
447 : }
448 :
449 : /* True if MODE is valid for the target. By "valid", we mean able to
450 : be manipulated in non-trivial ways. In particular, this means all
451 : the arithmetic is supported.
452 :
453 : By default we guess this means that any C type is supported. If
454 : we can't map the mode back to a type that would be available in C,
455 : then reject it. Special case, here, is the double-word arithmetic
456 : supported by optabs.cc. */
457 :
458 : bool
459 3069074 : default_scalar_mode_supported_p (scalar_mode mode)
460 : {
461 3069074 : int precision = GET_MODE_PRECISION (mode);
462 :
463 3069074 : switch (GET_MODE_CLASS (mode))
464 : {
465 1773290 : case MODE_PARTIAL_INT:
466 1773290 : case MODE_INT:
467 1773290 : if (precision == CHAR_TYPE_SIZE)
468 : return true;
469 1689473 : if (precision == SHORT_TYPE_SIZE)
470 : return true;
471 1618974 : if (precision == INT_TYPE_SIZE)
472 : return true;
473 1571154 : if (precision == LONG_TYPE_SIZE)
474 : return true;
475 1445834 : if (precision == LONG_LONG_TYPE_SIZE)
476 : return true;
477 1475902 : if (precision == 2 * BITS_PER_WORD)
478 : return true;
479 : return false;
480 :
481 1295784 : case MODE_FLOAT:
482 1295784 : if (mode == targetm.c.mode_for_floating_type (TI_FLOAT_TYPE))
483 : return true;
484 963195 : if (mode == targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE))
485 : return true;
486 332135 : if (mode == targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE))
487 : return true;
488 : return false;
489 :
490 : case MODE_DECIMAL_FLOAT:
491 : case MODE_FRACT:
492 : case MODE_UFRACT:
493 : case MODE_ACCUM:
494 : case MODE_UACCUM:
495 : return false;
496 :
497 0 : default:
498 0 : gcc_unreachable ();
499 : }
500 : }
501 :
502 : /* Return true if libgcc supports floating-point mode MODE (known to
503 : be supported as a scalar mode). */
504 :
505 : bool
506 1623463 : default_libgcc_floating_mode_supported_p (scalar_float_mode mode)
507 : {
508 1623463 : switch (mode)
509 : {
510 : #ifdef HAVE_SFmode
511 : case E_SFmode:
512 : #endif
513 : #ifdef HAVE_DFmode
514 : case E_DFmode:
515 : #endif
516 : #ifdef HAVE_XFmode
517 : case E_XFmode:
518 : #endif
519 : #ifdef HAVE_TFmode
520 : case E_TFmode:
521 : #endif
522 : return true;
523 :
524 0 : default:
525 0 : return false;
526 : }
527 : }
528 :
529 : /* Return the machine mode to use for the type _FloatN, if EXTENDED is
530 : false, or _FloatNx, if EXTENDED is true, or VOIDmode if not
531 : supported. */
532 : opt_scalar_float_mode
533 2089353 : default_floatn_mode (int n, bool extended)
534 : {
535 2089353 : if (extended)
536 : {
537 895437 : opt_scalar_float_mode cand1, cand2;
538 895437 : scalar_float_mode mode;
539 895437 : switch (n)
540 : {
541 298479 : case 32:
542 : #ifdef HAVE_DFmode
543 298479 : cand1 = DFmode;
544 : #endif
545 298479 : break;
546 :
547 298479 : case 64:
548 : #ifdef HAVE_XFmode
549 298479 : cand1 = XFmode;
550 : #endif
551 : #ifdef HAVE_TFmode
552 298479 : cand2 = TFmode;
553 : #endif
554 298479 : break;
555 :
556 : case 128:
557 : break;
558 :
559 0 : default:
560 : /* Those are the only valid _FloatNx types. */
561 0 : gcc_unreachable ();
562 : }
563 895437 : if (cand1.exists (&mode)
564 596958 : && REAL_MODE_FORMAT (mode)->ieee_bits > n
565 596958 : && targetm.scalar_mode_supported_p (mode)
566 596936 : && targetm.libgcc_floating_mode_supported_p (mode))
567 596936 : return cand1;
568 298501 : if (cand2.exists (&mode)
569 22 : && REAL_MODE_FORMAT (mode)->ieee_bits > n
570 298501 : && targetm.scalar_mode_supported_p (mode)
571 22 : && targetm.libgcc_floating_mode_supported_p (mode))
572 22 : return cand2;
573 : }
574 : else
575 : {
576 1193916 : opt_scalar_float_mode cand;
577 1193916 : scalar_float_mode mode;
578 1193916 : switch (n)
579 : {
580 : case 16:
581 : /* Always enable _Float16 if we have basic support for the mode.
582 : Targets can control the range and precision of operations on
583 : the _Float16 type using TARGET_C_EXCESS_PRECISION. */
584 : #ifdef HAVE_HFmode
585 : cand = HFmode;
586 : #endif
587 : break;
588 :
589 : case 32:
590 : #ifdef HAVE_SFmode
591 : cand = SFmode;
592 : #endif
593 : break;
594 :
595 : case 64:
596 : #ifdef HAVE_DFmode
597 : cand = DFmode;
598 : #endif
599 : break;
600 :
601 : case 128:
602 : #ifdef HAVE_TFmode
603 : cand = TFmode;
604 : #endif
605 : break;
606 :
607 : default:
608 : break;
609 : }
610 1193916 : if (cand.exists (&mode)
611 1193916 : && REAL_MODE_FORMAT (mode)->ieee_bits == n
612 1193916 : && targetm.scalar_mode_supported_p (mode)
613 1193916 : && targetm.libgcc_floating_mode_supported_p (mode))
614 1193916 : return cand;
615 : }
616 298479 : return opt_scalar_float_mode ();
617 : }
618 :
619 : /* Define this to return true if the _Floatn and _Floatnx built-in functions
620 : should implicitly enable the built-in function without the __builtin_ prefix
621 : in addition to the normal built-in function with the __builtin_ prefix. The
622 : default is to only enable built-in functions without the __builtin_ prefix
623 : for the GNU C language. The argument FUNC is the enum builtin_in_function
624 : id of the function to be enabled. */
625 :
626 : bool
627 140193557 : default_floatn_builtin_p (int func ATTRIBUTE_UNUSED)
628 : {
629 140193557 : static bool first_time_p = true;
630 140193557 : static bool c_or_objective_c;
631 :
632 140193557 : if (first_time_p)
633 : {
634 241297 : first_time_p = false;
635 357925 : c_or_objective_c = lang_GNU_C () || lang_GNU_OBJC ();
636 : }
637 :
638 140193557 : return c_or_objective_c;
639 : }
640 :
641 : /* Make some target macros usable by target-independent code. */
642 : bool
643 0 : targhook_words_big_endian (void)
644 : {
645 0 : return !!WORDS_BIG_ENDIAN;
646 : }
647 :
648 : bool
649 216946 : targhook_float_words_big_endian (void)
650 : {
651 216946 : return !!FLOAT_WORDS_BIG_ENDIAN;
652 : }
653 :
654 : /* True if the target supports floating-point exceptions and rounding
655 : modes. */
656 :
657 : bool
658 0 : default_float_exceptions_rounding_supported_p (void)
659 : {
660 : #ifdef HAVE_adddf3
661 0 : return HAVE_adddf3;
662 : #else
663 : return false;
664 : #endif
665 : }
666 :
667 : /* True if the target supports decimal floating point. */
668 :
669 : bool
670 1276061 : default_decimal_float_supported_p (void)
671 : {
672 1276061 : return ENABLE_DECIMAL_FLOAT;
673 : }
674 :
675 : /* True if the target supports fixed-point arithmetic. */
676 :
677 : bool
678 332855 : default_fixed_point_supported_p (void)
679 : {
680 332855 : return ENABLE_FIXED_POINT;
681 : }
682 :
683 : /* True if the target supports GNU indirect functions. */
684 :
685 : bool
686 585 : default_has_ifunc_p (void)
687 : {
688 585 : return HAVE_GNU_INDIRECT_FUNCTION;
689 : }
690 :
691 : /* Return true if we predict the loop LOOP will be transformed to a
692 : low-overhead loop, otherwise return false.
693 :
694 : By default, false is returned, as this hook's applicability should be
695 : verified for each target. Target maintainers should re-define the hook
696 : if the target can take advantage of it. */
697 :
698 : bool
699 500623 : default_predict_doloop_p (class loop *loop ATTRIBUTE_UNUSED)
700 : {
701 500623 : return false;
702 : }
703 :
704 : /* By default, just use the input MODE itself. */
705 :
706 : machine_mode
707 0 : default_preferred_doloop_mode (machine_mode mode)
708 : {
709 0 : return mode;
710 : }
711 :
712 : /* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
713 : an error message.
714 :
715 : This function checks whether a given INSN is valid within a low-overhead
716 : loop. If INSN is invalid it returns the reason for that, otherwise it
717 : returns NULL. A called function may clobber any special registers required
718 : for low-overhead looping. Additionally, some targets (eg, PPC) use the count
719 : register for branch on table instructions. We reject the doloop pattern in
720 : these cases. */
721 :
722 : const char *
723 0 : default_invalid_within_doloop (const rtx_insn *insn)
724 : {
725 0 : if (CALL_P (insn))
726 : return "Function call in loop.";
727 :
728 0 : if (tablejump_p (insn, NULL, NULL) || computed_jump_p (insn))
729 0 : return "Computed branch in the loop.";
730 :
731 : return NULL;
732 : }
733 :
734 : /* Mapping of builtin functions to vectorized variants. */
735 :
736 : tree
737 0 : default_builtin_vectorized_function (unsigned int, tree, tree)
738 : {
739 0 : return NULL_TREE;
740 : }
741 :
742 : /* Mapping of target builtin functions to vectorized variants. */
743 :
744 : tree
745 24 : default_builtin_md_vectorized_function (tree, tree, tree)
746 : {
747 24 : return NULL_TREE;
748 : }
749 :
750 : /* Default vectorizer cost model values. */
751 :
752 : int
753 0 : default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
754 : tree vectype,
755 : int misalign ATTRIBUTE_UNUSED)
756 : {
757 0 : switch (type_of_cost)
758 : {
759 : case scalar_stmt:
760 : case scalar_load:
761 : case scalar_store:
762 : case vector_stmt:
763 : case vector_load:
764 : case vector_store:
765 : case vec_to_scalar:
766 : case scalar_to_vec:
767 : case cond_branch_not_taken:
768 : case vec_perm:
769 : case vec_promote_demote:
770 : return 1;
771 :
772 0 : case unaligned_load:
773 0 : case unaligned_store:
774 0 : return 2;
775 :
776 0 : case cond_branch_taken:
777 0 : return 3;
778 :
779 0 : case vec_construct:
780 0 : case vec_deconstruct:
781 0 : return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)) - 1;
782 :
783 0 : default:
784 0 : gcc_unreachable ();
785 : }
786 : }
787 :
788 : /* Reciprocal. */
789 :
790 : tree
791 0 : default_builtin_reciprocal (tree)
792 : {
793 0 : return NULL_TREE;
794 : }
795 :
796 : void
797 0 : default_emit_support_tinfos (emit_support_tinfos_callback)
798 : {
799 0 : }
800 :
801 : bool
802 5332 : hook_bool_CUMULATIVE_ARGS_arg_info_false (cumulative_args_t,
803 : const function_arg_info &)
804 : {
805 5332 : return false;
806 : }
807 :
808 : bool
809 0 : hook_bool_CUMULATIVE_ARGS_arg_info_true (cumulative_args_t,
810 : const function_arg_info &)
811 : {
812 0 : return true;
813 : }
814 :
815 : int
816 12167114 : hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t,
817 : const function_arg_info &)
818 : {
819 12167114 : return 0;
820 : }
821 :
822 : void
823 11906472 : hook_void_CUMULATIVE_ARGS (cumulative_args_t)
824 : {
825 11906472 : }
826 :
827 : void
828 0 : hook_void_CUMULATIVE_ARGS_tree (cumulative_args_t ca ATTRIBUTE_UNUSED,
829 : tree ATTRIBUTE_UNUSED)
830 : {
831 0 : }
832 :
833 : void
834 11524026 : hook_void_CUMULATIVE_ARGS_rtx_tree (cumulative_args_t, rtx, tree)
835 : {
836 11524026 : }
837 :
838 : /* Default implementation of TARGET_PUSH_ARGUMENT. */
839 :
840 : bool
841 0 : default_push_argument (unsigned int)
842 : {
843 : #ifdef PUSH_ROUNDING
844 0 : return !ACCUMULATE_OUTGOING_ARGS;
845 : #else
846 : return false;
847 : #endif
848 : }
849 :
850 : void
851 0 : default_function_arg_advance (cumulative_args_t, const function_arg_info &)
852 : {
853 0 : gcc_unreachable ();
854 : }
855 :
856 : /* Default implementation of TARGET_FUNCTION_ARG_OFFSET. */
857 :
858 : HOST_WIDE_INT
859 5443480 : default_function_arg_offset (machine_mode, const_tree)
860 : {
861 5443480 : return 0;
862 : }
863 :
864 : /* Default implementation of TARGET_FUNCTION_ARG_PADDING: usually pad
865 : upward, but pad short args downward on big-endian machines. */
866 :
867 : pad_direction
868 12358576 : default_function_arg_padding (machine_mode mode, const_tree type)
869 : {
870 12358576 : if (!BYTES_BIG_ENDIAN)
871 12358576 : return PAD_UPWARD;
872 :
873 : unsigned HOST_WIDE_INT size;
874 : if (mode == BLKmode)
875 : {
876 : if (!type || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
877 : return PAD_UPWARD;
878 : size = int_size_in_bytes (type);
879 : }
880 : else
881 : /* Targets with variable-sized modes must override this hook
882 : and handle variable-sized modes explicitly. */
883 : size = GET_MODE_SIZE (mode).to_constant ();
884 :
885 : if (size < (PARM_BOUNDARY / BITS_PER_UNIT))
886 : return PAD_DOWNWARD;
887 :
888 : return PAD_UPWARD;
889 : }
890 :
891 : rtx
892 0 : default_function_arg (cumulative_args_t, const function_arg_info &)
893 : {
894 0 : gcc_unreachable ();
895 : }
896 :
897 : rtx
898 0 : default_function_incoming_arg (cumulative_args_t, const function_arg_info &)
899 : {
900 0 : gcc_unreachable ();
901 : }
902 :
903 : unsigned int
904 0 : default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
905 : const_tree type ATTRIBUTE_UNUSED)
906 : {
907 0 : return PARM_BOUNDARY;
908 : }
909 :
910 : unsigned int
911 5443480 : default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
912 : const_tree type ATTRIBUTE_UNUSED)
913 : {
914 5443480 : return PARM_BOUNDARY;
915 : }
916 :
917 : void
918 0 : hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
919 : {
920 0 : }
921 :
922 : const char *
923 791380 : hook_invalid_arg_for_unprototyped_fn (
924 : const_tree typelist ATTRIBUTE_UNUSED,
925 : const_tree funcdecl ATTRIBUTE_UNUSED,
926 : const_tree val ATTRIBUTE_UNUSED)
927 : {
928 791380 : return NULL;
929 : }
930 :
931 : /* Initialize the stack protection decls. */
932 :
933 : /* Stack protection related decls living in libgcc. */
934 : static GTY(()) tree stack_chk_guard_decl;
935 :
936 : tree
937 75 : default_stack_protect_guard (void)
938 : {
939 75 : tree t = stack_chk_guard_decl;
940 :
941 75 : if (t == NULL)
942 : {
943 40 : rtx x;
944 :
945 40 : if (UINTPTR_TYPE && targetm.stack_protect_guard_symbol_p ())
946 : /* Get unsigned integer type for uintptr_t. */
947 40 : t = unsigned_integer_tree_node_for_type (UINTPTR_TYPE);
948 : else
949 0 : t = ptr_type_node;
950 40 : t = build_decl (UNKNOWN_LOCATION,
951 : VAR_DECL, get_identifier ("__stack_chk_guard"), t);
952 40 : TREE_STATIC (t) = 1;
953 40 : TREE_PUBLIC (t) = 1;
954 40 : DECL_EXTERNAL (t) = 1;
955 40 : TREE_USED (t) = 1;
956 40 : TREE_THIS_VOLATILE (t) = 1;
957 40 : DECL_ARTIFICIAL (t) = 1;
958 40 : DECL_IGNORED_P (t) = 1;
959 :
960 : /* Do not share RTL as the declaration is visible outside of
961 : current function. */
962 40 : if (mode_mem_attrs[(int) DECL_MODE (t)])
963 : {
964 : /* NB: Don't call make_decl_rtl when mode_mem_attrs isn't
965 : initialized. -save-temps won't initialize mode_mem_attrs
966 : and make_decl_rtl will fail. */
967 34 : x = DECL_RTL (t);
968 34 : RTX_FLAG (x, used) = 1;
969 : }
970 :
971 40 : stack_chk_guard_decl = t;
972 : }
973 :
974 75 : return t;
975 : }
976 :
977 : static GTY(()) tree stack_chk_fail_decl;
978 :
979 : tree
980 334 : default_external_stack_protect_fail (void)
981 : {
982 334 : tree t = stack_chk_fail_decl;
983 :
984 334 : if (t == NULL_TREE)
985 : {
986 183 : t = build_function_type_list (void_type_node, NULL_TREE);
987 183 : t = build_decl (UNKNOWN_LOCATION,
988 : FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
989 183 : TREE_STATIC (t) = 1;
990 183 : TREE_PUBLIC (t) = 1;
991 183 : DECL_EXTERNAL (t) = 1;
992 183 : TREE_USED (t) = 1;
993 183 : TREE_THIS_VOLATILE (t) = 1;
994 183 : TREE_NOTHROW (t) = 1;
995 183 : DECL_ARTIFICIAL (t) = 1;
996 183 : DECL_IGNORED_P (t) = 1;
997 183 : DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
998 183 : DECL_VISIBILITY_SPECIFIED (t) = 1;
999 :
1000 183 : stack_chk_fail_decl = t;
1001 : }
1002 :
1003 334 : return build_call_expr (t, 0);
1004 : }
1005 :
1006 : tree
1007 1 : default_hidden_stack_protect_fail (void)
1008 : {
1009 : #ifndef HAVE_GAS_HIDDEN
1010 : return default_external_stack_protect_fail ();
1011 : #else
1012 1 : tree t = stack_chk_fail_decl;
1013 :
1014 1 : if (!flag_pic)
1015 1 : return default_external_stack_protect_fail ();
1016 :
1017 0 : if (t == NULL_TREE)
1018 : {
1019 0 : t = build_function_type_list (void_type_node, NULL_TREE);
1020 0 : t = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
1021 : get_identifier ("__stack_chk_fail_local"), t);
1022 0 : TREE_STATIC (t) = 1;
1023 0 : TREE_PUBLIC (t) = 1;
1024 0 : DECL_EXTERNAL (t) = 1;
1025 0 : TREE_USED (t) = 1;
1026 0 : TREE_THIS_VOLATILE (t) = 1;
1027 0 : TREE_NOTHROW (t) = 1;
1028 0 : DECL_ARTIFICIAL (t) = 1;
1029 0 : DECL_IGNORED_P (t) = 1;
1030 0 : DECL_VISIBILITY_SPECIFIED (t) = 1;
1031 0 : DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
1032 :
1033 0 : stack_chk_fail_decl = t;
1034 : }
1035 :
1036 0 : return build_call_expr (t, 0);
1037 : #endif
1038 : }
1039 :
1040 : bool
1041 71226771 : hook_bool_const_rtx_commutative_p (const_rtx x,
1042 : int outer_code ATTRIBUTE_UNUSED)
1043 : {
1044 71226771 : return COMMUTATIVE_P (x);
1045 : }
1046 :
1047 : rtx
1048 0 : default_function_value (const_tree ret_type ATTRIBUTE_UNUSED,
1049 : const_tree fn_decl_or_type,
1050 : bool outgoing ATTRIBUTE_UNUSED)
1051 : {
1052 : /* The old interface doesn't handle receiving the function type. */
1053 0 : if (fn_decl_or_type
1054 : && !DECL_P (fn_decl_or_type))
1055 : fn_decl_or_type = NULL;
1056 :
1057 : #ifdef FUNCTION_VALUE
1058 : return FUNCTION_VALUE (ret_type, fn_decl_or_type);
1059 : #else
1060 0 : gcc_unreachable ();
1061 : #endif
1062 : }
1063 :
1064 : rtx
1065 105893 : default_libcall_value (machine_mode mode ATTRIBUTE_UNUSED,
1066 : const_rtx fun ATTRIBUTE_UNUSED)
1067 : {
1068 : #ifdef LIBCALL_VALUE
1069 105893 : return LIBCALL_VALUE (MACRO_MODE (mode));
1070 : #else
1071 : gcc_unreachable ();
1072 : #endif
1073 : }
1074 :
1075 : /* The default hook for TARGET_FUNCTION_VALUE_REGNO_P. */
1076 :
1077 : bool
1078 0 : default_function_value_regno_p (const unsigned int regno ATTRIBUTE_UNUSED)
1079 : {
1080 : #ifdef FUNCTION_VALUE_REGNO_P
1081 : return FUNCTION_VALUE_REGNO_P (regno);
1082 : #else
1083 0 : gcc_unreachable ();
1084 : #endif
1085 : }
1086 :
1087 : /* Choose the mode and rtx to use to zero REGNO, storing tem in PMODE and
1088 : PREGNO_RTX and returning TRUE if successful, otherwise returning FALSE. If
1089 : the natural mode for REGNO doesn't work, attempt to group it with subsequent
1090 : adjacent registers set in TOZERO. */
1091 :
1092 : static inline bool
1093 0 : zcur_select_mode_rtx (unsigned int regno, machine_mode *pmode,
1094 : rtx *pregno_rtx, HARD_REG_SET tozero)
1095 : {
1096 0 : rtx regno_rtx = regno_reg_rtx[regno];
1097 0 : machine_mode mode = GET_MODE (regno_rtx);
1098 :
1099 : /* If the natural mode doesn't work, try some wider mode. */
1100 0 : if (!targetm.hard_regno_mode_ok (regno, mode))
1101 : {
1102 : bool found = false;
1103 0 : for (int nregs = 2;
1104 0 : !found && nregs <= hard_regno_max_nregs
1105 0 : && regno + nregs <= FIRST_PSEUDO_REGISTER
1106 0 : && TEST_HARD_REG_BIT (tozero,
1107 : regno + nregs - 1);
1108 : nregs++)
1109 : {
1110 0 : mode = choose_hard_reg_mode (regno, nregs, 0);
1111 0 : if (mode == E_VOIDmode)
1112 0 : continue;
1113 0 : gcc_checking_assert (targetm.hard_regno_mode_ok (regno, mode));
1114 0 : regno_rtx = gen_rtx_REG (mode, regno);
1115 0 : found = true;
1116 : }
1117 0 : if (!found)
1118 : return false;
1119 : }
1120 :
1121 0 : *pmode = mode;
1122 0 : *pregno_rtx = regno_rtx;
1123 0 : return true;
1124 : }
1125 :
1126 : /* The default hook for TARGET_ZERO_CALL_USED_REGS. */
1127 :
1128 : HARD_REG_SET
1129 0 : default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
1130 : {
1131 0 : gcc_assert (!hard_reg_set_empty_p (need_zeroed_hardregs));
1132 :
1133 : HARD_REG_SET failed;
1134 0 : CLEAR_HARD_REG_SET (failed);
1135 : bool progress = false;
1136 :
1137 : /* First, try to zero each register in need_zeroed_hardregs by
1138 : loading a zero into it, taking note of any failures in
1139 : FAILED. */
1140 0 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1141 0 : if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
1142 : {
1143 0 : rtx_insn *last_insn = get_last_insn ();
1144 0 : rtx regno_rtx;
1145 0 : machine_mode mode;
1146 :
1147 0 : if (!zcur_select_mode_rtx (regno, &mode, ®no_rtx,
1148 : need_zeroed_hardregs))
1149 : {
1150 0 : SET_HARD_REG_BIT (failed, regno);
1151 0 : continue;
1152 : }
1153 :
1154 0 : rtx zero = CONST0_RTX (mode);
1155 0 : rtx_insn *insn = emit_move_insn (regno_rtx, zero);
1156 0 : if (!valid_insn_p (insn))
1157 : {
1158 0 : SET_HARD_REG_BIT (failed, regno);
1159 0 : delete_insns_since (last_insn);
1160 : }
1161 : else
1162 : {
1163 0 : progress = true;
1164 0 : regno += hard_regno_nregs (regno, mode) - 1;
1165 : }
1166 : }
1167 :
1168 : /* Now retry with copies from zeroed registers, as long as we've
1169 : made some PROGRESS, and registers remain to be zeroed in
1170 : FAILED. */
1171 0 : while (progress && !hard_reg_set_empty_p (failed))
1172 : {
1173 0 : HARD_REG_SET retrying = failed;
1174 :
1175 0 : CLEAR_HARD_REG_SET (failed);
1176 : progress = false;
1177 :
1178 0 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1179 0 : if (TEST_HARD_REG_BIT (retrying, regno))
1180 : {
1181 0 : rtx regno_rtx;
1182 0 : machine_mode mode;
1183 :
1184 : /* This might select registers we've already zeroed. If grouping
1185 : with them is what it takes to get regno zeroed, so be it. */
1186 0 : if (!zcur_select_mode_rtx (regno, &mode, ®no_rtx,
1187 : need_zeroed_hardregs))
1188 : {
1189 0 : SET_HARD_REG_BIT (failed, regno);
1190 0 : continue;
1191 : }
1192 :
1193 0 : bool success = false;
1194 : /* Look for a source. */
1195 0 : for (unsigned int src = 0; src < FIRST_PSEUDO_REGISTER; src++)
1196 : {
1197 : /* If SRC hasn't been zeroed (yet?), skip it. */
1198 0 : if (! TEST_HARD_REG_BIT (need_zeroed_hardregs, src))
1199 0 : continue;
1200 0 : if (TEST_HARD_REG_BIT (retrying, src))
1201 0 : continue;
1202 :
1203 : /* Check that SRC can hold MODE, and that any other
1204 : registers needed to hold MODE in SRC have also been
1205 : zeroed. */
1206 0 : if (!targetm.hard_regno_mode_ok (src, mode))
1207 0 : continue;
1208 0 : unsigned n = targetm.hard_regno_nregs (src, mode);
1209 0 : bool ok = true;
1210 0 : for (unsigned i = 1; ok && i < n; i++)
1211 0 : ok = (TEST_HARD_REG_BIT (need_zeroed_hardregs, src + i)
1212 0 : && !TEST_HARD_REG_BIT (retrying, src + i));
1213 0 : if (!ok)
1214 0 : continue;
1215 :
1216 : /* SRC is usable, try to copy from it. */
1217 0 : rtx_insn *last_insn = get_last_insn ();
1218 0 : rtx src_rtx = gen_rtx_REG (mode, src);
1219 0 : rtx_insn *insn = emit_move_insn (regno_rtx, src_rtx);
1220 0 : if (!valid_insn_p (insn))
1221 : /* It didn't work, remove any inserts. We'll look
1222 : for another SRC. */
1223 0 : delete_insns_since (last_insn);
1224 : else
1225 : {
1226 : /* We're done for REGNO. */
1227 : success = true;
1228 : break;
1229 : }
1230 : }
1231 :
1232 : /* If nothing worked for REGNO this round, mark it to be
1233 : retried if we get another round. */
1234 0 : if (!success)
1235 0 : SET_HARD_REG_BIT (failed, regno);
1236 : else
1237 : {
1238 : /* Take note so as to enable another round if needed. */
1239 0 : progress = true;
1240 0 : regno += hard_regno_nregs (regno, mode) - 1;
1241 : }
1242 : }
1243 : }
1244 :
1245 : /* If any register remained, report it. */
1246 0 : if (!progress)
1247 : {
1248 0 : static bool issued_error;
1249 0 : if (!issued_error)
1250 : {
1251 0 : const char *name = NULL;
1252 0 : for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL;
1253 : ++i)
1254 0 : if (flag_zero_call_used_regs == zero_call_used_regs_opts[i].flag)
1255 : {
1256 : name = zero_call_used_regs_opts[i].name;
1257 : break;
1258 : }
1259 :
1260 0 : if (!name)
1261 0 : name = "";
1262 :
1263 0 : issued_error = true;
1264 0 : sorry ("argument %qs is not supported for %qs on this target",
1265 : name, "-fzero-call-used-regs");
1266 : }
1267 : }
1268 :
1269 0 : return need_zeroed_hardregs;
1270 : }
1271 :
1272 : rtx
1273 0 : default_internal_arg_pointer (void)
1274 : {
1275 : /* If the reg that the virtual arg pointer will be translated into is
1276 : not a fixed reg or is the stack pointer, make a copy of the virtual
1277 : arg pointer, and address parms via the copy. The frame pointer is
1278 : considered fixed even though it is not marked as such. */
1279 0 : if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
1280 0 : || ! (fixed_regs[ARG_POINTER_REGNUM]
1281 : || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
1282 0 : return copy_to_reg (virtual_incoming_args_rtx);
1283 : else
1284 0 : return virtual_incoming_args_rtx;
1285 : }
1286 :
1287 : rtx
1288 0 : default_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
1289 : {
1290 0 : if (incoming_p)
1291 : {
1292 : #ifdef STATIC_CHAIN_INCOMING_REGNUM
1293 : return gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
1294 : #endif
1295 : }
1296 :
1297 : #ifdef STATIC_CHAIN_REGNUM
1298 : return gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
1299 : #endif
1300 :
1301 0 : {
1302 0 : static bool issued_error;
1303 0 : if (!issued_error)
1304 : {
1305 0 : issued_error = true;
1306 0 : sorry ("nested functions not supported on this target");
1307 : }
1308 :
1309 : /* It really doesn't matter what we return here, so long at it
1310 : doesn't cause the rest of the compiler to crash. */
1311 0 : return gen_rtx_MEM (Pmode, stack_pointer_rtx);
1312 : }
1313 : }
1314 :
1315 : void
1316 0 : default_trampoline_init (rtx ARG_UNUSED (m_tramp), tree ARG_UNUSED (t_func),
1317 : rtx ARG_UNUSED (r_chain))
1318 : {
1319 0 : sorry ("nested function trampolines not supported on this target");
1320 0 : }
1321 :
1322 : poly_int64
1323 0 : default_return_pops_args (tree, tree, poly_int64)
1324 : {
1325 0 : return 0;
1326 : }
1327 :
1328 : reg_class_t
1329 49326863 : default_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED,
1330 : reg_class_t cl,
1331 : reg_class_t best_cl ATTRIBUTE_UNUSED)
1332 : {
1333 49326863 : return cl;
1334 : }
1335 :
1336 : int
1337 0 : default_ira_callee_saved_register_cost_scale (int)
1338 : {
1339 0 : return (optimize_size
1340 0 : ? 1
1341 0 : : REG_FREQ_FROM_BB (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
1342 : }
1343 :
1344 : extern bool
1345 303628154 : default_lra_p (void)
1346 : {
1347 303628154 : return true;
1348 : }
1349 :
1350 : int
1351 0 : default_register_priority (int hard_regno ATTRIBUTE_UNUSED)
1352 : {
1353 0 : return 0;
1354 : }
1355 :
1356 : extern bool
1357 0 : default_register_usage_leveling_p (void)
1358 : {
1359 0 : return false;
1360 : }
1361 :
1362 : extern bool
1363 4817280 : default_different_addr_displacement_p (void)
1364 : {
1365 4817280 : return false;
1366 : }
1367 :
1368 : reg_class_t
1369 0 : default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
1370 : reg_class_t reload_class_i ATTRIBUTE_UNUSED,
1371 : machine_mode reload_mode ATTRIBUTE_UNUSED,
1372 : secondary_reload_info *sri)
1373 : {
1374 0 : enum reg_class rclass = NO_REGS;
1375 0 : enum reg_class reload_class = (enum reg_class) reload_class_i;
1376 :
1377 0 : if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
1378 : {
1379 0 : sri->icode = sri->prev_sri->t_icode;
1380 0 : return NO_REGS;
1381 : }
1382 : #ifdef SECONDARY_INPUT_RELOAD_CLASS
1383 : if (in_p)
1384 : rclass = SECONDARY_INPUT_RELOAD_CLASS (reload_class,
1385 : MACRO_MODE (reload_mode), x);
1386 : #endif
1387 : #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
1388 : if (! in_p)
1389 : rclass = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class,
1390 : MACRO_MODE (reload_mode), x);
1391 : #endif
1392 : if (rclass != NO_REGS)
1393 : {
1394 : enum insn_code icode
1395 : = direct_optab_handler (in_p ? reload_in_optab : reload_out_optab,
1396 : reload_mode);
1397 :
1398 : if (icode != CODE_FOR_nothing
1399 : && !insn_operand_matches (icode, in_p, x))
1400 : icode = CODE_FOR_nothing;
1401 : else if (icode != CODE_FOR_nothing)
1402 : {
1403 : const char *insn_constraint, *scratch_constraint;
1404 : enum reg_class insn_class, scratch_class;
1405 :
1406 : gcc_assert (insn_data[(int) icode].n_operands == 3);
1407 : insn_constraint = insn_data[(int) icode].operand[!in_p].constraint;
1408 : if (!*insn_constraint)
1409 : insn_class = ALL_REGS;
1410 : else
1411 : {
1412 : if (in_p)
1413 : {
1414 : gcc_assert (*insn_constraint == '=');
1415 : insn_constraint++;
1416 : }
1417 : insn_class = (reg_class_for_constraint
1418 : (lookup_constraint (insn_constraint)));
1419 : gcc_assert (insn_class != NO_REGS);
1420 : }
1421 :
1422 : scratch_constraint = insn_data[(int) icode].operand[2].constraint;
1423 : /* The scratch register's constraint must start with "=&",
1424 : except for an input reload, where only "=" is necessary,
1425 : and where it might be beneficial to re-use registers from
1426 : the input. */
1427 : gcc_assert (scratch_constraint[0] == '='
1428 : && (in_p || scratch_constraint[1] == '&'));
1429 : scratch_constraint++;
1430 : if (*scratch_constraint == '&')
1431 : scratch_constraint++;
1432 : scratch_class = (reg_class_for_constraint
1433 : (lookup_constraint (scratch_constraint)));
1434 :
1435 : if (reg_class_subset_p (reload_class, insn_class))
1436 : {
1437 : gcc_assert (scratch_class == rclass);
1438 : rclass = NO_REGS;
1439 : }
1440 : else
1441 : rclass = insn_class;
1442 :
1443 : }
1444 : if (rclass == NO_REGS)
1445 : sri->icode = icode;
1446 : else
1447 : sri->t_icode = icode;
1448 : }
1449 : return rclass;
1450 : }
1451 :
1452 : /* The default implementation of TARGET_SECONDARY_MEMORY_NEEDED_MODE. */
1453 :
1454 : machine_mode
1455 0 : default_secondary_memory_needed_mode (machine_mode mode)
1456 : {
1457 0 : if (!targetm.lra_p ()
1458 0 : && known_lt (GET_MODE_BITSIZE (mode), BITS_PER_WORD)
1459 0 : && INTEGRAL_MODE_P (mode))
1460 0 : return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
1461 : return mode;
1462 : }
1463 :
1464 : /* By default, if flag_pic is true, then neither local nor global relocs
1465 : should be placed in readonly memory. */
1466 :
1467 : int
1468 0 : default_reloc_rw_mask (void)
1469 : {
1470 0 : return flag_pic ? 3 : 0;
1471 : }
1472 :
1473 : /* By default, address diff vectors are generated
1474 : for jump tables when flag_pic is true. */
1475 :
1476 : bool
1477 15467 : default_generate_pic_addr_diff_vec (void)
1478 : {
1479 15467 : return flag_pic;
1480 : }
1481 :
1482 : /* Record an element in the table of global constructors. SYMBOL is
1483 : a SYMBOL_REF of the function to be called; PRIORITY is a number
1484 : between 0 and MAX_INIT_PRIORITY. */
1485 :
1486 : void
1487 0 : default_asm_out_constructor (rtx symbol ATTRIBUTE_UNUSED,
1488 : int priority ATTRIBUTE_UNUSED)
1489 : {
1490 0 : sorry ("global constructors not supported on this target");
1491 0 : }
1492 :
1493 : /* Likewise for global destructors. */
1494 :
1495 : void
1496 0 : default_asm_out_destructor (rtx symbol ATTRIBUTE_UNUSED,
1497 : int priority ATTRIBUTE_UNUSED)
1498 : {
1499 0 : sorry ("global destructors not supported on this target");
1500 0 : }
1501 :
1502 : /* By default, do no modification. */
1503 0 : tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED,
1504 : tree id)
1505 : {
1506 0 : return id;
1507 : }
1508 :
1509 : /* The default implementation of TARGET_STATIC_RTX_ALIGNMENT. */
1510 :
1511 : HOST_WIDE_INT
1512 0 : default_static_rtx_alignment (machine_mode mode)
1513 : {
1514 0 : return GET_MODE_ALIGNMENT (mode);
1515 : }
1516 :
1517 : /* The default implementation of TARGET_CONSTANT_ALIGNMENT. */
1518 :
1519 : HOST_WIDE_INT
1520 0 : default_constant_alignment (const_tree, HOST_WIDE_INT align)
1521 : {
1522 0 : return align;
1523 : }
1524 :
1525 : /* An implementation of TARGET_CONSTANT_ALIGNMENT that aligns strings
1526 : to at least BITS_PER_WORD but otherwise makes no changes. */
1527 :
1528 : HOST_WIDE_INT
1529 0 : constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align)
1530 : {
1531 0 : if (TREE_CODE (exp) == STRING_CST)
1532 0 : return MAX (align, BITS_PER_WORD);
1533 : return align;
1534 : }
1535 :
1536 : /* Default to natural alignment for vector types, bounded by
1537 : MAX_OFILE_ALIGNMENT. */
1538 :
1539 : HOST_WIDE_INT
1540 72009518 : default_vector_alignment (const_tree type)
1541 : {
1542 72009518 : unsigned HOST_WIDE_INT align = MAX_OFILE_ALIGNMENT;
1543 72009518 : tree size = TYPE_SIZE (type);
1544 72009518 : if (tree_fits_uhwi_p (size))
1545 72009518 : align = tree_to_uhwi (size);
1546 72009518 : if (align >= MAX_OFILE_ALIGNMENT)
1547 : return MAX_OFILE_ALIGNMENT;
1548 72009511 : return MAX (align, GET_MODE_ALIGNMENT (TYPE_MODE (type)));
1549 : }
1550 :
1551 : /* The default implementation of
1552 : TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
1553 :
1554 : poly_uint64
1555 6426456 : default_preferred_vector_alignment (const_tree type)
1556 : {
1557 6426456 : return TYPE_ALIGN (type);
1558 : }
1559 :
1560 : /* The default implementation of
1561 : TARGET_VECTORIZE_PREFERRED_DIV_AS_SHIFTS_OVER_MULT. */
1562 :
1563 : bool
1564 17717 : default_preferred_div_as_shifts_over_mult (const_tree type)
1565 : {
1566 17717 : return !can_mult_highpart_p (TYPE_MODE (type), TYPE_UNSIGNED (type));
1567 : }
1568 :
1569 : /* By default assume vectors of element TYPE require a multiple of the natural
1570 : alignment of TYPE. TYPE is naturally aligned if IS_PACKED is false. */
1571 : bool
1572 237651 : default_builtin_vector_alignment_reachable (const_tree /*type*/, bool is_packed)
1573 : {
1574 237651 : return ! is_packed;
1575 : }
1576 :
1577 : /* By default, assume that a target supports any factor of misalignment
1578 : memory access if it supports movmisalign pattern.
1579 : is_packed is true if the memory access is defined in a packed struct. */
1580 : bool
1581 1359207 : default_builtin_support_vector_misalignment (machine_mode mode,
1582 : int misalignment
1583 : ATTRIBUTE_UNUSED,
1584 : bool is_packed
1585 : ATTRIBUTE_UNUSED,
1586 : bool is_gather_scatter
1587 : ATTRIBUTE_UNUSED)
1588 : {
1589 1359207 : if (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing)
1590 1359012 : return true;
1591 : return false;
1592 : }
1593 :
1594 : /* By default, only attempt to parallelize bitwise operations, and
1595 : possibly adds/subtracts using bit-twiddling. */
1596 :
1597 : machine_mode
1598 0 : default_preferred_simd_mode (scalar_mode)
1599 : {
1600 0 : return word_mode;
1601 : }
1602 :
1603 : /* By default do not split reductions further. */
1604 :
1605 : machine_mode
1606 0 : default_split_reduction (machine_mode mode)
1607 : {
1608 0 : return mode;
1609 : }
1610 :
1611 : /* By default only the preferred vector mode is tried. */
1612 :
1613 : unsigned int
1614 0 : default_autovectorize_vector_modes (vector_modes *, bool)
1615 : {
1616 0 : return 0;
1617 : }
1618 :
1619 : /* The default implementation of TARGET_VECTORIZE_RELATED_MODE. */
1620 :
1621 : opt_machine_mode
1622 34055093 : default_vectorize_related_mode (machine_mode vector_mode,
1623 : scalar_mode element_mode,
1624 : poly_uint64 nunits)
1625 : {
1626 34055093 : machine_mode result_mode;
1627 34055093 : if ((maybe_ne (nunits, 0U)
1628 57612753 : || multiple_p (GET_MODE_SIZE (vector_mode),
1629 29820782 : GET_MODE_SIZE (element_mode), &nunits))
1630 32026282 : && mode_for_vector (element_mode, nunits).exists (&result_mode)
1631 31856659 : && VECTOR_MODE_P (result_mode)
1632 65910424 : && targetm.vector_mode_supported_p (result_mode))
1633 31845998 : return result_mode;
1634 :
1635 2209095 : return opt_machine_mode ();
1636 : }
1637 :
1638 : /* By default a vector of integers is used as a mask. */
1639 :
1640 : opt_machine_mode
1641 0 : default_get_mask_mode (machine_mode mode)
1642 : {
1643 0 : return related_int_vector_mode (mode);
1644 : }
1645 :
1646 : /* By default consider masked stores to be expensive. */
1647 :
1648 : bool
1649 9381 : default_conditional_operation_is_expensive (unsigned ifn)
1650 : {
1651 9381 : return ifn == IFN_MASK_STORE;
1652 : }
1653 :
1654 : /* By default consider masked stores to be expensive. */
1655 :
1656 : bool
1657 493 : default_empty_mask_is_expensive (unsigned ifn)
1658 : {
1659 493 : return ifn == IFN_MASK_STORE;
1660 : }
1661 :
1662 : /* By default, the cost model accumulates three separate costs (prologue,
1663 : loop body, and epilogue) for a vectorized loop or block. So allocate an
1664 : array of three unsigned ints, set it to zero, and return its address. */
1665 :
1666 : vector_costs *
1667 0 : default_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
1668 : {
1669 0 : return new vector_costs (vinfo, costing_for_scalar);
1670 : }
1671 :
1672 : /* Determine whether or not a pointer mode is valid. Assume defaults
1673 : of ptr_mode or Pmode - can be overridden. */
1674 : bool
1675 6708964 : default_valid_pointer_mode (scalar_int_mode mode)
1676 : {
1677 6708964 : return (mode == ptr_mode || mode == Pmode);
1678 : }
1679 :
1680 : /* Determine whether the memory reference specified by REF may alias
1681 : the C libraries errno location. */
1682 : bool
1683 7763191 : default_ref_may_alias_errno (ao_ref *ref)
1684 : {
1685 7763191 : tree base = ao_ref_base (ref);
1686 : /* The default implementation assumes the errno location is
1687 : a declaration of type int or is always accessed via a
1688 : pointer to int. We assume that accesses to errno are
1689 : not deliberately obfuscated (even in conforming ways). */
1690 7763191 : if (TYPE_UNSIGNED (TREE_TYPE (base))
1691 7763191 : || TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node))
1692 7395534 : return false;
1693 : /* The default implementation assumes an errno location declaration
1694 : is never defined in the current compilation unit and may not be
1695 : aliased by a local variable. */
1696 367657 : if (DECL_P (base)
1697 257880 : && DECL_EXTERNAL (base)
1698 369215 : && !TREE_STATIC (base))
1699 : return true;
1700 367564 : else if (TREE_CODE (base) == MEM_REF
1701 367564 : && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1702 : {
1703 101461 : struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
1704 128014 : return !pi || pi->pt.anything || pi->pt.nonlocal;
1705 : }
1706 : return false;
1707 : }
1708 :
1709 : /* Return the mode for a pointer to a given ADDRSPACE,
1710 : defaulting to ptr_mode for all address spaces. */
1711 :
1712 : scalar_int_mode
1713 3059005496 : default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
1714 : {
1715 3059005496 : return ptr_mode;
1716 : }
1717 :
1718 : /* Return the mode for an address in a given ADDRSPACE,
1719 : defaulting to Pmode for all address spaces. */
1720 :
1721 : scalar_int_mode
1722 99576335 : default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
1723 : {
1724 99576335 : return Pmode;
1725 : }
1726 :
1727 : /* Named address space version of valid_pointer_mode.
1728 : To match the above, the same modes apply to all address spaces. */
1729 :
1730 : bool
1731 6708964 : default_addr_space_valid_pointer_mode (scalar_int_mode mode,
1732 : addr_space_t as ATTRIBUTE_UNUSED)
1733 : {
1734 6708964 : return targetm.valid_pointer_mode (mode);
1735 : }
1736 :
1737 : /* Some places still assume that all pointer or address modes are the
1738 : standard Pmode and ptr_mode. These optimizations become invalid if
1739 : the target actually supports multiple different modes. For now,
1740 : we disable such optimizations on such targets, using this function. */
1741 :
1742 : bool
1743 697245037 : target_default_pointer_address_modes_p (void)
1744 : {
1745 697245037 : if (targetm.addr_space.address_mode != default_addr_space_address_mode)
1746 : return false;
1747 697245037 : if (targetm.addr_space.pointer_mode != default_addr_space_pointer_mode)
1748 0 : return false;
1749 :
1750 : return true;
1751 : }
1752 :
1753 : /* Named address space version of legitimate_address_p.
1754 : By default, all address spaces have the same form. */
1755 :
1756 : bool
1757 1521936108 : default_addr_space_legitimate_address_p (machine_mode mode, rtx mem,
1758 : bool strict,
1759 : addr_space_t as ATTRIBUTE_UNUSED,
1760 : code_helper code)
1761 : {
1762 1521936108 : return targetm.legitimate_address_p (mode, mem, strict, code);
1763 : }
1764 :
1765 : /* Named address space version of LEGITIMIZE_ADDRESS.
1766 : By default, all address spaces have the same form. */
1767 :
1768 : rtx
1769 664871 : default_addr_space_legitimize_address (rtx x, rtx oldx, machine_mode mode,
1770 : addr_space_t as ATTRIBUTE_UNUSED)
1771 : {
1772 664871 : return targetm.legitimize_address (x, oldx, mode);
1773 : }
1774 :
1775 : /* The default hook for determining if one named address space is a subset of
1776 : another and to return which address space to use as the common address
1777 : space. */
1778 :
1779 : bool
1780 3 : default_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
1781 : {
1782 3 : return (subset == superset);
1783 : }
1784 :
1785 : /* The default hook for determining if 0 within a named address
1786 : space is a valid address. */
1787 :
1788 : bool
1789 0 : default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED)
1790 : {
1791 0 : return false;
1792 : }
1793 :
1794 : /* The default hook for debugging the address space is to return the
1795 : address space number to indicate DW_AT_address_class. */
1796 : int
1797 3 : default_addr_space_debug (addr_space_t as)
1798 : {
1799 3 : return as;
1800 : }
1801 :
1802 : /* The default hook implementation for TARGET_ADDR_SPACE_DIAGNOSE_USAGE.
1803 : Don't complain about any address space. */
1804 :
1805 : void
1806 177 : default_addr_space_diagnose_usage (addr_space_t, location_t)
1807 : {
1808 177 : }
1809 :
1810 :
1811 : /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
1812 : called for targets with only a generic address space. */
1813 :
1814 : rtx
1815 0 : default_addr_space_convert (rtx op ATTRIBUTE_UNUSED,
1816 : tree from_type ATTRIBUTE_UNUSED,
1817 : tree to_type ATTRIBUTE_UNUSED)
1818 : {
1819 0 : gcc_unreachable ();
1820 : }
1821 :
1822 :
1823 : /* The default hook for TARGET_ADDR_SPACE_FOR_ARTIFICIAL_RODATA. */
1824 :
1825 : addr_space_t
1826 509 : default_addr_space_for_artificial_rodata (tree, artificial_rodata)
1827 : {
1828 509 : return ADDR_SPACE_GENERIC;
1829 : }
1830 :
1831 :
1832 : /* The default implementation of TARGET_HARD_REGNO_NREGS. */
1833 :
1834 : unsigned int
1835 0 : default_hard_regno_nregs (unsigned int, machine_mode mode)
1836 : {
1837 : /* Targets with variable-sized modes must provide their own definition
1838 : of this hook. */
1839 0 : return CEIL (GET_MODE_SIZE (mode).to_constant (), UNITS_PER_WORD);
1840 : }
1841 :
1842 : bool
1843 0 : default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
1844 : {
1845 0 : return true;
1846 : }
1847 :
1848 : /* The default implementation of TARGET_MODE_DEPENDENT_ADDRESS_P. */
1849 :
1850 : bool
1851 36275674 : default_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED,
1852 : addr_space_t addrspace ATTRIBUTE_UNUSED)
1853 : {
1854 36275674 : return false;
1855 : }
1856 :
1857 : extern bool default_new_address_profitable_p (rtx, rtx);
1858 :
1859 :
1860 : /* The default implementation of TARGET_NEW_ADDRESS_PROFITABLE_P. */
1861 :
1862 : bool
1863 1130577 : default_new_address_profitable_p (rtx memref ATTRIBUTE_UNUSED,
1864 : rtx_insn *insn ATTRIBUTE_UNUSED,
1865 : rtx new_addr ATTRIBUTE_UNUSED)
1866 : {
1867 1130577 : return true;
1868 : }
1869 :
1870 : bool
1871 0 : default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl),
1872 : tree ARG_UNUSED (name),
1873 : tree ARG_UNUSED (args),
1874 : int ARG_UNUSED (flags))
1875 : {
1876 0 : warning (OPT_Wattributes,
1877 : "%<target%> attribute is not supported on this machine");
1878 :
1879 0 : return false;
1880 : }
1881 :
1882 : bool
1883 0 : default_target_option_valid_version_attribute_p (tree ARG_UNUSED (fndecl),
1884 : tree ARG_UNUSED (name),
1885 : tree ARG_UNUSED (args),
1886 : int ARG_UNUSED (flags))
1887 : {
1888 0 : warning (OPT_Wattributes,
1889 : "%<target_version%> attribute is not supported on this machine");
1890 :
1891 0 : return false;
1892 : }
1893 :
1894 : bool
1895 0 : default_target_option_pragma_parse (tree ARG_UNUSED (args),
1896 : tree ARG_UNUSED (pop_target))
1897 : {
1898 : /* If args is NULL the caller is handle_pragma_pop_options (). In that case,
1899 : emit no warning because "#pragma GCC pop_target" is valid on targets that
1900 : do not have the "target" pragma. */
1901 0 : if (args)
1902 0 : warning (OPT_Wpragmas,
1903 : "%<#pragma GCC target%> is not supported for this machine");
1904 :
1905 0 : return false;
1906 : }
1907 :
1908 : bool
1909 0 : default_target_can_inline_p (tree caller, tree callee)
1910 : {
1911 0 : tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee);
1912 0 : tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller);
1913 0 : if (! callee_opts)
1914 0 : callee_opts = target_option_default_node;
1915 0 : if (! caller_opts)
1916 0 : caller_opts = target_option_default_node;
1917 :
1918 : /* If both caller and callee have attributes, assume that if the
1919 : pointer is different, the two functions have different target
1920 : options since build_target_option_node uses a hash table for the
1921 : options. */
1922 0 : return callee_opts == caller_opts;
1923 : }
1924 :
1925 : /* By default, return false to not need to collect any target information
1926 : for inlining. Target maintainer should re-define the hook if the
1927 : target want to take advantage of it. */
1928 :
1929 : bool
1930 5667196 : default_need_ipa_fn_target_info (const_tree, unsigned int &)
1931 : {
1932 5667196 : return false;
1933 : }
1934 :
1935 : bool
1936 0 : default_update_ipa_fn_target_info (unsigned int &, const gimple *)
1937 : {
1938 0 : return false;
1939 : }
1940 :
1941 : /* If the machine does not have a case insn that compares the bounds,
1942 : this means extra overhead for dispatch tables, which raises the
1943 : threshold for using them. */
1944 :
1945 : unsigned int
1946 6684787 : default_case_values_threshold (void)
1947 : {
1948 6684787 : return (targetm.have_casesi () ? 4 : 5);
1949 : }
1950 :
1951 : bool
1952 117461486 : default_have_conditional_execution (void)
1953 : {
1954 117461486 : return HAVE_conditional_execution;
1955 : }
1956 :
1957 : bool
1958 0 : default_have_ccmp (void)
1959 : {
1960 0 : return targetm.gen_ccmp_first != NULL;
1961 : }
1962 :
1963 : /* By default we assume that c99 functions are present at the runtime,
1964 : but sincos is not. */
1965 : bool
1966 0 : default_libc_has_function (enum function_class fn_class,
1967 : tree type ATTRIBUTE_UNUSED)
1968 : {
1969 0 : if (fn_class == function_c94
1970 : || fn_class == function_c99_misc
1971 : || fn_class == function_c99_math_complex)
1972 0 : return true;
1973 :
1974 : return false;
1975 : }
1976 :
1977 : /* By default assume that libc has not a fast implementation. */
1978 :
1979 : bool
1980 0 : default_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
1981 : {
1982 0 : return false;
1983 : }
1984 :
1985 : bool
1986 0 : gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
1987 : tree type ATTRIBUTE_UNUSED)
1988 : {
1989 0 : return true;
1990 : }
1991 :
1992 : bool
1993 0 : no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED,
1994 : tree type ATTRIBUTE_UNUSED)
1995 : {
1996 0 : return false;
1997 : }
1998 :
1999 : /* Assume some c99 functions are present at the runtime including sincos. */
2000 : bool
2001 0 : bsd_libc_has_function (enum function_class fn_class,
2002 : tree type ATTRIBUTE_UNUSED)
2003 : {
2004 0 : if (fn_class == function_c94
2005 0 : || fn_class == function_c99_misc
2006 0 : || fn_class == function_sincos)
2007 : return true;
2008 :
2009 : return false;
2010 : }
2011 :
2012 : /* By default, -fhardened will add -D_FORTIFY_SOURCE=2. */
2013 :
2014 : unsigned
2015 0 : default_fortify_source_default_level ()
2016 : {
2017 0 : return 2;
2018 : }
2019 :
2020 : unsigned
2021 118 : default_libm_function_max_error (unsigned, machine_mode, bool)
2022 : {
2023 118 : return ~0U;
2024 : }
2025 :
2026 : unsigned
2027 78204 : glibc_linux_libm_function_max_error (unsigned cfn, machine_mode mode,
2028 : bool boundary_p)
2029 : {
2030 : /* Let's use
2031 : https://www.gnu.org/software/libc/manual/2.22/html_node/Errors-in-Math-Functions.html
2032 : https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
2033 : with usual values recorded here and significant outliers handled in
2034 : target CPU specific overriders. The tables only record default
2035 : rounding to nearest, for -frounding-math let's add some extra ulps.
2036 : For boundary_p values (say finite results outside of [-1.,1.] for
2037 : sin/cos, or [-0.,+Inf] for sqrt etc. let's use custom random testers. */
2038 78204 : int rnd = flag_rounding_math ? 4 : 0;
2039 78204 : bool sf = (REAL_MODE_FORMAT (mode) == &ieee_single_format
2040 57568 : || REAL_MODE_FORMAT (mode) == &mips_single_format
2041 135772 : || REAL_MODE_FORMAT (mode) == &motorola_single_format);
2042 78204 : bool df = (REAL_MODE_FORMAT (mode) == &ieee_double_format
2043 39343 : || REAL_MODE_FORMAT (mode) == &mips_double_format
2044 117547 : || REAL_MODE_FORMAT (mode) == &motorola_double_format);
2045 78204 : bool xf = (REAL_MODE_FORMAT (mode) == &ieee_extended_intel_96_format
2046 74762 : || REAL_MODE_FORMAT (mode) == &ieee_extended_intel_128_format
2047 139977 : || REAL_MODE_FORMAT (mode) == &ieee_extended_motorola_format);
2048 78204 : bool tf = (REAL_MODE_FORMAT (mode) == &ieee_quad_format
2049 78204 : || REAL_MODE_FORMAT (mode) == &mips_quad_format);
2050 :
2051 78204 : switch (cfn)
2052 : {
2053 50886 : CASE_CFN_SQRT:
2054 50886 : CASE_CFN_SQRT_FN:
2055 50886 : if (boundary_p)
2056 : /* https://gcc.gnu.org/pipermail/gcc-patches/2023-April/616595.html */
2057 : return 0;
2058 25443 : if (sf || df || xf || tf)
2059 25325 : return 0 + rnd;
2060 : break;
2061 8996 : CASE_CFN_COS:
2062 8996 : CASE_CFN_COS_FN:
2063 : /* cos is generally errors like sin, but far more arches have 2ulps
2064 : for double. */
2065 8996 : if (!boundary_p && df)
2066 1700 : return 2 + rnd;
2067 25618 : gcc_fallthrough ();
2068 25618 : CASE_CFN_SIN:
2069 25618 : CASE_CFN_SIN_FN:
2070 25618 : if (boundary_p)
2071 : /* According to
2072 : https://sourceware.org/pipermail/gcc-patches/2023-April/616315.html
2073 : seems default rounding sin/cos stay strictly in [-1.,1.] range,
2074 : with rounding to infinity it can be 1ulp larger/smaller. */
2075 30002 : return flag_rounding_math ? 1 : 0;
2076 10591 : if (sf || df)
2077 6736 : return 1 + rnd;
2078 3855 : if (xf || tf)
2079 3855 : return 2 + rnd;
2080 : break;
2081 : default:
2082 : break;
2083 : }
2084 :
2085 118 : return default_libm_function_max_error (cfn, mode, boundary_p);
2086 : }
2087 :
2088 : tree
2089 0 : default_builtin_tm_load_store (tree ARG_UNUSED (type))
2090 : {
2091 0 : return NULL_TREE;
2092 : }
2093 :
2094 : /* Compute cost of moving registers to/from memory. */
2095 :
2096 : int
2097 0 : default_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2098 : reg_class_t rclass ATTRIBUTE_UNUSED,
2099 : bool in ATTRIBUTE_UNUSED)
2100 : {
2101 : #ifndef MEMORY_MOVE_COST
2102 0 : return (4 + memory_move_secondary_cost (mode, (enum reg_class) rclass, in));
2103 : #else
2104 : return MEMORY_MOVE_COST (MACRO_MODE (mode), (enum reg_class) rclass, in);
2105 : #endif
2106 : }
2107 :
2108 : /* Compute cost of moving data from a register of class FROM to one of
2109 : TO, using MODE. */
2110 :
2111 : int
2112 0 : default_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2113 : reg_class_t from ATTRIBUTE_UNUSED,
2114 : reg_class_t to ATTRIBUTE_UNUSED)
2115 : {
2116 : #ifndef REGISTER_MOVE_COST
2117 0 : return 2;
2118 : #else
2119 : return REGISTER_MOVE_COST (MACRO_MODE (mode),
2120 : (enum reg_class) from, (enum reg_class) to);
2121 : #endif
2122 : }
2123 :
2124 : /* The default implementation of TARGET_CALLEE_SAVE_COST. */
2125 :
2126 : int
2127 0 : default_callee_save_cost (spill_cost_type spill_type, unsigned int,
2128 : machine_mode, unsigned int, int mem_cost,
2129 : const HARD_REG_SET &callee_saved_regs,
2130 : bool existing_spills_p)
2131 : {
2132 0 : if (!existing_spills_p)
2133 : {
2134 0 : auto frame_type = (spill_type == spill_cost_type::SAVE
2135 0 : ? frame_cost_type::ALLOCATION
2136 : : frame_cost_type::DEALLOCATION);
2137 0 : mem_cost += targetm.frame_allocation_cost (frame_type,
2138 : callee_saved_regs);
2139 : }
2140 0 : return mem_cost;
2141 : }
2142 :
2143 : /* The default implementation of TARGET_FRAME_ALLOCATION_COST. */
2144 :
2145 : int
2146 16249152 : default_frame_allocation_cost (frame_cost_type, const HARD_REG_SET &)
2147 : {
2148 16249152 : return 0;
2149 : }
2150 :
2151 : /* The default implementation of TARGET_SLOW_UNALIGNED_ACCESS. */
2152 :
2153 : bool
2154 3472676 : default_slow_unaligned_access (machine_mode, unsigned int)
2155 : {
2156 3472676 : return STRICT_ALIGNMENT;
2157 : }
2158 :
2159 : /* The default implementation of TARGET_ESTIMATED_POLY_VALUE. */
2160 :
2161 : HOST_WIDE_INT
2162 0 : default_estimated_poly_value (poly_int64 x, poly_value_estimate_kind)
2163 : {
2164 0 : return x.coeffs[0];
2165 : }
2166 :
2167 : /* For hooks which use the MOVE_RATIO macro, this gives the legacy default
2168 : behavior. SPEED_P is true if we are compiling for speed. */
2169 :
2170 : unsigned int
2171 1701946 : get_move_ratio (bool speed_p ATTRIBUTE_UNUSED)
2172 : {
2173 1701946 : unsigned int move_ratio;
2174 : #ifdef MOVE_RATIO
2175 1701946 : move_ratio = (unsigned int) MOVE_RATIO (speed_p);
2176 : #else
2177 : #if defined (HAVE_cpymemqi) || defined (HAVE_cpymemhi) || defined (HAVE_cpymemsi) || defined (HAVE_cpymemdi) || defined (HAVE_cpymemti)
2178 : move_ratio = 2;
2179 : #else /* No cpymem patterns, pick a default. */
2180 : move_ratio = ((speed_p) ? 15 : 3);
2181 : #endif
2182 : #endif
2183 1701946 : return move_ratio;
2184 : }
2185 :
2186 : /* Return TRUE if the move_by_pieces/set_by_pieces infrastructure should be
2187 : used; return FALSE if the cpymem/setmem optab should be expanded, or
2188 : a call to memcpy emitted. */
2189 :
2190 : bool
2191 1177579 : default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
2192 : unsigned int alignment,
2193 : enum by_pieces_operation op,
2194 : bool speed_p)
2195 : {
2196 1177579 : unsigned int max_size = 0;
2197 1177579 : unsigned int ratio = 0;
2198 :
2199 1177579 : switch (op)
2200 : {
2201 85882 : case CLEAR_BY_PIECES:
2202 85882 : max_size = STORE_MAX_PIECES;
2203 85882 : ratio = CLEAR_RATIO (speed_p);
2204 : break;
2205 890242 : case MOVE_BY_PIECES:
2206 890242 : max_size = MOVE_MAX_PIECES;
2207 890242 : ratio = get_move_ratio (speed_p);
2208 890242 : break;
2209 49831 : case SET_BY_PIECES:
2210 49831 : max_size = STORE_MAX_PIECES;
2211 49831 : ratio = SET_RATIO (speed_p);
2212 : break;
2213 83146 : case STORE_BY_PIECES:
2214 83146 : max_size = STORE_MAX_PIECES;
2215 83146 : ratio = get_move_ratio (speed_p);
2216 83146 : break;
2217 68478 : case COMPARE_BY_PIECES:
2218 68478 : max_size = COMPARE_MAX_PIECES;
2219 : /* Pick a likely default, just as in get_move_ratio. */
2220 68478 : ratio = speed_p ? 15 : 3;
2221 : break;
2222 : }
2223 :
2224 1177579 : return by_pieces_ninsns (size, alignment, max_size + 1, op) < ratio;
2225 : }
2226 :
2227 : /* This hook controls code generation for expanding a memcmp operation by
2228 : pieces. Return 1 for the normal pattern of compare/jump after each pair
2229 : of loads, or a higher number to reduce the number of branches. */
2230 :
2231 : int
2232 161070 : default_compare_by_pieces_branch_ratio (machine_mode)
2233 : {
2234 161070 : return 1;
2235 : }
2236 :
2237 : /* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
2238 : entry. If RECORD_P is true and the target supports named sections,
2239 : the location of the NOPs will be recorded in a special object section
2240 : called "__patchable_function_entries". This routine may be called
2241 : twice per function to put NOPs before and after the function
2242 : entry. */
2243 :
2244 : void
2245 59 : default_print_patchable_function_entry (FILE *file,
2246 : unsigned HOST_WIDE_INT patch_area_size,
2247 : bool record_p)
2248 : {
2249 59 : const char *nop_templ = 0;
2250 59 : int code_num;
2251 59 : rtx_insn *my_nop = make_insn_raw (gen_nop ());
2252 :
2253 : /* We use the template alone, relying on the (currently sane) assumption
2254 : that the NOP template does not have variable operands. */
2255 59 : code_num = recog_memoized (my_nop);
2256 59 : nop_templ = get_insn_template (code_num, my_nop);
2257 :
2258 59 : if (record_p && targetm_common.have_named_sections)
2259 : {
2260 53 : char buf[256];
2261 53 : section *previous_section = in_section;
2262 53 : const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
2263 :
2264 53 : gcc_assert (asm_op != NULL);
2265 : /* If SECTION_LINK_ORDER is supported, this internal label will
2266 : be filled as the symbol for linked_to section. */
2267 53 : ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", current_function_funcdef_no);
2268 :
2269 53 : unsigned int flags = SECTION_WRITE | SECTION_RELRO;
2270 53 : if (HAVE_GAS_SECTION_LINK_ORDER)
2271 53 : flags |= SECTION_LINK_ORDER;
2272 :
2273 53 : section *sect = get_section ("__patchable_function_entries",
2274 : flags, current_function_decl);
2275 53 : if (HAVE_COMDAT_GROUP && DECL_COMDAT_GROUP (current_function_decl))
2276 12 : switch_to_comdat_section (sect, current_function_decl);
2277 : else
2278 41 : switch_to_section (sect);
2279 53 : assemble_align (POINTER_SIZE);
2280 53 : fputs (asm_op, file);
2281 53 : assemble_name_raw (file, buf);
2282 53 : fputc ('\n', file);
2283 :
2284 53 : switch_to_section (previous_section);
2285 53 : ASM_OUTPUT_LABEL (file, buf);
2286 : }
2287 :
2288 : unsigned i;
2289 136 : for (i = 0; i < patch_area_size; ++i)
2290 77 : output_asm_insn (nop_templ, NULL);
2291 59 : }
2292 :
2293 : bool
2294 0 : default_profile_before_prologue (void)
2295 : {
2296 : #ifdef PROFILE_BEFORE_PROLOGUE
2297 : return true;
2298 : #else
2299 0 : return false;
2300 : #endif
2301 : }
2302 :
2303 : /* The default implementation of TARGET_PREFERRED_RELOAD_CLASS. */
2304 :
2305 : reg_class_t
2306 0 : default_preferred_reload_class (rtx x ATTRIBUTE_UNUSED,
2307 : reg_class_t rclass)
2308 : {
2309 : #ifdef PREFERRED_RELOAD_CLASS
2310 : return (reg_class_t) PREFERRED_RELOAD_CLASS (x, (enum reg_class) rclass);
2311 : #else
2312 0 : return rclass;
2313 : #endif
2314 : }
2315 :
2316 : /* The default implementation of TARGET_OUTPUT_PREFERRED_RELOAD_CLASS. */
2317 :
2318 : reg_class_t
2319 0 : default_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED,
2320 : reg_class_t rclass)
2321 : {
2322 0 : return rclass;
2323 : }
2324 :
2325 : /* The default implementation of TARGET_PREFERRED_RENAME_CLASS. */
2326 : reg_class_t
2327 993481 : default_preferred_rename_class (reg_class_t rclass ATTRIBUTE_UNUSED)
2328 : {
2329 993481 : return NO_REGS;
2330 : }
2331 :
2332 : /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */
2333 :
2334 : bool
2335 0 : default_class_likely_spilled_p (reg_class_t rclass)
2336 : {
2337 0 : return (reg_class_size[(int) rclass] == 1);
2338 : }
2339 :
2340 : /* The default implementation of TARGET_CLASS_MAX_NREGS. */
2341 :
2342 : unsigned char
2343 0 : default_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
2344 : machine_mode mode ATTRIBUTE_UNUSED)
2345 : {
2346 : #ifdef CLASS_MAX_NREGS
2347 : return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass,
2348 : MACRO_MODE (mode));
2349 : #else
2350 : /* Targets with variable-sized modes must provide their own definition
2351 : of this hook. */
2352 0 : unsigned int size = GET_MODE_SIZE (mode).to_constant ();
2353 0 : return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2354 : #endif
2355 : }
2356 :
2357 : /* The default implementation of TARGET_AVOID_STORE_FORWARDING_P. */
2358 :
2359 : bool
2360 11 : default_avoid_store_forwarding_p (vec<store_fwd_info>, rtx, int total_cost,
2361 : bool)
2362 : {
2363 : /* Use a simple cost heurstic base on param_store_forwarding_max_distance.
2364 : In general the distance should be somewhat correlated to the store
2365 : forwarding penalty; if the penalty is large then it is justified to
2366 : increase the window size. Use this to reject sequences that are clearly
2367 : unprofitable.
2368 : Skip the cost check if param_store_forwarding_max_distance is 0. */
2369 11 : int max_cost = COSTS_N_INSNS (param_store_forwarding_max_distance / 2);
2370 11 : const bool unlimited_cost = (param_store_forwarding_max_distance == 0);
2371 11 : if (!unlimited_cost && total_cost > max_cost && max_cost)
2372 : {
2373 1 : if (dump_file)
2374 0 : fprintf (dump_file, "Not transformed due to cost: %d > %d.\n",
2375 : total_cost, max_cost);
2376 :
2377 1 : return false;
2378 : }
2379 :
2380 : return true;
2381 : }
2382 :
2383 : /* Determine the debugging unwind mechanism for the target. */
2384 :
2385 : enum unwind_info_type
2386 1304612 : default_debug_unwind_info (void)
2387 : {
2388 : /* If the target wants to force the use of dwarf2 unwind info, let it. */
2389 : /* ??? Change all users to the hook, then poison this. */
2390 : #ifdef DWARF2_FRAME_INFO
2391 : if (DWARF2_FRAME_INFO)
2392 : return UI_DWARF2;
2393 : #endif
2394 :
2395 : /* Otherwise, only turn it on if dwarf2 debugging is enabled. */
2396 : #ifdef DWARF2_DEBUGGING_INFO
2397 1304612 : if (dwarf_debuginfo_p ())
2398 653507 : return UI_DWARF2;
2399 : #endif
2400 :
2401 : return UI_NONE;
2402 : }
2403 :
2404 : /* Targets that set NUM_POLY_INT_COEFFS to something greater than 1
2405 : must define this hook. */
2406 :
2407 : unsigned int
2408 0 : default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *)
2409 : {
2410 0 : gcc_unreachable ();
2411 : }
2412 :
2413 : /* Determine the correct mode for a Dwarf frame register that represents
2414 : register REGNO. */
2415 :
2416 : machine_mode
2417 736 : default_dwarf_frame_reg_mode (int regno)
2418 : {
2419 736 : machine_mode save_mode = reg_raw_mode[regno];
2420 :
2421 736 : if (targetm.hard_regno_call_part_clobbered (eh_edge_abi.id (),
2422 : regno, save_mode))
2423 0 : save_mode = choose_hard_reg_mode (regno, 1, &eh_edge_abi);
2424 736 : return save_mode;
2425 : }
2426 :
2427 : /* To be used by targets where reg_raw_mode doesn't return the right
2428 : mode for registers used in apply_builtin_return and apply_builtin_arg. */
2429 :
2430 : fixed_size_mode
2431 7530 : default_get_reg_raw_mode (int regno)
2432 : {
2433 : /* Targets must override this hook if the underlying register is
2434 : variable-sized. */
2435 7530 : return as_a <fixed_size_mode> (reg_raw_mode[regno]);
2436 : }
2437 :
2438 : /* Return true if a leaf function should stay leaf even with profiling
2439 : enabled. */
2440 :
2441 : bool
2442 818 : default_keep_leaf_when_profiled ()
2443 : {
2444 818 : return false;
2445 : }
2446 :
2447 : /* Return true if the state of option OPTION should be stored in PCH files
2448 : and checked by default_pch_valid_p. Store the option's current state
2449 : in STATE if so. */
2450 :
2451 : static inline bool
2452 45403042 : option_affects_pch_p (int option, struct cl_option_state *state)
2453 : {
2454 45403042 : if ((cl_options[option].flags & CL_TARGET) == 0)
2455 : return false;
2456 3709442 : if ((cl_options[option].flags & CL_PCH_IGNORE) != 0)
2457 : return false;
2458 3709442 : if (option_flag_var (option, &global_options) == &target_flags)
2459 623320 : if (targetm.check_pch_target_flags)
2460 : return false;
2461 3709442 : return get_option_state (&global_options, option, state);
2462 : }
2463 :
2464 : /* Default version of get_pch_validity.
2465 : By default, every flag difference is fatal; that will be mostly right for
2466 : most targets, but completely right for very few. */
2467 :
2468 : void *
2469 474 : default_get_pch_validity (size_t *sz)
2470 : {
2471 474 : struct cl_option_state state;
2472 474 : size_t i;
2473 474 : char *result, *r;
2474 :
2475 474 : *sz = 2;
2476 474 : if (targetm.check_pch_target_flags)
2477 0 : *sz += sizeof (target_flags);
2478 1218654 : for (i = 0; i < cl_options_count; i++)
2479 1218180 : if (option_affects_pch_p (i, &state))
2480 110442 : *sz += state.size;
2481 :
2482 474 : result = r = XNEWVEC (char, *sz);
2483 474 : r[0] = flag_pic;
2484 474 : r[1] = flag_pie;
2485 474 : r += 2;
2486 474 : if (targetm.check_pch_target_flags)
2487 : {
2488 0 : memcpy (r, &target_flags, sizeof (target_flags));
2489 0 : r += sizeof (target_flags);
2490 : }
2491 :
2492 1218654 : for (i = 0; i < cl_options_count; i++)
2493 1218180 : if (option_affects_pch_p (i, &state))
2494 : {
2495 110442 : memcpy (r, state.data, state.size);
2496 110442 : r += state.size;
2497 : }
2498 :
2499 474 : return result;
2500 : }
2501 :
2502 : /* Return a message which says that a PCH file was created with a different
2503 : setting of OPTION. */
2504 :
2505 : static const char *
2506 17880 : pch_option_mismatch (const char *option)
2507 : {
2508 17880 : return xasprintf (_("created and used with differing settings of '%s'"),
2509 17880 : option);
2510 : }
2511 :
2512 : /* Default version of pch_valid_p. */
2513 :
2514 : const char *
2515 18242 : default_pch_valid_p (const void *data_p, size_t len ATTRIBUTE_UNUSED)
2516 : {
2517 18242 : struct cl_option_state state;
2518 18242 : const char *data = (const char *)data_p;
2519 18242 : size_t i;
2520 :
2521 : /* -fpic and -fpie also usually make a PCH invalid. */
2522 18242 : if (data[0] != flag_pic)
2523 0 : return _("created and used with different settings of %<-fpic%>");
2524 18242 : if (data[1] != flag_pie)
2525 0 : return _("created and used with different settings of %<-fpie%>");
2526 18242 : data += 2;
2527 :
2528 : /* Check target_flags. */
2529 18242 : if (targetm.check_pch_target_flags)
2530 : {
2531 0 : int tf;
2532 0 : const char *r;
2533 :
2534 0 : memcpy (&tf, data, sizeof (target_flags));
2535 0 : data += sizeof (target_flags);
2536 0 : r = targetm.check_pch_target_flags (tf);
2537 0 : if (r != NULL)
2538 : return r;
2539 : }
2540 :
2541 42967044 : for (i = 0; i < cl_options_count; i++)
2542 42966682 : if (option_affects_pch_p (i, &state))
2543 : {
2544 3410474 : if (memcmp (data, state.data, state.size) != 0)
2545 17880 : return pch_option_mismatch (cl_options[i].opt_text);
2546 3392594 : data += state.size;
2547 : }
2548 :
2549 : return NULL;
2550 : }
2551 :
2552 : /* Default version of cstore_mode. */
2553 :
2554 : scalar_int_mode
2555 708908 : default_cstore_mode (enum insn_code icode)
2556 : {
2557 708908 : return as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
2558 : }
2559 :
2560 : /* Default version of member_type_forces_blk. */
2561 :
2562 : bool
2563 0 : default_member_type_forces_blk (const_tree, machine_mode)
2564 : {
2565 0 : return false;
2566 : }
2567 :
2568 : /* Default version of canonicalize_comparison. */
2569 :
2570 : void
2571 0 : default_canonicalize_comparison (int *, rtx *, rtx *, bool)
2572 : {
2573 0 : }
2574 :
2575 : /* Default implementation of TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
2576 :
2577 : void
2578 0 : default_atomic_assign_expand_fenv (tree *, tree *, tree *)
2579 : {
2580 0 : }
2581 :
2582 : #ifndef PAD_VARARGS_DOWN
2583 : #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
2584 : #endif
2585 :
2586 : /* Build an indirect-ref expression over the given TREE, which represents a
2587 : piece of a va_arg() expansion. */
2588 : tree
2589 55111 : build_va_arg_indirect_ref (tree addr)
2590 : {
2591 55111 : addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
2592 55111 : return addr;
2593 : }
2594 :
2595 : /* The "standard" implementation of va_arg: read the value from the
2596 : current (padded) address and increment by the (padded) size. */
2597 :
2598 : tree
2599 260 : std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
2600 : gimple_seq *post_p)
2601 : {
2602 260 : tree addr, t, type_size, rounded_size, valist_tmp;
2603 260 : unsigned HOST_WIDE_INT align, boundary;
2604 260 : bool indirect;
2605 :
2606 : /* All of the alignment and movement below is for args-grow-up machines.
2607 : As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
2608 : implement their own specialized gimplify_va_arg_expr routines. */
2609 260 : if (ARGS_GROW_DOWNWARD)
2610 : gcc_unreachable ();
2611 :
2612 260 : indirect = pass_va_arg_by_reference (type);
2613 260 : if (indirect)
2614 33 : type = build_pointer_type (type);
2615 :
2616 260 : if (targetm.calls.split_complex_arg
2617 0 : && TREE_CODE (type) == COMPLEX_TYPE
2618 260 : && targetm.calls.split_complex_arg (type))
2619 : {
2620 0 : tree real_part, imag_part;
2621 :
2622 0 : real_part = std_gimplify_va_arg_expr (valist,
2623 0 : TREE_TYPE (type), pre_p, NULL);
2624 0 : real_part = get_initialized_tmp_var (real_part, pre_p);
2625 :
2626 0 : imag_part = std_gimplify_va_arg_expr (unshare_expr (valist),
2627 0 : TREE_TYPE (type), pre_p, NULL);
2628 0 : imag_part = get_initialized_tmp_var (imag_part, pre_p);
2629 :
2630 0 : return build2 (COMPLEX_EXPR, type, real_part, imag_part);
2631 : }
2632 :
2633 260 : align = PARM_BOUNDARY / BITS_PER_UNIT;
2634 260 : boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
2635 :
2636 : /* When we align parameter on stack for caller, if the parameter
2637 : alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
2638 : aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
2639 : here with caller. */
2640 260 : if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
2641 : boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
2642 :
2643 260 : boundary /= BITS_PER_UNIT;
2644 :
2645 : /* Hoist the valist value into a temporary for the moment. */
2646 260 : valist_tmp = get_initialized_tmp_var (valist, pre_p);
2647 :
2648 : /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
2649 : requires greater alignment, we must perform dynamic alignment. */
2650 260 : if (boundary > align
2651 4 : && !TYPE_EMPTY_P (type)
2652 264 : && !integer_zerop (TYPE_SIZE (type)))
2653 : {
2654 4 : t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
2655 4 : fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
2656 4 : gimplify_and_add (t, pre_p);
2657 :
2658 8 : t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
2659 8 : fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
2660 : valist_tmp,
2661 : build_int_cst (TREE_TYPE (valist), -boundary)));
2662 4 : gimplify_and_add (t, pre_p);
2663 : }
2664 : else
2665 : boundary = align;
2666 :
2667 : /* If the actual alignment is less than the alignment of the type,
2668 : adjust the type accordingly so that we don't assume strict alignment
2669 : when dereferencing the pointer. */
2670 260 : boundary *= BITS_PER_UNIT;
2671 260 : if (boundary < TYPE_ALIGN (type))
2672 : {
2673 22 : type = build_variant_type_copy (type);
2674 22 : SET_TYPE_ALIGN (type, boundary);
2675 : }
2676 :
2677 : /* Compute the rounded size of the type. */
2678 260 : type_size = arg_size_in_bytes (type);
2679 260 : rounded_size = round_up (type_size, align);
2680 :
2681 : /* Reduce rounded_size so it's sharable with the postqueue. */
2682 260 : gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
2683 :
2684 : /* Get AP. */
2685 260 : addr = valist_tmp;
2686 260 : if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
2687 : {
2688 : /* Small args are padded downward. */
2689 : t = fold_build2_loc (input_location, GT_EXPR, sizetype,
2690 : rounded_size, size_int (align));
2691 : t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
2692 : size_binop (MINUS_EXPR, rounded_size, type_size));
2693 : addr = fold_build_pointer_plus (addr, t);
2694 : }
2695 :
2696 : /* Compute new value for AP. */
2697 260 : t = fold_build_pointer_plus (valist_tmp, rounded_size);
2698 260 : t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
2699 260 : gimplify_and_add (t, pre_p);
2700 :
2701 260 : addr = fold_convert (build_pointer_type (type), addr);
2702 :
2703 260 : if (indirect)
2704 33 : addr = build_va_arg_indirect_ref (addr);
2705 :
2706 260 : return build_va_arg_indirect_ref (addr);
2707 : }
2708 :
2709 : /* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do
2710 : not support nested low-overhead loops. */
2711 :
2712 : bool
2713 0 : can_use_doloop_if_innermost (const widest_int &, const widest_int &,
2714 : unsigned int loop_depth, bool)
2715 : {
2716 0 : return loop_depth == 1;
2717 : }
2718 :
2719 : /* Default implementation of TARGET_OPTAB_SUPPORTED_P. */
2720 :
2721 : bool
2722 0 : default_optab_supported_p (int, machine_mode, machine_mode, optimization_type)
2723 : {
2724 0 : return true;
2725 : }
2726 :
2727 : /* Default implementation of TARGET_MAX_NOCE_IFCVT_SEQ_COST. */
2728 :
2729 : unsigned int
2730 0 : default_max_noce_ifcvt_seq_cost (edge e)
2731 : {
2732 0 : bool predictable_p = predictable_edge_p (e);
2733 :
2734 0 : if (predictable_p)
2735 : {
2736 0 : if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
2737 0 : return param_max_rtl_if_conversion_predictable_cost;
2738 : }
2739 : else
2740 : {
2741 0 : if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
2742 0 : return param_max_rtl_if_conversion_unpredictable_cost;
2743 : }
2744 :
2745 0 : return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);
2746 : }
2747 :
2748 : /* Default implementation of TARGET_MIN_ARITHMETIC_PRECISION. */
2749 :
2750 : unsigned int
2751 71975 : default_min_arithmetic_precision (void)
2752 : {
2753 71975 : return WORD_REGISTER_OPERATIONS ? BITS_PER_WORD : BITS_PER_UNIT;
2754 : }
2755 :
2756 : /* Default implementation of TARGET_C_EXCESS_PRECISION. */
2757 :
2758 : enum flt_eval_method
2759 0 : default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED)
2760 : {
2761 0 : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
2762 : }
2763 :
2764 : /* Return true if _BitInt(N) is supported and fill details about it into
2765 : *INFO. */
2766 : bool
2767 0 : default_bitint_type_info (int, struct bitint_info *)
2768 : {
2769 0 : return false;
2770 : }
2771 :
2772 : /* Default implementation for
2773 : TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE. */
2774 : HOST_WIDE_INT
2775 16 : default_stack_clash_protection_alloca_probe_range (void)
2776 : {
2777 16 : return 0;
2778 : }
2779 :
2780 : /* The default implementation of TARGET_EARLY_REMAT_MODES. */
2781 :
2782 : void
2783 0 : default_select_early_remat_modes (sbitmap)
2784 : {
2785 0 : }
2786 :
2787 : /* The default implementation of TARGET_PREFERRED_ELSE_VALUE. */
2788 :
2789 : tree
2790 519 : default_preferred_else_value (unsigned, tree type, unsigned, tree *)
2791 : {
2792 519 : return build_zero_cst (type);
2793 : }
2794 :
2795 : /* The default implementation of TARGET_INSTRUCTION_SELECTION. */
2796 :
2797 : bool
2798 94684062 : default_instruction_selection (function *, gimple_stmt_iterator *)
2799 : {
2800 94684062 : return false;
2801 : }
2802 :
2803 : /* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */
2804 : bool
2805 215840 : default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED)
2806 : {
2807 : #ifdef HAVE_speculation_barrier
2808 215840 : return active ? HAVE_speculation_barrier : true;
2809 : #else
2810 : return false;
2811 : #endif
2812 : }
2813 : /* Alternative implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE
2814 : that can be used on targets that never have speculative execution. */
2815 : bool
2816 0 : speculation_safe_value_not_needed (bool active)
2817 : {
2818 0 : return !active;
2819 : }
2820 :
2821 : /* Default implementation of the speculation-safe-load builtin. This
2822 : implementation simply copies val to result and generates a
2823 : speculation_barrier insn, if such a pattern is defined. */
2824 : rtx
2825 34 : default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED,
2826 : rtx result, rtx val,
2827 : rtx failval ATTRIBUTE_UNUSED)
2828 : {
2829 34 : emit_move_insn (result, val);
2830 :
2831 : #ifdef HAVE_speculation_barrier
2832 : /* Assume the target knows what it is doing: if it defines a
2833 : speculation barrier, but it is not enabled, then assume that one
2834 : isn't needed. */
2835 34 : if (HAVE_speculation_barrier)
2836 34 : emit_insn (gen_speculation_barrier ());
2837 : #endif
2838 :
2839 34 : return result;
2840 : }
2841 :
2842 : /* How many bits to shift in order to access the tag bits.
2843 : The default is to store the tag in the top 8 bits of a 64 bit pointer, hence
2844 : shifting 56 bits will leave just the tag. */
2845 : #define HWASAN_SHIFT (GET_MODE_PRECISION (Pmode) - 8)
2846 : #define HWASAN_SHIFT_RTX GEN_INT (HWASAN_SHIFT)
2847 :
2848 : bool
2849 0 : default_memtag_can_tag_addresses ()
2850 : {
2851 0 : return false;
2852 : }
2853 :
2854 : uint8_t
2855 0 : default_memtag_tag_bitsize ()
2856 : {
2857 0 : return 8;
2858 : }
2859 :
2860 : uint8_t
2861 1238 : default_memtag_granule_size ()
2862 : {
2863 1238 : return 16;
2864 : }
2865 :
2866 : /* The default implementation of TARGET_MEMTAG_INSERT_RANDOM_TAG. */
2867 : rtx
2868 64 : default_memtag_insert_random_tag (rtx untagged, rtx target)
2869 : {
2870 64 : gcc_assert (param_hwasan_instrument_stack);
2871 64 : if (param_hwasan_random_frame_tag)
2872 : {
2873 16 : rtx fn = init_one_libfunc ("__hwasan_generate_tag");
2874 16 : rtx new_tag = emit_library_call_value (fn, NULL_RTX, LCT_NORMAL, QImode);
2875 16 : return targetm.memtag.set_tag (untagged, new_tag, target);
2876 : }
2877 : else
2878 : {
2879 : /* NOTE: The kernel API does not have __hwasan_generate_tag exposed.
2880 : In the future we may add the option emit random tags with inline
2881 : instrumentation instead of function calls. This would be the same
2882 : between the kernel and userland. */
2883 : return untagged;
2884 : }
2885 : }
2886 :
2887 : /* The default implementation of TARGET_MEMTAG_ADD_TAG. */
2888 : rtx
2889 0 : default_memtag_add_tag (rtx base, poly_int64 offset, uint8_t tag_offset)
2890 : {
2891 : /* Need to look into what the most efficient code sequence is.
2892 : This is a code sequence that would be emitted *many* times, so we
2893 : want it as small as possible.
2894 :
2895 : There are two places where tag overflow is a question:
2896 : - Tagging the shadow stack.
2897 : (both tagging and untagging).
2898 : - Tagging addressable pointers.
2899 :
2900 : We need to ensure both behaviors are the same (i.e. that the tag that
2901 : ends up in a pointer after "overflowing" the tag bits with a tag addition
2902 : is the same that ends up in the shadow space).
2903 :
2904 : The aim is that the behavior of tag addition should follow modulo
2905 : wrapping in both instances.
2906 :
2907 : The libhwasan code doesn't have any path that increments a pointer's tag,
2908 : which means it has no opinion on what happens when a tag increment
2909 : overflows (and hence we can choose our own behavior). */
2910 :
2911 0 : offset += ((uint64_t)tag_offset << HWASAN_SHIFT);
2912 0 : return plus_constant (Pmode, base, offset);
2913 : }
2914 :
2915 : /* The default implementation of TARGET_MEMTAG_SET_TAG. */
2916 : rtx
2917 0 : default_memtag_set_tag (rtx untagged, rtx tag, rtx target)
2918 : {
2919 0 : gcc_assert (GET_MODE (untagged) == Pmode && GET_MODE (tag) == QImode);
2920 0 : tag = expand_simple_binop (Pmode, ASHIFT, tag, HWASAN_SHIFT_RTX, NULL_RTX,
2921 : /* unsignedp = */1, OPTAB_WIDEN);
2922 0 : rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
2923 : /* unsignedp = */1, OPTAB_DIRECT);
2924 0 : gcc_assert (ret);
2925 0 : return ret;
2926 : }
2927 :
2928 : /* The default implementation of TARGET_MEMTAG_EXTRACT_TAG. */
2929 : rtx
2930 0 : default_memtag_extract_tag (rtx tagged_pointer, rtx target)
2931 : {
2932 0 : rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
2933 0 : HWASAN_SHIFT_RTX, target,
2934 : /* unsignedp = */0,
2935 : OPTAB_DIRECT);
2936 0 : rtx ret = gen_lowpart (QImode, tag);
2937 0 : gcc_assert (ret);
2938 0 : return ret;
2939 : }
2940 :
2941 : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER. */
2942 : rtx
2943 0 : default_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
2944 : {
2945 0 : rtx tag_mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_SHIFT) - 1, Pmode);
2946 0 : rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
2947 : tag_mask, target, true,
2948 : OPTAB_DIRECT);
2949 0 : gcc_assert (untagged_base);
2950 0 : return untagged_base;
2951 : }
2952 :
2953 : #include "gt-targhooks.h"
|