]>
Commit | Line | Data |
---|---|---|
45550790 | 1 | /* Default target hook functions. |
fbd26352 | 2 | Copyright (C) 2003-2019 Free Software Foundation, Inc. |
45550790 | 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 | |
8c4c00c1 | 8 | Software Foundation; either version 3, or (at your option) any later |
45550790 | 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 | |
8c4c00c1 | 17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
45550790 | 19 | |
3974200f | 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 | ||
45550790 | 49 | #include "config.h" |
50 | #include "system.h" | |
51 | #include "coretypes.h" | |
7c29e30e | 52 | #include "target.h" |
53 | #include "function.h" | |
45550790 | 54 | #include "rtl.h" |
55 | #include "tree.h" | |
7c29e30e | 56 | #include "tree-ssa-alias.h" |
57 | #include "gimple-expr.h" | |
ad7b10a2 | 58 | #include "memmodel.h" |
7c29e30e | 59 | #include "tm_p.h" |
60 | #include "stringpool.h" | |
c296f633 | 61 | #include "tree-vrp.h" |
7c29e30e | 62 | #include "tree-ssanames.h" |
720cfc43 | 63 | #include "profile-count.h" |
7c29e30e | 64 | #include "optabs.h" |
65 | #include "regs.h" | |
7c29e30e | 66 | #include "recog.h" |
67 | #include "diagnostic-core.h" | |
b20a8bb4 | 68 | #include "fold-const.h" |
9ed99284 | 69 | #include "stor-layout.h" |
70 | #include "varasm.h" | |
d53441c8 | 71 | #include "flags.h" |
d53441c8 | 72 | #include "explow.h" |
73 | #include "calls.h" | |
45550790 | 74 | #include "expr.h" |
daeb6b83 | 75 | #include "output.h" |
e6c4532a | 76 | #include "common/common-target.h" |
4d58fa46 | 77 | #include "reload.h" |
0e763b2a | 78 | #include "intl.h" |
79 | #include "opts.h" | |
a8783bee | 80 | #include "gimplify.h" |
1019399a | 81 | #include "predict.h" |
82 | #include "params.h" | |
82c85aba | 83 | #include "real.h" |
842a8149 | 84 | #include "langhooks.h" |
62958b22 | 85 | #include "sbitmap.h" |
b2aef146 | 86 | |
fd50b071 | 87 | bool |
3754d046 | 88 | default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, |
fd50b071 | 89 | rtx addr ATTRIBUTE_UNUSED, |
90 | bool strict ATTRIBUTE_UNUSED) | |
91 | { | |
92 | #ifdef GO_IF_LEGITIMATE_ADDRESS | |
93 | /* Defer to the old implementation using a goto. */ | |
94 | if (strict) | |
95 | return strict_memory_address_p (mode, addr); | |
96 | else | |
97 | return memory_address_p (mode, addr); | |
98 | #else | |
99 | gcc_unreachable (); | |
100 | #endif | |
101 | } | |
102 | ||
864af209 | 103 | void |
104 | default_external_libcall (rtx fun ATTRIBUTE_UNUSED) | |
105 | { | |
106 | #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL | |
9af5ce0c | 107 | ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun); |
864af209 | 108 | #endif |
109 | } | |
110 | ||
77ad8e5a | 111 | int |
112 | default_unspec_may_trap_p (const_rtx x, unsigned flags) | |
113 | { | |
114 | int i; | |
115 | ||
bcbfcebe | 116 | /* Any floating arithmetic may trap. */ |
117 | if ((SCALAR_FLOAT_MODE_P (GET_MODE (x)) && flag_trapping_math)) | |
77ad8e5a | 118 | return 1; |
119 | ||
120 | for (i = 0; i < XVECLEN (x, 0); ++i) | |
121 | { | |
122 | if (may_trap_p_1 (XVECEXP (x, 0, i), flags)) | |
123 | return 1; | |
124 | } | |
125 | ||
126 | return 0; | |
127 | } | |
128 | ||
3754d046 | 129 | machine_mode |
3b2411a8 | 130 | default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, |
3754d046 | 131 | machine_mode mode, |
3b2411a8 | 132 | int *punsignedp ATTRIBUTE_UNUSED, |
133 | const_tree funtype ATTRIBUTE_UNUSED, | |
134 | int for_return ATTRIBUTE_UNUSED) | |
135 | { | |
adaf4ef0 | 136 | if (type != NULL_TREE && for_return == 2) |
c879dbcf | 137 | return promote_mode (type, mode, punsignedp); |
3b2411a8 | 138 | return mode; |
139 | } | |
140 | ||
3754d046 | 141 | machine_mode |
3b2411a8 | 142 | default_promote_function_mode_always_promote (const_tree type, |
3754d046 | 143 | machine_mode mode, |
3b2411a8 | 144 | int *punsignedp, |
145 | const_tree funtype ATTRIBUTE_UNUSED, | |
146 | int for_return ATTRIBUTE_UNUSED) | |
147 | { | |
148 | return promote_mode (type, mode, punsignedp); | |
149 | } | |
150 | ||
3754d046 | 151 | machine_mode |
152 | default_cc_modes_compatible (machine_mode m1, machine_mode m2) | |
124ac4e4 | 153 | { |
154 | if (m1 == m2) | |
155 | return m1; | |
156 | return VOIDmode; | |
157 | } | |
158 | ||
45550790 | 159 | bool |
fb80456a | 160 | default_return_in_memory (const_tree type, |
161 | const_tree fntype ATTRIBUTE_UNUSED) | |
45550790 | 162 | { |
e409e1ba | 163 | return (TYPE_MODE (type) == BLKmode); |
45550790 | 164 | } |
165 | ||
41e3a0c7 | 166 | rtx |
167 | default_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED, | |
3754d046 | 168 | machine_mode mode ATTRIBUTE_UNUSED) |
41e3a0c7 | 169 | { |
170 | return x; | |
171 | } | |
172 | ||
968ba45e | 173 | bool |
6cc181b3 | 174 | default_legitimize_address_displacement (rtx *, rtx *, poly_int64, |
175 | machine_mode) | |
968ba45e | 176 | { |
177 | return false; | |
178 | } | |
179 | ||
c68c23ab | 180 | bool |
181 | default_const_not_ok_for_debug_p (rtx x) | |
182 | { | |
183 | if (GET_CODE (x) == UNSPEC) | |
184 | return true; | |
185 | return false; | |
186 | } | |
187 | ||
45550790 | 188 | rtx |
189 | default_expand_builtin_saveregs (void) | |
190 | { | |
2f6d557f | 191 | error ("%<__builtin_saveregs%> not supported by this target"); |
45550790 | 192 | return const0_rtx; |
45550790 | 193 | } |
194 | ||
195 | void | |
39cba157 | 196 | default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 197 | machine_mode mode ATTRIBUTE_UNUSED, |
45550790 | 198 | tree type ATTRIBUTE_UNUSED, |
199 | int *pretend_arg_size ATTRIBUTE_UNUSED, | |
200 | int second_time ATTRIBUTE_UNUSED) | |
201 | { | |
45550790 | 202 | } |
203 | ||
e3e026e8 | 204 | /* The default implementation of TARGET_BUILTIN_SETJMP_FRAME_VALUE. */ |
205 | ||
206 | rtx | |
207 | default_builtin_setjmp_frame_value (void) | |
208 | { | |
209 | return virtual_stack_vars_rtx; | |
210 | } | |
211 | ||
30a10006 | 212 | /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ |
9878c8d9 | 213 | |
45550790 | 214 | bool |
39cba157 | 215 | hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t ca ATTRIBUTE_UNUSED) |
45550790 | 216 | { |
1ce13983 | 217 | return false; |
45550790 | 218 | } |
219 | ||
220 | bool | |
39cba157 | 221 | default_pretend_outgoing_varargs_named (cumulative_args_t ca ATTRIBUTE_UNUSED) |
45550790 | 222 | { |
30a10006 | 223 | return (targetm.calls.setup_incoming_varargs |
224 | != default_setup_incoming_varargs); | |
45550790 | 225 | } |
4e00ee67 | 226 | |
f77c4496 | 227 | scalar_int_mode |
95215948 | 228 | default_eh_return_filter_mode (void) |
229 | { | |
1bd43494 | 230 | return targetm.unwind_word_mode (); |
95215948 | 231 | } |
232 | ||
f77c4496 | 233 | scalar_int_mode |
0ef89dfd | 234 | default_libgcc_cmp_return_mode (void) |
235 | { | |
236 | return word_mode; | |
237 | } | |
238 | ||
f77c4496 | 239 | scalar_int_mode |
0ef89dfd | 240 | default_libgcc_shift_count_mode (void) |
241 | { | |
242 | return word_mode; | |
243 | } | |
244 | ||
f77c4496 | 245 | scalar_int_mode |
1bd43494 | 246 | default_unwind_word_mode (void) |
247 | { | |
248 | return word_mode; | |
249 | } | |
250 | ||
c49547c4 | 251 | /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */ |
252 | ||
253 | unsigned HOST_WIDE_INT | |
3754d046 | 254 | default_shift_truncation_mask (machine_mode mode) |
c49547c4 | 255 | { |
332d11bd | 256 | return SHIFT_COUNT_TRUNCATED ? GET_MODE_UNIT_BITSIZE (mode) - 1 : 0; |
c49547c4 | 257 | } |
258 | ||
ac70caad | 259 | /* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. */ |
260 | ||
261 | unsigned int | |
3754d046 | 262 | default_min_divisions_for_recip_mul (machine_mode mode ATTRIBUTE_UNUSED) |
ac70caad | 263 | { |
264 | return have_insn_for (DIV, mode) ? 3 : 2; | |
265 | } | |
266 | ||
4956440a | 267 | /* The default implementation of TARGET_MODE_REP_EXTENDED. */ |
268 | ||
269 | int | |
f77c4496 | 270 | default_mode_rep_extended (scalar_int_mode, scalar_int_mode) |
4956440a | 271 | { |
272 | return UNKNOWN; | |
273 | } | |
274 | ||
4e00ee67 | 275 | /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ |
b6ea32c3 | 276 | |
4e00ee67 | 277 | bool |
39cba157 | 278 | hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t a ATTRIBUTE_UNUSED) |
4e00ee67 | 279 | { |
280 | return true; | |
281 | } | |
c1dc02de | 282 | |
430be8e2 | 283 | /* Return machine mode for non-standard suffix |
284 | or VOIDmode if non-standard suffixes are unsupported. */ | |
3754d046 | 285 | machine_mode |
430be8e2 | 286 | default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED) |
287 | { | |
288 | return VOIDmode; | |
289 | } | |
c1dc02de | 290 | |
291 | /* The generic C++ ABI specifies this is a 64-bit value. */ | |
292 | tree | |
293 | default_cxx_guard_type (void) | |
294 | { | |
295 | return long_long_integer_type_node; | |
296 | } | |
600f4be7 | 297 | |
600f4be7 | 298 | /* Returns the size of the cookie to use when allocating an array |
299 | whose elements have the indicated TYPE. Assumes that it is already | |
300 | known that a cookie is needed. */ | |
301 | ||
302 | tree | |
303 | default_cxx_get_cookie_size (tree type) | |
304 | { | |
305 | tree cookie_size; | |
306 | ||
307 | /* We need to allocate an additional max (sizeof (size_t), alignof | |
308 | (true_type)) bytes. */ | |
309 | tree sizetype_size; | |
310 | tree type_align; | |
8ff30ff6 | 311 | |
600f4be7 | 312 | sizetype_size = size_in_bytes (sizetype); |
313 | type_align = size_int (TYPE_ALIGN_UNIT (type)); | |
d99d10ca | 314 | if (tree_int_cst_lt (type_align, sizetype_size)) |
600f4be7 | 315 | cookie_size = sizetype_size; |
316 | else | |
317 | cookie_size = type_align; | |
318 | ||
319 | return cookie_size; | |
320 | } | |
b981d932 | 321 | |
b981d932 | 322 | /* Return true if a parameter must be passed by reference. This version |
323 | of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ | |
324 | ||
325 | bool | |
39cba157 | 326 | hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED, |
3754d046 | 327 | machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, |
b981d932 | 328 | bool named_arg ATTRIBUTE_UNUSED) |
329 | { | |
330 | return targetm.calls.must_pass_in_stack (mode, type); | |
331 | } | |
8ec87476 | 332 | |
13f08ee7 | 333 | /* Return true if a parameter follows callee copies conventions. This |
334 | version of the hook is true for all named arguments. */ | |
335 | ||
336 | bool | |
39cba157 | 337 | hook_callee_copies_named (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 338 | machine_mode mode ATTRIBUTE_UNUSED, |
fb80456a | 339 | const_tree type ATTRIBUTE_UNUSED, bool named) |
13f08ee7 | 340 | { |
341 | return named; | |
342 | } | |
8ec87476 | 343 | |
182e98f4 | 344 | /* Emit to STREAM the assembler syntax for insn operand X. */ |
345 | ||
346 | void | |
347 | default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, | |
348 | int code ATTRIBUTE_UNUSED) | |
349 | { | |
350 | #ifdef PRINT_OPERAND | |
351 | PRINT_OPERAND (stream, x, code); | |
352 | #else | |
353 | gcc_unreachable (); | |
354 | #endif | |
355 | } | |
356 | ||
357 | /* Emit to STREAM the assembler syntax for an insn operand whose memory | |
358 | address is X. */ | |
359 | ||
360 | void | |
361 | default_print_operand_address (FILE *stream ATTRIBUTE_UNUSED, | |
3c047fe9 | 362 | machine_mode /*mode*/, |
182e98f4 | 363 | rtx x ATTRIBUTE_UNUSED) |
364 | { | |
365 | #ifdef PRINT_OPERAND_ADDRESS | |
366 | PRINT_OPERAND_ADDRESS (stream, x); | |
367 | #else | |
368 | gcc_unreachable (); | |
369 | #endif | |
370 | } | |
371 | ||
372 | /* Return true if CODE is a valid punctuation character for the | |
373 | `print_operand' hook. */ | |
374 | ||
375 | bool | |
376 | default_print_operand_punct_valid_p (unsigned char code ATTRIBUTE_UNUSED) | |
377 | { | |
378 | #ifdef PRINT_OPERAND_PUNCT_VALID_P | |
379 | return PRINT_OPERAND_PUNCT_VALID_P (code); | |
380 | #else | |
381 | return false; | |
382 | #endif | |
383 | } | |
384 | ||
d86d364d | 385 | /* The default implementation of TARGET_MANGLE_ASSEMBLER_NAME. */ |
386 | tree | |
387 | default_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED) | |
388 | { | |
389 | const char *skipped = name + (*name == '*' ? 1 : 0); | |
390 | const char *stripped = targetm.strip_name_encoding (skipped); | |
391 | if (*name != '*' && user_label_prefix[0]) | |
392 | stripped = ACONCAT ((user_label_prefix, stripped, NULL)); | |
393 | return get_identifier (stripped); | |
394 | } | |
395 | ||
93711a35 | 396 | /* The default implementation of TARGET_TRANSLATE_MODE_ATTRIBUTE. */ |
397 | ||
398 | machine_mode | |
399 | default_translate_mode_attribute (machine_mode mode) | |
400 | { | |
401 | return mode; | |
402 | } | |
403 | ||
b2aef146 | 404 | /* True if MODE is valid for the target. By "valid", we mean able to |
405 | be manipulated in non-trivial ways. In particular, this means all | |
406 | the arithmetic is supported. | |
407 | ||
408 | By default we guess this means that any C type is supported. If | |
409 | we can't map the mode back to a type that would be available in C, | |
410 | then reject it. Special case, here, is the double-word arithmetic | |
411 | supported by optabs.c. */ | |
412 | ||
413 | bool | |
8aec1ebb | 414 | default_scalar_mode_supported_p (scalar_mode mode) |
b2aef146 | 415 | { |
416 | int precision = GET_MODE_PRECISION (mode); | |
417 | ||
418 | switch (GET_MODE_CLASS (mode)) | |
419 | { | |
420 | case MODE_PARTIAL_INT: | |
421 | case MODE_INT: | |
422 | if (precision == CHAR_TYPE_SIZE) | |
423 | return true; | |
424 | if (precision == SHORT_TYPE_SIZE) | |
425 | return true; | |
426 | if (precision == INT_TYPE_SIZE) | |
427 | return true; | |
428 | if (precision == LONG_TYPE_SIZE) | |
429 | return true; | |
430 | if (precision == LONG_LONG_TYPE_SIZE) | |
431 | return true; | |
432 | if (precision == 2 * BITS_PER_WORD) | |
433 | return true; | |
434 | return false; | |
435 | ||
436 | case MODE_FLOAT: | |
437 | if (precision == FLOAT_TYPE_SIZE) | |
438 | return true; | |
439 | if (precision == DOUBLE_TYPE_SIZE) | |
440 | return true; | |
441 | if (precision == LONG_DOUBLE_TYPE_SIZE) | |
442 | return true; | |
443 | return false; | |
444 | ||
c4503c0a | 445 | case MODE_DECIMAL_FLOAT: |
9421ebb9 | 446 | case MODE_FRACT: |
447 | case MODE_UFRACT: | |
448 | case MODE_ACCUM: | |
449 | case MODE_UACCUM: | |
c4503c0a | 450 | return false; |
451 | ||
b2aef146 | 452 | default: |
8c0963c4 | 453 | gcc_unreachable (); |
b2aef146 | 454 | } |
455 | } | |
13f08ee7 | 456 | |
d5957f0d | 457 | /* Return true if libgcc supports floating-point mode MODE (known to |
458 | be supported as a scalar mode). */ | |
459 | ||
460 | bool | |
d067137d | 461 | default_libgcc_floating_mode_supported_p (scalar_float_mode mode) |
d5957f0d | 462 | { |
463 | switch (mode) | |
464 | { | |
465 | #ifdef HAVE_SFmode | |
916ace94 | 466 | case E_SFmode: |
d5957f0d | 467 | #endif |
468 | #ifdef HAVE_DFmode | |
916ace94 | 469 | case E_DFmode: |
d5957f0d | 470 | #endif |
471 | #ifdef HAVE_XFmode | |
916ace94 | 472 | case E_XFmode: |
d5957f0d | 473 | #endif |
474 | #ifdef HAVE_TFmode | |
916ace94 | 475 | case E_TFmode: |
d5957f0d | 476 | #endif |
477 | return true; | |
478 | ||
479 | default: | |
480 | return false; | |
481 | } | |
482 | } | |
483 | ||
82c85aba | 484 | /* Return the machine mode to use for the type _FloatN, if EXTENDED is |
485 | false, or _FloatNx, if EXTENDED is true, or VOIDmode if not | |
486 | supported. */ | |
a15787d8 | 487 | opt_scalar_float_mode |
82c85aba | 488 | default_floatn_mode (int n, bool extended) |
489 | { | |
490 | if (extended) | |
491 | { | |
a15787d8 | 492 | opt_scalar_float_mode cand1, cand2; |
493 | scalar_float_mode mode; | |
82c85aba | 494 | switch (n) |
495 | { | |
496 | case 32: | |
497 | #ifdef HAVE_DFmode | |
498 | cand1 = DFmode; | |
499 | #endif | |
500 | break; | |
501 | ||
502 | case 64: | |
503 | #ifdef HAVE_XFmode | |
504 | cand1 = XFmode; | |
505 | #endif | |
506 | #ifdef HAVE_TFmode | |
507 | cand2 = TFmode; | |
508 | #endif | |
509 | break; | |
510 | ||
511 | case 128: | |
512 | break; | |
513 | ||
514 | default: | |
515 | /* Those are the only valid _FloatNx types. */ | |
516 | gcc_unreachable (); | |
517 | } | |
a15787d8 | 518 | if (cand1.exists (&mode) |
519 | && REAL_MODE_FORMAT (mode)->ieee_bits > n | |
520 | && targetm.scalar_mode_supported_p (mode) | |
521 | && targetm.libgcc_floating_mode_supported_p (mode)) | |
82c85aba | 522 | return cand1; |
a15787d8 | 523 | if (cand2.exists (&mode) |
524 | && REAL_MODE_FORMAT (mode)->ieee_bits > n | |
525 | && targetm.scalar_mode_supported_p (mode) | |
526 | && targetm.libgcc_floating_mode_supported_p (mode)) | |
82c85aba | 527 | return cand2; |
528 | } | |
529 | else | |
530 | { | |
a15787d8 | 531 | opt_scalar_float_mode cand; |
532 | scalar_float_mode mode; | |
82c85aba | 533 | switch (n) |
534 | { | |
535 | case 16: | |
e3151177 | 536 | /* Always enable _Float16 if we have basic support for the mode. |
537 | Targets can control the range and precision of operations on | |
538 | the _Float16 type using TARGET_C_EXCESS_PRECISION. */ | |
539 | #ifdef HAVE_HFmode | |
540 | cand = HFmode; | |
541 | #endif | |
82c85aba | 542 | break; |
543 | ||
544 | case 32: | |
545 | #ifdef HAVE_SFmode | |
546 | cand = SFmode; | |
547 | #endif | |
548 | break; | |
549 | ||
550 | case 64: | |
551 | #ifdef HAVE_DFmode | |
552 | cand = DFmode; | |
553 | #endif | |
554 | break; | |
555 | ||
556 | case 128: | |
557 | #ifdef HAVE_TFmode | |
558 | cand = TFmode; | |
559 | #endif | |
560 | break; | |
561 | ||
562 | default: | |
563 | break; | |
564 | } | |
a15787d8 | 565 | if (cand.exists (&mode) |
566 | && REAL_MODE_FORMAT (mode)->ieee_bits == n | |
567 | && targetm.scalar_mode_supported_p (mode) | |
568 | && targetm.libgcc_floating_mode_supported_p (mode)) | |
82c85aba | 569 | return cand; |
570 | } | |
a15787d8 | 571 | return opt_scalar_float_mode (); |
82c85aba | 572 | } |
573 | ||
842a8149 | 574 | /* Define this to return true if the _Floatn and _Floatnx built-in functions |
575 | should implicitly enable the built-in function without the __builtin_ prefix | |
576 | in addition to the normal built-in function with the __builtin_ prefix. The | |
577 | default is to only enable built-in functions without the __builtin_ prefix | |
578 | for the GNU C langauge. The argument FUNC is the enum builtin_in_function | |
579 | id of the function to be enabled. */ | |
580 | ||
581 | bool | |
582 | default_floatn_builtin_p (int func ATTRIBUTE_UNUSED) | |
583 | { | |
584 | static bool first_time_p = true; | |
585 | static bool c_or_objective_c; | |
586 | ||
587 | if (first_time_p) | |
588 | { | |
589 | first_time_p = false; | |
590 | c_or_objective_c = lang_GNU_C () || lang_GNU_OBJC (); | |
591 | } | |
592 | ||
593 | return c_or_objective_c; | |
594 | } | |
595 | ||
183dc110 | 596 | /* Make some target macros useable by target-independent code. */ |
597 | bool | |
598 | targhook_words_big_endian (void) | |
599 | { | |
600 | return !!WORDS_BIG_ENDIAN; | |
601 | } | |
602 | ||
603 | bool | |
604 | targhook_float_words_big_endian (void) | |
605 | { | |
606 | return !!FLOAT_WORDS_BIG_ENDIAN; | |
607 | } | |
608 | ||
4c866b9b | 609 | /* True if the target supports floating-point exceptions and rounding |
610 | modes. */ | |
611 | ||
612 | bool | |
613 | default_float_exceptions_rounding_supported_p (void) | |
614 | { | |
615 | #ifdef HAVE_adddf3 | |
616 | return HAVE_adddf3; | |
617 | #else | |
618 | return false; | |
619 | #endif | |
620 | } | |
621 | ||
1398cbfd | 622 | /* True if the target supports decimal floating point. */ |
623 | ||
624 | bool | |
625 | default_decimal_float_supported_p (void) | |
626 | { | |
627 | return ENABLE_DECIMAL_FLOAT; | |
628 | } | |
629 | ||
9421ebb9 | 630 | /* True if the target supports fixed-point arithmetic. */ |
631 | ||
632 | bool | |
633 | default_fixed_point_supported_p (void) | |
634 | { | |
635 | return ENABLE_FIXED_POINT; | |
636 | } | |
637 | ||
df9f2e40 | 638 | /* True if the target supports GNU indirect functions. */ |
639 | ||
640 | bool | |
641 | default_has_ifunc_p (void) | |
642 | { | |
643 | return HAVE_GNU_INDIRECT_FUNCTION; | |
644 | } | |
645 | ||
1606e68a | 646 | /* NULL if INSN insn is valid within a low-overhead loop, otherwise returns |
647 | an error message. | |
48e1416a | 648 | |
442e3cb9 | 649 | This function checks whether a given INSN is valid within a low-overhead |
1606e68a | 650 | loop. If INSN is invalid it returns the reason for that, otherwise it |
651 | returns NULL. A called function may clobber any special registers required | |
652 | for low-overhead looping. Additionally, some targets (eg, PPC) use the count | |
7dfa5ce3 | 653 | register for branch on table instructions. We reject the doloop pattern in |
654 | these cases. */ | |
655 | ||
1606e68a | 656 | const char * |
18282db0 | 657 | default_invalid_within_doloop (const rtx_insn *insn) |
7dfa5ce3 | 658 | { |
659 | if (CALL_P (insn)) | |
1606e68a | 660 | return "Function call in loop."; |
48e1416a | 661 | |
91f71fa3 | 662 | if (tablejump_p (insn, NULL, NULL) || computed_jump_p (insn)) |
1606e68a | 663 | return "Computed branch in the loop."; |
48e1416a | 664 | |
1606e68a | 665 | return NULL; |
7dfa5ce3 | 666 | } |
667 | ||
22c2f6bd | 668 | /* Mapping of builtin functions to vectorized variants. */ |
669 | ||
670 | tree | |
b6c464fe | 671 | default_builtin_vectorized_function (unsigned int, tree, tree) |
672 | { | |
673 | return NULL_TREE; | |
674 | } | |
675 | ||
676 | /* Mapping of target builtin functions to vectorized variants. */ | |
677 | ||
678 | tree | |
679 | default_builtin_md_vectorized_function (tree, tree, tree) | |
22c2f6bd | 680 | { |
681 | return NULL_TREE; | |
682 | } | |
683 | ||
9d8bf4aa | 684 | /* Vectorized conversion. */ |
685 | ||
686 | tree | |
d5b637fa | 687 | default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED, |
011d9d16 | 688 | tree dest_type ATTRIBUTE_UNUSED, |
689 | tree src_type ATTRIBUTE_UNUSED) | |
9d8bf4aa | 690 | { |
691 | return NULL_TREE; | |
692 | } | |
693 | ||
559093aa | 694 | /* Default vectorizer cost model values. */ |
695 | ||
696 | int | |
0822b158 | 697 | default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, |
d13adc77 | 698 | tree vectype, |
0822b158 | 699 | int misalign ATTRIBUTE_UNUSED) |
559093aa | 700 | { |
701 | switch (type_of_cost) | |
702 | { | |
703 | case scalar_stmt: | |
704 | case scalar_load: | |
705 | case scalar_store: | |
706 | case vector_stmt: | |
707 | case vector_load: | |
708 | case vector_store: | |
709 | case vec_to_scalar: | |
710 | case scalar_to_vec: | |
711 | case cond_branch_not_taken: | |
712 | case vec_perm: | |
5df2530b | 713 | case vec_promote_demote: |
559093aa | 714 | return 1; |
715 | ||
716 | case unaligned_load: | |
0822b158 | 717 | case unaligned_store: |
559093aa | 718 | return 2; |
719 | ||
720 | case cond_branch_taken: | |
721 | return 3; | |
722 | ||
d13adc77 | 723 | case vec_construct: |
f08ee65f | 724 | return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)) - 1; |
d13adc77 | 725 | |
559093aa | 726 | default: |
727 | gcc_unreachable (); | |
728 | } | |
729 | } | |
730 | ||
c3cc39c4 | 731 | /* Reciprocal. */ |
732 | ||
733 | tree | |
4cfd27a5 | 734 | default_builtin_reciprocal (tree) |
c3cc39c4 | 735 | { |
736 | return NULL_TREE; | |
737 | } | |
738 | ||
13f08ee7 | 739 | bool |
740 | hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( | |
39cba157 | 741 | cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 742 | machine_mode mode ATTRIBUTE_UNUSED, |
fb80456a | 743 | const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) |
13f08ee7 | 744 | { |
745 | return false; | |
746 | } | |
747 | ||
748 | bool | |
749 | hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( | |
39cba157 | 750 | cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 751 | machine_mode mode ATTRIBUTE_UNUSED, |
fb80456a | 752 | const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) |
13f08ee7 | 753 | { |
754 | return true; | |
755 | } | |
f054eb3c | 756 | |
757 | int | |
758 | hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( | |
39cba157 | 759 | cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 760 | machine_mode mode ATTRIBUTE_UNUSED, |
f054eb3c | 761 | tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) |
762 | { | |
763 | return 0; | |
764 | } | |
10fda9eb | 765 | |
532d84ff | 766 | void |
767 | hook_void_CUMULATIVE_ARGS_tree (cumulative_args_t ca ATTRIBUTE_UNUSED, | |
768 | tree ATTRIBUTE_UNUSED) | |
769 | { | |
770 | } | |
771 | ||
f387af4f | 772 | void |
39cba157 | 773 | default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 774 | machine_mode mode ATTRIBUTE_UNUSED, |
f387af4f | 775 | const_tree type ATTRIBUTE_UNUSED, |
776 | bool named ATTRIBUTE_UNUSED) | |
777 | { | |
f387af4f | 778 | gcc_unreachable (); |
f387af4f | 779 | } |
780 | ||
8adb95eb | 781 | /* Default implementation of TARGET_FUNCTION_ARG_OFFSET. */ |
782 | ||
783 | HOST_WIDE_INT | |
784 | default_function_arg_offset (machine_mode, const_tree) | |
785 | { | |
786 | return 0; | |
787 | } | |
788 | ||
d7ab0e3d | 789 | /* Default implementation of TARGET_FUNCTION_ARG_PADDING: usually pad |
790 | upward, but pad short args downward on big-endian machines. */ | |
791 | ||
792 | pad_direction | |
793 | default_function_arg_padding (machine_mode mode, const_tree type) | |
794 | { | |
795 | if (!BYTES_BIG_ENDIAN) | |
796 | return PAD_UPWARD; | |
797 | ||
798 | unsigned HOST_WIDE_INT size; | |
799 | if (mode == BLKmode) | |
800 | { | |
801 | if (!type || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) | |
802 | return PAD_UPWARD; | |
803 | size = int_size_in_bytes (type); | |
804 | } | |
805 | else | |
52acb7ae | 806 | /* Targets with variable-sized modes must override this hook |
807 | and handle variable-sized modes explicitly. */ | |
808 | size = GET_MODE_SIZE (mode).to_constant (); | |
d7ab0e3d | 809 | |
810 | if (size < (PARM_BOUNDARY / BITS_PER_UNIT)) | |
811 | return PAD_DOWNWARD; | |
812 | ||
813 | return PAD_UPWARD; | |
814 | } | |
815 | ||
f387af4f | 816 | rtx |
39cba157 | 817 | default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 818 | machine_mode mode ATTRIBUTE_UNUSED, |
f387af4f | 819 | const_tree type ATTRIBUTE_UNUSED, |
820 | bool named ATTRIBUTE_UNUSED) | |
821 | { | |
f387af4f | 822 | gcc_unreachable (); |
f387af4f | 823 | } |
824 | ||
825 | rtx | |
39cba157 | 826 | default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3754d046 | 827 | machine_mode mode ATTRIBUTE_UNUSED, |
f387af4f | 828 | const_tree type ATTRIBUTE_UNUSED, |
829 | bool named ATTRIBUTE_UNUSED) | |
830 | { | |
f387af4f | 831 | gcc_unreachable (); |
f387af4f | 832 | } |
833 | ||
bd99ba64 | 834 | unsigned int |
3754d046 | 835 | default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, |
bd99ba64 | 836 | const_tree type ATTRIBUTE_UNUSED) |
837 | { | |
838 | return PARM_BOUNDARY; | |
839 | } | |
840 | ||
17bfc2bc | 841 | unsigned int |
3754d046 | 842 | default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, |
17bfc2bc | 843 | const_tree type ATTRIBUTE_UNUSED) |
844 | { | |
845 | return PARM_BOUNDARY; | |
846 | } | |
847 | ||
48e1416a | 848 | void |
fcf2ad9f | 849 | hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) |
850 | { | |
851 | } | |
852 | ||
10fda9eb | 853 | const char * |
854 | hook_invalid_arg_for_unprototyped_fn ( | |
a9f1838b | 855 | const_tree typelist ATTRIBUTE_UNUSED, |
856 | const_tree funcdecl ATTRIBUTE_UNUSED, | |
857 | const_tree val ATTRIBUTE_UNUSED) | |
10fda9eb | 858 | { |
859 | return NULL; | |
860 | } | |
f1a0edff | 861 | |
862 | /* Initialize the stack protection decls. */ | |
863 | ||
864 | /* Stack protection related decls living in libgcc. */ | |
865 | static GTY(()) tree stack_chk_guard_decl; | |
866 | ||
867 | tree | |
868 | default_stack_protect_guard (void) | |
869 | { | |
870 | tree t = stack_chk_guard_decl; | |
871 | ||
872 | if (t == NULL) | |
873 | { | |
b5d5f0d6 | 874 | rtx x; |
875 | ||
e60a6f7b | 876 | t = build_decl (UNKNOWN_LOCATION, |
877 | VAR_DECL, get_identifier ("__stack_chk_guard"), | |
f1a0edff | 878 | ptr_type_node); |
879 | TREE_STATIC (t) = 1; | |
880 | TREE_PUBLIC (t) = 1; | |
881 | DECL_EXTERNAL (t) = 1; | |
882 | TREE_USED (t) = 1; | |
883 | TREE_THIS_VOLATILE (t) = 1; | |
884 | DECL_ARTIFICIAL (t) = 1; | |
885 | DECL_IGNORED_P (t) = 1; | |
886 | ||
b5d5f0d6 | 887 | /* Do not share RTL as the declaration is visible outside of |
888 | current function. */ | |
889 | x = DECL_RTL (t); | |
890 | RTX_FLAG (x, used) = 1; | |
891 | ||
f1a0edff | 892 | stack_chk_guard_decl = t; |
893 | } | |
894 | ||
895 | return t; | |
896 | } | |
897 | ||
898 | static GTY(()) tree stack_chk_fail_decl; | |
899 | ||
48e1416a | 900 | tree |
f1a0edff | 901 | default_external_stack_protect_fail (void) |
902 | { | |
903 | tree t = stack_chk_fail_decl; | |
904 | ||
905 | if (t == NULL_TREE) | |
906 | { | |
907 | t = build_function_type_list (void_type_node, NULL_TREE); | |
e60a6f7b | 908 | t = build_decl (UNKNOWN_LOCATION, |
909 | FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t); | |
f1a0edff | 910 | TREE_STATIC (t) = 1; |
911 | TREE_PUBLIC (t) = 1; | |
912 | DECL_EXTERNAL (t) = 1; | |
913 | TREE_USED (t) = 1; | |
914 | TREE_THIS_VOLATILE (t) = 1; | |
915 | TREE_NOTHROW (t) = 1; | |
916 | DECL_ARTIFICIAL (t) = 1; | |
917 | DECL_IGNORED_P (t) = 1; | |
f0f2eb24 | 918 | DECL_VISIBILITY (t) = VISIBILITY_DEFAULT; |
919 | DECL_VISIBILITY_SPECIFIED (t) = 1; | |
f1a0edff | 920 | |
921 | stack_chk_fail_decl = t; | |
922 | } | |
923 | ||
c2f47e15 | 924 | return build_call_expr (t, 0); |
f1a0edff | 925 | } |
926 | ||
927 | tree | |
928 | default_hidden_stack_protect_fail (void) | |
929 | { | |
c99ffbd2 | 930 | #ifndef HAVE_GAS_HIDDEN |
931 | return default_external_stack_protect_fail (); | |
932 | #else | |
f1a0edff | 933 | tree t = stack_chk_fail_decl; |
934 | ||
c99ffbd2 | 935 | if (!flag_pic) |
936 | return default_external_stack_protect_fail (); | |
937 | ||
938 | if (t == NULL_TREE) | |
f1a0edff | 939 | { |
940 | t = build_function_type_list (void_type_node, NULL_TREE); | |
e60a6f7b | 941 | t = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, |
f1a0edff | 942 | get_identifier ("__stack_chk_fail_local"), t); |
943 | TREE_STATIC (t) = 1; | |
944 | TREE_PUBLIC (t) = 1; | |
945 | DECL_EXTERNAL (t) = 1; | |
946 | TREE_USED (t) = 1; | |
947 | TREE_THIS_VOLATILE (t) = 1; | |
948 | TREE_NOTHROW (t) = 1; | |
949 | DECL_ARTIFICIAL (t) = 1; | |
950 | DECL_IGNORED_P (t) = 1; | |
951 | DECL_VISIBILITY_SPECIFIED (t) = 1; | |
952 | DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; | |
953 | ||
954 | stack_chk_fail_decl = t; | |
955 | } | |
956 | ||
c2f47e15 | 957 | return build_call_expr (t, 0); |
c99ffbd2 | 958 | #endif |
f1a0edff | 959 | } |
960 | ||
280566a7 | 961 | bool |
a9f1838b | 962 | hook_bool_const_rtx_commutative_p (const_rtx x, |
963 | int outer_code ATTRIBUTE_UNUSED) | |
280566a7 | 964 | { |
965 | return COMMUTATIVE_P (x); | |
966 | } | |
967 | ||
46b3ff29 | 968 | rtx |
fb80456a | 969 | default_function_value (const_tree ret_type ATTRIBUTE_UNUSED, |
970 | const_tree fn_decl_or_type, | |
46b3ff29 | 971 | bool outgoing ATTRIBUTE_UNUSED) |
972 | { | |
973 | /* The old interface doesn't handle receiving the function type. */ | |
974 | if (fn_decl_or_type | |
975 | && !DECL_P (fn_decl_or_type)) | |
976 | fn_decl_or_type = NULL; | |
977 | ||
46b3ff29 | 978 | #ifdef FUNCTION_VALUE |
979 | return FUNCTION_VALUE (ret_type, fn_decl_or_type); | |
980 | #else | |
e5ce1073 | 981 | gcc_unreachable (); |
46b3ff29 | 982 | #endif |
983 | } | |
984 | ||
578d1295 | 985 | rtx |
3754d046 | 986 | default_libcall_value (machine_mode mode ATTRIBUTE_UNUSED, |
e5ce1073 | 987 | const_rtx fun ATTRIBUTE_UNUSED) |
578d1295 | 988 | { |
e5ce1073 | 989 | #ifdef LIBCALL_VALUE |
42d5183d | 990 | return LIBCALL_VALUE (MACRO_MODE (mode)); |
e5ce1073 | 991 | #else |
992 | gcc_unreachable (); | |
993 | #endif | |
578d1295 | 994 | } |
995 | ||
e1ce1485 | 996 | /* The default hook for TARGET_FUNCTION_VALUE_REGNO_P. */ |
997 | ||
998 | bool | |
999 | default_function_value_regno_p (const unsigned int regno ATTRIBUTE_UNUSED) | |
1000 | { | |
1001 | #ifdef FUNCTION_VALUE_REGNO_P | |
1002 | return FUNCTION_VALUE_REGNO_P (regno); | |
1003 | #else | |
1004 | gcc_unreachable (); | |
1005 | #endif | |
1006 | } | |
1007 | ||
567925e3 | 1008 | rtx |
1009 | default_internal_arg_pointer (void) | |
1010 | { | |
1011 | /* If the reg that the virtual arg pointer will be translated into is | |
1012 | not a fixed reg or is the stack pointer, make a copy of the virtual | |
1013 | arg pointer, and address parms via the copy. The frame pointer is | |
1014 | considered fixed even though it is not marked as such. */ | |
1015 | if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM | |
1016 | || ! (fixed_regs[ARG_POINTER_REGNUM] | |
1017 | || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))) | |
1018 | return copy_to_reg (virtual_incoming_args_rtx); | |
1019 | else | |
1020 | return virtual_incoming_args_rtx; | |
1021 | } | |
1022 | ||
82c7907c | 1023 | rtx |
8d54d6a0 | 1024 | default_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p) |
82c7907c | 1025 | { |
82c7907c | 1026 | if (incoming_p) |
1027 | { | |
82c7907c | 1028 | #ifdef STATIC_CHAIN_INCOMING_REGNUM |
1029 | return gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM); | |
1030 | #endif | |
1031 | } | |
1032 | ||
82c7907c | 1033 | #ifdef STATIC_CHAIN_REGNUM |
1034 | return gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); | |
1035 | #endif | |
1036 | ||
974b8df6 | 1037 | { |
1038 | static bool issued_error; | |
1039 | if (!issued_error) | |
1040 | { | |
1041 | issued_error = true; | |
1042 | sorry ("nested functions not supported on this target"); | |
1043 | } | |
1044 | ||
1045 | /* It really doesn't matter what we return here, so long at it | |
1046 | doesn't cause the rest of the compiler to crash. */ | |
1047 | return gen_rtx_MEM (Pmode, stack_pointer_rtx); | |
1048 | } | |
82c7907c | 1049 | } |
1050 | ||
82c7907c | 1051 | void |
1052 | default_trampoline_init (rtx ARG_UNUSED (m_tramp), tree ARG_UNUSED (t_func), | |
1053 | rtx ARG_UNUSED (r_chain)) | |
1054 | { | |
82c7907c | 1055 | sorry ("nested function trampolines not supported on this target"); |
82c7907c | 1056 | } |
1057 | ||
e0deb08c | 1058 | poly_int64 |
1059 | default_return_pops_args (tree, tree, poly_int64) | |
f5bc28da | 1060 | { |
1061 | return 0; | |
1062 | } | |
1063 | ||
964229b7 | 1064 | reg_class_t |
bc620c5c | 1065 | default_branch_target_register_class (void) |
1066 | { | |
1067 | return NO_REGS; | |
1068 | } | |
1069 | ||
20c3c7fc | 1070 | reg_class_t |
1071 | default_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED, | |
ef704984 | 1072 | reg_class_t cl, |
1073 | reg_class_t best_cl ATTRIBUTE_UNUSED) | |
20c3c7fc | 1074 | { |
1075 | return cl; | |
1076 | } | |
1077 | ||
c6a6cdaa | 1078 | extern bool |
1079 | default_lra_p (void) | |
1080 | { | |
2ebea89e | 1081 | return true; |
c6a6cdaa | 1082 | } |
1083 | ||
1084 | int | |
1085 | default_register_priority (int hard_regno ATTRIBUTE_UNUSED) | |
1086 | { | |
1087 | return 0; | |
1088 | } | |
1089 | ||
4a2ca8f3 | 1090 | extern bool |
1091 | default_register_usage_leveling_p (void) | |
1092 | { | |
1093 | return false; | |
1094 | } | |
1095 | ||
c6a6cdaa | 1096 | extern bool |
1097 | default_different_addr_displacement_p (void) | |
1098 | { | |
1099 | return false; | |
1100 | } | |
1101 | ||
964229b7 | 1102 | reg_class_t |
4d58fa46 | 1103 | default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, |
964229b7 | 1104 | reg_class_t reload_class_i ATTRIBUTE_UNUSED, |
3754d046 | 1105 | machine_mode reload_mode ATTRIBUTE_UNUSED, |
4d58fa46 | 1106 | secondary_reload_info *sri) |
1107 | { | |
c32319fc | 1108 | enum reg_class rclass = NO_REGS; |
964229b7 | 1109 | enum reg_class reload_class = (enum reg_class) reload_class_i; |
4d58fa46 | 1110 | |
1111 | if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) | |
1112 | { | |
1113 | sri->icode = sri->prev_sri->t_icode; | |
1114 | return NO_REGS; | |
1115 | } | |
1116 | #ifdef SECONDARY_INPUT_RELOAD_CLASS | |
1117 | if (in_p) | |
42d5183d | 1118 | rclass = SECONDARY_INPUT_RELOAD_CLASS (reload_class, |
1119 | MACRO_MODE (reload_mode), x); | |
4d58fa46 | 1120 | #endif |
1121 | #ifdef SECONDARY_OUTPUT_RELOAD_CLASS | |
1122 | if (! in_p) | |
42d5183d | 1123 | rclass = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, |
1124 | MACRO_MODE (reload_mode), x); | |
4d58fa46 | 1125 | #endif |
c32319fc | 1126 | if (rclass != NO_REGS) |
4d58fa46 | 1127 | { |
6b531606 | 1128 | enum insn_code icode |
1129 | = direct_optab_handler (in_p ? reload_in_optab : reload_out_optab, | |
1130 | reload_mode); | |
4d58fa46 | 1131 | |
1132 | if (icode != CODE_FOR_nothing | |
39c56a89 | 1133 | && !insn_operand_matches (icode, in_p, x)) |
4d58fa46 | 1134 | icode = CODE_FOR_nothing; |
1135 | else if (icode != CODE_FOR_nothing) | |
1136 | { | |
1137 | const char *insn_constraint, *scratch_constraint; | |
4d58fa46 | 1138 | enum reg_class insn_class, scratch_class; |
1139 | ||
1140 | gcc_assert (insn_data[(int) icode].n_operands == 3); | |
1141 | insn_constraint = insn_data[(int) icode].operand[!in_p].constraint; | |
1142 | if (!*insn_constraint) | |
1143 | insn_class = ALL_REGS; | |
1144 | else | |
1145 | { | |
1146 | if (in_p) | |
1147 | { | |
1148 | gcc_assert (*insn_constraint == '='); | |
1149 | insn_constraint++; | |
1150 | } | |
69449463 | 1151 | insn_class = (reg_class_for_constraint |
1152 | (lookup_constraint (insn_constraint))); | |
4d58fa46 | 1153 | gcc_assert (insn_class != NO_REGS); |
1154 | } | |
1155 | ||
1156 | scratch_constraint = insn_data[(int) icode].operand[2].constraint; | |
eb7c310b | 1157 | /* The scratch register's constraint must start with "=&", |
1158 | except for an input reload, where only "=" is necessary, | |
1159 | and where it might be beneficial to re-use registers from | |
1160 | the input. */ | |
4d58fa46 | 1161 | gcc_assert (scratch_constraint[0] == '=' |
eb7c310b | 1162 | && (in_p || scratch_constraint[1] == '&')); |
1163 | scratch_constraint++; | |
1164 | if (*scratch_constraint == '&') | |
1165 | scratch_constraint++; | |
69449463 | 1166 | scratch_class = (reg_class_for_constraint |
1167 | (lookup_constraint (scratch_constraint))); | |
4d58fa46 | 1168 | |
1169 | if (reg_class_subset_p (reload_class, insn_class)) | |
1170 | { | |
c32319fc | 1171 | gcc_assert (scratch_class == rclass); |
1172 | rclass = NO_REGS; | |
4d58fa46 | 1173 | } |
1174 | else | |
c32319fc | 1175 | rclass = insn_class; |
4d58fa46 | 1176 | |
1177 | } | |
c32319fc | 1178 | if (rclass == NO_REGS) |
4d58fa46 | 1179 | sri->icode = icode; |
1180 | else | |
1181 | sri->t_icode = icode; | |
1182 | } | |
c32319fc | 1183 | return rclass; |
4d58fa46 | 1184 | } |
1185 | ||
1041f930 | 1186 | /* The default implementation of TARGET_SECONDARY_MEMORY_NEEDED_MODE. */ |
1187 | ||
1188 | machine_mode | |
1189 | default_secondary_memory_needed_mode (machine_mode mode) | |
1190 | { | |
1191 | if (!targetm.lra_p () | |
eafbcd13 | 1192 | && known_lt (GET_MODE_BITSIZE (mode), BITS_PER_WORD) |
1041f930 | 1193 | && INTEGRAL_MODE_P (mode)) |
1194 | return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require (); | |
1195 | return mode; | |
1196 | } | |
1197 | ||
4e151b05 | 1198 | /* By default, if flag_pic is true, then neither local nor global relocs |
1199 | should be placed in readonly memory. */ | |
1200 | ||
1201 | int | |
1202 | default_reloc_rw_mask (void) | |
1203 | { | |
1204 | return flag_pic ? 3 : 0; | |
1205 | } | |
1206 | ||
a5cb9559 | 1207 | /* By default, address diff vectors are generated |
1208 | for jump tables when flag_pic is true. */ | |
1209 | ||
1210 | bool | |
1211 | default_generate_pic_addr_diff_vec (void) | |
1212 | { | |
1213 | return flag_pic; | |
1214 | } | |
1215 | ||
97a424bc | 1216 | /* By default, do no modification. */ |
1217 | tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED, | |
1218 | tree id) | |
1219 | { | |
1220 | return id; | |
1221 | } | |
1222 | ||
1cdbc719 | 1223 | /* The default implementation of TARGET_STATIC_RTX_ALIGNMENT. */ |
1224 | ||
1225 | HOST_WIDE_INT | |
1226 | default_static_rtx_alignment (machine_mode mode) | |
1227 | { | |
1228 | return GET_MODE_ALIGNMENT (mode); | |
1229 | } | |
1230 | ||
579d67ba | 1231 | /* The default implementation of TARGET_CONSTANT_ALIGNMENT. */ |
1232 | ||
1233 | HOST_WIDE_INT | |
1234 | default_constant_alignment (const_tree, HOST_WIDE_INT align) | |
1235 | { | |
1236 | return align; | |
1237 | } | |
1238 | ||
1239 | /* An implementation of TARGET_CONSTANT_ALIGNMENT that aligns strings | |
1240 | to at least BITS_PER_WORD but otherwise makes no changes. */ | |
1241 | ||
1242 | HOST_WIDE_INT | |
1243 | constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align) | |
1244 | { | |
1245 | if (TREE_CODE (exp) == STRING_CST) | |
1246 | return MAX (align, BITS_PER_WORD); | |
1247 | return align; | |
1248 | } | |
1249 | ||
482a44fa | 1250 | /* Default to natural alignment for vector types. */ |
1251 | HOST_WIDE_INT | |
1252 | default_vector_alignment (const_tree type) | |
1253 | { | |
0e43078e | 1254 | HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type)); |
1255 | if (align > MAX_OFILE_ALIGNMENT) | |
1256 | align = MAX_OFILE_ALIGNMENT; | |
1257 | return align; | |
482a44fa | 1258 | } |
1259 | ||
aec313e5 | 1260 | /* The default implementation of |
1261 | TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */ | |
1262 | ||
e092c20e | 1263 | poly_uint64 |
aec313e5 | 1264 | default_preferred_vector_alignment (const_tree type) |
1265 | { | |
1266 | return TYPE_ALIGN (type); | |
1267 | } | |
1268 | ||
33a82fb9 | 1269 | /* By default assume vectors of element TYPE require a multiple of the natural |
1270 | alignment of TYPE. TYPE is naturally aligned if IS_PACKED is false. */ | |
5a2538e1 | 1271 | bool |
700a9760 | 1272 | default_builtin_vector_alignment_reachable (const_tree /*type*/, bool is_packed) |
5a2538e1 | 1273 | { |
700a9760 | 1274 | return ! is_packed; |
5a2538e1 | 1275 | } |
1276 | ||
c6b19c5f | 1277 | /* By default, assume that a target supports any factor of misalignment |
48e1416a | 1278 | memory access if it supports movmisalign patten. |
c6b19c5f | 1279 | is_packed is true if the memory access is defined in a packed struct. */ |
1280 | bool | |
3754d046 | 1281 | default_builtin_support_vector_misalignment (machine_mode mode, |
c6b19c5f | 1282 | const_tree type |
1283 | ATTRIBUTE_UNUSED, | |
1284 | int misalignment | |
1285 | ATTRIBUTE_UNUSED, | |
1286 | bool is_packed | |
1287 | ATTRIBUTE_UNUSED) | |
1288 | { | |
d6bf3b14 | 1289 | if (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing) |
c6b19c5f | 1290 | return true; |
1291 | return false; | |
1292 | } | |
1293 | ||
2101edf2 | 1294 | /* By default, only attempt to parallelize bitwise operations, and |
1295 | possibly adds/subtracts using bit-twiddling. */ | |
1296 | ||
3754d046 | 1297 | machine_mode |
4c1a1be2 | 1298 | default_preferred_simd_mode (scalar_mode) |
2101edf2 | 1299 | { |
b24d851f | 1300 | return word_mode; |
2101edf2 | 1301 | } |
1302 | ||
41b4a935 | 1303 | /* By default do not split reductions further. */ |
1304 | ||
1305 | machine_mode | |
1306 | default_split_reduction (machine_mode mode) | |
1307 | { | |
1308 | return mode; | |
1309 | } | |
1310 | ||
421b11b1 | 1311 | /* By default only the size derived from the preferred vector mode |
1312 | is tried. */ | |
1313 | ||
3106770a | 1314 | void |
1315 | default_autovectorize_vector_sizes (vector_sizes *) | |
421b11b1 | 1316 | { |
421b11b1 | 1317 | } |
1318 | ||
f5e07737 | 1319 | /* By default a vector of integers is used as a mask. */ |
1f137e6d | 1320 | |
38d5f204 | 1321 | opt_machine_mode |
f5e07737 | 1322 | default_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size) |
1f137e6d | 1323 | { |
f5e07737 | 1324 | unsigned int elem_size = vector_element_size (vector_size, nunits); |
1a5d4b27 | 1325 | scalar_int_mode elem_mode |
1326 | = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT); | |
562458b4 | 1327 | machine_mode vector_mode; |
1f137e6d | 1328 | |
f5e07737 | 1329 | gcc_assert (known_eq (elem_size * nunits, vector_size)); |
1f137e6d | 1330 | |
38d5f204 | 1331 | if (mode_for_vector (elem_mode, nunits).exists (&vector_mode) |
1332 | && VECTOR_MODE_P (vector_mode) | |
1333 | && targetm.vector_mode_supported_p (vector_mode)) | |
1334 | return vector_mode; | |
562458b4 | 1335 | |
38d5f204 | 1336 | return opt_machine_mode (); |
1f137e6d | 1337 | } |
1338 | ||
e75a6670 | 1339 | /* By default consider masked stores to be expensive. */ |
1340 | ||
1341 | bool | |
1342 | default_empty_mask_is_expensive (unsigned ifn) | |
1343 | { | |
1344 | return ifn == IFN_MASK_STORE; | |
1345 | } | |
1346 | ||
f97dec81 | 1347 | /* By default, the cost model accumulates three separate costs (prologue, |
1348 | loop body, and epilogue) for a vectorized loop or block. So allocate an | |
1349 | array of three unsigned ints, set it to zero, and return its address. */ | |
4db2b577 | 1350 | |
1351 | void * | |
1352 | default_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED) | |
1353 | { | |
f97dec81 | 1354 | unsigned *cost = XNEWVEC (unsigned, 3); |
1355 | cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0; | |
4db2b577 | 1356 | return cost; |
1357 | } | |
1358 | ||
1359 | /* By default, the cost model looks up the cost of the given statement | |
1360 | kind and mode, multiplies it by the occurrence count, accumulates | |
f97dec81 | 1361 | it into the cost specified by WHERE, and returns the cost added. */ |
4db2b577 | 1362 | |
1363 | unsigned | |
1364 | default_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, | |
f97dec81 | 1365 | struct _stmt_vec_info *stmt_info, int misalign, |
1366 | enum vect_cost_model_location where) | |
4db2b577 | 1367 | { |
1368 | unsigned *cost = (unsigned *) data; | |
1369 | unsigned retval = 0; | |
1370 | ||
1dbf9bd1 | 1371 | tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; |
c820693e | 1372 | int stmt_cost = targetm.vectorize.builtin_vectorization_cost (kind, vectype, |
1373 | misalign); | |
1dbf9bd1 | 1374 | /* Statements in an inner loop relative to the loop being |
1375 | vectorized are weighted more heavily. The value here is | |
1376 | arbitrary and could potentially be improved with analysis. */ | |
1377 | if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) | |
1378 | count *= 50; /* FIXME. */ | |
1379 | ||
1380 | retval = (unsigned) (count * stmt_cost); | |
1381 | cost[where] += retval; | |
4db2b577 | 1382 | |
1383 | return retval; | |
1384 | } | |
1385 | ||
f97dec81 | 1386 | /* By default, the cost model just returns the accumulated costs. */ |
4db2b577 | 1387 | |
f97dec81 | 1388 | void |
1389 | default_finish_cost (void *data, unsigned *prologue_cost, | |
1390 | unsigned *body_cost, unsigned *epilogue_cost) | |
4db2b577 | 1391 | { |
f97dec81 | 1392 | unsigned *cost = (unsigned *) data; |
1393 | *prologue_cost = cost[vect_prologue]; | |
1394 | *body_cost = cost[vect_body]; | |
1395 | *epilogue_cost = cost[vect_epilogue]; | |
4db2b577 | 1396 | } |
1397 | ||
1398 | /* Free the cost data. */ | |
1399 | ||
1400 | void | |
1401 | default_destroy_cost_data (void *data) | |
1402 | { | |
1403 | free (data); | |
1404 | } | |
1405 | ||
98155838 | 1406 | /* Determine whether or not a pointer mode is valid. Assume defaults |
1407 | of ptr_mode or Pmode - can be overridden. */ | |
1408 | bool | |
f77c4496 | 1409 | default_valid_pointer_mode (scalar_int_mode mode) |
98155838 | 1410 | { |
1411 | return (mode == ptr_mode || mode == Pmode); | |
1412 | } | |
1413 | ||
be97d4b6 | 1414 | /* Determine whether the memory reference specified by REF may alias |
1415 | the C libraries errno location. */ | |
1416 | bool | |
1417 | default_ref_may_alias_errno (ao_ref *ref) | |
1418 | { | |
1419 | tree base = ao_ref_base (ref); | |
1420 | /* The default implementation assumes the errno location is | |
1421 | a declaration of type int or is always accessed via a | |
1422 | pointer to int. We assume that accesses to errno are | |
1423 | not deliberately obfuscated (even in conforming ways). */ | |
1424 | if (TYPE_UNSIGNED (TREE_TYPE (base)) | |
1425 | || TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node)) | |
1426 | return false; | |
1427 | /* The default implementation assumes an errno location | |
1428 | declaration is never defined in the current compilation unit. */ | |
1429 | if (DECL_P (base) | |
1430 | && !TREE_STATIC (base)) | |
1431 | return true; | |
1432 | else if (TREE_CODE (base) == MEM_REF | |
1433 | && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) | |
1434 | { | |
1435 | struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)); | |
1436 | return !pi || pi->pt.anything || pi->pt.nonlocal; | |
1437 | } | |
1438 | return false; | |
1439 | } | |
1440 | ||
d06612ae | 1441 | /* Return the mode for a pointer to a given ADDRSPACE, |
1442 | defaulting to ptr_mode for all address spaces. */ | |
98155838 | 1443 | |
f77c4496 | 1444 | scalar_int_mode |
98155838 | 1445 | default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED) |
1446 | { | |
98155838 | 1447 | return ptr_mode; |
1448 | } | |
1449 | ||
d06612ae | 1450 | /* Return the mode for an address in a given ADDRSPACE, |
1451 | defaulting to Pmode for all address spaces. */ | |
98155838 | 1452 | |
f77c4496 | 1453 | scalar_int_mode |
98155838 | 1454 | default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED) |
1455 | { | |
98155838 | 1456 | return Pmode; |
1457 | } | |
1458 | ||
d06612ae | 1459 | /* Named address space version of valid_pointer_mode. |
1460 | To match the above, the same modes apply to all address spaces. */ | |
98155838 | 1461 | |
1462 | bool | |
f77c4496 | 1463 | default_addr_space_valid_pointer_mode (scalar_int_mode mode, |
d06612ae | 1464 | addr_space_t as ATTRIBUTE_UNUSED) |
98155838 | 1465 | { |
98155838 | 1466 | return targetm.valid_pointer_mode (mode); |
1467 | } | |
1468 | ||
1469 | /* Some places still assume that all pointer or address modes are the | |
1470 | standard Pmode and ptr_mode. These optimizations become invalid if | |
1471 | the target actually supports multiple different modes. For now, | |
1472 | we disable such optimizations on such targets, using this function. */ | |
1473 | ||
1474 | bool | |
1475 | target_default_pointer_address_modes_p (void) | |
1476 | { | |
1477 | if (targetm.addr_space.address_mode != default_addr_space_address_mode) | |
1478 | return false; | |
1479 | if (targetm.addr_space.pointer_mode != default_addr_space_pointer_mode) | |
1480 | return false; | |
1481 | ||
1482 | return true; | |
1483 | } | |
1484 | ||
d06612ae | 1485 | /* Named address space version of legitimate_address_p. |
1486 | By default, all address spaces have the same form. */ | |
bd1a81f7 | 1487 | |
1488 | bool | |
3754d046 | 1489 | default_addr_space_legitimate_address_p (machine_mode mode, rtx mem, |
d06612ae | 1490 | bool strict, |
1491 | addr_space_t as ATTRIBUTE_UNUSED) | |
bd1a81f7 | 1492 | { |
bd1a81f7 | 1493 | return targetm.legitimate_address_p (mode, mem, strict); |
1494 | } | |
1495 | ||
d06612ae | 1496 | /* Named address space version of LEGITIMIZE_ADDRESS. |
1497 | By default, all address spaces have the same form. */ | |
bd1a81f7 | 1498 | |
1499 | rtx | |
d06612ae | 1500 | default_addr_space_legitimize_address (rtx x, rtx oldx, machine_mode mode, |
1501 | addr_space_t as ATTRIBUTE_UNUSED) | |
bd1a81f7 | 1502 | { |
bd1a81f7 | 1503 | return targetm.legitimize_address (x, oldx, mode); |
1504 | } | |
1505 | ||
1506 | /* The default hook for determining if one named address space is a subset of | |
1507 | another and to return which address space to use as the common address | |
1508 | space. */ | |
1509 | ||
1510 | bool | |
1511 | default_addr_space_subset_p (addr_space_t subset, addr_space_t superset) | |
1512 | { | |
1513 | return (subset == superset); | |
1514 | } | |
1515 | ||
9cb89654 | 1516 | /* The default hook for determining if 0 within a named address |
1517 | space is a valid address. */ | |
1518 | ||
1519 | bool | |
1520 | default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED) | |
1521 | { | |
1522 | return false; | |
1523 | } | |
1524 | ||
2e7a553a | 1525 | /* The default hook for debugging the address space is to return the |
1526 | address space number to indicate DW_AT_address_class. */ | |
1527 | int | |
1528 | default_addr_space_debug (addr_space_t as) | |
1529 | { | |
1530 | return as; | |
1531 | } | |
1532 | ||
a91a5f8a | 1533 | /* The default hook implementation for TARGET_ADDR_SPACE_DIAGNOSE_USAGE. |
1534 | Don't complain about any address space. */ | |
1535 | ||
1536 | void | |
1537 | default_addr_space_diagnose_usage (addr_space_t, location_t) | |
1538 | { | |
1539 | } | |
1540 | ||
1541 | ||
bd1a81f7 | 1542 | /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be |
1543 | called for targets with only a generic address space. */ | |
1544 | ||
1545 | rtx | |
1546 | default_addr_space_convert (rtx op ATTRIBUTE_UNUSED, | |
1547 | tree from_type ATTRIBUTE_UNUSED, | |
1548 | tree to_type ATTRIBUTE_UNUSED) | |
1549 | { | |
1550 | gcc_unreachable (); | |
1551 | } | |
1552 | ||
74f68e49 | 1553 | /* The defualt implementation of TARGET_HARD_REGNO_NREGS. */ |
1554 | ||
1555 | unsigned int | |
1556 | default_hard_regno_nregs (unsigned int, machine_mode mode) | |
1557 | { | |
52acb7ae | 1558 | /* Targets with variable-sized modes must provide their own definition |
1559 | of this hook. */ | |
1560 | return CEIL (GET_MODE_SIZE (mode).to_constant (), UNITS_PER_WORD); | |
74f68e49 | 1561 | } |
1562 | ||
747bf50d | 1563 | bool |
1564 | default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED) | |
1565 | { | |
1566 | return true; | |
1567 | } | |
1568 | ||
98e22cb6 | 1569 | /* The default implementation of TARGET_MODE_DEPENDENT_ADDRESS_P. */ |
1570 | ||
1571 | bool | |
4e27ffd0 | 1572 | default_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, |
1573 | addr_space_t addrspace ATTRIBUTE_UNUSED) | |
98e22cb6 | 1574 | { |
98e22cb6 | 1575 | return false; |
98e22cb6 | 1576 | } |
1577 | ||
46f8e3b0 | 1578 | bool |
1579 | default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl), | |
1580 | tree ARG_UNUSED (name), | |
1581 | tree ARG_UNUSED (args), | |
1582 | int ARG_UNUSED (flags)) | |
1583 | { | |
24470055 | 1584 | warning (OPT_Wattributes, |
1585 | "target attribute is not supported on this machine"); | |
1586 | ||
1587 | return false; | |
1588 | } | |
1589 | ||
1590 | bool | |
1591 | default_target_option_pragma_parse (tree ARG_UNUSED (args), | |
1592 | tree ARG_UNUSED (pop_target)) | |
1593 | { | |
0cb9d971 | 1594 | /* If args is NULL the caller is handle_pragma_pop_options (). In that case, |
1595 | emit no warning because "#pragma GCC pop_target" is valid on targets that | |
1596 | do not have the "target" pragma. */ | |
1597 | if (args) | |
1598 | warning (OPT_Wpragmas, | |
1599 | "#pragma GCC target is not supported for this machine"); | |
24470055 | 1600 | |
46f8e3b0 | 1601 | return false; |
1602 | } | |
1603 | ||
1604 | bool | |
7c88e513 | 1605 | default_target_can_inline_p (tree caller, tree callee) |
46f8e3b0 | 1606 | { |
46f8e3b0 | 1607 | tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee); |
1608 | tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller); | |
4e42a196 | 1609 | if (! callee_opts) |
1610 | callee_opts = target_option_default_node; | |
1611 | if (! caller_opts) | |
1612 | caller_opts = target_option_default_node; | |
46f8e3b0 | 1613 | |
851d9296 | 1614 | /* If both caller and callee have attributes, assume that if the |
1615 | pointer is different, the two functions have different target | |
1616 | options since build_target_option_node uses a hash table for the | |
1617 | options. */ | |
4e42a196 | 1618 | return callee_opts == caller_opts; |
46f8e3b0 | 1619 | } |
1620 | ||
906bb5c3 | 1621 | /* If the machine does not have a case insn that compares the bounds, |
1622 | this means extra overhead for dispatch tables, which raises the | |
1623 | threshold for using them. */ | |
1624 | ||
bfb10994 | 1625 | unsigned int |
1626 | default_case_values_threshold (void) | |
906bb5c3 | 1627 | { |
9a1bd12f | 1628 | return (targetm.have_casesi () ? 4 : 5); |
906bb5c3 | 1629 | } |
1630 | ||
751d3ba7 | 1631 | bool |
1632 | default_have_conditional_execution (void) | |
1633 | { | |
751d3ba7 | 1634 | return HAVE_conditional_execution; |
751d3ba7 | 1635 | } |
1636 | ||
f7715905 | 1637 | /* By default we assume that c99 functions are present at the runtime, |
1638 | but sincos is not. */ | |
1639 | bool | |
1640 | default_libc_has_function (enum function_class fn_class) | |
1641 | { | |
1642 | if (fn_class == function_c94 | |
1643 | || fn_class == function_c99_misc | |
1644 | || fn_class == function_c99_math_complex) | |
1645 | return true; | |
1646 | ||
1647 | return false; | |
1648 | } | |
1649 | ||
1650 | bool | |
1651 | gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED) | |
1652 | { | |
1653 | return true; | |
1654 | } | |
1655 | ||
1656 | bool | |
1657 | no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED) | |
1658 | { | |
1659 | return false; | |
1660 | } | |
1661 | ||
4c0315d0 | 1662 | tree |
1663 | default_builtin_tm_load_store (tree ARG_UNUSED (type)) | |
1664 | { | |
1665 | return NULL_TREE; | |
1666 | } | |
1667 | ||
251a613e | 1668 | /* Compute cost of moving registers to/from memory. */ |
1669 | ||
1670 | int | |
3754d046 | 1671 | default_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, |
964229b7 | 1672 | reg_class_t rclass ATTRIBUTE_UNUSED, |
251a613e | 1673 | bool in ATTRIBUTE_UNUSED) |
1674 | { | |
1675 | #ifndef MEMORY_MOVE_COST | |
964229b7 | 1676 | return (4 + memory_move_secondary_cost (mode, (enum reg_class) rclass, in)); |
251a613e | 1677 | #else |
42d5183d | 1678 | return MEMORY_MOVE_COST (MACRO_MODE (mode), (enum reg_class) rclass, in); |
251a613e | 1679 | #endif |
1680 | } | |
1681 | ||
e6078fbb | 1682 | /* Compute cost of moving data from a register of class FROM to one of |
1683 | TO, using MODE. */ | |
1684 | ||
1685 | int | |
3754d046 | 1686 | default_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, |
964229b7 | 1687 | reg_class_t from ATTRIBUTE_UNUSED, |
1688 | reg_class_t to ATTRIBUTE_UNUSED) | |
e6078fbb | 1689 | { |
1690 | #ifndef REGISTER_MOVE_COST | |
1691 | return 2; | |
1692 | #else | |
42d5183d | 1693 | return REGISTER_MOVE_COST (MACRO_MODE (mode), |
1694 | (enum reg_class) from, (enum reg_class) to); | |
e6078fbb | 1695 | #endif |
1696 | } | |
1697 | ||
dfdced85 | 1698 | /* The default implementation of TARGET_SLOW_UNALIGNED_ACCESS. */ |
1699 | ||
1700 | bool | |
1701 | default_slow_unaligned_access (machine_mode, unsigned int) | |
1702 | { | |
1703 | return STRICT_ALIGNMENT; | |
1704 | } | |
1705 | ||
466432a3 | 1706 | /* The default implementation of TARGET_ESTIMATED_POLY_VALUE. */ |
1707 | ||
1708 | HOST_WIDE_INT | |
1709 | default_estimated_poly_value (poly_int64 x) | |
1710 | { | |
1711 | return x.coeffs[0]; | |
1712 | } | |
1713 | ||
0ec3791c | 1714 | /* For hooks which use the MOVE_RATIO macro, this gives the legacy default |
67cf9b55 | 1715 | behavior. SPEED_P is true if we are compiling for speed. */ |
0ec3791c | 1716 | |
67622758 | 1717 | unsigned int |
0ec3791c | 1718 | get_move_ratio (bool speed_p ATTRIBUTE_UNUSED) |
1719 | { | |
1720 | unsigned int move_ratio; | |
1721 | #ifdef MOVE_RATIO | |
1722 | move_ratio = (unsigned int) MOVE_RATIO (speed_p); | |
1723 | #else | |
1724 | #if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti) | |
1725 | move_ratio = 2; | |
1726 | #else /* No movmem patterns, pick a default. */ | |
1727 | move_ratio = ((speed_p) ? 15 : 3); | |
1728 | #endif | |
1729 | #endif | |
1730 | return move_ratio; | |
1731 | } | |
1732 | ||
1733 | /* Return TRUE if the move_by_pieces/set_by_pieces infrastructure should be | |
1734 | used; return FALSE if the movmem/setmem optab should be expanded, or | |
1735 | a call to memcpy emitted. */ | |
1736 | ||
1737 | bool | |
89da42b6 | 1738 | default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, |
0ec3791c | 1739 | unsigned int alignment, |
1740 | enum by_pieces_operation op, | |
1741 | bool speed_p) | |
1742 | { | |
1743 | unsigned int max_size = 0; | |
1744 | unsigned int ratio = 0; | |
1745 | ||
1746 | switch (op) | |
1747 | { | |
3e346f54 | 1748 | case CLEAR_BY_PIECES: |
1749 | max_size = STORE_MAX_PIECES; | |
1750 | ratio = CLEAR_RATIO (speed_p); | |
1751 | break; | |
1752 | case MOVE_BY_PIECES: | |
1753 | max_size = MOVE_MAX_PIECES; | |
1754 | ratio = get_move_ratio (speed_p); | |
1755 | break; | |
1756 | case SET_BY_PIECES: | |
1757 | max_size = STORE_MAX_PIECES; | |
1758 | ratio = SET_RATIO (speed_p); | |
1759 | break; | |
1760 | case STORE_BY_PIECES: | |
1761 | max_size = STORE_MAX_PIECES; | |
1762 | ratio = get_move_ratio (speed_p); | |
1763 | break; | |
1764 | case COMPARE_BY_PIECES: | |
1765 | max_size = COMPARE_MAX_PIECES; | |
1766 | /* Pick a likely default, just as in get_move_ratio. */ | |
1767 | ratio = speed_p ? 15 : 3; | |
1768 | break; | |
0ec3791c | 1769 | } |
1770 | ||
3e346f54 | 1771 | return by_pieces_ninsns (size, alignment, max_size + 1, op) < ratio; |
1772 | } | |
1773 | ||
1774 | /* This hook controls code generation for expanding a memcmp operation by | |
1775 | pieces. Return 1 for the normal pattern of compare/jump after each pair | |
1776 | of loads, or a higher number to reduce the number of branches. */ | |
1777 | ||
1778 | int | |
1779 | default_compare_by_pieces_branch_ratio (machine_mode) | |
1780 | { | |
1781 | return 1; | |
0ec3791c | 1782 | } |
1783 | ||
e6c4532a | 1784 | /* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function |
1785 | entry. If RECORD_P is true and the target supports named sections, | |
1786 | the location of the NOPs will be recorded in a special object section | |
1787 | called "__patchable_function_entries". This routine may be called | |
1788 | twice per function to put NOPs before and after the function | |
1789 | entry. */ | |
1790 | ||
1791 | void | |
1792 | default_print_patchable_function_entry (FILE *file, | |
1793 | unsigned HOST_WIDE_INT patch_area_size, | |
1794 | bool record_p) | |
1795 | { | |
1796 | const char *nop_templ = 0; | |
1797 | int code_num; | |
1798 | rtx_insn *my_nop = make_insn_raw (gen_nop ()); | |
1799 | ||
1800 | /* We use the template alone, relying on the (currently sane) assumption | |
1801 | that the NOP template does not have variable operands. */ | |
1802 | code_num = recog_memoized (my_nop); | |
1803 | nop_templ = get_insn_template (code_num, my_nop); | |
1804 | ||
1805 | if (record_p && targetm_common.have_named_sections) | |
1806 | { | |
1807 | char buf[256]; | |
1808 | static int patch_area_number; | |
1809 | section *previous_section = in_section; | |
db879ec7 | 1810 | const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false); |
e6c4532a | 1811 | |
db879ec7 | 1812 | gcc_assert (asm_op != NULL); |
e6c4532a | 1813 | patch_area_number++; |
1814 | ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number); | |
1815 | ||
1816 | switch_to_section (get_section ("__patchable_function_entries", | |
1817 | 0, NULL)); | |
db879ec7 | 1818 | fputs (asm_op, file); |
e6c4532a | 1819 | assemble_name_raw (file, buf); |
1820 | fputc ('\n', file); | |
1821 | ||
1822 | switch_to_section (previous_section); | |
1823 | ASM_OUTPUT_LABEL (file, buf); | |
1824 | } | |
1825 | ||
1826 | unsigned i; | |
1827 | for (i = 0; i < patch_area_size; ++i) | |
1828 | fprintf (file, "\t%s\n", nop_templ); | |
1829 | } | |
1830 | ||
8637d6a2 | 1831 | bool |
1832 | default_profile_before_prologue (void) | |
1833 | { | |
1834 | #ifdef PROFILE_BEFORE_PROLOGUE | |
1835 | return true; | |
1836 | #else | |
1837 | return false; | |
1838 | #endif | |
1839 | } | |
1840 | ||
09a17585 | 1841 | /* The default implementation of TARGET_PREFERRED_RELOAD_CLASS. */ |
1842 | ||
1843 | reg_class_t | |
1844 | default_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, | |
1845 | reg_class_t rclass) | |
1846 | { | |
1847 | #ifdef PREFERRED_RELOAD_CLASS | |
1848 | return (reg_class_t) PREFERRED_RELOAD_CLASS (x, (enum reg_class) rclass); | |
1849 | #else | |
1850 | return rclass; | |
1851 | #endif | |
1852 | } | |
1853 | ||
71db0d8b | 1854 | /* The default implementation of TARGET_OUTPUT_PREFERRED_RELOAD_CLASS. */ |
1855 | ||
1856 | reg_class_t | |
1857 | default_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED, | |
1858 | reg_class_t rclass) | |
1859 | { | |
71db0d8b | 1860 | return rclass; |
71db0d8b | 1861 | } |
1862 | ||
d78118a3 | 1863 | /* The default implementation of TARGET_PREFERRED_RENAME_CLASS. */ |
1864 | reg_class_t | |
1865 | default_preferred_rename_class (reg_class_t rclass ATTRIBUTE_UNUSED) | |
1866 | { | |
1867 | return NO_REGS; | |
1868 | } | |
1869 | ||
24dd0668 | 1870 | /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */ |
1871 | ||
1872 | bool | |
1873 | default_class_likely_spilled_p (reg_class_t rclass) | |
1874 | { | |
24dd0668 | 1875 | return (reg_class_size[(int) rclass] == 1); |
24dd0668 | 1876 | } |
1877 | ||
d3ba22dc | 1878 | /* The default implementation of TARGET_CLASS_MAX_NREGS. */ |
1879 | ||
1880 | unsigned char | |
1881 | default_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED, | |
3754d046 | 1882 | machine_mode mode ATTRIBUTE_UNUSED) |
d3ba22dc | 1883 | { |
1884 | #ifdef CLASS_MAX_NREGS | |
42d5183d | 1885 | return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass, |
1886 | MACRO_MODE (mode)); | |
d3ba22dc | 1887 | #else |
52acb7ae | 1888 | /* Targets with variable-sized modes must provide their own definition |
1889 | of this hook. */ | |
1890 | unsigned int size = GET_MODE_SIZE (mode).to_constant (); | |
1891 | return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | |
d3ba22dc | 1892 | #endif |
1893 | } | |
1894 | ||
cc7d6aed | 1895 | /* Determine the debugging unwind mechanism for the target. */ |
1896 | ||
1897 | enum unwind_info_type | |
1898 | default_debug_unwind_info (void) | |
1899 | { | |
1900 | /* If the target wants to force the use of dwarf2 unwind info, let it. */ | |
1901 | /* ??? Change all users to the hook, then poison this. */ | |
1902 | #ifdef DWARF2_FRAME_INFO | |
1903 | if (DWARF2_FRAME_INFO) | |
1904 | return UI_DWARF2; | |
1905 | #endif | |
1906 | ||
1907 | /* Otherwise, only turn it on if dwarf2 debugging is enabled. */ | |
1908 | #ifdef DWARF2_DEBUGGING_INFO | |
1909 | if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) | |
1910 | return UI_DWARF2; | |
1911 | #endif | |
1912 | ||
1913 | return UI_NONE; | |
1914 | } | |
1915 | ||
de41115b | 1916 | /* Targets that set NUM_POLY_INT_COEFFS to something greater than 1 |
1917 | must define this hook. */ | |
1918 | ||
1919 | unsigned int | |
1920 | default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *) | |
1921 | { | |
1922 | gcc_unreachable (); | |
1923 | } | |
1924 | ||
d626297e | 1925 | /* Determine the correct mode for a Dwarf frame register that represents |
1926 | register REGNO. */ | |
1927 | ||
3754d046 | 1928 | machine_mode |
d626297e | 1929 | default_dwarf_frame_reg_mode (int regno) |
1930 | { | |
3754d046 | 1931 | machine_mode save_mode = reg_raw_mode[regno]; |
d626297e | 1932 | |
5c62f29a | 1933 | if (targetm.hard_regno_call_part_clobbered (NULL, regno, save_mode)) |
d626297e | 1934 | save_mode = choose_hard_reg_mode (regno, 1, true); |
1935 | return save_mode; | |
1936 | } | |
1937 | ||
4bac51c9 | 1938 | /* To be used by targets where reg_raw_mode doesn't return the right |
1939 | mode for registers used in apply_builtin_return and apply_builtin_arg. */ | |
1940 | ||
d2401312 | 1941 | fixed_size_mode |
9af5ce0c | 1942 | default_get_reg_raw_mode (int regno) |
4bac51c9 | 1943 | { |
d2401312 | 1944 | /* Targets must override this hook if the underlying register is |
1945 | variable-sized. */ | |
1946 | return as_a <fixed_size_mode> (reg_raw_mode[regno]); | |
4bac51c9 | 1947 | } |
1948 | ||
d44f2f7c | 1949 | /* Return true if a leaf function should stay leaf even with profiling |
1950 | enabled. */ | |
1951 | ||
1952 | bool | |
1953 | default_keep_leaf_when_profiled () | |
1954 | { | |
1955 | return false; | |
1956 | } | |
1957 | ||
0e763b2a | 1958 | /* Return true if the state of option OPTION should be stored in PCH files |
1959 | and checked by default_pch_valid_p. Store the option's current state | |
1960 | in STATE if so. */ | |
1961 | ||
1962 | static inline bool | |
1963 | option_affects_pch_p (int option, struct cl_option_state *state) | |
1964 | { | |
1965 | if ((cl_options[option].flags & CL_TARGET) == 0) | |
1966 | return false; | |
d8f2baf5 | 1967 | if ((cl_options[option].flags & CL_PCH_IGNORE) != 0) |
1968 | return false; | |
0e763b2a | 1969 | if (option_flag_var (option, &global_options) == &target_flags) |
1970 | if (targetm.check_pch_target_flags) | |
1971 | return false; | |
1972 | return get_option_state (&global_options, option, state); | |
1973 | } | |
1974 | ||
1975 | /* Default version of get_pch_validity. | |
1976 | By default, every flag difference is fatal; that will be mostly right for | |
1977 | most targets, but completely right for very few. */ | |
1978 | ||
1979 | void * | |
1980 | default_get_pch_validity (size_t *sz) | |
1981 | { | |
1982 | struct cl_option_state state; | |
1983 | size_t i; | |
1984 | char *result, *r; | |
1985 | ||
1986 | *sz = 2; | |
1987 | if (targetm.check_pch_target_flags) | |
1988 | *sz += sizeof (target_flags); | |
1989 | for (i = 0; i < cl_options_count; i++) | |
1990 | if (option_affects_pch_p (i, &state)) | |
1991 | *sz += state.size; | |
1992 | ||
1993 | result = r = XNEWVEC (char, *sz); | |
1994 | r[0] = flag_pic; | |
1995 | r[1] = flag_pie; | |
1996 | r += 2; | |
1997 | if (targetm.check_pch_target_flags) | |
1998 | { | |
1999 | memcpy (r, &target_flags, sizeof (target_flags)); | |
2000 | r += sizeof (target_flags); | |
2001 | } | |
2002 | ||
2003 | for (i = 0; i < cl_options_count; i++) | |
2004 | if (option_affects_pch_p (i, &state)) | |
2005 | { | |
2006 | memcpy (r, state.data, state.size); | |
2007 | r += state.size; | |
2008 | } | |
2009 | ||
2010 | return result; | |
2011 | } | |
2012 | ||
2013 | /* Return a message which says that a PCH file was created with a different | |
2014 | setting of OPTION. */ | |
2015 | ||
2016 | static const char * | |
2017 | pch_option_mismatch (const char *option) | |
2018 | { | |
5e9ac72e | 2019 | return xasprintf (_("created and used with differing settings of '%s'"), |
2020 | option); | |
0e763b2a | 2021 | } |
2022 | ||
2023 | /* Default version of pch_valid_p. */ | |
2024 | ||
2025 | const char * | |
2026 | default_pch_valid_p (const void *data_p, size_t len) | |
2027 | { | |
2028 | struct cl_option_state state; | |
2029 | const char *data = (const char *)data_p; | |
2030 | size_t i; | |
2031 | ||
2032 | /* -fpic and -fpie also usually make a PCH invalid. */ | |
2033 | if (data[0] != flag_pic) | |
2f6d557f | 2034 | return _("created and used with different settings of %<-fpic%>"); |
0e763b2a | 2035 | if (data[1] != flag_pie) |
2f6d557f | 2036 | return _("created and used with different settings of %<-fpie%>"); |
0e763b2a | 2037 | data += 2; |
2038 | ||
2039 | /* Check target_flags. */ | |
2040 | if (targetm.check_pch_target_flags) | |
2041 | { | |
2042 | int tf; | |
2043 | const char *r; | |
2044 | ||
2045 | memcpy (&tf, data, sizeof (target_flags)); | |
2046 | data += sizeof (target_flags); | |
2047 | len -= sizeof (target_flags); | |
2048 | r = targetm.check_pch_target_flags (tf); | |
2049 | if (r != NULL) | |
2050 | return r; | |
2051 | } | |
2052 | ||
2053 | for (i = 0; i < cl_options_count; i++) | |
2054 | if (option_affects_pch_p (i, &state)) | |
2055 | { | |
2056 | if (memcmp (data, state.data, state.size) != 0) | |
2057 | return pch_option_mismatch (cl_options[i].opt_text); | |
2058 | data += state.size; | |
2059 | len -= state.size; | |
2060 | } | |
2061 | ||
2062 | return NULL; | |
2063 | } | |
2064 | ||
17f446a0 | 2065 | /* Default version of cstore_mode. */ |
2066 | ||
7cae74a7 | 2067 | scalar_int_mode |
17f446a0 | 2068 | default_cstore_mode (enum insn_code icode) |
2069 | { | |
7cae74a7 | 2070 | return as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode); |
17f446a0 | 2071 | } |
2072 | ||
f91ed644 | 2073 | /* Default version of member_type_forces_blk. */ |
2074 | ||
2075 | bool | |
3754d046 | 2076 | default_member_type_forces_blk (const_tree, machine_mode) |
f91ed644 | 2077 | { |
2078 | return false; | |
2079 | } | |
2080 | ||
058a1b7a | 2081 | rtx |
2082 | default_load_bounds_for_arg (rtx addr ATTRIBUTE_UNUSED, | |
2083 | rtx ptr ATTRIBUTE_UNUSED, | |
2084 | rtx bnd ATTRIBUTE_UNUSED) | |
2085 | { | |
2086 | gcc_unreachable (); | |
2087 | } | |
2088 | ||
2089 | void | |
2090 | default_store_bounds_for_arg (rtx val ATTRIBUTE_UNUSED, | |
2091 | rtx addr ATTRIBUTE_UNUSED, | |
2092 | rtx bounds ATTRIBUTE_UNUSED, | |
2093 | rtx to ATTRIBUTE_UNUSED) | |
2094 | { | |
2095 | gcc_unreachable (); | |
2096 | } | |
2097 | ||
2098 | rtx | |
2099 | default_load_returned_bounds (rtx slot ATTRIBUTE_UNUSED) | |
2100 | { | |
2101 | gcc_unreachable (); | |
2102 | } | |
2103 | ||
2104 | void | |
2105 | default_store_returned_bounds (rtx slot ATTRIBUTE_UNUSED, | |
2106 | rtx bounds ATTRIBUTE_UNUSED) | |
2107 | { | |
2108 | gcc_unreachable (); | |
2109 | } | |
2110 | ||
b7740973 | 2111 | /* Default version of canonicalize_comparison. */ |
2112 | ||
2113 | void | |
2114 | default_canonicalize_comparison (int *, rtx *, rtx *, bool) | |
2115 | { | |
2116 | } | |
2117 | ||
b560fabd | 2118 | /* Default implementation of TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */ |
2119 | ||
2120 | void | |
2121 | default_atomic_assign_expand_fenv (tree *, tree *, tree *) | |
2122 | { | |
2123 | } | |
2124 | ||
b94f16f4 | 2125 | #ifndef PAD_VARARGS_DOWN |
2126 | #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN | |
2127 | #endif | |
2128 | ||
2129 | /* Build an indirect-ref expression over the given TREE, which represents a | |
2130 | piece of a va_arg() expansion. */ | |
2131 | tree | |
2132 | build_va_arg_indirect_ref (tree addr) | |
2133 | { | |
2134 | addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr); | |
b94f16f4 | 2135 | return addr; |
2136 | } | |
2137 | ||
2138 | /* The "standard" implementation of va_arg: read the value from the | |
2139 | current (padded) address and increment by the (padded) size. */ | |
2140 | ||
2141 | tree | |
2142 | std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, | |
2143 | gimple_seq *post_p) | |
2144 | { | |
2145 | tree addr, t, type_size, rounded_size, valist_tmp; | |
2146 | unsigned HOST_WIDE_INT align, boundary; | |
2147 | bool indirect; | |
2148 | ||
b94f16f4 | 2149 | /* All of the alignment and movement below is for args-grow-up machines. |
2150 | As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all | |
2151 | implement their own specialized gimplify_va_arg_expr routines. */ | |
ccccd62c | 2152 | if (ARGS_GROW_DOWNWARD) |
2153 | gcc_unreachable (); | |
b94f16f4 | 2154 | |
2155 | indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false); | |
2156 | if (indirect) | |
2157 | type = build_pointer_type (type); | |
2158 | ||
aca107a7 | 2159 | if (targetm.calls.split_complex_arg |
2160 | && TREE_CODE (type) == COMPLEX_TYPE | |
2161 | && targetm.calls.split_complex_arg (type)) | |
2162 | { | |
2163 | tree real_part, imag_part; | |
2164 | ||
2165 | real_part = std_gimplify_va_arg_expr (valist, | |
2166 | TREE_TYPE (type), pre_p, NULL); | |
2167 | real_part = get_initialized_tmp_var (real_part, pre_p, NULL); | |
2168 | ||
2169 | imag_part = std_gimplify_va_arg_expr (unshare_expr (valist), | |
2170 | TREE_TYPE (type), pre_p, NULL); | |
2171 | imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL); | |
2172 | ||
2173 | return build2 (COMPLEX_EXPR, type, real_part, imag_part); | |
2174 | } | |
2175 | ||
b94f16f4 | 2176 | align = PARM_BOUNDARY / BITS_PER_UNIT; |
2177 | boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type); | |
2178 | ||
2179 | /* When we align parameter on stack for caller, if the parameter | |
2180 | alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be | |
2181 | aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee | |
2182 | here with caller. */ | |
2183 | if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) | |
2184 | boundary = MAX_SUPPORTED_STACK_ALIGNMENT; | |
2185 | ||
2186 | boundary /= BITS_PER_UNIT; | |
2187 | ||
2188 | /* Hoist the valist value into a temporary for the moment. */ | |
2189 | valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); | |
2190 | ||
2191 | /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually | |
2192 | requires greater alignment, we must perform dynamic alignment. */ | |
2193 | if (boundary > align | |
532d84ff | 2194 | && !TYPE_EMPTY_P (type) |
b94f16f4 | 2195 | && !integer_zerop (TYPE_SIZE (type))) |
2196 | { | |
2197 | t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, | |
2198 | fold_build_pointer_plus_hwi (valist_tmp, boundary - 1)); | |
2199 | gimplify_and_add (t, pre_p); | |
2200 | ||
2201 | t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, | |
2202 | fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist), | |
2203 | valist_tmp, | |
2204 | build_int_cst (TREE_TYPE (valist), -boundary))); | |
2205 | gimplify_and_add (t, pre_p); | |
2206 | } | |
2207 | else | |
2208 | boundary = align; | |
2209 | ||
2210 | /* If the actual alignment is less than the alignment of the type, | |
2211 | adjust the type accordingly so that we don't assume strict alignment | |
2212 | when dereferencing the pointer. */ | |
2213 | boundary *= BITS_PER_UNIT; | |
2214 | if (boundary < TYPE_ALIGN (type)) | |
2215 | { | |
2216 | type = build_variant_type_copy (type); | |
5d4b30ea | 2217 | SET_TYPE_ALIGN (type, boundary); |
b94f16f4 | 2218 | } |
2219 | ||
2220 | /* Compute the rounded size of the type. */ | |
532d84ff | 2221 | type_size = arg_size_in_bytes (type); |
b94f16f4 | 2222 | rounded_size = round_up (type_size, align); |
2223 | ||
2224 | /* Reduce rounded_size so it's sharable with the postqueue. */ | |
2225 | gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); | |
2226 | ||
2227 | /* Get AP. */ | |
2228 | addr = valist_tmp; | |
2229 | if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size)) | |
2230 | { | |
2231 | /* Small args are padded downward. */ | |
2232 | t = fold_build2_loc (input_location, GT_EXPR, sizetype, | |
2233 | rounded_size, size_int (align)); | |
2234 | t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node, | |
2235 | size_binop (MINUS_EXPR, rounded_size, type_size)); | |
2236 | addr = fold_build_pointer_plus (addr, t); | |
2237 | } | |
2238 | ||
2239 | /* Compute new value for AP. */ | |
2240 | t = fold_build_pointer_plus (valist_tmp, rounded_size); | |
2241 | t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); | |
2242 | gimplify_and_add (t, pre_p); | |
2243 | ||
2244 | addr = fold_convert (build_pointer_type (type), addr); | |
2245 | ||
2246 | if (indirect) | |
2247 | addr = build_va_arg_indirect_ref (addr); | |
2248 | ||
2249 | return build_va_arg_indirect_ref (addr); | |
2250 | } | |
2251 | ||
058a1b7a | 2252 | void |
2253 | default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, | |
582adad1 | 2254 | machine_mode mode ATTRIBUTE_UNUSED, |
058a1b7a | 2255 | tree type ATTRIBUTE_UNUSED, |
2256 | int *pretend_arg_size ATTRIBUTE_UNUSED, | |
2257 | int second_time ATTRIBUTE_UNUSED) | |
2258 | { | |
2259 | } | |
2260 | ||
5f35dd0e | 2261 | /* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do |
2262 | not support nested low-overhead loops. */ | |
2263 | ||
2264 | bool | |
55af3bae | 2265 | can_use_doloop_if_innermost (const widest_int &, const widest_int &, |
5f35dd0e | 2266 | unsigned int loop_depth, bool) |
2267 | { | |
2268 | return loop_depth == 1; | |
2269 | } | |
b94f16f4 | 2270 | |
acdfe9e0 | 2271 | /* Default implementation of TARGET_OPTAB_SUPPORTED_P. */ |
2272 | ||
2273 | bool | |
2274 | default_optab_supported_p (int, machine_mode, machine_mode, optimization_type) | |
2275 | { | |
2276 | return true; | |
2277 | } | |
2278 | ||
1019399a | 2279 | /* Default implementation of TARGET_MAX_NOCE_IFCVT_SEQ_COST. */ |
2280 | ||
2281 | unsigned int | |
2282 | default_max_noce_ifcvt_seq_cost (edge e) | |
2283 | { | |
2284 | bool predictable_p = predictable_edge_p (e); | |
2285 | ||
2286 | enum compiler_param param | |
2287 | = (predictable_p | |
2288 | ? PARAM_MAX_RTL_IF_CONVERSION_PREDICTABLE_COST | |
2289 | : PARAM_MAX_RTL_IF_CONVERSION_UNPREDICTABLE_COST); | |
2290 | ||
2291 | /* If we have a parameter set, use that, otherwise take a guess using | |
2292 | BRANCH_COST. */ | |
2293 | if (global_options_set.x_param_values[param]) | |
2294 | return PARAM_VALUE (param); | |
2295 | else | |
2296 | return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3); | |
2297 | } | |
2298 | ||
97574c57 | 2299 | /* Default implementation of TARGET_MIN_ARITHMETIC_PRECISION. */ |
2300 | ||
2301 | unsigned int | |
2302 | default_min_arithmetic_precision (void) | |
2303 | { | |
2304 | return WORD_REGISTER_OPERATIONS ? BITS_PER_WORD : BITS_PER_UNIT; | |
2305 | } | |
2306 | ||
069d39e6 | 2307 | /* Default implementation of TARGET_C_EXCESS_PRECISION. */ |
2308 | ||
2309 | enum flt_eval_method | |
2310 | default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED) | |
2311 | { | |
2312 | return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT; | |
2313 | } | |
2314 | ||
6b2ca3ef | 2315 | /* Default implementation for |
2316 | TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE. */ | |
2317 | HOST_WIDE_INT | |
2318 | default_stack_clash_protection_alloca_probe_range (void) | |
f21f2061 | 2319 | { |
2320 | return 0; | |
2321 | } | |
2322 | ||
62958b22 | 2323 | /* The default implementation of TARGET_EARLY_REMAT_MODES. */ |
2324 | ||
2325 | void | |
2326 | default_select_early_remat_modes (sbitmap) | |
2327 | { | |
2328 | } | |
2329 | ||
d8483dd1 | 2330 | /* The default implementation of TARGET_PREFERRED_ELSE_VALUE. */ |
2331 | ||
2332 | tree | |
2333 | default_preferred_else_value (unsigned, tree type, unsigned, tree *) | |
2334 | { | |
2335 | return build_zero_cst (type); | |
2336 | } | |
2337 | ||
123081ef | 2338 | /* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */ |
2339 | bool | |
30929ff6 | 2340 | default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED) |
123081ef | 2341 | { |
2342 | #ifdef HAVE_speculation_barrier | |
2343 | return active ? HAVE_speculation_barrier : true; | |
2344 | #else | |
2345 | return false; | |
2346 | #endif | |
2347 | } | |
3e3448a9 | 2348 | /* Alternative implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE |
2349 | that can be used on targets that never have speculative execution. */ | |
2350 | bool | |
2351 | speculation_safe_value_not_needed (bool active) | |
2352 | { | |
2353 | return !active; | |
2354 | } | |
123081ef | 2355 | |
2356 | /* Default implementation of the speculation-safe-load builtin. This | |
2357 | implementation simply copies val to result and generates a | |
2358 | speculation_barrier insn, if such a pattern is defined. */ | |
2359 | rtx | |
2360 | default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED, | |
2361 | rtx result, rtx val, | |
2362 | rtx failval ATTRIBUTE_UNUSED) | |
2363 | { | |
2364 | emit_move_insn (result, val); | |
2365 | ||
2366 | #ifdef HAVE_speculation_barrier | |
2367 | /* Assume the target knows what it is doing: if it defines a | |
2368 | speculation barrier, but it is not enabled, then assume that one | |
2369 | isn't needed. */ | |
2370 | if (HAVE_speculation_barrier) | |
2371 | emit_insn (gen_speculation_barrier ()); | |
2372 | #endif | |
2373 | ||
2374 | return result; | |
2375 | } | |
2376 | ||
76855875 | 2377 | void |
2378 | default_remove_extra_call_preserved_regs (rtx_insn *, HARD_REG_SET *) | |
2379 | { | |
2380 | } | |
2381 | ||
f1a0edff | 2382 | #include "gt-targhooks.h" |