Mercurial > hg > CbC > CbC_gcc
diff gcc/config/iq2000/iq2000.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/config/iq2000/iq2000.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/iq2000/iq2000.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,6 +1,5 @@ /* Subroutines used for code generation on Vitesse IQ2000 processors - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 2003-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -21,30 +20,32 @@ #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" +#include "backend.h" +#include "target.h" +#include "rtl.h" #include "tree.h" -#include "rtl.h" +#include "stringpool.h" +#include "attribs.h" +#include "df.h" +#include "memmodel.h" +#include "tm_p.h" +#include "optabs.h" #include "regs.h" -#include "hard-reg-set.h" -#include "insn-config.h" -#include "conditions.h" +#include "emit-rtl.h" +#include "recog.h" +#include "diagnostic-core.h" +#include "stor-layout.h" +#include "calls.h" +#include "varasm.h" #include "output.h" #include "insn-attr.h" -#include "flags.h" -#include "function.h" +#include "explow.h" #include "expr.h" -#include "optabs.h" -#include "libfuncs.h" -#include "recog.h" -#include "diagnostic-core.h" -#include "reload.h" -#include "ggc.h" -#include "tm_p.h" -#include "debug.h" -#include "target.h" +#include "langhooks.h" +#include "builtins.h" + +/* This file should be included last. */ #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 @@ -111,9 +112,6 @@ /* 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; - /* Which instruction set architecture to use. */ int iq2000_isa; @@ -140,52 +138,50 @@ static rtx iq2000_load_reg4; /* Mode used for saving/restoring general purpose registers. */ -static enum machine_mode gpr_mode; +static machine_mode gpr_mode; /* 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, +static section *iq2000_select_rtx_section (machine_mode, rtx, unsigned HOST_WIDE_INT); static void iq2000_init_builtins (void); -static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); +static rtx iq2000_expand_builtin (tree, rtx, rtx, machine_mode, int); static bool iq2000_return_in_memory (const_tree, const_tree); -static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *, - enum machine_mode, tree, int *, +static void iq2000_setup_incoming_varargs (cumulative_args_t, + machine_mode, tree, int *, int); -static bool iq2000_rtx_costs (rtx, int, int, int *, bool); -static int iq2000_address_cost (rtx, bool); +static bool iq2000_rtx_costs (rtx, machine_mode, int, int, int *, bool); +static int iq2000_address_cost (rtx, machine_mode, addr_space_t, + bool); static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); -static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode); -static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static rtx iq2000_legitimize_address (rtx, rtx, machine_mode); +static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode, const_tree, bool); -static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int iq2000_arg_partial_bytes (cumulative_args_t, 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, +static rtx iq2000_function_arg (cumulative_args_t, + machine_mode, const_tree, bool); +static void iq2000_function_arg_advance (cumulative_args_t, + machine_mode, const_tree, bool); +static pad_direction iq2000_function_arg_padding (machine_mode, const_tree); +static unsigned int iq2000_function_arg_boundary (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_legitimate_address_p (machine_mode, rtx, bool); static bool iq2000_can_eliminate (const int, const int); static void iq2000_asm_trampoline_template (FILE *); 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 rtx iq2000_libcall_value (machine_mode, const_rtx); static void iq2000_print_operand (FILE *, rtx, int); -static void iq2000_print_operand_address (FILE *, rtx); +static void iq2000_print_operand_address (FILE *, machine_mode, 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 } - }; +static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode); +static bool iq2000_modes_tieable_p (machine_mode, machine_mode); +static HOST_WIDE_INT iq2000_constant_alignment (const_tree, HOST_WIDE_INT); +static HOST_WIDE_INT iq2000_starting_frame_offset (void); #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS iq2000_init_builtins @@ -193,12 +189,8 @@ #define TARGET_EXPAND_BUILTIN iq2000_expand_builtin #undef TARGET_ASM_SELECT_RTX_SECTION #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 @@ -242,6 +234,8 @@ #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_PADDING +#define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding #undef TARGET_FUNCTION_ARG_BOUNDARY #define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary @@ -253,6 +247,9 @@ #undef TARGET_EXPAND_BUILTIN_VA_START #define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start +#undef TARGET_LRA_P +#define TARGET_LRA_P hook_bool_void_false + #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p @@ -264,12 +261,23 @@ #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT iq2000_trampoline_init +#undef TARGET_HARD_REGNO_MODE_OK +#define TARGET_HARD_REGNO_MODE_OK iq2000_hard_regno_mode_ok +#undef TARGET_MODES_TIEABLE_P +#define TARGET_MODES_TIEABLE_P iq2000_modes_tieable_p + +#undef TARGET_CONSTANT_ALIGNMENT +#define TARGET_CONSTANT_ALIGNMENT iq2000_constant_alignment + +#undef TARGET_STARTING_FRAME_OFFSET +#define TARGET_STARTING_FRAME_OFFSET iq2000_starting_frame_offset + struct gcc_target targetm = TARGET_INITIALIZER; /* Return nonzero if we split the address into high and low parts. */ int -iq2000_check_split (rtx address, enum machine_mode mode) +iq2000_check_split (rtx address, machine_mode mode) { /* This is the same check used in simple_memory_operand. We use it here because LO_SUM is not offsettable. */ @@ -289,7 +297,7 @@ int iq2000_reg_mode_ok_for_base_p (rtx reg, - enum machine_mode mode ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, int strict) { return (strict @@ -302,7 +310,7 @@ function is called during reload. */ bool -iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict) +iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict) { if (TARGET_DEBUG_A_MODE) { @@ -363,7 +371,7 @@ } if (TARGET_DEBUG_A_MODE) - GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n"); + GO_PRINTF ("Not a machine_mode mode, legitimate address\n"); /* The address was not legitimate. */ return 0; @@ -380,11 +388,11 @@ const char * iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[], - rtx cur_insn) + rtx_insn *cur_insn) { rtx set_reg; - enum machine_mode mode; - rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX; + machine_mode mode; + rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL; int num_nops; if (type == DELAY_LOAD || type == DELAY_FCMP) @@ -396,8 +404,7 @@ /* Make sure that we don't put nop's after labels. */ next_insn = NEXT_INSN (cur_insn); while (next_insn != 0 - && (GET_CODE (next_insn) == NOTE - || GET_CODE (next_insn) == CODE_LABEL)) + && (NOTE_P (next_insn) || LABEL_P (next_insn))) next_insn = NEXT_INSN (next_insn); dslots_load_total += num_nops; @@ -406,7 +413,7 @@ || operands == 0 || cur_insn == 0 || next_insn == 0 - || GET_CODE (next_insn) == CODE_LABEL + || LABEL_P (next_insn) || (set_reg = operands[0]) == 0) { dslots_number_nops = 0; @@ -564,14 +571,14 @@ /* Return the appropriate instructions to move one operand to another. */ const char * -iq2000_move_1word (rtx operands[], rtx insn, int unsignedp) +iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp) { const char *ret = 0; rtx op0 = operands[0]; rtx op1 = operands[1]; enum rtx_code code0 = GET_CODE (op0); enum rtx_code code1 = GET_CODE (op1); - enum machine_mode mode = GET_MODE (op0); + machine_mode mode = GET_MODE (op0); int subreg_offset0 = 0; int subreg_offset1 = 0; enum delay_type delay = DELAY_NONE; @@ -635,17 +642,17 @@ { default: break; - case SFmode: + case E_SFmode: ret = "lw\t%0,%1"; break; - case SImode: - case CCmode: + case E_SImode: + case E_CCmode: ret = "lw\t%0,%1"; break; - case HImode: + case E_HImode: ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; break; - case QImode: + case E_QImode: ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; break; } @@ -745,10 +752,10 @@ { switch (mode) { - case SFmode: ret = "sw\t%1,%0"; break; - case SImode: ret = "sw\t%1,%0"; break; - case HImode: ret = "sh\t%1,%0"; break; - case QImode: ret = "sb\t%1,%0"; break; + case E_SFmode: ret = "sw\t%1,%0"; break; + case E_SImode: ret = "sw\t%1,%0"; break; + case E_HImode: ret = "sh\t%1,%0"; break; + case E_QImode: ret = "sb\t%1,%0"; break; default: break; } } @@ -758,10 +765,10 @@ { switch (mode) { - case SFmode: ret = "sw\t%z1,%0"; break; - case SImode: ret = "sw\t%z1,%0"; break; - case HImode: ret = "sh\t%z1,%0"; break; - case QImode: ret = "sb\t%z1,%0"; break; + case E_SFmode: ret = "sw\t%z1,%0"; break; + case E_SImode: ret = "sw\t%z1,%0"; break; + case E_HImode: ret = "sh\t%z1,%0"; break; + case E_QImode: ret = "sb\t%z1,%0"; break; default: break; } } @@ -770,10 +777,10 @@ { switch (mode) { - case SFmode: ret = "sw\t%.,%0"; break; - case SImode: ret = "sw\t%.,%0"; break; - case HImode: ret = "sh\t%.,%0"; break; - case QImode: ret = "sb\t%.,%0"; break; + case E_SFmode: ret = "sw\t%.,%0"; break; + case E_SImode: ret = "sw\t%.,%0"; break; + case E_HImode: ret = "sh\t%.,%0"; break; + case E_QImode: ret = "sb\t%.,%0"; break; default: break; } } @@ -794,7 +801,8 @@ /* Provide the costs of an addressing mode that contains ADDR. */ static int -iq2000_address_cost (rtx addr, bool speed) +iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as, + bool speed) { switch (GET_CODE (addr)) { @@ -845,7 +853,7 @@ case LABEL_REF: case HIGH: case LO_SUM: - return iq2000_address_cost (plus1, speed) + 1; + return iq2000_address_cost (plus1, mode, as, speed) + 1; default: break; @@ -921,7 +929,7 @@ }; enum internal_test test; - enum machine_mode mode; + machine_mode mode; struct cmp_info *p_info; int branch_p; int eqne_p; @@ -1055,7 +1063,7 @@ The comparison operands are saved away by cmp{si,di,sf,df}. */ void -gen_conditional_branch (rtx operands[], enum machine_mode mode) +gen_conditional_branch (rtx operands[], machine_mode mode) { enum rtx_code test_code = GET_CODE (operands[0]); rtx cmp0 = operands[1]; @@ -1088,10 +1096,10 @@ label1 = pc_rtx; } - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, + emit_jump_insn (gen_rtx_SET (pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, gen_rtx_fmt_ee (test_code, - mode, + VOIDmode, cmp0, cmp1), label1, label2))); } @@ -1119,8 +1127,8 @@ tree ret_type = TREE_TYPE (fntype); fprintf (stderr, ", fntype code = %s, ret code = %s\n", - tree_code_name[(int)TREE_CODE (fntype)], - tree_code_name[(int)TREE_CODE (ret_type)]); + get_tree_code_name (TREE_CODE (fntype)), + get_tree_code_name (TREE_CODE (ret_type))); } } @@ -1144,23 +1152,25 @@ position in CUM. */ static void -iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (TARGET_DEBUG_D_MODE) { fprintf (stderr, "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", CONST_CAST2 (void *, const_tree, type)); + fprintf (stderr, "%p", (const void *) type); fprintf (stderr, ", %d )\n\n", named); } cum->arg_number++; switch (mode) { - case VOIDmode: + case E_VOIDmode: break; default: @@ -1172,37 +1182,37 @@ / UNITS_PER_WORD); break; - case BLKmode: + case E_BLKmode: cum->gp_reg_found = 1; cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); break; - case SFmode: + case E_SFmode: cum->arg_words ++; if (! cum->gp_reg_found && cum->arg_number <= 2) cum->fp_code += 1 << ((cum->arg_number - 1) * 2); break; - case DFmode: + case E_DFmode: cum->arg_words += 2; if (! cum->gp_reg_found && cum->arg_number <= 2) cum->fp_code += 2 << ((cum->arg_number - 1) * 2); break; - case DImode: + case E_DImode: cum->gp_reg_found = 1; cum->arg_words += 2; break; - case TImode: + case E_TImode: cum->gp_reg_found = 1; cum->arg_words += 4; break; - case QImode: - case HImode: - case SImode: + case E_QImode: + case E_HImode: + case E_SImode: cum->gp_reg_found = 1; cum->arg_words ++; break; @@ -1213,9 +1223,10 @@ and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ static rtx -iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); rtx ret; int regbase = -1; int bias = 0; @@ -1239,11 +1250,11 @@ cum->last_arg_fp = 0; switch (mode) { - case SFmode: + case E_SFmode: regbase = GP_ARG_FIRST; break; - case DFmode: + case E_DFmode: cum->arg_words += cum->arg_words & 1; regbase = GP_ARG_FIRST; @@ -1253,26 +1264,26 @@ gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT); - /* Drops through. */ - case BLKmode: + /* FALLTHRU */ + case E_BLKmode: if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD) cum->arg_words += (cum->arg_words & 1); regbase = GP_ARG_FIRST; break; - case VOIDmode: - case QImode: - case HImode: - case SImode: + case E_VOIDmode: + case E_QImode: + case E_HImode: + case E_SImode: regbase = GP_ARG_FIRST; break; - case DImode: + case E_DImode: cum->arg_words += (cum->arg_words & 1); regbase = GP_ARG_FIRST; break; - case TImode: + case E_TImode: cum->arg_words += (cum->arg_words & 3); regbase = GP_ARG_FIRST; break; @@ -1291,7 +1302,7 @@ if (! type || TREE_CODE (type) != RECORD_TYPE || ! named || ! TYPE_SIZE_UNIT (type) - || ! host_integerp (TYPE_SIZE_UNIT (type), 1)) + || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))) ret = gen_rtx_REG (mode, regbase + *arg_words + bias); else { @@ -1301,7 +1312,7 @@ if (TREE_CODE (field) == FIELD_DECL && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD - && host_integerp (bit_position (field), 0) + && tree_fits_shwi_p (bit_position (field)) && int_bit_position (field) % BITS_PER_WORD == 0) break; @@ -1319,7 +1330,7 @@ /* ??? If this is a packed structure, then the last hunk won't be 64 bits. */ chunks - = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD; + = tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD; if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS) chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias; @@ -1369,15 +1380,31 @@ if (mode == VOIDmode) { if (cum->num_adjusts > 0) - ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code, + ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code, gen_rtvec_v (cum->num_adjusts, cum->adjust)); } return ret; } +/* Implement TARGET_FUNCTION_ARG_PADDING. */ + +static pad_direction +iq2000_function_arg_padding (machine_mode mode, const_tree type) +{ + return (! BYTES_BIG_ENDIAN + ? PAD_UPWARD + : ((mode == BLKmode + ? (type + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST + && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT)) + : (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY + && GET_MODE_CLASS (mode) == MODE_INT)) + ? PAD_DOWNWARD : PAD_UPWARD)); +} + static unsigned int -iq2000_function_arg_boundary (enum machine_mode mode, const_tree type) +iq2000_function_arg_boundary (machine_mode mode, const_tree type) { return (type != NULL_TREE ? (TYPE_ALIGN (type) <= PARM_BOUNDARY @@ -1389,10 +1416,12 @@ } static int -iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1) { if (TARGET_DEBUG_D_MODE) @@ -1422,7 +1451,7 @@ /* Everything is in the GPR save area, or in the overflow area which is contiguous with it. */ - nextarg = plus_constant (nextarg, - gpr_save_area_size); + nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size); std_expand_builtin_va_start (valist, nextarg); } @@ -1431,34 +1460,7 @@ static struct machine_function * iq2000_init_machine_status (void) { - return ggc_alloc_cleared_machine_function (); -} - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) -{ - switch (code) - { - case OPT_mcpu_: - if (strcmp (arg, "iq10") == 0) - iq2000_tune = PROCESSOR_IQ10; - else if (strcmp (arg, "iq2000") == 0) - iq2000_tune = PROCESSOR_IQ2000; - else - return false; - return true; - - case OPT_march_: - /* This option has no effect at the moment. */ - return (strcmp (arg, "default") == 0 - || strcmp (arg, "DEFAULT") == 0 - || strcmp (arg, "iq2000") == 0); - - default: - return true; - } + return ggc_cleared_alloc<machine_function> (); } /* Detect any conflicts in the switches. */ @@ -1540,7 +1542,7 @@ of load delays, and also to update the delay slot statistics. */ void -final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, +final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED, int noperands ATTRIBUTE_UNUSED) { if (dslots_number_nops > 0) @@ -1569,18 +1571,23 @@ iq2000_load_reg4 = 0; } - if ( (GET_CODE (insn) == JUMP_INSN - || GET_CODE (insn) == CALL_INSN + if ( (JUMP_P (insn) + || CALL_P (insn) || (GET_CODE (PATTERN (insn)) == RETURN)) && NEXT_INSN (PREV_INSN (insn)) == insn) { - rtx nop_insn = emit_insn_after (gen_nop (), insn); - + rtx_insn *tmp = insn; + while (NEXT_INSN (tmp) + && NOTE_P (NEXT_INSN (tmp)) + && NOTE_KIND (NEXT_INSN (tmp)) == NOTE_INSN_CALL_ARG_LOCATION) + tmp = NEXT_INSN (tmp); + + rtx_insn *nop_insn = emit_insn_after (gen_nop (), tmp); INSN_ADDRESSES_NEW (nop_insn, -1); } if (TARGET_STATS - && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)) + && (JUMP_P (insn) || CALL_P (insn))) dslots_jump_total ++; } @@ -1806,7 +1813,7 @@ operation DWARF_PATTERN. */ static void -iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern) +iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern) { RTX_FRAME_RELATED_P (insn) = 1; REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, @@ -1820,11 +1827,11 @@ static void iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset) { - rtx dwarf_address = plus_constant (stack_pointer_rtx, offset); + rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset); rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address); iq2000_annotate_frame_insn (emit_move_insn (mem, reg), - gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg)); + gen_rtx_SET (dwarf_mem, reg)); } /* Emit instructions to save/restore registers, as determined by STORE_P. */ @@ -1921,7 +1928,8 @@ int i; tree next_arg; tree cur_arg; - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; int store_args_on_stack = (iq2000_can_use_return_insn ()); /* If struct value address is treated as the first argument. */ @@ -1945,13 +1953,14 @@ variable arguments. This is only needed if store_args_on_stack is true. */ - INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0); + INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0); + args_so_far = pack_cumulative_args (&args_so_far_v); regno = GP_ARG_FIRST; for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg) { tree passed_type = DECL_ARG_TYPE (cur_arg); - enum machine_mode passed_mode = TYPE_MODE (passed_type); + machine_mode passed_mode = TYPE_MODE (passed_type); rtx entry_parm; if (TREE_ADDRESSABLE (passed_type)) @@ -1960,10 +1969,10 @@ passed_mode = Pmode; } - entry_parm = iq2000_function_arg (&args_so_far, passed_mode, + entry_parm = iq2000_function_arg (args_so_far, passed_mode, passed_type, true); - iq2000_function_arg_advance (&args_so_far, passed_mode, + iq2000_function_arg_advance (args_so_far, passed_mode, passed_type, true); next_arg = DECL_CHAIN (cur_arg); @@ -2006,7 +2015,7 @@ 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, + 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) { @@ -2052,7 +2061,8 @@ if (tsize > 0) { rtx tsize_rtx = GEN_INT (tsize); - rtx adjustment_rtx, insn, dwarf_pattern; + rtx adjustment_rtx, dwarf_pattern; + rtx_insn *insn; if (tsize > 32767) { @@ -2065,8 +2075,9 @@ insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, adjustment_rtx)); - dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx, - plus_constant (stack_pointer_rtx, -tsize)); + dwarf_pattern = gen_rtx_SET (stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, + -tsize)); iq2000_annotate_frame_insn (insn, dwarf_pattern); @@ -2074,7 +2085,7 @@ if (frame_pointer_needed) { - rtx insn = 0; + rtx_insn *insn = 0; insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx)); @@ -2084,6 +2095,9 @@ } } + if (flag_stack_usage_info) + current_function_static_stack_size = cfun->machine->total_size; + emit_insn (gen_blockage ()); } @@ -2155,7 +2169,7 @@ HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset; rtx scratch; - scratch = plus_constant (stack_pointer_rtx, gp_offset); + scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset); emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address); } @@ -2182,7 +2196,7 @@ mode MODE. */ static section * -iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED, +iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED, unsigned HOST_WIDE_INT align) { /* For embedded applications, always put constants in read-only data, @@ -2241,7 +2255,7 @@ bool outgoing ATTRIBUTE_UNUSED) { int reg = GP_RETURN; - enum machine_mode mode = TYPE_MODE (valtype); + machine_mode mode = TYPE_MODE (valtype); int unsignedp = TYPE_UNSIGNED (valtype); const_tree func = fn_decl_or_type; @@ -2258,7 +2272,7 @@ /* Worker function for TARGET_LIBCALL_VALUE. */ static rtx -iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) +iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) { return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT || GET_MODE_SIZE (mode) >= 4) @@ -2280,9 +2294,10 @@ /* Return true when an argument must be passed by reference. */ static bool -iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int size; /* We must pass by reference if we would be both passing in registers @@ -2296,7 +2311,8 @@ CUMULATIVE_ARGS temp; temp = *cum; - if (iq2000_function_arg (&temp, mode, type, named) != 0) + if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named) + != 0) return 1; } @@ -2311,13 +2327,13 @@ attributes in the machine-description file. */ int -iq2000_adjust_insn_length (rtx insn, int length) +iq2000_adjust_insn_length (rtx_insn *insn, int length) { /* A unconditional jump has an unfilled delay slot if it is not part of a sequence. A conditional jump normally has a delay slot. */ if (simplejump_p (insn) - || ( (GET_CODE (insn) == JUMP_INSN - || GET_CODE (insn) == CALL_INSN))) + || ( (JUMP_P (insn) + || CALL_P (insn)))) length += 4; return length; @@ -2339,8 +2355,9 @@ reversed conditional branch around a `jr' instruction. */ char * -iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p, - int float_p, int inverted_p, int length) +iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands, + int two_operands_p, int float_p, + int inverted_p, int length) { static char buffer[200]; /* The kind of comparison we are doing. */ @@ -2499,7 +2516,6 @@ static void iq2000_init_builtins (void) { - tree endlink = void_list_node; tree void_ftype, void_ftype_int, void_ftype_int_int; tree void_ftype_int_int_int; tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int; @@ -2507,76 +2523,55 @@ /* func () */ void_ftype - = build_function_type (void_type_node, - tree_cons (NULL_TREE, void_type_node, endlink)); + = build_function_type_list (void_type_node, NULL_TREE); /* func (int) */ void_ftype_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, integer_type_node, endlink)); + = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); /* void func (int, int) */ void_ftype_int_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))); + = build_function_type_list (void_type_node, + integer_type_node, + integer_type_node, + NULL_TREE); /* int func (int) */ int_ftype_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, endlink)); + = build_function_type_list (integer_type_node, + integer_type_node, NULL_TREE); /* int func (int, int) */ int_ftype_int_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - endlink))); + = build_function_type_list (integer_type_node, + integer_type_node, + integer_type_node, + NULL_TREE); /* void func (int, int, int) */ -void_ftype_int_int_int - = build_function_type - (void_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)))); + void_ftype_int_int_int + = build_function_type_list (void_type_node, + integer_type_node, + integer_type_node, + integer_type_node, + NULL_TREE); + + /* int func (int, int, int) */ + int_ftype_int_int_int + = build_function_type_list (integer_type_node, + integer_type_node, + integer_type_node, + integer_type_node, + NULL_TREE); /* int func (int, int, int, int) */ int_ftype_int_int_int_int - = build_function_type - (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink))))); - - /* int func (int, int, int) */ - int_ftype_int_int_int - = build_function_type - (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)))); - - /* int func (int, int, int, int) */ - int_ftype_int_int_int_int - = build_function_type - (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink))))); + = build_function_type_list (integer_type_node, + integer_type_node, + integer_type_node, + integer_type_node, + integer_type_node, + NULL_TREE); def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16); def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM); @@ -2636,7 +2631,7 @@ rtx pat; tree arg [5]; rtx op [5]; - enum machine_mode mode [5]; + machine_mode mode [5]; int i; mode[0] = insn_data[icode].operand[0].mode; @@ -2666,6 +2661,7 @@ { case 0: pat = GEN_FCN (icode) (target); + break; case 1: if (target) pat = GEN_FCN (icode) (target, op[0]); @@ -2708,7 +2704,7 @@ static rtx iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED) { tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); @@ -2899,11 +2895,12 @@ /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum, - enum machine_mode mode ATTRIBUTE_UNUSED, +iq2000_setup_incoming_varargs (cumulative_args_t cum_v, + machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int * pretend_size, int no_rtl) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); unsigned int iq2000_off = ! cum->last_arg_fp; unsigned int iq2000_fp_off = cum->last_arg_fp; @@ -2927,9 +2924,9 @@ if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off) { rtx ptr, mem; - ptr = plus_constant (virtual_incoming_args_rtx, - - (iq2000_save_gp_regs - * UNITS_PER_WORD)); + ptr = plus_constant (Pmode, virtual_incoming_args_rtx, + - (iq2000_save_gp_regs + * UNITS_PER_WORD)); mem = gen_rtx_MEM (BLKmode, ptr); move_block_from_reg (cum->arg_words + GP_ARG_FIRST + iq2000_off, @@ -2945,7 +2942,7 @@ reference whose address is ADDR. ADDR is an RTL expression. */ static void -iq2000_print_operand_address (FILE * file, rtx addr) +iq2000_print_operand_address (FILE * file, machine_mode mode, rtx addr) { if (!addr) error ("PRINT_OPERAND_ADDRESS, null pointer"); @@ -2970,7 +2967,7 @@ "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."); fprintf (file, "%%lo("); - iq2000_print_operand_address (file, arg1); + iq2000_print_operand_address (file, mode, arg1); fprintf (file, ")(%s)", reg_names [REGNO (arg0)]); } break; @@ -3218,10 +3215,12 @@ else if (code == MEM) { + machine_mode mode = GET_MODE (op); + if (letter == 'D') - output_address (plus_constant (XEXP (op, 0), 4)); + output_address (mode, plus_constant (Pmode, XEXP (op, 0), 4)); else - output_address (XEXP (op, 0)); + output_address (mode, XEXP (op, 0)); } else if (code == CONST_DOUBLE @@ -3283,7 +3282,7 @@ rtx iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED, - enum machine_mode mode) + machine_mode mode) { if (TARGET_DEBUG_B_MODE) { @@ -3323,11 +3322,10 @@ emit_move_insn (int_reg, GEN_INT (INTVAL (xplus1) & ~ 0x7fff)); - emit_insn (gen_rtx_SET (VOIDmode, - ptr_reg, + emit_insn (gen_rtx_SET (ptr_reg, gen_rtx_PLUS (Pmode, xplus0, int_reg))); - return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff); + return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff); } } @@ -3339,10 +3337,11 @@ static bool -iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total, +iq2000_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, int * total, bool speed ATTRIBUTE_UNUSED) { - enum machine_mode mode = GET_MODE (x); + int code = GET_CODE (x); switch (code) { @@ -3351,7 +3350,7 @@ int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1; if (simple_memory_operand (x, mode)) - return COSTS_N_INSNS (num_words); + return COSTS_N_INSNS (num_words) != 0; * total = COSTS_N_INSNS (2 * num_words); break; @@ -3520,4 +3519,43 @@ emit_move_insn (mem, chain_value); } +/* Implement TARGET_HARD_REGNO_MODE_OK. */ + +static bool +iq2000_hard_regno_mode_ok (unsigned int regno, machine_mode mode) +{ + return (REGNO_REG_CLASS (regno) == GR_REGS + ? (regno & 1) == 0 || GET_MODE_SIZE (mode) <= 4 + : (regno & 1) == 0 || GET_MODE_SIZE (mode) == 4); +} + +/* Implement TARGET_MODES_TIEABLE_P. */ + +static bool +iq2000_modes_tieable_p (machine_mode mode1, machine_mode mode2) +{ + return ((GET_MODE_CLASS (mode1) == MODE_FLOAT + || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT) + == (GET_MODE_CLASS (mode2) == MODE_FLOAT + || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); +} + +/* Implement TARGET_CONSTANT_ALIGNMENT. */ + +static HOST_WIDE_INT +iq2000_constant_alignment (const_tree exp, HOST_WIDE_INT align) +{ + if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR) + return MAX (align, BITS_PER_WORD); + return align; +} + +/* Implement TARGET_STARTING_FRAME_OFFSET. */ + +static HOST_WIDE_INT +iq2000_starting_frame_offset (void) +{ + return crtl->outgoing_args_size; +} + #include "gt-iq2000.h"