OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [targhooks.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* 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
/* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL.  */
149
 
150
unsigned int
151
default_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
 
158
bool
159
hook_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.  */
166
tree
167
default_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
 
177
tree
178
default_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
 
200
bool
201
hook_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
 
211
bool
212
hook_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
 
221
void
222
default_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
 
238
bool
239
default_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
 
285
const char *
286
default_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
 
299
bool
300
hook_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
 
308
bool
309
hook_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
 
317
int
318
hook_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
 
326
const char *
327
hook_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.  */
338
static GTY(()) tree stack_chk_guard_decl;
339
 
340
tree
341
default_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
 
363
static GTY(()) tree stack_chk_fail_decl;
364
 
365
tree
366
default_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
 
391
tree
392
default_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
      DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
417
 
418
      stack_chk_fail_decl = t;
419
    }
420
 
421
  return build_function_call_expr (t, NULL_TREE);
422
#endif
423
}
424
 
425
bool
426
hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED)
427
{
428
  return COMMUTATIVE_P (x);
429
}
430
 
431
rtx
432
default_function_value (tree ret_type ATTRIBUTE_UNUSED,
433
                        tree fn_decl_or_type,
434
                        bool outgoing ATTRIBUTE_UNUSED)
435
{
436
  /* The old interface doesn't handle receiving the function type.  */
437
  if (fn_decl_or_type
438
      && !DECL_P (fn_decl_or_type))
439
    fn_decl_or_type = NULL;
440
 
441
#ifdef FUNCTION_OUTGOING_VALUE
442
  if (outgoing)
443
    return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type);
444
#endif
445
 
446
#ifdef FUNCTION_VALUE
447
  return FUNCTION_VALUE (ret_type, fn_decl_or_type);
448
#else
449
  return NULL_RTX;
450
#endif
451
}
452
 
453
rtx
454
default_internal_arg_pointer (void)
455
{
456
  /* If the reg that the virtual arg pointer will be translated into is
457
     not a fixed reg or is the stack pointer, make a copy of the virtual
458
     arg pointer, and address parms via the copy.  The frame pointer is
459
     considered fixed even though it is not marked as such.  */
460
  if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
461
       || ! (fixed_regs[ARG_POINTER_REGNUM]
462
             || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
463
    return copy_to_reg (virtual_incoming_args_rtx);
464
  else
465
    return virtual_incoming_args_rtx;
466
}
467
 
468
#include "gt-targhooks.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.