aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv/riscv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/riscv/riscv.cc')
-rw-r--r--gcc/config/riscv/riscv.cc78
1 files changed, 70 insertions, 8 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 74462cc..3c1bb74 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -450,6 +450,29 @@ static const struct cpu_vector_cost generic_vector_cost = {
&rvv_regmove_vector_cost, /* regmove */
};
+/* Costs to use when optimizing for generic. */
+static const struct riscv_tune_param generic_tune_info = {
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
+ {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
+ {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */
+ 1, /* issue_rate */
+ 4, /* branch_cost */
+ 5, /* memory_cost */
+ 8, /* fmv_cost */
+ true, /* slow_unaligned_access */
+ false, /* vector_unaligned_access */
+ false, /* use_divmod_expansion */
+ false, /* overlap_op_by_pieces */
+ false, /* speculative_sched_vsetvl */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
+ NULL, /* vector cost */
+ NULL, /* function_align */
+ NULL, /* jump_align */
+ NULL, /* loop_align */
+};
+
/* Costs to use when optimizing for rocket. */
static const struct riscv_tune_param rocket_tune_info = {
{COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
@@ -814,6 +837,16 @@ void riscv_frame_info::reset(void)
arg_pointer_offset = 0;
}
+/* Check if the mode is twice the size of the XLEN mode. */
+
+static bool
+riscv_2x_xlen_mode_p (machine_mode mode)
+{
+ poly_int64 mode_size = GET_MODE_SIZE (mode);
+ return mode_size.is_constant ()
+ && (mode_size.to_constant () == UNITS_PER_WORD * 2);
+}
+
/* Implement TARGET_MIN_ARITHMETIC_PRECISION. */
static unsigned int
@@ -3778,10 +3811,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
return true;
}
- if (TARGET_ZILSD
- && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2))
- && ((REG_P (dest) && MEM_P (src))
- || (MEM_P (dest) && REG_P (src)))
+ if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode)
+ && ((REG_P (dest) && MEM_P (src)) || (MEM_P (dest) && REG_P (src)))
&& can_create_pseudo_p ())
{
rtx reg = REG_P (dest) ? dest : src;
@@ -3868,7 +3899,7 @@ static int
riscv_binary_cost (rtx x, int single_insns, int double_insns)
{
if (!riscv_v_ext_mode_p (GET_MODE (x))
- && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
+ && riscv_2x_xlen_mode_p (GET_MODE (x)))
return COSTS_N_INSNS (double_insns);
return COSTS_N_INSNS (single_insns);
}
@@ -3980,6 +4011,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
case MULT:
case SMAX:
case UMAX:
+ case SMIN:
+ case UMIN:
{
rtx op;
rtx op_0 = XEXP (x, 0);
@@ -4022,10 +4055,41 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return true;
}
+
+ /* Register move for XLEN * 2. */
+ if (TARGET_ZILSD
+ && register_operand (SET_SRC (x), GET_MODE (SET_SRC (x)))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* We still need two instruction for move with ZILSD,
+ but let minus one cost to let subreg split don't.
+ TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (2) - 1;
+ return true;
+ }
+
+ /* Load for XLEN * 2. */
+ if (TARGET_ZILSD && MEM_P (SET_SRC (x))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed);
return true;
}
+ /* Store for XLEN * 2. */
+ if (TARGET_ZILSD && MEM_P (SET_DEST (x)) && REG_P (SET_SRC (x))
+ && riscv_2x_xlen_mode_p (mode))
+ {
+ /* TODO: Add riscv_tune_param for this. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
/* Otherwise return FALSE indicating we should recurse into both the
SET_DEST and SET_SRC combining the cost of both. */
return false;
@@ -9973,9 +10037,7 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
return false;
/* Zilsd require load/store with even-odd reg pair. */
- if (TARGET_ZILSD
- && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2))
- && ((regno % 2) != 0))
+ if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) && ((regno % 2) != 0))
return false;
if (!GP_REG_P (regno + nregs - 1))