]>
Commit | Line | Data |
---|---|---|
61f71b34 | 1 | /* Default target hook functions. |
9b580a0b | 2 | Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. |
61f71b34 DD |
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 | |
9dcd6f09 | 8 | Software Foundation; either version 3, or (at your option) any later |
61f71b34 DD |
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 | |
9dcd6f09 NC |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
61f71b34 | 19 | |
dd37c5a0 DD |
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 | ||
61f71b34 DD |
49 | #include "config.h" |
50 | #include "system.h" | |
51 | #include "coretypes.h" | |
52 | #include "tm.h" | |
53 | #include "machmode.h" | |
54 | #include "rtl.h" | |
55 | #include "tree.h" | |
56 | #include "expr.h" | |
d84a4ef1 | 57 | #include "output.h" |
61f71b34 DD |
58 | #include "toplev.h" |
59 | #include "function.h" | |
60 | #include "target.h" | |
61 | #include "tm_p.h" | |
62 | #include "target-def.h" | |
7d69de61 | 63 | #include "ggc.h" |
150cdc9e | 64 | #include "hard-reg-set.h" |
8a99f6f9 R |
65 | #include "reload.h" |
66 | #include "optabs.h" | |
67 | #include "recog.h" | |
61f71b34 | 68 | |
6dd53648 | 69 | |
6773a41c RO |
70 | void |
71 | default_external_libcall (rtx fun ATTRIBUTE_UNUSED) | |
72 | { | |
73 | #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL | |
74 | ASM_OUTPUT_EXTERNAL_LIBCALL(asm_out_file, fun); | |
75 | #endif | |
76 | } | |
77 | ||
e129d93a ILT |
78 | enum machine_mode |
79 | default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2) | |
80 | { | |
81 | if (m1 == m2) | |
82 | return m1; | |
83 | return VOIDmode; | |
84 | } | |
85 | ||
61f71b34 | 86 | bool |
586de218 KG |
87 | default_return_in_memory (const_tree type, |
88 | const_tree fntype ATTRIBUTE_UNUSED) | |
61f71b34 | 89 | { |
be6acd4b | 90 | #ifndef RETURN_IN_MEMORY |
33d05111 | 91 | return (TYPE_MODE (type) == BLKmode); |
be6acd4b EC |
92 | #else |
93 | return RETURN_IN_MEMORY (type); | |
94 | #endif | |
61f71b34 DD |
95 | } |
96 | ||
97 | rtx | |
98 | default_expand_builtin_saveregs (void) | |
99 | { | |
61f71b34 DD |
100 | error ("__builtin_saveregs not supported by this target"); |
101 | return const0_rtx; | |
61f71b34 DD |
102 | } |
103 | ||
104 | void | |
105 | default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | |
106 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
107 | tree type ATTRIBUTE_UNUSED, | |
108 | int *pretend_arg_size ATTRIBUTE_UNUSED, | |
109 | int second_time ATTRIBUTE_UNUSED) | |
110 | { | |
61f71b34 DD |
111 | } |
112 | ||
d6da68b9 KH |
113 | /* The default implementation of TARGET_BUILTIN_SETJMP_FRAME_VALUE. */ |
114 | ||
115 | rtx | |
116 | default_builtin_setjmp_frame_value (void) | |
117 | { | |
118 | return virtual_stack_vars_rtx; | |
119 | } | |
120 | ||
3a4d587b | 121 | /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ |
8dfa8fcd | 122 | |
61f71b34 | 123 | bool |
8dfa8fcd | 124 | hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) |
61f71b34 | 125 | { |
b602b7b6 | 126 | return false; |
61f71b34 DD |
127 | } |
128 | ||
129 | bool | |
3a4d587b | 130 | default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) |
61f71b34 | 131 | { |
3a4d587b AM |
132 | return (targetm.calls.setup_incoming_varargs |
133 | != default_setup_incoming_varargs); | |
61f71b34 | 134 | } |
c6e8c921 | 135 | |
a1c496cb | 136 | enum machine_mode |
93f90be6 FJ |
137 | default_eh_return_filter_mode (void) |
138 | { | |
139 | return word_mode; | |
140 | } | |
141 | ||
c7ff6e7a AK |
142 | enum machine_mode |
143 | default_libgcc_cmp_return_mode (void) | |
144 | { | |
145 | return word_mode; | |
146 | } | |
147 | ||
148 | enum machine_mode | |
149 | default_libgcc_shift_count_mode (void) | |
150 | { | |
151 | return word_mode; | |
152 | } | |
153 | ||
273a2526 RS |
154 | /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */ |
155 | ||
156 | unsigned HOST_WIDE_INT | |
157 | default_shift_truncation_mask (enum machine_mode mode) | |
158 | { | |
159 | return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0; | |
160 | } | |
161 | ||
bc23502b PB |
162 | /* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. */ |
163 | ||
164 | unsigned int | |
165 | default_min_divisions_for_recip_mul (enum machine_mode mode ATTRIBUTE_UNUSED) | |
166 | { | |
167 | return have_insn_for (DIV, mode) ? 3 : 2; | |
168 | } | |
169 | ||
b12cbf2c AN |
170 | /* The default implementation of TARGET_MODE_REP_EXTENDED. */ |
171 | ||
172 | int | |
173 | default_mode_rep_extended (enum machine_mode mode ATTRIBUTE_UNUSED, | |
174 | enum machine_mode mode_rep ATTRIBUTE_UNUSED) | |
175 | { | |
176 | return UNKNOWN; | |
177 | } | |
178 | ||
c6e8c921 | 179 | /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ |
0938c9e8 | 180 | |
c6e8c921 GK |
181 | bool |
182 | hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED) | |
183 | { | |
184 | return true; | |
185 | } | |
4185ae53 | 186 | |
c77cd3d1 UB |
187 | /* Return machine mode for non-standard suffix |
188 | or VOIDmode if non-standard suffixes are unsupported. */ | |
189 | enum machine_mode | |
190 | default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED) | |
191 | { | |
192 | return VOIDmode; | |
193 | } | |
4185ae53 PB |
194 | |
195 | /* The generic C++ ABI specifies this is a 64-bit value. */ | |
196 | tree | |
197 | default_cxx_guard_type (void) | |
198 | { | |
199 | return long_long_integer_type_node; | |
200 | } | |
46e995e0 PB |
201 | |
202 | ||
203 | /* Returns the size of the cookie to use when allocating an array | |
204 | whose elements have the indicated TYPE. Assumes that it is already | |
205 | known that a cookie is needed. */ | |
206 | ||
207 | tree | |
208 | default_cxx_get_cookie_size (tree type) | |
209 | { | |
210 | tree cookie_size; | |
211 | ||
212 | /* We need to allocate an additional max (sizeof (size_t), alignof | |
213 | (true_type)) bytes. */ | |
214 | tree sizetype_size; | |
215 | tree type_align; | |
a1c496cb | 216 | |
46e995e0 PB |
217 | sizetype_size = size_in_bytes (sizetype); |
218 | type_align = size_int (TYPE_ALIGN_UNIT (type)); | |
219 | if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) | |
220 | cookie_size = sizetype_size; | |
221 | else | |
222 | cookie_size = type_align; | |
223 | ||
224 | return cookie_size; | |
225 | } | |
8cd5a4e0 | 226 | |
8cd5a4e0 RH |
227 | /* Return true if a parameter must be passed by reference. This version |
228 | of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ | |
229 | ||
230 | bool | |
231 | hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, | |
586de218 | 232 | enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, |
8cd5a4e0 RH |
233 | bool named_arg ATTRIBUTE_UNUSED) |
234 | { | |
235 | return targetm.calls.must_pass_in_stack (mode, type); | |
236 | } | |
951120ea | 237 | |
6cdd5672 RH |
238 | /* Return true if a parameter follows callee copies conventions. This |
239 | version of the hook is true for all named arguments. */ | |
240 | ||
241 | bool | |
242 | hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | |
243 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
586de218 | 244 | const_tree type ATTRIBUTE_UNUSED, bool named) |
6cdd5672 RH |
245 | { |
246 | return named; | |
247 | } | |
951120ea PB |
248 | |
249 | /* Emit any directives required to unwind this instruction. */ | |
250 | ||
251 | void | |
252 | default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED, | |
253 | rtx insn ATTRIBUTE_UNUSED) | |
254 | { | |
255 | /* Should never happen. */ | |
1e128c5f | 256 | gcc_unreachable (); |
951120ea | 257 | } |
6dd53648 RH |
258 | |
259 | /* True if MODE is valid for the target. By "valid", we mean able to | |
260 | be manipulated in non-trivial ways. In particular, this means all | |
261 | the arithmetic is supported. | |
262 | ||
263 | By default we guess this means that any C type is supported. If | |
264 | we can't map the mode back to a type that would be available in C, | |
265 | then reject it. Special case, here, is the double-word arithmetic | |
266 | supported by optabs.c. */ | |
267 | ||
268 | bool | |
269 | default_scalar_mode_supported_p (enum machine_mode mode) | |
270 | { | |
271 | int precision = GET_MODE_PRECISION (mode); | |
272 | ||
273 | switch (GET_MODE_CLASS (mode)) | |
274 | { | |
275 | case MODE_PARTIAL_INT: | |
276 | case MODE_INT: | |
277 | if (precision == CHAR_TYPE_SIZE) | |
278 | return true; | |
279 | if (precision == SHORT_TYPE_SIZE) | |
280 | return true; | |
281 | if (precision == INT_TYPE_SIZE) | |
282 | return true; | |
283 | if (precision == LONG_TYPE_SIZE) | |
284 | return true; | |
285 | if (precision == LONG_LONG_TYPE_SIZE) | |
286 | return true; | |
287 | if (precision == 2 * BITS_PER_WORD) | |
288 | return true; | |
289 | return false; | |
290 | ||
291 | case MODE_FLOAT: | |
292 | if (precision == FLOAT_TYPE_SIZE) | |
293 | return true; | |
294 | if (precision == DOUBLE_TYPE_SIZE) | |
295 | return true; | |
296 | if (precision == LONG_DOUBLE_TYPE_SIZE) | |
297 | return true; | |
298 | return false; | |
299 | ||
9a8ce21f | 300 | case MODE_DECIMAL_FLOAT: |
ab22c1fa CF |
301 | case MODE_FRACT: |
302 | case MODE_UFRACT: | |
303 | case MODE_ACCUM: | |
304 | case MODE_UACCUM: | |
9a8ce21f JG |
305 | return false; |
306 | ||
6dd53648 | 307 | default: |
1e128c5f | 308 | gcc_unreachable (); |
6dd53648 RH |
309 | } |
310 | } | |
6cdd5672 | 311 | |
0884546e BE |
312 | /* True if the target supports decimal floating point. */ |
313 | ||
314 | bool | |
315 | default_decimal_float_supported_p (void) | |
316 | { | |
317 | return ENABLE_DECIMAL_FLOAT; | |
318 | } | |
319 | ||
ab22c1fa CF |
320 | /* True if the target supports fixed-point arithmetic. */ |
321 | ||
322 | bool | |
323 | default_fixed_point_supported_p (void) | |
324 | { | |
325 | return ENABLE_FIXED_POINT; | |
326 | } | |
327 | ||
e7e64a25 AS |
328 | /* NULL if INSN insn is valid within a low-overhead loop, otherwise returns |
329 | an error message. | |
a71a498d | 330 | |
0fa2e4df | 331 | This function checks whether a given INSN is valid within a low-overhead |
e7e64a25 AS |
332 | loop. If INSN is invalid it returns the reason for that, otherwise it |
333 | returns NULL. A called function may clobber any special registers required | |
334 | for low-overhead looping. Additionally, some targets (eg, PPC) use the count | |
a71a498d AS |
335 | register for branch on table instructions. We reject the doloop pattern in |
336 | these cases. */ | |
337 | ||
e7e64a25 AS |
338 | const char * |
339 | default_invalid_within_doloop (rtx insn) | |
a71a498d AS |
340 | { |
341 | if (CALL_P (insn)) | |
e7e64a25 | 342 | return "Function call in loop."; |
a71a498d AS |
343 | |
344 | if (JUMP_P (insn) | |
345 | && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC | |
346 | || GET_CODE (PATTERN (insn)) == ADDR_VEC)) | |
e7e64a25 | 347 | return "Computed branch in the loop."; |
a71a498d | 348 | |
e7e64a25 | 349 | return NULL; |
a71a498d AS |
350 | } |
351 | ||
2505a3f2 RG |
352 | /* Mapping of builtin functions to vectorized variants. */ |
353 | ||
354 | tree | |
355 | default_builtin_vectorized_function (enum built_in_function fn ATTRIBUTE_UNUSED, | |
b95becfc RG |
356 | tree type_out ATTRIBUTE_UNUSED, |
357 | tree type_in ATTRIBUTE_UNUSED) | |
2505a3f2 RG |
358 | { |
359 | return NULL_TREE; | |
360 | } | |
361 | ||
f57d17f1 TM |
362 | /* Vectorized conversion. */ |
363 | ||
364 | tree | |
365 | default_builtin_vectorized_conversion (enum tree_code code ATTRIBUTE_UNUSED, | |
366 | tree type ATTRIBUTE_UNUSED) | |
367 | { | |
368 | return NULL_TREE; | |
369 | } | |
370 | ||
cc2137be UB |
371 | /* Reciprocal. */ |
372 | ||
373 | tree | |
374 | default_builtin_reciprocal (enum built_in_function fn ATTRIBUTE_UNUSED, | |
ac10986f | 375 | bool md_fn ATTRIBUTE_UNUSED, |
cc2137be UB |
376 | bool sqrt ATTRIBUTE_UNUSED) |
377 | { | |
378 | return NULL_TREE; | |
379 | } | |
380 | ||
6cdd5672 RH |
381 | bool |
382 | hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( | |
383 | CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | |
384 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
586de218 | 385 | const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) |
6cdd5672 RH |
386 | { |
387 | return false; | |
388 | } | |
389 | ||
390 | bool | |
391 | hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( | |
392 | CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | |
393 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
586de218 | 394 | const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) |
6cdd5672 RH |
395 | { |
396 | return true; | |
397 | } | |
78a52f11 RH |
398 | |
399 | int | |
400 | hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( | |
401 | CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | |
402 | enum machine_mode mode ATTRIBUTE_UNUSED, | |
403 | tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) | |
404 | { | |
405 | return 0; | |
406 | } | |
4d3e6fae | 407 | |
912f2dac DB |
408 | void |
409 | hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) | |
410 | { | |
411 | } | |
412 | ||
4d3e6fae FJ |
413 | const char * |
414 | hook_invalid_arg_for_unprototyped_fn ( | |
415 | tree typelist ATTRIBUTE_UNUSED, | |
416 | tree funcdecl ATTRIBUTE_UNUSED, | |
417 | tree val ATTRIBUTE_UNUSED) | |
418 | { | |
419 | return NULL; | |
420 | } | |
7d69de61 RH |
421 | |
422 | /* Initialize the stack protection decls. */ | |
423 | ||
424 | /* Stack protection related decls living in libgcc. */ | |
425 | static GTY(()) tree stack_chk_guard_decl; | |
426 | ||
427 | tree | |
428 | default_stack_protect_guard (void) | |
429 | { | |
430 | tree t = stack_chk_guard_decl; | |
431 | ||
432 | if (t == NULL) | |
433 | { | |
434 | t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"), | |
435 | ptr_type_node); | |
436 | TREE_STATIC (t) = 1; | |
437 | TREE_PUBLIC (t) = 1; | |
438 | DECL_EXTERNAL (t) = 1; | |
439 | TREE_USED (t) = 1; | |
440 | TREE_THIS_VOLATILE (t) = 1; | |
441 | DECL_ARTIFICIAL (t) = 1; | |
442 | DECL_IGNORED_P (t) = 1; | |
443 | ||
444 | stack_chk_guard_decl = t; | |
445 | } | |
446 | ||
447 | return t; | |
448 | } | |
449 | ||
450 | static GTY(()) tree stack_chk_fail_decl; | |
451 | ||
452 | tree | |
453 | default_external_stack_protect_fail (void) | |
454 | { | |
455 | tree t = stack_chk_fail_decl; | |
456 | ||
457 | if (t == NULL_TREE) | |
458 | { | |
459 | t = build_function_type_list (void_type_node, NULL_TREE); | |
460 | t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t); | |
461 | TREE_STATIC (t) = 1; | |
462 | TREE_PUBLIC (t) = 1; | |
463 | DECL_EXTERNAL (t) = 1; | |
464 | TREE_USED (t) = 1; | |
465 | TREE_THIS_VOLATILE (t) = 1; | |
466 | TREE_NOTHROW (t) = 1; | |
467 | DECL_ARTIFICIAL (t) = 1; | |
468 | DECL_IGNORED_P (t) = 1; | |
5b5cba1f JM |
469 | DECL_VISIBILITY (t) = VISIBILITY_DEFAULT; |
470 | DECL_VISIBILITY_SPECIFIED (t) = 1; | |
7d69de61 RH |
471 | |
472 | stack_chk_fail_decl = t; | |
473 | } | |
474 | ||
5039610b | 475 | return build_call_expr (t, 0); |
7d69de61 RH |
476 | } |
477 | ||
478 | tree | |
479 | default_hidden_stack_protect_fail (void) | |
480 | { | |
7ce918c5 JJ |
481 | #ifndef HAVE_GAS_HIDDEN |
482 | return default_external_stack_protect_fail (); | |
483 | #else | |
7d69de61 RH |
484 | tree t = stack_chk_fail_decl; |
485 | ||
7ce918c5 JJ |
486 | if (!flag_pic) |
487 | return default_external_stack_protect_fail (); | |
488 | ||
489 | if (t == NULL_TREE) | |
7d69de61 RH |
490 | { |
491 | t = build_function_type_list (void_type_node, NULL_TREE); | |
492 | t = build_decl (FUNCTION_DECL, | |
493 | get_identifier ("__stack_chk_fail_local"), t); | |
494 | TREE_STATIC (t) = 1; | |
495 | TREE_PUBLIC (t) = 1; | |
496 | DECL_EXTERNAL (t) = 1; | |
497 | TREE_USED (t) = 1; | |
498 | TREE_THIS_VOLATILE (t) = 1; | |
499 | TREE_NOTHROW (t) = 1; | |
500 | DECL_ARTIFICIAL (t) = 1; | |
501 | DECL_IGNORED_P (t) = 1; | |
502 | DECL_VISIBILITY_SPECIFIED (t) = 1; | |
503 | DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; | |
504 | ||
505 | stack_chk_fail_decl = t; | |
506 | } | |
507 | ||
5039610b | 508 | return build_call_expr (t, 0); |
7ce918c5 | 509 | #endif |
7d69de61 RH |
510 | } |
511 | ||
8ddf681a R |
512 | bool |
513 | hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED) | |
514 | { | |
515 | return COMMUTATIVE_P (x); | |
516 | } | |
517 | ||
1d636cc6 | 518 | rtx |
586de218 KG |
519 | default_function_value (const_tree ret_type ATTRIBUTE_UNUSED, |
520 | const_tree fn_decl_or_type, | |
1d636cc6 RG |
521 | bool outgoing ATTRIBUTE_UNUSED) |
522 | { | |
523 | /* The old interface doesn't handle receiving the function type. */ | |
524 | if (fn_decl_or_type | |
525 | && !DECL_P (fn_decl_or_type)) | |
526 | fn_decl_or_type = NULL; | |
527 | ||
528 | #ifdef FUNCTION_OUTGOING_VALUE | |
529 | if (outgoing) | |
530 | return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type); | |
531 | #endif | |
532 | ||
533 | #ifdef FUNCTION_VALUE | |
534 | return FUNCTION_VALUE (ret_type, fn_decl_or_type); | |
535 | #else | |
536 | return NULL_RTX; | |
537 | #endif | |
538 | } | |
539 | ||
150cdc9e RH |
540 | rtx |
541 | default_internal_arg_pointer (void) | |
542 | { | |
543 | /* If the reg that the virtual arg pointer will be translated into is | |
544 | not a fixed reg or is the stack pointer, make a copy of the virtual | |
545 | arg pointer, and address parms via the copy. The frame pointer is | |
546 | considered fixed even though it is not marked as such. */ | |
547 | if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM | |
548 | || ! (fixed_regs[ARG_POINTER_REGNUM] | |
549 | || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))) | |
550 | return copy_to_reg (virtual_incoming_args_rtx); | |
551 | else | |
552 | return virtual_incoming_args_rtx; | |
553 | } | |
554 | ||
8a99f6f9 R |
555 | enum reg_class |
556 | default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, | |
557 | enum reg_class reload_class ATTRIBUTE_UNUSED, | |
558 | enum machine_mode reload_mode ATTRIBUTE_UNUSED, | |
559 | secondary_reload_info *sri) | |
560 | { | |
561 | enum reg_class class = NO_REGS; | |
562 | ||
563 | if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) | |
564 | { | |
565 | sri->icode = sri->prev_sri->t_icode; | |
566 | return NO_REGS; | |
567 | } | |
568 | #ifdef SECONDARY_INPUT_RELOAD_CLASS | |
569 | if (in_p) | |
570 | class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x); | |
571 | #endif | |
572 | #ifdef SECONDARY_OUTPUT_RELOAD_CLASS | |
573 | if (! in_p) | |
574 | class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x); | |
575 | #endif | |
576 | if (class != NO_REGS) | |
577 | { | |
578 | enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode] | |
579 | : reload_out_optab[(int) reload_mode]); | |
580 | ||
581 | if (icode != CODE_FOR_nothing | |
582 | && insn_data[(int) icode].operand[in_p].predicate | |
583 | && ! insn_data[(int) icode].operand[in_p].predicate (x, reload_mode)) | |
584 | icode = CODE_FOR_nothing; | |
585 | else if (icode != CODE_FOR_nothing) | |
586 | { | |
587 | const char *insn_constraint, *scratch_constraint; | |
588 | char insn_letter, scratch_letter; | |
589 | enum reg_class insn_class, scratch_class; | |
590 | ||
591 | gcc_assert (insn_data[(int) icode].n_operands == 3); | |
592 | insn_constraint = insn_data[(int) icode].operand[!in_p].constraint; | |
593 | if (!*insn_constraint) | |
594 | insn_class = ALL_REGS; | |
595 | else | |
596 | { | |
597 | if (in_p) | |
598 | { | |
599 | gcc_assert (*insn_constraint == '='); | |
600 | insn_constraint++; | |
601 | } | |
602 | insn_letter = *insn_constraint; | |
603 | insn_class | |
604 | = (insn_letter == 'r' ? GENERAL_REGS | |
605 | : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter, | |
606 | insn_constraint)); | |
607 | gcc_assert (insn_class != NO_REGS); | |
608 | } | |
609 | ||
610 | scratch_constraint = insn_data[(int) icode].operand[2].constraint; | |
11e30dd8 HPN |
611 | /* The scratch register's constraint must start with "=&", |
612 | except for an input reload, where only "=" is necessary, | |
613 | and where it might be beneficial to re-use registers from | |
614 | the input. */ | |
8a99f6f9 | 615 | gcc_assert (scratch_constraint[0] == '=' |
11e30dd8 HPN |
616 | && (in_p || scratch_constraint[1] == '&')); |
617 | scratch_constraint++; | |
618 | if (*scratch_constraint == '&') | |
619 | scratch_constraint++; | |
8a99f6f9 R |
620 | scratch_letter = *scratch_constraint; |
621 | scratch_class | |
622 | = (scratch_letter == 'r' ? GENERAL_REGS | |
623 | : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, | |
624 | scratch_constraint)); | |
625 | ||
626 | if (reg_class_subset_p (reload_class, insn_class)) | |
627 | { | |
628 | gcc_assert (scratch_class == class); | |
629 | class = NO_REGS; | |
630 | } | |
631 | else | |
632 | class = insn_class; | |
633 | ||
634 | } | |
635 | if (class == NO_REGS) | |
636 | sri->icode = icode; | |
637 | else | |
638 | sri->t_icode = icode; | |
639 | } | |
640 | return class; | |
641 | } | |
642 | ||
1f1d5130 MS |
643 | bool |
644 | default_handle_c_option (size_t code ATTRIBUTE_UNUSED, | |
645 | const char *arg ATTRIBUTE_UNUSED, | |
646 | int value ATTRIBUTE_UNUSED) | |
647 | { | |
648 | return false; | |
649 | } | |
650 | ||
9b580a0b RH |
651 | /* By default, if flag_pic is true, then neither local nor global relocs |
652 | should be placed in readonly memory. */ | |
653 | ||
654 | int | |
655 | default_reloc_rw_mask (void) | |
656 | { | |
657 | return flag_pic ? 3 : 0; | |
658 | } | |
659 | ||
5234b8f5 DS |
660 | /* By default, do no modification. */ |
661 | tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED, | |
662 | tree id) | |
663 | { | |
664 | return id; | |
665 | } | |
666 | ||
5b900a4c DN |
667 | bool |
668 | default_builtin_vector_alignment_reachable (tree type, bool is_packed) | |
669 | { | |
670 | if (is_packed) | |
671 | return false; | |
672 | ||
673 | /* Assuming that types whose size is > pointer-size are not guaranteed to be | |
674 | naturally aligned. */ | |
675 | if (tree_int_cst_compare (TYPE_SIZE (type), bitsize_int (POINTER_SIZE)) > 0) | |
676 | return false; | |
677 | ||
678 | /* Assuming that types whose size is <= pointer-size | |
679 | are naturally aligned. */ | |
680 | return true; | |
681 | } | |
682 | ||
7d69de61 | 683 | #include "gt-targhooks.h" |