X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftarghooks.c;h=8e3d74ea356645c3c94f9a0b293cd67ea993f0ac;hb=010926660581ba94e6d07e3188f8ce0101793fe9;hp=16f481ec7d8b7535fea648f4214f9db70f594a58;hpb=c34a092122a7cf3f644084534d0ab4f960d51cec;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 16f481ec7d8..8e3d74ea356 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1,5 +1,5 @@ /* Default target hook functions. - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -56,16 +56,21 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "expr.h" #include "output.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "function.h" #include "target.h" #include "tm_p.h" #include "target-def.h" #include "ggc.h" #include "hard-reg-set.h" +#include "regs.h" #include "reload.h" #include "optabs.h" #include "recog.h" +#include "intl.h" +#include "opts.h" +#include "tree-flow.h" +#include "tree-ssa-alias.h" bool @@ -119,7 +124,7 @@ default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { - if (for_return == 2) + if (type != NULL_TREE && for_return == 2) return promote_mode (type, mode, punsignedp); return mode; } @@ -165,7 +170,7 @@ default_expand_builtin_saveregs (void) } void -default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_arg_size ATTRIBUTE_UNUSED, @@ -184,13 +189,13 @@ default_builtin_setjmp_frame_value (void) /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ bool -hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t ca ATTRIBUTE_UNUSED) { return false; } bool -default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +default_pretend_outgoing_varargs_named (cumulative_args_t ca ATTRIBUTE_UNUSED) { return (targetm.calls.setup_incoming_varargs != default_setup_incoming_varargs); @@ -248,7 +253,7 @@ default_mode_rep_extended (enum machine_mode mode ATTRIBUTE_UNUSED, /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ bool -hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED) +hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t a ATTRIBUTE_UNUSED) { return true; } @@ -297,7 +302,7 @@ default_cxx_get_cookie_size (tree type) 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, +hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named_arg ATTRIBUTE_UNUSED) { @@ -308,21 +313,62 @@ hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, version of the hook is true for all named arguments. */ bool -hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +hook_callee_copies_named (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named) { return named; } -/* Emit any directives required to unwind this instruction. */ +/* Emit to STREAM the assembler syntax for insn operand X. */ void -default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED, - rtx insn ATTRIBUTE_UNUSED) +default_print_operand (FILE *stream ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, + int code ATTRIBUTE_UNUSED) { - /* Should never happen. */ +#ifdef PRINT_OPERAND + PRINT_OPERAND (stream, x, code); +#else + gcc_unreachable (); +#endif +} + +/* Emit to STREAM the assembler syntax for an insn operand whose memory + address is X. */ + +void +default_print_operand_address (FILE *stream ATTRIBUTE_UNUSED, + rtx x ATTRIBUTE_UNUSED) +{ +#ifdef PRINT_OPERAND_ADDRESS + PRINT_OPERAND_ADDRESS (stream, x); +#else gcc_unreachable (); +#endif +} + +/* Return true if CODE is a valid punctuation character for the + `print_operand' hook. */ + +bool +default_print_operand_punct_valid_p (unsigned char code ATTRIBUTE_UNUSED) +{ +#ifdef PRINT_OPERAND_PUNCT_VALID_P + return PRINT_OPERAND_PUNCT_VALID_P (code); +#else + return false; +#endif +} + +/* The default implementation of TARGET_MANGLE_ASSEMBLER_NAME. */ +tree +default_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED) +{ + const char *skipped = name + (*name == '*' ? 1 : 0); + const char *stripped = targetm.strip_name_encoding (skipped); + if (*name != '*' && user_label_prefix[0]) + stripped = ACONCAT ((user_label_prefix, stripped, NULL)); + return get_identifier (stripped); } /* True if MODE is valid for the target. By "valid", we mean able to @@ -378,6 +424,19 @@ default_scalar_mode_supported_p (enum machine_mode mode) } } +/* Make some target macros useable by target-independent code. */ +bool +targhook_words_big_endian (void) +{ + return !!WORDS_BIG_ENDIAN; +} + +bool +targhook_float_words_big_endian (void) +{ + return !!FLOAT_WORDS_BIG_ENDIAN; +} + /* True if the target supports decimal floating point. */ bool @@ -396,7 +455,7 @@ default_fixed_point_supported_p (void) /* 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 @@ -409,17 +468,17 @@ default_invalid_within_doloop (const_rtx insn) { if (CALL_P (insn)) return "Function call in loop."; - + if (JUMP_TABLE_DATA_P (insn)) return "Computed branch in the loop."; - + return NULL; } /* Mapping of builtin functions to vectorized variants. */ tree -default_builtin_vectorized_function (unsigned int fn ATTRIBUTE_UNUSED, +default_builtin_vectorized_function (tree fndecl ATTRIBUTE_UNUSED, tree type_out ATTRIBUTE_UNUSED, tree type_in ATTRIBUTE_UNUSED) { @@ -430,11 +489,46 @@ default_builtin_vectorized_function (unsigned int fn ATTRIBUTE_UNUSED, tree default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED) + tree dest_type ATTRIBUTE_UNUSED, + tree src_type ATTRIBUTE_UNUSED) { return NULL_TREE; } +/* Default vectorizer cost model values. */ + +int +default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, + tree vectype ATTRIBUTE_UNUSED, + int misalign ATTRIBUTE_UNUSED) +{ + switch (type_of_cost) + { + case scalar_stmt: + case scalar_load: + case scalar_store: + case vector_stmt: + case vector_load: + case vector_store: + case vec_to_scalar: + case scalar_to_vec: + case cond_branch_not_taken: + case vec_perm: + case vec_promote_demote: + return 1; + + case unaligned_load: + case unaligned_store: + return 2; + + case cond_branch_taken: + return 3; + + default: + gcc_unreachable (); + } +} + /* Reciprocal. */ tree @@ -447,7 +541,7 @@ default_builtin_reciprocal (unsigned int fn ATTRIBUTE_UNUSED, bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { @@ -456,7 +550,7 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { @@ -465,14 +559,55 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { return 0; } -void +void +default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +rtx +default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +rtx +default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +unsigned int +default_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +{ + return PARM_BOUNDARY; +} + +unsigned int +default_function_arg_round_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +{ + return PARM_BOUNDARY; +} + +void hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) { } @@ -498,6 +633,8 @@ default_stack_protect_guard (void) if (t == NULL) { + rtx x; + t = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ("__stack_chk_guard"), ptr_type_node); @@ -509,6 +646,11 @@ default_stack_protect_guard (void) DECL_ARTIFICIAL (t) = 1; DECL_IGNORED_P (t) = 1; + /* Do not share RTL as the declaration is visible outside of + current function. */ + x = DECL_RTL (t); + RTX_FLAG (x, used) = 1; + stack_chk_guard_decl = t; } @@ -517,7 +659,7 @@ default_stack_protect_guard (void) static GTY(()) tree stack_chk_fail_decl; -tree +tree default_external_stack_protect_fail (void) { tree t = stack_chk_fail_decl; @@ -595,22 +737,34 @@ default_function_value (const_tree ret_type ATTRIBUTE_UNUSED, && !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; + gcc_unreachable (); #endif } rtx -default_libcall_value (enum machine_mode mode, rtx fun ATTRIBUTE_UNUSED) +default_libcall_value (enum machine_mode mode ATTRIBUTE_UNUSED, + const_rtx fun ATTRIBUTE_UNUSED) { +#ifdef LIBCALL_VALUE return LIBCALL_VALUE (mode); +#else + gcc_unreachable (); +#endif +} + +/* The default hook for TARGET_FUNCTION_VALUE_REGNO_P. */ + +bool +default_function_value_regno_p (const unsigned int regno ATTRIBUTE_UNUSED) +{ +#ifdef FUNCTION_VALUE_REGNO_P + return FUNCTION_VALUE_REGNO_P (regno); +#else + gcc_unreachable (); +#endif } rtx @@ -631,27 +785,32 @@ default_internal_arg_pointer (void) rtx default_static_chain (const_tree fndecl, bool incoming_p) { - if (DECL_NO_STATIC_CHAIN (fndecl)) + if (!DECL_STATIC_CHAIN (fndecl)) return NULL; if (incoming_p) { -#ifdef STATIC_CHAIN_INCOMING - return STATIC_CHAIN_INCOMING; -#endif #ifdef STATIC_CHAIN_INCOMING_REGNUM return gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM); #endif } -#ifdef STATIC_CHAIN - return STATIC_CHAIN; -#endif #ifdef STATIC_CHAIN_REGNUM return gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); #endif - gcc_unreachable (); + { + static bool issued_error; + if (!issued_error) + { + issued_error = true; + sorry ("nested functions not supported on this target"); + } + + /* It really doesn't matter what we return here, so long at it + doesn't cause the rest of the compiler to crash. */ + return gen_rtx_MEM (Pmode, stack_pointer_rtx); + } } void @@ -661,28 +820,28 @@ default_trampoline_init (rtx ARG_UNUSED (m_tramp), tree ARG_UNUSED (t_func), sorry ("nested function trampolines not supported on this target"); } -enum reg_class -default_branch_target_register_class (void) +int +default_return_pops_args (tree fundecl ATTRIBUTE_UNUSED, + tree funtype ATTRIBUTE_UNUSED, + int size ATTRIBUTE_UNUSED) { - return NO_REGS; + return 0; } -#ifdef IRA_COVER_CLASSES -const enum reg_class * -default_ira_cover_classes (void) +reg_class_t +default_branch_target_register_class (void) { - static enum reg_class classes[] = IRA_COVER_CLASSES; - return classes; + return NO_REGS; } -#endif -enum reg_class +reg_class_t default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, - enum reg_class reload_class ATTRIBUTE_UNUSED, + reg_class_t reload_class_i ATTRIBUTE_UNUSED, enum machine_mode reload_mode ATTRIBUTE_UNUSED, secondary_reload_info *sri) { enum reg_class rclass = NO_REGS; + enum reg_class reload_class = (enum reg_class) reload_class_i; if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) { @@ -699,12 +858,12 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, #endif if (rclass != NO_REGS) { - enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode] - : reload_out_optab[(int) reload_mode]); + enum insn_code icode + = direct_optab_handler (in_p ? reload_in_optab : reload_out_optab, + reload_mode); if (icode != CODE_FOR_nothing - && insn_data[(int) icode].operand[in_p].predicate - && ! insn_data[(int) icode].operand[in_p].predicate (x, reload_mode)) + && !insn_operand_matches (icode, in_p, x)) icode = CODE_FOR_nothing; else if (icode != CODE_FOR_nothing) { @@ -764,14 +923,6 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, return rclass; } -bool -default_handle_c_option (size_t code ATTRIBUTE_UNUSED, - const char *arg ATTRIBUTE_UNUSED, - int value ATTRIBUTE_UNUSED) -{ - return false; -} - /* By default, if flag_pic is true, then neither local nor global relocs should be placed in readonly memory. */ @@ -805,7 +956,7 @@ default_builtin_vector_alignment_reachable (const_tree type, bool is_packed) } /* By default, assume that a target supports any factor of misalignment - memory access if it supports movmisalign patten. + memory access if it supports movmisalign patten. is_packed is true if the memory access is defined in a packed struct. */ bool default_builtin_support_vector_misalignment (enum machine_mode mode, @@ -816,17 +967,183 @@ default_builtin_support_vector_misalignment (enum machine_mode mode, bool is_packed ATTRIBUTE_UNUSED) { - if (optab_handler (movmisalign_optab, mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing) return true; return false; } +/* By default, only attempt to parallelize bitwise operations, and + possibly adds/subtracts using bit-twiddling. */ + +enum machine_mode +default_preferred_simd_mode (enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return word_mode; +} + +/* By default only the size derived from the preferred vector mode + is tried. */ + +unsigned int +default_autovectorize_vector_sizes (void) +{ + return 0; +} + +/* Determine whether or not a pointer mode is valid. Assume defaults + of ptr_mode or Pmode - can be overridden. */ +bool +default_valid_pointer_mode (enum machine_mode mode) +{ + return (mode == ptr_mode || mode == Pmode); +} + +/* Determine whether the memory reference specified by REF may alias + the C libraries errno location. */ +bool +default_ref_may_alias_errno (ao_ref *ref) +{ + tree base = ao_ref_base (ref); + /* The default implementation assumes the errno location is + a declaration of type int or is always accessed via a + pointer to int. We assume that accesses to errno are + not deliberately obfuscated (even in conforming ways). */ + if (TYPE_UNSIGNED (TREE_TYPE (base)) + || TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node)) + return false; + /* The default implementation assumes an errno location + declaration is never defined in the current compilation unit. */ + if (DECL_P (base) + && !TREE_STATIC (base)) + return true; + else if (TREE_CODE (base) == MEM_REF + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) + { + struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)); + return !pi || pi->pt.anything || pi->pt.nonlocal; + } + return false; +} + +/* Return the mode for a pointer to a given ADDRSPACE, defaulting to ptr_mode + for the generic address space only. */ + +enum machine_mode +default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED) +{ + gcc_assert (ADDR_SPACE_GENERIC_P (addrspace)); + return ptr_mode; +} + +/* Return the mode for an address in a given ADDRSPACE, defaulting to Pmode + for the generic address space only. */ + +enum machine_mode +default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED) +{ + gcc_assert (ADDR_SPACE_GENERIC_P (addrspace)); + return Pmode; +} + +/* Named address space version of valid_pointer_mode. */ + +bool +default_addr_space_valid_pointer_mode (enum machine_mode mode, addr_space_t as) +{ + if (!ADDR_SPACE_GENERIC_P (as)) + return (mode == targetm.addr_space.pointer_mode (as) + || mode == targetm.addr_space.address_mode (as)); + + return targetm.valid_pointer_mode (mode); +} + +/* Some places still assume that all pointer or address modes are the + standard Pmode and ptr_mode. These optimizations become invalid if + the target actually supports multiple different modes. For now, + we disable such optimizations on such targets, using this function. */ + +bool +target_default_pointer_address_modes_p (void) +{ + if (targetm.addr_space.address_mode != default_addr_space_address_mode) + return false; + if (targetm.addr_space.pointer_mode != default_addr_space_pointer_mode) + return false; + + return true; +} + +/* Named address space version of legitimate_address_p. */ + +bool +default_addr_space_legitimate_address_p (enum machine_mode mode, rtx mem, + bool strict, addr_space_t as) +{ + if (!ADDR_SPACE_GENERIC_P (as)) + gcc_unreachable (); + + return targetm.legitimate_address_p (mode, mem, strict); +} + +/* Named address space version of LEGITIMIZE_ADDRESS. */ + +rtx +default_addr_space_legitimize_address (rtx x, rtx oldx, + enum machine_mode mode, addr_space_t as) +{ + if (!ADDR_SPACE_GENERIC_P (as)) + return x; + + return targetm.legitimize_address (x, oldx, mode); +} + +/* The default hook for determining if one named address space is a subset of + another and to return which address space to use as the common address + space. */ + +bool +default_addr_space_subset_p (addr_space_t subset, addr_space_t superset) +{ + return (subset == superset); +} + +/* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be + called for targets with only a generic address space. */ + +rtx +default_addr_space_convert (rtx op ATTRIBUTE_UNUSED, + tree from_type ATTRIBUTE_UNUSED, + tree to_type ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + bool default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED) { return true; } +/* The default implementation of TARGET_MODE_DEPENDENT_ADDRESS_P. */ + +bool +default_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED) +{ +#ifdef GO_IF_MODE_DEPENDENT_ADDRESS + + GO_IF_MODE_DEPENDENT_ADDRESS (CONST_CAST_RTX (addr), win); + return false; + /* Label `win' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS. */ + win: ATTRIBUTE_UNUSED_LABEL + return true; + +#else + + return false; + +#endif +} + bool default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl), tree ARG_UNUSED (name), @@ -865,9 +1182,10 @@ default_target_can_inline_p (tree caller, tree callee) else if (!caller_opts) ret = false; - /* If both caller and callee have attributes, assume that if the pointer is - different, the the two functions have different target options since - build_target_option_node uses a hash table for the options. */ + /* If both caller and callee have attributes, assume that if the + pointer is different, the two functions have different target + options since build_target_option_node uses a hash table for the + options. */ else ret = (callee_opts == caller_opts); @@ -887,4 +1205,248 @@ unsigned int default_case_values_threshold (void) return (HAVE_casesi ? 4 : 5); } +bool +default_have_conditional_execution (void) +{ +#ifdef HAVE_conditional_execution + return HAVE_conditional_execution; +#else + return false; +#endif +} + +tree +default_builtin_tm_load_store (tree ARG_UNUSED (type)) +{ + return NULL_TREE; +} + +/* Compute cost of moving registers to/from memory. */ + +int +default_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, + reg_class_t rclass ATTRIBUTE_UNUSED, + bool in ATTRIBUTE_UNUSED) +{ +#ifndef MEMORY_MOVE_COST + return (4 + memory_move_secondary_cost (mode, (enum reg_class) rclass, in)); +#else + return MEMORY_MOVE_COST (mode, (enum reg_class) rclass, in); +#endif +} + +/* Compute cost of moving data from a register of class FROM to one of + TO, using MODE. */ + +int +default_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, + reg_class_t from ATTRIBUTE_UNUSED, + reg_class_t to ATTRIBUTE_UNUSED) +{ +#ifndef REGISTER_MOVE_COST + return 2; +#else + return REGISTER_MOVE_COST (mode, (enum reg_class) from, (enum reg_class) to); +#endif +} + +bool +default_profile_before_prologue (void) +{ +#ifdef PROFILE_BEFORE_PROLOGUE + return true; +#else + return false; +#endif +} + +/* The default implementation of TARGET_PREFERRED_RELOAD_CLASS. */ + +reg_class_t +default_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, + reg_class_t rclass) +{ +#ifdef PREFERRED_RELOAD_CLASS + return (reg_class_t) PREFERRED_RELOAD_CLASS (x, (enum reg_class) rclass); +#else + return rclass; +#endif +} + +/* The default implementation of TARGET_OUTPUT_PREFERRED_RELOAD_CLASS. */ + +reg_class_t +default_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED, + reg_class_t rclass) +{ + return rclass; +} + +/* The default implementation of TARGET_PREFERRED_RENAME_CLASS. */ +reg_class_t +default_preferred_rename_class (reg_class_t rclass ATTRIBUTE_UNUSED) +{ + return NO_REGS; +} + +/* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */ + +bool +default_class_likely_spilled_p (reg_class_t rclass) +{ + return (reg_class_size[(int) rclass] == 1); +} + +/* The default implementation of TARGET_CLASS_MAX_NREGS. */ + +unsigned char +default_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ +#ifdef CLASS_MAX_NREGS + return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass, mode); +#else + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); +#endif +} + +/* Determine the debugging unwind mechanism for the target. */ + +enum unwind_info_type +default_debug_unwind_info (void) +{ + /* If the target wants to force the use of dwarf2 unwind info, let it. */ + /* ??? Change all users to the hook, then poison this. */ +#ifdef DWARF2_FRAME_INFO + if (DWARF2_FRAME_INFO) + return UI_DWARF2; +#endif + + /* Otherwise, only turn it on if dwarf2 debugging is enabled. */ +#ifdef DWARF2_DEBUGGING_INFO + if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) + return UI_DWARF2; +#endif + + return UI_NONE; +} + +/* To be used by targets where reg_raw_mode doesn't return the right + mode for registers used in apply_builtin_return and apply_builtin_arg. */ + +enum machine_mode +default_get_reg_raw_mode(int regno) +{ + return reg_raw_mode[regno]; +} + +/* Return true if the state of option OPTION should be stored in PCH files + and checked by default_pch_valid_p. Store the option's current state + in STATE if so. */ + +static inline bool +option_affects_pch_p (int option, struct cl_option_state *state) +{ + if ((cl_options[option].flags & CL_TARGET) == 0) + return false; + if (option_flag_var (option, &global_options) == &target_flags) + if (targetm.check_pch_target_flags) + return false; + return get_option_state (&global_options, option, state); +} + +/* Default version of get_pch_validity. + By default, every flag difference is fatal; that will be mostly right for + most targets, but completely right for very few. */ + +void * +default_get_pch_validity (size_t *sz) +{ + struct cl_option_state state; + size_t i; + char *result, *r; + + *sz = 2; + if (targetm.check_pch_target_flags) + *sz += sizeof (target_flags); + for (i = 0; i < cl_options_count; i++) + if (option_affects_pch_p (i, &state)) + *sz += state.size; + + result = r = XNEWVEC (char, *sz); + r[0] = flag_pic; + r[1] = flag_pie; + r += 2; + if (targetm.check_pch_target_flags) + { + memcpy (r, &target_flags, sizeof (target_flags)); + r += sizeof (target_flags); + } + + for (i = 0; i < cl_options_count; i++) + if (option_affects_pch_p (i, &state)) + { + memcpy (r, state.data, state.size); + r += state.size; + } + + return result; +} + +/* Return a message which says that a PCH file was created with a different + setting of OPTION. */ + +static const char * +pch_option_mismatch (const char *option) +{ + char *r; + + asprintf (&r, _("created and used with differing settings of '%s'"), option); + if (r == NULL) + return _("out of memory"); + return r; +} + +/* Default version of pch_valid_p. */ + +const char * +default_pch_valid_p (const void *data_p, size_t len) +{ + struct cl_option_state state; + const char *data = (const char *)data_p; + size_t i; + + /* -fpic and -fpie also usually make a PCH invalid. */ + if (data[0] != flag_pic) + return _("created and used with different settings of -fpic"); + if (data[1] != flag_pie) + return _("created and used with different settings of -fpie"); + data += 2; + + /* Check target_flags. */ + if (targetm.check_pch_target_flags) + { + int tf; + const char *r; + + memcpy (&tf, data, sizeof (target_flags)); + data += sizeof (target_flags); + len -= sizeof (target_flags); + r = targetm.check_pch_target_flags (tf); + if (r != NULL) + return r; + } + + for (i = 0; i < cl_options_count; i++) + if (option_affects_pch_p (i, &state)) + { + if (memcmp (data, state.data, state.size) != 0) + return pch_option_mismatch (cl_options[i].opt_text); + data += state.size; + len -= state.size; + } + + return NULL; +} + #include "gt-targhooks.h"