1/* Default target hook functions.
2   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to the Free
18Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
1902110-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
68void
69default_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
76enum machine_mode
77default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
78{
79  if (m1 == m2)
80    return m1;
81  return VOIDmode;
82}
83
84bool
85default_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
95rtx
96default_expand_builtin_saveregs (void)
97{
98  error ("__builtin_saveregs not supported by this target");
99  return const0_rtx;
100}
101
102void
103default_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
113rtx
114default_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
121bool
122hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
123{
124  return false;
125}
126
127bool
128default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
129{
130  return (targetm.calls.setup_incoming_varargs
131	  != default_setup_incoming_varargs);
132}
133
134enum machine_mode
135default_eh_return_filter_mode (void)
136{
137  return word_mode;
138}
139
140/* The default implementation of TARGET_SHIFT_TRUNCATION_MASK.  */
141
142unsigned HOST_WIDE_INT
143default_shift_truncation_mask (enum machine_mode mode)
144{
145  return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0;
146}
147
148/* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL.  */
149
150unsigned int
151default_min_divisions_for_recip_mul (enum machine_mode mode ATTRIBUTE_UNUSED)
152{
153  return have_insn_for (DIV, mode) ? 3 : 2;
154}
155
156/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true.  */
157
158bool
159hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
160{
161  return true;
162}
163
164
165/* The generic C++ ABI specifies this is a 64-bit value.  */
166tree
167default_cxx_guard_type (void)
168{
169  return long_long_integer_type_node;
170}
171
172
173/* Returns the size of the cookie to use when allocating an array
174   whose elements have the indicated TYPE.  Assumes that it is already
175   known that a cookie is needed.  */
176
177tree
178default_cxx_get_cookie_size (tree type)
179{
180  tree cookie_size;
181
182  /* We need to allocate an additional max (sizeof (size_t), alignof
183     (true_type)) bytes.  */
184  tree sizetype_size;
185  tree type_align;
186
187  sizetype_size = size_in_bytes (sizetype);
188  type_align = size_int (TYPE_ALIGN_UNIT (type));
189  if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
190    cookie_size = sizetype_size;
191  else
192    cookie_size = type_align;
193
194  return cookie_size;
195}
196
197/* Return true if a parameter must be passed by reference.  This version
198   of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK.  */
199
200bool
201hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
202	enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED,
203	bool named_arg ATTRIBUTE_UNUSED)
204{
205  return targetm.calls.must_pass_in_stack (mode, type);
206}
207
208/* Return true if a parameter follows callee copies conventions.  This
209   version of the hook is true for all named arguments.  */
210
211bool
212hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
213			  enum machine_mode mode ATTRIBUTE_UNUSED,
214			  tree type ATTRIBUTE_UNUSED, bool named)
215{
216  return named;
217}
218
219/* Emit any directives required to unwind this instruction.  */
220
221void
222default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED,
223		     rtx insn ATTRIBUTE_UNUSED)
224{
225  /* Should never happen.  */
226  gcc_unreachable ();
227}
228
229/* True if MODE is valid for the target.  By "valid", we mean able to
230   be manipulated in non-trivial ways.  In particular, this means all
231   the arithmetic is supported.
232
233   By default we guess this means that any C type is supported.  If
234   we can't map the mode back to a type that would be available in C,
235   then reject it.  Special case, here, is the double-word arithmetic
236   supported by optabs.c.  */
237
238bool
239default_scalar_mode_supported_p (enum machine_mode mode)
240{
241  int precision = GET_MODE_PRECISION (mode);
242
243  switch (GET_MODE_CLASS (mode))
244    {
245    case MODE_PARTIAL_INT:
246    case MODE_INT:
247      if (precision == CHAR_TYPE_SIZE)
248	return true;
249      if (precision == SHORT_TYPE_SIZE)
250	return true;
251      if (precision == INT_TYPE_SIZE)
252	return true;
253      if (precision == LONG_TYPE_SIZE)
254	return true;
255      if (precision == LONG_LONG_TYPE_SIZE)
256	return true;
257      if (precision == 2 * BITS_PER_WORD)
258	return true;
259      return false;
260
261    case MODE_FLOAT:
262      if (precision == FLOAT_TYPE_SIZE)
263	return true;
264      if (precision == DOUBLE_TYPE_SIZE)
265	return true;
266      if (precision == LONG_DOUBLE_TYPE_SIZE)
267	return true;
268      return false;
269
270    default:
271      gcc_unreachable ();
272    }
273}
274
275/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
276   an error message.
277
278   This function checks whether a given INSN is valid within a low-overhead
279   loop.  If INSN is invalid it returns the reason for that, otherwise it
280   returns NULL. A called function may clobber any special registers required
281   for low-overhead looping. Additionally, some targets (eg, PPC) use the count
282   register for branch on table instructions. We reject the doloop pattern in
283   these cases.  */
284
285const char *
286default_invalid_within_doloop (rtx insn)
287{
288  if (CALL_P (insn))
289    return "Function call in loop.";
290
291  if (JUMP_P (insn)
292      && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
293	  || GET_CODE (PATTERN (insn)) == ADDR_VEC))
294    return "Computed branch in the loop.";
295
296  return NULL;
297}
298
299bool
300hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
301	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
302	enum machine_mode mode ATTRIBUTE_UNUSED,
303	tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
304{
305  return false;
306}
307
308bool
309hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
310	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
311	enum machine_mode mode ATTRIBUTE_UNUSED,
312	tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
313{
314  return true;
315}
316
317int
318hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
319	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
320	enum machine_mode mode ATTRIBUTE_UNUSED,
321	tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
322{
323  return 0;
324}
325
326const char *
327hook_invalid_arg_for_unprototyped_fn (
328	tree typelist ATTRIBUTE_UNUSED,
329	tree funcdecl ATTRIBUTE_UNUSED,
330	tree val ATTRIBUTE_UNUSED)
331{
332  return NULL;
333}
334
335/* Initialize the stack protection decls.  */
336
337/* Stack protection related decls living in libgcc.  */
338static GTY(()) tree stack_chk_guard_decl;
339
340tree
341default_stack_protect_guard (void)
342{
343  tree t = stack_chk_guard_decl;
344
345  if (t == NULL)
346    {
347      t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"),
348		      ptr_type_node);
349      TREE_STATIC (t) = 1;
350      TREE_PUBLIC (t) = 1;
351      DECL_EXTERNAL (t) = 1;
352      TREE_USED (t) = 1;
353      TREE_THIS_VOLATILE (t) = 1;
354      DECL_ARTIFICIAL (t) = 1;
355      DECL_IGNORED_P (t) = 1;
356
357      stack_chk_guard_decl = t;
358    }
359
360  return t;
361}
362
363static GTY(()) tree stack_chk_fail_decl;
364
365tree
366default_external_stack_protect_fail (void)
367{
368  tree t = stack_chk_fail_decl;
369
370  if (t == NULL_TREE)
371    {
372      t = build_function_type_list (void_type_node, NULL_TREE);
373      t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
374      TREE_STATIC (t) = 1;
375      TREE_PUBLIC (t) = 1;
376      DECL_EXTERNAL (t) = 1;
377      TREE_USED (t) = 1;
378      TREE_THIS_VOLATILE (t) = 1;
379      TREE_NOTHROW (t) = 1;
380      DECL_ARTIFICIAL (t) = 1;
381      DECL_IGNORED_P (t) = 1;
382      DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
383      DECL_VISIBILITY_SPECIFIED (t) = 1;
384
385      stack_chk_fail_decl = t;
386    }
387
388  return build_function_call_expr (t, NULL_TREE);
389}
390
391tree
392default_hidden_stack_protect_fail (void)
393{
394#ifndef HAVE_GAS_HIDDEN
395  return default_external_stack_protect_fail ();
396#else
397  tree t = stack_chk_fail_decl;
398
399  if (!flag_pic)
400    return default_external_stack_protect_fail ();
401
402  if (t == NULL_TREE)
403    {
404      t = build_function_type_list (void_type_node, NULL_TREE);
405      t = build_decl (FUNCTION_DECL,
406		      get_identifier ("__stack_chk_fail_local"), t);
407      TREE_STATIC (t) = 1;
408      TREE_PUBLIC (t) = 1;
409      DECL_EXTERNAL (t) = 1;
410      TREE_USED (t) = 1;
411      TREE_THIS_VOLATILE (t) = 1;
412      TREE_NOTHROW (t) = 1;
413      DECL_ARTIFICIAL (t) = 1;
414      DECL_IGNORED_P (t) = 1;
415      DECL_VISIBILITY_SPECIFIED (t) = 1;
416#if 1
417      /*
418       * This is a hack:
419       * It appears that our gas does not generate @PLT for hidden
420       * symbols. It could be that we need a newer version, or that
421       * this local function is handled differently on linux.
422       */
423      DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
424#else
425      DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
426#endif
427
428      stack_chk_fail_decl = t;
429    }
430
431  return build_function_call_expr (t, NULL_TREE);
432#endif
433}
434
435bool
436hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED)
437{
438  return COMMUTATIVE_P (x);
439}
440
441rtx
442default_function_value (tree ret_type ATTRIBUTE_UNUSED,
443			tree fn_decl_or_type,
444			bool outgoing ATTRIBUTE_UNUSED)
445{
446  /* The old interface doesn't handle receiving the function type.  */
447  if (fn_decl_or_type
448      && !DECL_P (fn_decl_or_type))
449    fn_decl_or_type = NULL;
450
451#ifdef FUNCTION_OUTGOING_VALUE
452  if (outgoing)
453    return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type);
454#endif
455
456#ifdef FUNCTION_VALUE
457  return FUNCTION_VALUE (ret_type, fn_decl_or_type);
458#else
459  return NULL_RTX;
460#endif
461}
462
463rtx
464default_internal_arg_pointer (void)
465{
466  /* If the reg that the virtual arg pointer will be translated into is
467     not a fixed reg or is the stack pointer, make a copy of the virtual
468     arg pointer, and address parms via the copy.  The frame pointer is
469     considered fixed even though it is not marked as such.  */
470  if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
471       || ! (fixed_regs[ARG_POINTER_REGNUM]
472	     || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
473    return copy_to_reg (virtual_incoming_args_rtx);
474  else
475    return virtual_incoming_args_rtx;
476}
477
478#include "gt-targhooks.h"
479