summaryrefslogtreecommitdiff
path: root/gcc/config/mn10300/mn10300.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mn10300/mn10300.c')
-rw-r--r--gcc/config/mn10300/mn10300.c175
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);