diff options
Diffstat (limited to 'gcc/config/s390/s390.c')
-rw-r--r-- | gcc/config/s390/s390.c | 76 |
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 |