X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftarghooks.c;h=c0c42019a04a6bee45a48af7e7563606a1acf167;hb=3082825d5ade85aaf16d38c1747af094fbfcc278;hp=5d2a75fe3154accd369891bdf5e9edf8de5048b9;hpb=c1dc02de6c120c546fedbe5348c4f5e78ef95aa6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 5d2a75fe315..c0c42019a04 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1,5 +1,5 @@ /* Default target hook functions. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -15,8 +15,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ /* The migration of target macros to target hooks works as follows: @@ -61,6 +61,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "tm_p.h" #include "target-def.h" +#include "ggc.h" + void default_external_libcall (rtx fun ATTRIBUTE_UNUSED) @@ -128,6 +130,20 @@ default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) != default_setup_incoming_varargs); } +enum machine_mode +default_eh_return_filter_mode (void) +{ + return word_mode; +} + +/* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */ + +unsigned HOST_WIDE_INT +default_shift_truncation_mask (enum machine_mode mode) +{ + return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0; +} + /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ bool @@ -143,3 +159,284 @@ default_cxx_guard_type (void) { return long_long_integer_type_node; } + + +/* Returns the size of the cookie to use when allocating an array + whose elements have the indicated TYPE. Assumes that it is already + known that a cookie is needed. */ + +tree +default_cxx_get_cookie_size (tree type) +{ + tree cookie_size; + + /* We need to allocate an additional max (sizeof (size_t), alignof + (true_type)) bytes. */ + tree sizetype_size; + tree type_align; + + sizetype_size = size_in_bytes (sizetype); + type_align = size_int (TYPE_ALIGN_UNIT (type)); + if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) + cookie_size = sizetype_size; + else + cookie_size = type_align; + + return cookie_size; +} + +/* Return true if a parameter must be passed by reference. This version + of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ + +bool +hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, + bool named_arg ATTRIBUTE_UNUSED) +{ + return targetm.calls.must_pass_in_stack (mode, type); +} + +/* Return true if a parameter follows callee copies conventions. This + version of the hook is true for all named arguments. */ + +bool +hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, bool named) +{ + return named; +} + +/* Emit any directives required to unwind this instruction. */ + +void +default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED, + rtx insn ATTRIBUTE_UNUSED) +{ + /* Should never happen. */ + gcc_unreachable (); +} + +/* True if MODE is valid for the target. By "valid", we mean able to + be manipulated in non-trivial ways. In particular, this means all + the arithmetic is supported. + + By default we guess this means that any C type is supported. If + we can't map the mode back to a type that would be available in C, + then reject it. Special case, here, is the double-word arithmetic + supported by optabs.c. */ + +bool +default_scalar_mode_supported_p (enum machine_mode mode) +{ + int precision = GET_MODE_PRECISION (mode); + + switch (GET_MODE_CLASS (mode)) + { + case MODE_PARTIAL_INT: + case MODE_INT: + if (precision == CHAR_TYPE_SIZE) + return true; + if (precision == SHORT_TYPE_SIZE) + return true; + if (precision == INT_TYPE_SIZE) + return true; + if (precision == LONG_TYPE_SIZE) + return true; + if (precision == LONG_LONG_TYPE_SIZE) + return true; + if (precision == 2 * BITS_PER_WORD) + return true; + return false; + + case MODE_FLOAT: + if (precision == FLOAT_TYPE_SIZE) + return true; + if (precision == DOUBLE_TYPE_SIZE) + return true; + if (precision == LONG_DOUBLE_TYPE_SIZE) + return true; + return false; + + default: + gcc_unreachable (); + } +} + +/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns + an error message. + + This function checks whether a given INSN is valid within a low-overhead + loop. If INSN is invalid it returns the reason for that, otherwise it + returns NULL. A called function may clobber any special registers required + for low-overhead looping. Additionally, some targets (eg, PPC) use the count + register for branch on table instructions. We reject the doloop pattern in + these cases. */ + +const char * +default_invalid_within_doloop (rtx insn) +{ + if (CALL_P (insn)) + return "Function call in loop."; + + if (JUMP_P (insn) + && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC + || GET_CODE (PATTERN (insn)) == ADDR_VEC)) + return "Computed branch in the loop."; + + return NULL; +} + +bool +hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( + CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) +{ + return false; +} + +bool +hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( + CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) +{ + return true; +} + +int +hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( + CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) +{ + return 0; +} + +const char * +hook_invalid_arg_for_unprototyped_fn ( + tree typelist ATTRIBUTE_UNUSED, + tree funcdecl ATTRIBUTE_UNUSED, + tree val ATTRIBUTE_UNUSED) +{ + return NULL; +} + +/* Initialize the stack protection decls. */ + +/* Stack protection related decls living in libgcc. */ +static GTY(()) tree stack_chk_guard_decl; + +tree +default_stack_protect_guard (void) +{ + tree t = stack_chk_guard_decl; + + if (t == NULL) + { + t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"), + ptr_type_node); + TREE_STATIC (t) = 1; + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + TREE_USED (t) = 1; + TREE_THIS_VOLATILE (t) = 1; + DECL_ARTIFICIAL (t) = 1; + DECL_IGNORED_P (t) = 1; + + stack_chk_guard_decl = t; + } + + return t; +} + +static GTY(()) tree stack_chk_fail_decl; + +tree +default_external_stack_protect_fail (void) +{ + tree t = stack_chk_fail_decl; + + if (t == NULL_TREE) + { + t = build_function_type_list (void_type_node, NULL_TREE); + t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t); + TREE_STATIC (t) = 1; + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + TREE_USED (t) = 1; + TREE_THIS_VOLATILE (t) = 1; + TREE_NOTHROW (t) = 1; + DECL_ARTIFICIAL (t) = 1; + DECL_IGNORED_P (t) = 1; + + stack_chk_fail_decl = t; + } + + return build_function_call_expr (t, NULL_TREE); +} + +tree +default_hidden_stack_protect_fail (void) +{ +#ifndef HAVE_GAS_HIDDEN + return default_external_stack_protect_fail (); +#else + tree t = stack_chk_fail_decl; + + if (!flag_pic) + return default_external_stack_protect_fail (); + + if (t == NULL_TREE) + { + t = build_function_type_list (void_type_node, NULL_TREE); + t = build_decl (FUNCTION_DECL, + get_identifier ("__stack_chk_fail_local"), t); + TREE_STATIC (t) = 1; + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + TREE_USED (t) = 1; + TREE_THIS_VOLATILE (t) = 1; + TREE_NOTHROW (t) = 1; + DECL_ARTIFICIAL (t) = 1; + DECL_IGNORED_P (t) = 1; + DECL_VISIBILITY_SPECIFIED (t) = 1; + DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; + + stack_chk_fail_decl = t; + } + + return build_function_call_expr (t, NULL_TREE); +#endif +} + +bool +hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED) +{ + return COMMUTATIVE_P (x); +} + +rtx +default_function_value (tree ret_type ATTRIBUTE_UNUSED, + tree fn_decl_or_type, + bool outgoing ATTRIBUTE_UNUSED) +{ + /* The old interface doesn't handle receiving the function type. */ + if (fn_decl_or_type + && !DECL_P (fn_decl_or_type)) + fn_decl_or_type = NULL; + +#ifdef FUNCTION_OUTGOING_VALUE + if (outgoing) + return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type); +#endif + +#ifdef FUNCTION_VALUE + return FUNCTION_VALUE (ret_type, fn_decl_or_type); +#else + return NULL_RTX; +#endif +} + +#include "gt-targhooks.h"