summaryrefslogtreecommitdiff
path: root/gcc/config/s390/s390.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/s390/s390.c')
-rw-r--r--gcc/config/s390/s390.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index b22c9c420d9..7149ae90f75 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -66,6 +66,7 @@ static enum attr_type s390_safe_attr_type PARAMS ((rtx));
static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int s390_issue_rate PARAMS ((void));
static int s390_use_dfa_pipeline_interface PARAMS ((void));
+static bool s390_rtx_costs PARAMS ((rtx, int, int, int *));
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -113,6 +114,8 @@ static int s390_use_dfa_pipeline_interface PARAMS ((void));
#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS s390_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -1192,6 +1195,79 @@ q_constraint (op)
return 1;
}
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
+
+static bool
+s390_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST:
+ if (GET_CODE (XEXP (x, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+ *total = 1000;
+ else
+ *total = 0;
+ return true;
+
+ case CONST_INT:
+ /* Force_const_mem does not work out of reload, because the
+ saveable_obstack is set to reload_obstack, which does not
+ live long enough. Because of this we cannot use force_const_mem
+ in addsi3. This leads to problems with gen_add2_insn with a
+ constant greater than a short. Because of that we give an
+ addition of greater constants a cost of 3 (reload1.c 10096). */
+ /* ??? saveable_obstack no longer exists. */
+ if (outer_code == PLUS
+ && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = 0;
+ return true;
+
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = 0;
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case PLUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case MINUS:
+ case NEG:
+ case NOT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case MULT:
+ if (GET_MODE (XEXP (x, 0)) == DImode)
+ *total = COSTS_N_INSNS (40);
+ else
+ *total = COSTS_N_INSNS (7);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Return the cost of an address rtx ADDR. */
int