Mercurial > hg > CbC > CbC_gcc
diff gcc/config/iq2000/iq2000.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/config/iq2000/iq2000.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/config/iq2000/iq2000.c Tue Mar 22 17:18:12 2011 +0900 @@ -1,5 +1,5 @@ /* Subroutines used for code generation on Vitesse IQ2000 processors - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -21,7 +21,6 @@ #include "config.h" #include "system.h" #include "coretypes.h" -#include <signal.h> #include "tm.h" #include "tree.h" #include "rtl.h" @@ -37,7 +36,7 @@ #include "optabs.h" #include "libfuncs.h" #include "recog.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "reload.h" #include "ggc.h" #include "tm_p.h" @@ -45,6 +44,7 @@ #include "target.h" #include "target-def.h" #include "langhooks.h" +#include "df.h" /* Enumeration for all of the relational tests, so that we can build arrays indexed by the test type, and not worry about the order @@ -108,8 +108,8 @@ /* Global variables for machine-dependent things. */ -/* List of all IQ2000 punctuation characters used by print_operand. */ -char iq2000_print_operand_punct[256]; +/* List of all IQ2000 punctuation characters used by iq2000_print_operand. */ +static char iq2000_print_operand_punct[256]; /* The target cpu for optimization and scheduling. */ enum processor_type iq2000_tune; @@ -146,6 +146,7 @@ /* Initialize the GCC target structure. */ static struct machine_function* iq2000_init_machine_status (void); static bool iq2000_handle_option (size_t, const char *, int); +static void iq2000_option_override (void); static section *iq2000_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); static void iq2000_init_builtins (void); @@ -162,6 +163,12 @@ const_tree, bool); static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); +static rtx iq2000_function_arg (CUMULATIVE_ARGS *, + enum machine_mode, const_tree, bool); +static void iq2000_function_arg_advance (CUMULATIVE_ARGS *, + enum machine_mode, const_tree, bool); +static unsigned int iq2000_function_arg_boundary (enum machine_mode, + const_tree); static void iq2000_va_start (tree, rtx); static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); static bool iq2000_can_eliminate (const int, const int); @@ -169,6 +176,16 @@ static void iq2000_trampoline_init (rtx, tree, rtx); static rtx iq2000_function_value (const_tree, const_tree, bool); static rtx iq2000_libcall_value (enum machine_mode, const_rtx); +static void iq2000_print_operand (FILE *, rtx, int); +static void iq2000_print_operand_address (FILE *, rtx); +static bool iq2000_print_operand_punct_valid_p (unsigned char code); + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options iq2000_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS iq2000_init_builtins @@ -178,6 +195,10 @@ #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION iq2000_handle_option +#undef TARGET_OPTION_OVERRIDE +#define TARGET_OPTION_OVERRIDE iq2000_option_override +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS iq2000_rtx_costs #undef TARGET_ADDRESS_COST @@ -193,6 +214,13 @@ #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false +#undef TARGET_PRINT_OPERAND +#define TARGET_PRINT_OPERAND iq2000_print_operand +#undef TARGET_PRINT_OPERAND_ADDRESS +#define TARGET_PRINT_OPERAND_ADDRESS iq2000_print_operand_address +#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P +#define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p + #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES @@ -210,6 +238,12 @@ #define TARGET_CALLEE_COPIES hook_callee_copies_named #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG iq2000_function_arg +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs @@ -1109,9 +1143,9 @@ /* Advance the argument of type TYPE and mode MODE to the next argument position in CUM. */ -void -function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, - int named) +static void +iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, + const_tree type, bool named) { if (TARGET_DEBUG_D_MODE) { @@ -1119,7 +1153,7 @@ "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ", cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode)); - fprintf (stderr, "%p", (void *) type); + fprintf (stderr, "%p", CONST_CAST2 (void *, const_tree, type)); fprintf (stderr, ", %d )\n\n", named); } @@ -1178,9 +1212,9 @@ /* Return an RTL expression containing the register for the given mode MODE and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ -struct rtx_def * -function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, - int named) +static rtx +iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, + const_tree type, bool named) { rtx ret; int regbase = -1; @@ -1263,7 +1297,7 @@ { tree field; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD @@ -1300,7 +1334,7 @@ { rtx reg; - for (; field; field = TREE_CHAIN (field)) + for (; field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && int_bit_position (field) >= bitpos) break; @@ -1342,6 +1376,18 @@ return ret; } +static unsigned int +iq2000_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + return (type != NULL_TREE + ? (TYPE_ALIGN (type) <= PARM_BOUNDARY + ? PARM_BOUNDARY + : TYPE_ALIGN (type)) + : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY + ? PARM_BOUNDARY + : GET_MODE_ALIGNMENT (mode))); +} + static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, @@ -1385,11 +1431,7 @@ static struct machine_function * iq2000_init_machine_status (void) { - struct machine_function *f; - - f = GGC_CNEW (struct machine_function); - - return f; + return ggc_alloc_cleared_machine_function (); } /* Implement TARGET_HANDLE_OPTION. */ @@ -1421,8 +1463,8 @@ /* Detect any conflicts in the switches. */ -void -override_options (void) +static void +iq2000_option_override (void) { target_flags &= ~MASK_GPOPT; @@ -1605,8 +1647,6 @@ HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */ HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */ long mask; /* mask of saved gp registers. */ - int fp_inc; /* 1 or 2 depending on the size of fp regs. */ - long fp_bits; /* bitmask to use for each fp register. */ gp_reg_size = 0; fp_reg_size = 0; @@ -1647,8 +1687,6 @@ } } - fp_inc = 2; - fp_bits = 3; gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size); total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size); @@ -1703,7 +1741,7 @@ { return (from == RETURN_ADDRESS_POINTER_REGNUM && (! leaf_function_p () - || (to == GP_REG_FIRST + 31 && leaf_function_p))) + || (to == GP_REG_FIRST + 31 && leaf_function_p ()))) || (from != RETURN_ADDRESS_POINTER_REGNUM && (to == HARD_FRAME_POINTER_REGNUM || (to == STACK_POINTER_REGNUM @@ -1732,6 +1770,8 @@ + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT)) * (BYTES_BIG_ENDIAN != 0)); } + else + gcc_unreachable (); return offset; } @@ -1894,7 +1934,7 @@ PARM_DECL, NULL_TREE, type); DECL_ARG_TYPE (function_result_decl) = type; - TREE_CHAIN (function_result_decl) = fnargs; + DECL_CHAIN (function_result_decl) = fnargs; fnargs = function_result_decl; } @@ -1920,10 +1960,12 @@ passed_mode = Pmode; } - entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1); - - FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1); - next_arg = TREE_CHAIN (cur_arg); + entry_parm = iq2000_function_arg (&args_so_far, passed_mode, + passed_type, true); + + iq2000_function_arg_advance (&args_so_far, passed_mode, + passed_type, true); + next_arg = DECL_CHAIN (cur_arg); if (entry_parm && store_args_on_stack) { @@ -1961,10 +2003,11 @@ /* In order to pass small structures by value in registers we need to shift the value into the high part of the register. - Function_arg has encoded a PARALLEL rtx, holding a vector of - adjustments to be made as the next_arg_reg variable, so we split up the - insns, and emit them separately. */ - next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1); + iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of + adjustments to be made as the next_arg_reg variable, so we split up + the insns, and emit them separately. */ + next_arg_reg = iq2000_function_arg (&args_so_far, VOIDmode, + void_type_node, true); if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) { rtvec adjust = XVEC (next_arg_reg, 0); @@ -1972,7 +2015,7 @@ for (i = 0; i < num; i++) { - rtx insn, pattern; + rtx pattern; pattern = RTVEC_ELT (adjust, i); if (GET_CODE (pattern) != SET @@ -1980,7 +2023,7 @@ abort_with_insn (pattern, "Insn is not a shift"); PUT_CODE (SET_SRC (pattern), ASHIFTRT); - insn = emit_insn (pattern); + emit_insn (pattern); } } @@ -1989,9 +2032,7 @@ /* If this function is a varargs function, store any registers that would normally hold arguments ($4 - $7) on the stack. */ if (store_args_on_stack - && ((TYPE_ARG_TYPES (fntype) != 0 - && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) - != void_type_node)) + && (stdarg_p (fntype) || last_arg_is_vararg_marker)) { int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD; @@ -2137,27 +2178,6 @@ return compute_frame_size (get_frame_size ()) == 0; } -/* Returns nonzero if X contains a SYMBOL_REF. */ - -static int -symbolic_expression_p (rtx x) -{ - if (GET_CODE (x) == SYMBOL_REF) - return 1; - - if (GET_CODE (x) == CONST) - return symbolic_expression_p (XEXP (x, 0)); - - if (UNARY_P (x)) - return symbolic_expression_p (XEXP (x, 0)); - - if (ARITHMETIC_P (x)) - return (symbolic_expression_p (XEXP (x, 0)) - || symbolic_expression_p (XEXP (x, 1))); - - return 0; -} - /* Choose the section to use for the constant rtx expression X that has mode MODE. */ @@ -2223,7 +2243,7 @@ int reg = GP_RETURN; enum machine_mode mode = TYPE_MODE (valtype); int unsignedp = TYPE_UNSIGNED (valtype); - tree func = fn_decl_or_type; + const_tree func = fn_decl_or_type; if (fn_decl_or_type && !DECL_P (fn_decl_or_type)) @@ -2276,7 +2296,7 @@ CUMULATIVE_ARGS temp; temp = *cum; - if (FUNCTION_ARG (temp, mode, type, named) != 0) + if (iq2000_function_arg (&temp, mode, type, named) != 0) return 1; } @@ -2623,7 +2643,7 @@ for (i = 0; i < argcount; i++) { arg[i] = CALL_EXPR_ARG (exp, i); - op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0); + op[i] = expand_normal (arg[i]); mode[i] = insn_data[icode].operand[i].mode; if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT) error ("argument %qd is not a constant", i + 1); @@ -2924,8 +2944,8 @@ assembler syntax for an instruction operand that is a memory reference whose address is ADDR. ADDR is an RTL expression. */ -void -print_operand_address (FILE * file, rtx addr) +static void +iq2000_print_operand_address (FILE * file, rtx addr) { if (!addr) error ("PRINT_OPERAND_ADDRESS, null pointer"); @@ -2950,7 +2970,7 @@ "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."); fprintf (file, "%%lo("); - print_operand_address (file, arg1); + iq2000_print_operand_address (file, arg1); fprintf (file, ")(%s)", reg_names [REGNO (arg0)]); } break; @@ -3052,12 +3072,12 @@ '$' Print the name of the stack pointer register (sp or $29). '+' Print the name of the gp register (gp or $28). */ -void -print_operand (FILE *file, rtx op, int letter) +static void +iq2000_print_operand (FILE *file, rtx op, int letter) { enum rtx_code code; - if (PRINT_OPERAND_PUNCT_VALID_P (letter)) + if (iq2000_print_operand_punct_valid_p (letter)) { switch (letter) { @@ -3170,7 +3190,8 @@ if (code != CONST_INT || (value = exact_log2 (INTVAL (op))) < 0) output_operand_lossage ("invalid %%p value"); - fprintf (file, "%d", value); + else + fprintf (file, "%d", value); } else if (letter == 'Z') @@ -3238,13 +3259,18 @@ else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG) { - print_operand (file, XEXP (op, 0), letter); + iq2000_print_operand (file, XEXP (op, 0), letter); } else output_addr_const (file, op); } +static bool +iq2000_print_operand_punct_valid_p (unsigned char code) +{ + return iq2000_print_operand_punct[code]; +} /* For the IQ2000, transform: