OSDN Git Service

PR c++/20293
[pf3gnuchains/gcc-fork.git] / gcc / targhooks.c
1 /* Default target hook functions.
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.  */
20
21 /* The migration of target macros to target hooks works as follows:
22
23    1. Create a target hook that uses the existing target macros to
24       implement the same functionality.
25
26    2. Convert all the MI files to use the hook instead of the macro.
27
28    3. Repeat for a majority of the remaining target macros.  This will
29       take some time.
30
31    4. Tell target maintainers to start migrating.
32
33    5. Eventually convert the backends to override the hook instead of
34       defining the macros.  This will take some time too.
35
36    6. TBD when, poison the macros.  Unmigrated targets will break at
37       this point.
38
39    Note that we expect steps 1-3 to be done by the people that
40    understand what the MI does with each macro, and step 5 to be done
41    by the target maintainers for their respective targets.
42
43    Note that steps 1 and 2 don't have to be done together, but no
44    target can override the new hook until step 2 is complete for it.
45
46    Once the macros are poisoned, we will revert to the old migration
47    rules - migrate the macro, callers, and targets all at once.  This
48    comment can thus be removed at that point.  */
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "machmode.h"
55 #include "rtl.h"
56 #include "tree.h"
57 #include "expr.h"
58 #include "output.h"
59 #include "toplev.h"
60 #include "function.h"
61 #include "target.h"
62 #include "tm_p.h"
63 #include "target-def.h"
64 #include "ggc.h"
65 #include "hard-reg-set.h"
66
67
68 void
69 default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
70 {
71 #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
72   ASM_OUTPUT_EXTERNAL_LIBCALL(asm_out_file, fun);
73 #endif
74 }
75
76 enum machine_mode
77 default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
78 {
79   if (m1 == m2)
80     return m1;
81   return VOIDmode;
82 }
83
84 bool
85 default_return_in_memory (tree type,
86                           tree fntype ATTRIBUTE_UNUSED)
87 {
88 #ifndef RETURN_IN_MEMORY
89   return (TYPE_MODE (type) == BLKmode);
90 #else
91   return RETURN_IN_MEMORY (type);
92 #endif
93 }
94
95 rtx
96 default_expand_builtin_saveregs (void)
97 {
98   error ("__builtin_saveregs not supported by this target");
99   return const0_rtx;
100 }
101
102 void
103 default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
104                                 enum machine_mode mode ATTRIBUTE_UNUSED,
105                                 tree type ATTRIBUTE_UNUSED,
106                                 int *pretend_arg_size ATTRIBUTE_UNUSED,
107                                 int second_time ATTRIBUTE_UNUSED)
108 {
109 }
110
111 /* The default implementation of TARGET_BUILTIN_SETJMP_FRAME_VALUE.  */
112
113 rtx
114 default_builtin_setjmp_frame_value (void)
115 {
116   return virtual_stack_vars_rtx;
117 }
118
119 /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false.  */
120
121 bool
122 hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
123 {
124   return false;
125 }
126
127 bool
128 default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
129 {
130   return (targetm.calls.setup_incoming_varargs
131           != default_setup_incoming_varargs);
132 }
133
134 enum machine_mode
135 default_eh_return_filter_mode (void)
136 {
137   return word_mode;
138 }
139
140 /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK.  */
141
142 unsigned HOST_WIDE_INT
143 default_shift_truncation_mask (enum machine_mode mode)
144 {
145   return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0;
146 }
147
148 /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true.  */
149
150 bool
151 hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
152 {
153   return true;
154 }
155
156
157 /* The generic C++ ABI specifies this is a 64-bit value.  */
158 tree
159 default_cxx_guard_type (void)
160 {
161   return long_long_integer_type_node;
162 }
163
164
165 /* Returns the size of the cookie to use when allocating an array
166    whose elements have the indicated TYPE.  Assumes that it is already
167    known that a cookie is needed.  */
168
169 tree
170 default_cxx_get_cookie_size (tree type)
171 {
172   tree cookie_size;
173
174   /* We need to allocate an additional max (sizeof (size_t), alignof
175      (true_type)) bytes.  */
176   tree sizetype_size;
177   tree type_align;
178
179   sizetype_size = size_in_bytes (sizetype);
180   type_align = size_int (TYPE_ALIGN_UNIT (type));
181   if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
182     cookie_size = sizetype_size;
183   else
184     cookie_size = type_align;
185
186   return cookie_size;
187 }
188
189 /* Return true if a parameter must be passed by reference.  This version
190    of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK.  */
191
192 bool
193 hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
194         enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED,
195         bool named_arg ATTRIBUTE_UNUSED)
196 {
197   return targetm.calls.must_pass_in_stack (mode, type);
198 }
199
200 /* Return true if a parameter follows callee copies conventions.  This
201    version of the hook is true for all named arguments.  */
202
203 bool
204 hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
205                           enum machine_mode mode ATTRIBUTE_UNUSED,
206                           tree type ATTRIBUTE_UNUSED, bool named)
207 {
208   return named;
209 }
210
211 /* Emit any directives required to unwind this instruction.  */
212
213 void
214 default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED,
215                      rtx insn ATTRIBUTE_UNUSED)
216 {
217   /* Should never happen.  */
218   gcc_unreachable ();
219 }
220
221 /* True if MODE is valid for the target.  By "valid", we mean able to
222    be manipulated in non-trivial ways.  In particular, this means all
223    the arithmetic is supported.
224
225    By default we guess this means that any C type is supported.  If
226    we can't map the mode back to a type that would be available in C,
227    then reject it.  Special case, here, is the double-word arithmetic
228    supported by optabs.c.  */
229
230 bool
231 default_scalar_mode_supported_p (enum machine_mode mode)
232 {
233   int precision = GET_MODE_PRECISION (mode);
234
235   switch (GET_MODE_CLASS (mode))
236     {
237     case MODE_PARTIAL_INT:
238     case MODE_INT:
239       if (precision == CHAR_TYPE_SIZE)
240         return true;
241       if (precision == SHORT_TYPE_SIZE)
242         return true;
243       if (precision == INT_TYPE_SIZE)
244         return true;
245       if (precision == LONG_TYPE_SIZE)
246         return true;
247       if (precision == LONG_LONG_TYPE_SIZE)
248         return true;
249       if (precision == 2 * BITS_PER_WORD)
250         return true;
251       return false;
252
253     case MODE_FLOAT:
254       if (precision == FLOAT_TYPE_SIZE)
255         return true;
256       if (precision == DOUBLE_TYPE_SIZE)
257         return true;
258       if (precision == LONG_DOUBLE_TYPE_SIZE)
259         return true;
260       return false;
261
262     default:
263       gcc_unreachable ();
264     }
265 }
266
267 /* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
268    an error message.
269   
270    This function checks whether a given INSN is valid within a low-overhead
271    loop.  If INSN is invalid it returns the reason for that, otherwise it
272    returns NULL. A called function may clobber any special registers required
273    for low-overhead looping. Additionally, some targets (eg, PPC) use the count
274    register for branch on table instructions. We reject the doloop pattern in
275    these cases.  */
276
277 const char *
278 default_invalid_within_doloop (rtx insn)
279 {
280   if (CALL_P (insn))
281     return "Function call in loop.";
282   
283   if (JUMP_P (insn)
284       && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
285           || GET_CODE (PATTERN (insn)) == ADDR_VEC))
286     return "Computed branch in the loop.";
287   
288   return NULL;
289 }
290
291 bool
292 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
293         CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
294         enum machine_mode mode ATTRIBUTE_UNUSED,
295         tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
296 {
297   return false;
298 }
299
300 bool
301 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
302         CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
303         enum machine_mode mode ATTRIBUTE_UNUSED,
304         tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
305 {
306   return true;
307 }
308
309 int
310 hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
311         CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
312         enum machine_mode mode ATTRIBUTE_UNUSED,
313         tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
314 {
315   return 0;
316 }
317
318 const char *
319 hook_invalid_arg_for_unprototyped_fn (
320         tree typelist ATTRIBUTE_UNUSED,
321         tree funcdecl ATTRIBUTE_UNUSED,
322         tree val ATTRIBUTE_UNUSED)
323 {
324   return NULL;
325 }
326
327 /* Initialize the stack protection decls.  */
328
329 /* Stack protection related decls living in libgcc.  */
330 static GTY(()) tree stack_chk_guard_decl;
331
332 tree
333 default_stack_protect_guard (void)
334 {
335   tree t = stack_chk_guard_decl;
336
337   if (t == NULL)
338     {
339       t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"),
340                       ptr_type_node);
341       TREE_STATIC (t) = 1;
342       TREE_PUBLIC (t) = 1;
343       DECL_EXTERNAL (t) = 1;
344       TREE_USED (t) = 1;
345       TREE_THIS_VOLATILE (t) = 1;
346       DECL_ARTIFICIAL (t) = 1;
347       DECL_IGNORED_P (t) = 1;
348
349       stack_chk_guard_decl = t;
350     }
351
352   return t;
353 }
354
355 static GTY(()) tree stack_chk_fail_decl;
356
357 tree 
358 default_external_stack_protect_fail (void)
359 {
360   tree t = stack_chk_fail_decl;
361
362   if (t == NULL_TREE)
363     {
364       t = build_function_type_list (void_type_node, NULL_TREE);
365       t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
366       TREE_STATIC (t) = 1;
367       TREE_PUBLIC (t) = 1;
368       DECL_EXTERNAL (t) = 1;
369       TREE_USED (t) = 1;
370       TREE_THIS_VOLATILE (t) = 1;
371       TREE_NOTHROW (t) = 1;
372       DECL_ARTIFICIAL (t) = 1;
373       DECL_IGNORED_P (t) = 1;
374
375       stack_chk_fail_decl = t;
376     }
377
378   return build_function_call_expr (t, NULL_TREE);
379 }
380
381 tree
382 default_hidden_stack_protect_fail (void)
383 {
384 #ifndef HAVE_GAS_HIDDEN
385   return default_external_stack_protect_fail ();
386 #else
387   tree t = stack_chk_fail_decl;
388
389   if (!flag_pic)
390     return default_external_stack_protect_fail ();
391
392   if (t == NULL_TREE)
393     {
394       t = build_function_type_list (void_type_node, NULL_TREE);
395       t = build_decl (FUNCTION_DECL,
396                       get_identifier ("__stack_chk_fail_local"), t);
397       TREE_STATIC (t) = 1;
398       TREE_PUBLIC (t) = 1;
399       DECL_EXTERNAL (t) = 1;
400       TREE_USED (t) = 1;
401       TREE_THIS_VOLATILE (t) = 1;
402       TREE_NOTHROW (t) = 1;
403       DECL_ARTIFICIAL (t) = 1;
404       DECL_IGNORED_P (t) = 1;
405       DECL_VISIBILITY_SPECIFIED (t) = 1;
406       DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
407
408       stack_chk_fail_decl = t;
409     }
410
411   return build_function_call_expr (t, NULL_TREE);
412 #endif
413 }
414
415 bool
416 hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED)
417 {
418   return COMMUTATIVE_P (x);
419 }
420
421 rtx
422 default_function_value (tree ret_type ATTRIBUTE_UNUSED,
423                         tree fn_decl_or_type,
424                         bool outgoing ATTRIBUTE_UNUSED)
425 {
426   /* The old interface doesn't handle receiving the function type.  */
427   if (fn_decl_or_type
428       && !DECL_P (fn_decl_or_type))
429     fn_decl_or_type = NULL;
430
431 #ifdef FUNCTION_OUTGOING_VALUE
432   if (outgoing)
433     return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type);
434 #endif
435
436 #ifdef FUNCTION_VALUE
437   return FUNCTION_VALUE (ret_type, fn_decl_or_type);
438 #else
439   return NULL_RTX;
440 #endif
441 }
442
443 rtx
444 default_internal_arg_pointer (void)
445 {
446   /* If the reg that the virtual arg pointer will be translated into is
447      not a fixed reg or is the stack pointer, make a copy of the virtual
448      arg pointer, and address parms via the copy.  The frame pointer is
449      considered fixed even though it is not marked as such.  */
450   if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
451        || ! (fixed_regs[ARG_POINTER_REGNUM]
452              || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
453     return copy_to_reg (virtual_incoming_args_rtx);
454   else
455     return virtual_incoming_args_rtx;
456 }
457
458 #include "gt-targhooks.h"