diff options
Diffstat (limited to 'gcc/config/mn10300/mn10300.c')
-rw-r--r-- | gcc/config/mn10300/mn10300.c | 175 |
1 files changed, 100 insertions, 75 deletions
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index eb000776750..58c97e8cf7d 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Matsushita MN10300 series - Copyright (C) 1996-2014 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GCC. @@ -23,6 +23,15 @@ #include "coretypes.h" #include "tm.h" #include "rtl.h" +#include "hash-set.h" +#include "machmode.h" +#include "vec.h" +#include "double-int.h" +#include "input.h" +#include "alias.h" +#include "symtab.h" +#include "wide-int.h" +#include "inchash.h" #include "tree.h" #include "stor-layout.h" #include "varasm.h" @@ -36,19 +45,39 @@ #include "flags.h" #include "recog.h" #include "reload.h" +#include "hashtab.h" +#include "function.h" +#include "statistics.h" +#include "real.h" +#include "fixed-value.h" +#include "expmed.h" +#include "dojump.h" +#include "explow.h" +#include "emit-rtl.h" +#include "stmt.h" #include "expr.h" +#include "insn-codes.h" #include "optabs.h" -#include "function.h" #include "obstack.h" #include "diagnostic-core.h" #include "tm_p.h" #include "tm-constrs.h" #include "target.h" #include "target-def.h" +#include "dominance.h" +#include "cfg.h" +#include "cfgrtl.h" +#include "cfganal.h" +#include "lcm.h" +#include "cfgbuild.h" +#include "cfgcleanup.h" +#include "predict.h" +#include "basic-block.h" #include "df.h" #include "opts.h" #include "cfgloop.h" #include "dumpfile.h" +#include "builtins.h" /* This is used in the am33_2.0-linux-gnu port, in which global symbol names are not prefixed by underscores, to tell whether to prefix a @@ -64,7 +93,7 @@ enum processor_type mn10300_tune_cpu = PROCESSOR_DEFAULT; #define CC_FLAG_C 4 #define CC_FLAG_V 8 -static int cc_flags_for_mode(enum machine_mode); +static int cc_flags_for_mode(machine_mode); static int cc_flags_for_code(enum rtx_code); /* Implement TARGET_OPTION_OVERRIDE. */ @@ -145,7 +174,7 @@ mn10300_print_operand (FILE *file, rtx x, int code) case 'B': { enum rtx_code cmp = GET_CODE (x); - enum machine_mode mode = GET_MODE (XEXP (x, 0)); + machine_mode mode = GET_MODE (XEXP (x, 0)); const char *str; int have_flags; @@ -1354,7 +1383,7 @@ mn10300_preferred_output_reload_class (rtx x, reg_class_t rclass) static reg_class_t mn10300_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, - enum machine_mode mode, secondary_reload_info *sri) + machine_mode mode, secondary_reload_info *sri) { enum reg_class rclass = (enum reg_class) rclass_i; enum reg_class xclass = NO_REGS; @@ -1524,7 +1553,7 @@ mn10300_va_start (tree valist, rtx nextarg) static bool mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - enum machine_mode mode, const_tree type, + machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { unsigned HOST_WIDE_INT size; @@ -1541,7 +1570,7 @@ mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, from a function. If the result is NULL_RTX, the argument is pushed. */ static rtx -mn10300_function_arg (cumulative_args_t cum_v, enum machine_mode mode, +mn10300_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -1590,7 +1619,7 @@ mn10300_function_arg (cumulative_args_t cum_v, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -mn10300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, +mn10300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -1604,7 +1633,7 @@ mn10300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, partially in registers and partially in memory. */ static int -mn10300_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, +mn10300_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -1650,7 +1679,7 @@ mn10300_function_value (const_tree valtype, bool outgoing) { rtx rv; - enum machine_mode mode = TYPE_MODE (valtype); + machine_mode mode = TYPE_MODE (valtype); if (! POINTER_TYPE_P (valtype)) return gen_rtx_REG (mode, FIRST_DATA_REGNUM); @@ -1674,7 +1703,7 @@ mn10300_function_value (const_tree valtype, /* Implements TARGET_LIBCALL_VALUE. */ static rtx -mn10300_libcall_value (enum machine_mode mode, +mn10300_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) { return gen_rtx_REG (mode, FIRST_DATA_REGNUM); @@ -1786,7 +1815,7 @@ mn10300_output_add (rtx operands[3], bool need_flags) int mn10300_symbolic_operand (rtx op, - enum machine_mode mode ATTRIBUTE_UNUSED) + machine_mode mode ATTRIBUTE_UNUSED) { switch (GET_CODE (op)) { @@ -1818,7 +1847,7 @@ mn10300_symbolic_operand (rtx op, static rtx mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED) + machine_mode mode ATTRIBUTE_UNUSED) { if (flag_pic && ! mn10300_legitimate_pic_operand_p (x)) x = mn10300_legitimize_pic_address (oldx, NULL_RTX); @@ -1949,7 +1978,7 @@ mn10300_legitimate_pic_operand_p (rtx x) function record_unscaled_index_insn_codes. */ static bool -mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) +mn10300_legitimate_address_p (machine_mode mode, rtx x, bool strict) { rtx base, index; @@ -2017,7 +2046,7 @@ mn10300_regno_in_class_p (unsigned regno, int rclass, bool strict) rtx mn10300_legitimize_reload_address (rtx x, - enum machine_mode mode ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, int opnum, int type, int ind_levels ATTRIBUTE_UNUSED) { @@ -2054,7 +2083,7 @@ mn10300_legitimize_reload_address (rtx x, those here. */ static bool -mn10300_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +mn10300_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) { switch (GET_CODE (x)) { @@ -2160,7 +2189,7 @@ mn10300_delegitimize_address (rtx orig_x) with an address register. */ static int -mn10300_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED, +mn10300_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED, bool speed) { HOST_WIDE_INT i; @@ -2225,7 +2254,7 @@ mn10300_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED, early exit from reload meaning no work is required. */ static int -mn10300_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, +mn10300_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, reg_class_t ifrom, reg_class_t ito) { enum reg_class from = (enum reg_class) ifrom; @@ -2312,7 +2341,7 @@ mn10300_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, move cost above. This is not a problem. */ static int -mn10300_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, +mn10300_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, reg_class_t iclass, bool in ATTRIBUTE_UNUSED) { enum reg_class rclass = (enum reg_class) iclass; @@ -2624,7 +2653,7 @@ mn10300_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED, } bool -mn10300_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) +mn10300_hard_regno_mode_ok (unsigned int regno, machine_mode mode) { if (REGNO_REG_CLASS (regno) == FP_REGS || REGNO_REG_CLASS (regno) == FP_ACC_REGS) @@ -2646,7 +2675,7 @@ mn10300_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) } bool -mn10300_modes_tieable (enum machine_mode mode1, enum machine_mode mode2) +mn10300_modes_tieable (machine_mode mode1, machine_mode mode2) { if (GET_MODE_CLASS (mode1) == MODE_FLOAT && GET_MODE_CLASS (mode2) != MODE_FLOAT) @@ -2665,7 +2694,7 @@ mn10300_modes_tieable (enum machine_mode mode1, enum machine_mode mode2) } static int -cc_flags_for_mode (enum machine_mode mode) +cc_flags_for_mode (machine_mode mode) { switch (mode) { @@ -2723,7 +2752,7 @@ cc_flags_for_code (enum rtx_code code) } } -enum machine_mode +machine_mode mn10300_select_cc_mode (enum rtx_code code, rtx x, rtx y ATTRIBUTE_UNUSED) { int req; @@ -2741,21 +2770,15 @@ mn10300_select_cc_mode (enum rtx_code code, rtx x, rtx y ATTRIBUTE_UNUSED) } static inline bool -is_load_insn (rtx insn) +set_is_load_p (rtx set) { - if (GET_CODE (PATTERN (insn)) != SET) - return false; - - return MEM_P (SET_SRC (PATTERN (insn))); + return MEM_P (SET_SRC (set)); } static inline bool -is_store_insn (rtx insn) +set_is_store_p (rtx set) { - if (GET_CODE (PATTERN (insn)) != SET) - return false; - - return MEM_P (SET_DEST (PATTERN (insn))); + return MEM_P (SET_DEST (set)); } /* Update scheduling costs for situations that cannot be @@ -2765,35 +2788,38 @@ is_store_insn (rtx insn) COST is the current cycle cost for DEP. */ static int -mn10300_adjust_sched_cost (rtx insn, rtx link, rtx dep, int cost) +mn10300_adjust_sched_cost (rtx_insn *insn, rtx link, rtx_insn *dep, int cost) { - int timings = get_attr_timings (insn); + rtx insn_set; + rtx dep_set; + int timings; if (!TARGET_AM33) return 1; - if (GET_CODE (insn) == PARALLEL) - insn = XVECEXP (insn, 0, 0); + /* We are only interested in pairs of SET. */ + insn_set = single_set (insn); + if (!insn_set) + return cost; - if (GET_CODE (dep) == PARALLEL) - dep = XVECEXP (dep, 0, 0); + dep_set = single_set (dep); + if (!dep_set) + return cost; /* For the AM34 a load instruction that follows a store instruction incurs an extra cycle of delay. */ if (mn10300_tune_cpu == PROCESSOR_AM34 - && is_load_insn (dep) - && is_store_insn (insn)) + && set_is_load_p (dep_set) + && set_is_store_p (insn_set)) cost += 1; /* For the AM34 a non-store, non-branch FPU insn that follows another FPU insn incurs a one cycle throughput increase. */ else if (mn10300_tune_cpu == PROCESSOR_AM34 - && ! is_store_insn (insn) + && ! set_is_store_p (insn_set) && ! JUMP_P (insn) - && GET_CODE (PATTERN (dep)) == SET - && GET_CODE (PATTERN (insn)) == SET - && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) == MODE_FLOAT - && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) == MODE_FLOAT) + && GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) == MODE_FLOAT + && GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) == MODE_FLOAT) cost += 1; /* Resolve the conflict described in section 1-7-4 of @@ -2815,23 +2841,21 @@ mn10300_adjust_sched_cost (rtx insn, rtx link, rtx dep, int cost) return cost; /* Check that the instruction about to scheduled is an FPU instruction. */ - if (GET_CODE (PATTERN (dep)) != SET) - return cost; - - if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) != MODE_FLOAT) + if (GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) != MODE_FLOAT) return cost; /* Now check to see if the previous instruction is a load or store. */ - if (! is_load_insn (insn) && ! is_store_insn (insn)) + if (! set_is_load_p (insn_set) && ! set_is_store_p (insn_set)) return cost; /* XXX: Verify: The text of 1-7-4 implies that the restriction only applies when an INTEGER load/store precedes an FPU instruction, but is this true ? For now we assume that it is. */ - if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) != MODE_INT) + if (GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) != MODE_INT) return cost; /* Extract the latency value from the timings attribute. */ + timings = get_attr_timings (insn); return timings < 100 ? (timings % 10) : (timings % 100); } @@ -2874,7 +2898,7 @@ mn10300_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED, /* A helper function for splitting cbranch patterns after reload. */ void -mn10300_split_cbranch (enum machine_mode cmp_mode, rtx cmp_op, rtx label_ref) +mn10300_split_cbranch (machine_mode cmp_mode, rtx cmp_op, rtx label_ref) { rtx flags, x; @@ -2892,10 +2916,10 @@ mn10300_split_cbranch (enum machine_mode cmp_mode, rtx cmp_op, rtx label_ref) /* A helper function for matching parallels that set the flags. */ bool -mn10300_match_ccmode (rtx insn, enum machine_mode cc_mode) +mn10300_match_ccmode (rtx insn, machine_mode cc_mode) { rtx op1, flags; - enum machine_mode flags_mode; + machine_mode flags_mode; gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2); @@ -2978,14 +3002,14 @@ struct liw_data cannot be bundled. */ static bool -extract_bundle (rtx insn, struct liw_data * pdata) +extract_bundle (rtx_insn *insn, struct liw_data * pdata) { bool allow_consts = true; rtx p; gcc_assert (pdata != NULL); - if (insn == NULL_RTX) + if (insn == NULL) return false; /* Make sure that we are dealing with a simple SET insn. */ p = single_set (insn); @@ -3104,11 +3128,11 @@ check_liw_constraints (struct liw_data * pliw1, struct liw_data * pliw2) static void mn10300_bundle_liw (void) { - rtx r; + rtx_insn *r; - for (r = get_insns (); r != NULL_RTX; r = next_nonnote_nondebug_insn (r)) + for (r = get_insns (); r != NULL; r = next_nonnote_nondebug_insn (r)) { - rtx insn1, insn2; + rtx_insn *insn1, *insn2; struct liw_data liw1, liw2; insn1 = r; @@ -3134,17 +3158,18 @@ mn10300_bundle_liw (void) delete_insn (insn2); + rtx insn2_pat; if (liw1.op == LIW_OP_CMP) - insn2 = gen_cmp_liw (liw2.dest, liw2.src, liw1.dest, liw1.src, - GEN_INT (liw2.op)); + insn2_pat = gen_cmp_liw (liw2.dest, liw2.src, liw1.dest, liw1.src, + GEN_INT (liw2.op)); else if (liw2.op == LIW_OP_CMP) - insn2 = gen_liw_cmp (liw1.dest, liw1.src, liw2.dest, liw2.src, - GEN_INT (liw1.op)); + insn2_pat = gen_liw_cmp (liw1.dest, liw1.src, liw2.dest, liw2.src, + GEN_INT (liw1.op)); else - insn2 = gen_liw (liw1.dest, liw2.dest, liw1.src, liw2.src, - GEN_INT (liw1.op), GEN_INT (liw2.op)); + insn2_pat = gen_liw (liw1.dest, liw2.dest, liw1.src, liw2.src, + GEN_INT (liw1.op), GEN_INT (liw2.op)); - insn2 = emit_insn_after (insn2, insn1); + insn2 = emit_insn_after (insn2_pat, insn1); delete_insn (insn1); r = insn2; } @@ -3173,7 +3198,7 @@ mn10300_insert_setlb_lcc (rtx label, rtx branch) if (LABEL_NUSES (label) > 1) { - rtx insn; + rtx_insn *insn; /* This label is used both as an entry point to the loop and as a loop-back point for the loop. We need to separate @@ -3204,18 +3229,18 @@ mn10300_insert_setlb_lcc (rtx label, rtx branch) else lcc = gen_Lcc (comparison, label); - lcc = emit_jump_insn_before (lcc, branch); - mark_jump_label (XVECEXP (PATTERN (lcc), 0, 0), lcc, 0); - JUMP_LABEL (lcc) = label; + rtx_insn *jump = emit_jump_insn_before (lcc, branch); + mark_jump_label (XVECEXP (lcc, 0, 0), jump, 0); + JUMP_LABEL (jump) = label; DUMP ("Replacing branch insn...", branch); - DUMP ("... with Lcc insn:", lcc); + DUMP ("... with Lcc insn:", jump); delete_insn (branch); } static bool mn10300_block_contains_call (basic_block block) { - rtx insn; + rtx_insn *insn; FOR_BB_INSNS (block, insn) if (CALL_P (insn)) @@ -3278,7 +3303,7 @@ mn10300_scan_for_setlb_lcc (void) reason = "it contains CALL insns"; else { - rtx branch = BB_END (loop->latch); + rtx_insn *branch = BB_END (loop->latch); gcc_assert (JUMP_P (branch)); if (single_set (branch) == NULL_RTX || ! any_condjump_p (branch)) @@ -3287,7 +3312,7 @@ mn10300_scan_for_setlb_lcc (void) reason = "it is not a simple loop"; else { - rtx label; + rtx_insn *label; if (dump_file) flow_loop_dump (loop, dump_file, NULL, 0); |