summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-28 04:46:33 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-28 04:46:33 +0000
commitfab7adbfb5b8861f87531f939ad03f891bba055a (patch)
tree1eaff917ba37b6f409082db1a76c42c218320c5e /gcc
parentbb5d2966d86c25ca14d0d12cb96249b8069e0ab1 (diff)
downloadgcc-fab7adbfb5b8861f87531f939ad03f891bba055a.tar.gz
* Makefile.in (cse.o): Depend on TARGET_H.
* cse.c (rtx_cost): Use targetm.rtx_costs. * system.h (CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS): Poison. * doc/tm.texi: Update. * target.h (targetm.rtx_costs): New. * target-def.h (TARGET_RTX_COSTS): New. * hooks.c (hook_bool_rtx_int_int_intp_false): New. * hooks.h: Update. * config/alpha/alpha.c (alpha_rtx_cost_data): New. (alpha_rtx_costs, TARGET_RTX_COSTS): New. * config/alpha/alpha.h (PROCESSOR_MAX): New. (CONST_COSTS, RTX_COSTS): Remove. * config/arc/arc.c, config/arc/arc.h, config/c4x/c4x.c, config/c4x/c4x.h, config/cris/cris.c, config/cris/cris.h, config/d30v/d30v.c, config/d30v/d30v.h, config/dsp16xx/dsp16xx.c, config/dsp16xx/dsp16xx.h, config/frv/frv.c, config/frv/frv.h, config/h8300/h8300.c, config/h8300/h8300.h, config/i370/i370.c, config/i370/i370.h, config/i386/i386.c, config/i386/i386.h, config/i960/i960.c, config/i960/i960.h, config/ia64/ia64.c, config/ia64/ia64.h, config/m32r/m32r.c, config/m32r/m32r.h, config/m68k/m68k.c, config/m68k/m68k.h, config/m88k/m88k.c, config/m88k/m88k.h, config/mcore/mcore.c, config/mcore/mcore.h, config/mips/mips.c, config/mips/mips.h, config/mn10200/mn10200.c, config/mn10200/mn10200.h, config/mn10300/mn10300.c, config/mn10300/mn10300.h, config/ns32k/ns32k.c, config/ns32k/ns32k.h, config/pa/pa.c, config/pa/pa.h, config/pdp11/pdp11.c, config/pdp11/pdp11.h, config/romp/romp.c, config/romp/romp.h, config/rs6000/rs6000.c, config/rs6000/rs6000.h, config/s390/s390.c, config/s390/s390.h, config/sh/sh.c, config/sh/sh.h, config/stormy16/stormy16.c, config/stormy16/stormy16.h, config/v850/v850.c, config/v850/v850.h, config/xtensa/xtensa.c, config/xtensa/xtensa.h (CONST_COSTS, RTX_COSTS): Move code ... (foo_rtx_costs, TARGET_RTX_COSTS): ... here. * config/arm/arm.c (arm_rtx_costs_1): Rename from arm_rtx_costs. (arm_rtx_costs, TARGET_RTX_COSTS): New. * config/arm/arm-protos.h: Update. * config/arm/arm.h (DEFAULT_RTX_COSTS): Remove. * config/avr/avr.h (CONST_COSTS): Move code ... * config/avr/avr.c (avr_rtx_costs): ... here. (default_rtx_costs): Make static. * config/avr/avr-protos.h: Update. * config/h8300/h8300.c (const_costs): Make static. (h8300_and_costs, h8300_shift_costs): Likewise. * config/h8300/h8300-protos.h: Update. * config/ip2k/ip2k.h (DEFAULT_RTX_COSTS): Remove. (CONST_COSTS): Move code ... * config/ip2k/ip2k.c (ip2k_rtx_costs): ... here. Rename from default_rtx_costs; update for signature change. * config/ip2k/ip2k-protos.h: Update. * config/m68hc11/m68hc11.h (RTX_COSTS): Remove. (CONST_COSTS): Move code ... * config/m68hc11/m68hc11.c (m68hc11_rtx_costs): ... here. (TARGET_RTX_COSTS): New. (m68hc11_rtx_costs_1): Rename from m68hc11_rtx_costs; make static. * config/m68hc11/m68hc11-protos.h: Update. * config/m68k/m68k.c (const_int_cost): Make static. * config/m68k/m68k-protos.h: Update. * config/mcore/mcore.c (mcore_const_costs): Make static. (mcore_and_cost, mcore_ior_cost): Likewise. * config/mcore/mcore-protos.h: Update. * config/mmix/mmix.c (mmix_rtx_costs, TARGET_RTX_COSTS): New. (mmix_rtx_cost_recalculated): Remove. * config/mmix/mmix.h (DEFAULT_RTX_COSTS): Remove. * config/mmix/mmix-protos.h: Update. * config/sh/sh.c (shiftcosts): Make static. (addsubcosts, andcosts, multcosts): Likewise. * config/sh/sh-protos.h: Update. * config/sparc/sparc.c (TARGET_RTX_COSTS): New. (sparc_rtx_costs): Make static; update for change in signature. * config/sparc/sparc.h (RTX_COSTS_CASES, RTX_COSTS): Remove. * config/sparc/sparc-protos.h: Update. * config/v850/v850.c (const_costs): Make static. * config/v850/v850-protos.h: Update. * config/vax/vax.h (RTX_COSTS): Remove. (CONST_COSTS): Move code ... * config/vax/vax.c (vax_rtx_costs_1): ... here; rename from vax_rtx_cost. (vax_rtx_costs, TARGET_RTX_COSTS): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61954 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog97
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/config/alpha/alpha.c197
-rw-r--r--gcc/config/alpha/alpha.h163
-rw-r--r--gcc/config/arc/arc.c64
-rw-r--r--gcc/config/arc/arc.h44
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c20
-rw-r--r--gcc/config/arm/arm.h3
-rw-r--r--gcc/config/avr/avr-protos.h2
-rw-r--r--gcc/config/avr/avr.c56
-rw-r--r--gcc/config/avr/avr.h53
-rw-r--r--gcc/config/c4x/c4x.c99
-rw-r--r--gcc/config/c4x/c4x.h99
-rw-r--r--gcc/config/cris/cris.c109
-rw-r--r--gcc/config/cris/cris.h67
-rw-r--r--gcc/config/d30v/d30v.c24
-rw-r--r--gcc/config/d30v/d30v.h49
-rw-r--r--gcc/config/dsp16xx/dsp16xx.c92
-rw-r--r--gcc/config/dsp16xx/dsp16xx.h70
-rw-r--r--gcc/config/frv/frv.c65
-rw-r--r--gcc/config/frv/frv.h59
-rw-r--r--gcc/config/h8300/h8300-protos.h3
-rw-r--r--gcc/config/h8300/h8300.c56
-rw-r--r--gcc/config/h8300/h8300.h31
-rw-r--r--gcc/config/i370/i370.c35
-rw-r--r--gcc/config/i370/i370.h15
-rw-r--r--gcc/config/i386/i386.c263
-rw-r--r--gcc/config/i386/i386.h248
-rw-r--r--gcc/config/i960/i960.c53
-rw-r--r--gcc/config/i960/i960.h30
-rw-r--r--gcc/config/ia64/ia64.c83
-rw-r--r--gcc/config/ia64/ia64.h56
-rw-r--r--gcc/config/ip2k/ip2k-protos.h1
-rw-r--r--gcc/config/ip2k/ip2k.c98
-rw-r--r--gcc/config/ip2k/ip2k.h38
-rw-r--r--gcc/config/m32r/m32r.c54
-rw-r--r--gcc/config/m32r/m32r.h45
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h1
-rw-r--r--gcc/config/m68hc11/m68hc11.c66
-rw-r--r--gcc/config/m68hc11/m68hc11.h54
-rw-r--r--gcc/config/m68k/m68k-protos.h1
-rw-r--r--gcc/config/m68k/m68k.c126
-rw-r--r--gcc/config/m68k/m68k.h90
-rw-r--r--gcc/config/m88k/m88k.c67
-rw-r--r--gcc/config/m88k/m88k.h46
-rw-r--r--gcc/config/mcore/mcore-protos.h3
-rw-r--r--gcc/config/mcore/mcore.c55
-rw-r--r--gcc/config/mcore/mcore.h27
-rw-r--r--gcc/config/mips/mips.c335
-rw-r--r--gcc/config/mips/mips.h310
-rw-r--r--gcc/config/mmix/mmix-protos.h2
-rw-r--r--gcc/config/mmix/mmix.c19
-rw-r--r--gcc/config/mmix/mmix.h9
-rw-r--r--gcc/config/mn10200/mn10200.c60
-rw-r--r--gcc/config/mn10200/mn10200.h45
-rw-r--r--gcc/config/mn10300/mn10300.c58
-rw-r--r--gcc/config/mn10300/mn10300.h44
-rw-r--r--gcc/config/ns32k/ns32k.c36
-rw-r--r--gcc/config/ns32k/ns32k.h16
-rw-r--r--gcc/config/pa/pa.c85
-rw-r--r--gcc/config/pa/pa.h50
-rw-r--r--gcc/config/pdp11/pdp11.c114
-rw-r--r--gcc/config/pdp11/pdp11.h105
-rw-r--r--gcc/config/romp/romp.c66
-rw-r--r--gcc/config/romp/romp.h44
-rw-r--r--gcc/config/rs6000/rs6000.c208
-rw-r--r--gcc/config/rs6000/rs6000.h133
-rw-r--r--gcc/config/s390/s390.c76
-rw-r--r--gcc/config/s390/s390.h66
-rw-r--r--gcc/config/sh/sh-protos.h4
-rw-r--r--gcc/config/sh/sh.c112
-rw-r--r--gcc/config/sh/sh.h64
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c214
-rw-r--r--gcc/config/sparc/sparc.h21
-rw-r--r--gcc/config/stormy16/stormy16.c45
-rw-r--r--gcc/config/stormy16/stormy16.h37
-rw-r--r--gcc/config/v850/v850-protos.h1
-rw-r--r--gcc/config/v850/v850.c56
-rw-r--r--gcc/config/v850/v850.h58
-rw-r--r--gcc/config/vax/vax.c57
-rw-r--r--gcc/config/vax/vax.h43
-rw-r--r--gcc/config/xtensa/xtensa.c216
-rw-r--r--gcc/config/xtensa/xtensa.h147
-rw-r--r--gcc/cse.c15
-rw-r--r--gcc/doc/tm.texi64
-rw-r--r--gcc/hooks.c11
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h9
92 files changed, 3449 insertions, 2695 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e899b33d99..5bb0bad637b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,102 @@
2003-01-27 Richard Henderson <rth@redhat.com>
+ * Makefile.in (cse.o): Depend on TARGET_H.
+ * cse.c (rtx_cost): Use targetm.rtx_costs.
+ * system.h (CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS): Poison.
+ * doc/tm.texi: Update.
+
+ * target.h (targetm.rtx_costs): New.
+ * target-def.h (TARGET_RTX_COSTS): New.
+ * hooks.c (hook_bool_rtx_int_int_intp_false): New.
+ * hooks.h: Update.
+
+ * config/alpha/alpha.c (alpha_rtx_cost_data): New.
+ (alpha_rtx_costs, TARGET_RTX_COSTS): New.
+ * config/alpha/alpha.h (PROCESSOR_MAX): New.
+ (CONST_COSTS, RTX_COSTS): Remove.
+
+ * config/arc/arc.c, config/arc/arc.h, config/c4x/c4x.c,
+ config/c4x/c4x.h, config/cris/cris.c, config/cris/cris.h,
+ config/d30v/d30v.c, config/d30v/d30v.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/frv/frv.c, config/frv/frv.h,
+ config/h8300/h8300.c, config/h8300/h8300.h, config/i370/i370.c,
+ config/i370/i370.h, config/i386/i386.c, config/i386/i386.h,
+ config/i960/i960.c, config/i960/i960.h, config/ia64/ia64.c,
+ config/ia64/ia64.h, config/m32r/m32r.c, config/m32r/m32r.h,
+ config/m68k/m68k.c, config/m68k/m68k.h, config/m88k/m88k.c,
+ config/m88k/m88k.h, config/mcore/mcore.c, config/mcore/mcore.h,
+ config/mips/mips.c, config/mips/mips.h, config/mn10200/mn10200.c,
+ config/mn10200/mn10200.h, config/mn10300/mn10300.c,
+ config/mn10300/mn10300.h, config/ns32k/ns32k.c, config/ns32k/ns32k.h,
+ config/pa/pa.c, config/pa/pa.h, config/pdp11/pdp11.c,
+ config/pdp11/pdp11.h, config/romp/romp.c, config/romp/romp.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h, config/s390/s390.c,
+ config/s390/s390.h, config/sh/sh.c, config/sh/sh.h,
+ config/stormy16/stormy16.c, config/stormy16/stormy16.h,
+ config/v850/v850.c, config/v850/v850.h,
+ config/xtensa/xtensa.c, config/xtensa/xtensa.h
+ (CONST_COSTS, RTX_COSTS): Move code ...
+ (foo_rtx_costs, TARGET_RTX_COSTS): ... here.
+
+ * config/arm/arm.c (arm_rtx_costs_1): Rename from arm_rtx_costs.
+ (arm_rtx_costs, TARGET_RTX_COSTS): New.
+ * config/arm/arm-protos.h: Update.
+ * config/arm/arm.h (DEFAULT_RTX_COSTS): Remove.
+
+ * config/avr/avr.h (CONST_COSTS): Move code ...
+ * config/avr/avr.c (avr_rtx_costs): ... here.
+ (default_rtx_costs): Make static.
+ * config/avr/avr-protos.h: Update.
+
+ * config/h8300/h8300.c (const_costs): Make static.
+ (h8300_and_costs, h8300_shift_costs): Likewise.
+ * config/h8300/h8300-protos.h: Update.
+
+ * config/ip2k/ip2k.h (DEFAULT_RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/ip2k/ip2k.c (ip2k_rtx_costs): ... here. Rename from
+ default_rtx_costs; update for signature change.
+ * config/ip2k/ip2k-protos.h: Update.
+
+ * config/m68hc11/m68hc11.h (RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/m68hc11/m68hc11.c (m68hc11_rtx_costs): ... here.
+ (TARGET_RTX_COSTS): New.
+ (m68hc11_rtx_costs_1): Rename from m68hc11_rtx_costs; make static.
+ * config/m68hc11/m68hc11-protos.h: Update.
+
+ * config/m68k/m68k.c (const_int_cost): Make static.
+ * config/m68k/m68k-protos.h: Update.
+
+ * config/mcore/mcore.c (mcore_const_costs): Make static.
+ (mcore_and_cost, mcore_ior_cost): Likewise.
+ * config/mcore/mcore-protos.h: Update.
+
+ * config/mmix/mmix.c (mmix_rtx_costs, TARGET_RTX_COSTS): New.
+ (mmix_rtx_cost_recalculated): Remove.
+ * config/mmix/mmix.h (DEFAULT_RTX_COSTS): Remove.
+ * config/mmix/mmix-protos.h: Update.
+
+ * config/sh/sh.c (shiftcosts): Make static.
+ (addsubcosts, andcosts, multcosts): Likewise.
+ * config/sh/sh-protos.h: Update.
+
+ * config/sparc/sparc.c (TARGET_RTX_COSTS): New.
+ (sparc_rtx_costs): Make static; update for change in signature.
+ * config/sparc/sparc.h (RTX_COSTS_CASES, RTX_COSTS): Remove.
+ * config/sparc/sparc-protos.h: Update.
+
+ * config/v850/v850.c (const_costs): Make static.
+ * config/v850/v850-protos.h: Update.
+
+ * config/vax/vax.h (RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/vax/vax.c (vax_rtx_costs_1): ... here; rename
+ from vax_rtx_cost.
+ (vax_rtx_costs, TARGET_RTX_COSTS): New.
+
+2003-01-27 Richard Henderson <rth@redhat.com>
+
* config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove. Really.
* config/vax/vax-protos.h: Update. Really.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 4cb7de27116..d75db8f72ed 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1543,8 +1543,9 @@ cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h
cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
- hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h \
- function.h $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) except.h
+ hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
+ output.h function.h $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
+ except.h $(TARGET_H)
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h ggc.h $(RECOG_H) $(EXPR_H) \
$(BASIC_BLOCK_H) function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index cc5c9f2f2c6..d10396e6c0a 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -123,6 +123,54 @@ extern GTY(()) int alpha_this_gpdisp_sequence_number;
int alpha_this_literal_sequence_number;
int alpha_this_gpdisp_sequence_number;
+/* Costs of various operations on the different architectures. */
+
+struct alpha_rtx_cost_data
+{
+ unsigned char fp_add;
+ unsigned char fp_mult;
+ unsigned char fp_div_sf;
+ unsigned char fp_div_df;
+ unsigned char int_mult_si;
+ unsigned char int_mult_di;
+ unsigned char int_shift;
+ unsigned char int_cmov;
+};
+
+static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
+{
+ { /* EV4 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (6), /* fp_mult */
+ COSTS_N_INSNS (34), /* fp_div_sf */
+ COSTS_N_INSNS (63), /* fp_div_df */
+ COSTS_N_INSNS (23), /* int_mult_si */
+ COSTS_N_INSNS (23), /* int_mult_di */
+ COSTS_N_INSNS (2), /* int_shift */
+ COSTS_N_INSNS (2), /* int_cmov */
+ },
+ { /* EV5 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult */
+ COSTS_N_INSNS (15), /* fp_div_sf */
+ COSTS_N_INSNS (22), /* fp_div_df */
+ COSTS_N_INSNS (8), /* int_mult_si */
+ COSTS_N_INSNS (12), /* int_mult_di */
+ COSTS_N_INSNS (1) + 1, /* int_shift */
+ COSTS_N_INSNS (1), /* int_cmov */
+ },
+ { /* EV6 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult */
+ COSTS_N_INSNS (12), /* fp_div_sf */
+ COSTS_N_INSNS (15), /* fp_div_df */
+ COSTS_N_INSNS (7), /* int_mult_si */
+ COSTS_N_INSNS (7), /* int_mult_di */
+ COSTS_N_INSNS (1), /* int_shift */
+ COSTS_N_INSNS (2), /* int_cmov */
+ },
+};
+
/* Declarations of static functions. */
static bool alpha_function_ok_for_sibcall
PARAMS ((tree, tree));
@@ -144,6 +192,8 @@ static int some_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static int split_small_symbolic_operand_1
PARAMS ((rtx *, void *));
+static bool alpha_rtx_costs
+ PARAMS ((rtx, int, int, int *));
static void alpha_set_memflags_1
PARAMS ((rtx, int, int, int));
static rtx alpha_emit_set_const_1
@@ -319,6 +369,9 @@ static void unicosmk_unique_section PARAMS ((tree, int));
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
#endif
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS alpha_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse target option strings. */
@@ -2474,6 +2527,150 @@ alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
return NULL_RTX;
}
+/* 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
+alpha_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ enum machine_mode mode = GET_MODE (x);
+ bool float_mode_p = FLOAT_MODE_P (mode);
+
+ switch (code)
+ {
+ /* If this is an 8-bit constant, return zero since it can be used
+ nearly anywhere with no cost. If it is a valid operand for an
+ ADD or AND, likewise return 0 if we know it will be used in that
+ context. Otherwise, return 2 since it might be used there later.
+ All other constants take at least two insns. */
+ case CONST_INT:
+ if (INTVAL (x) >= 0 && INTVAL (x) < 256)
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST_DOUBLE:
+ if (x == CONST0_RTX (mode))
+ *total = 0;
+ else if ((outer_code == PLUS && add_operand (x, VOIDmode))
+ || (outer_code == AND && and_operand (x, VOIDmode)))
+ *total = 0;
+ else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
+ *total = 2;
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
+ *total = COSTS_N_INSNS (outer_code != MEM);
+ else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
+ *total = COSTS_N_INSNS (1 + (outer_code != MEM));
+ else if (tls_symbolic_operand_type (x))
+ /* Estimate of cost for call_pal rduniq. */
+ *total = COSTS_N_INSNS (15);
+ else
+ /* Otherwise we do a load from the GOT. */
+ *total = COSTS_N_INSNS (alpha_memory_latency);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ else if (GET_CODE (XEXP (x, 0)) == MULT
+ && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
+ {
+ *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
+ + rtx_cost (XEXP (x, 1), outer_code) + 2);
+ return true;
+ }
+ return false;
+
+ case MULT:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_mult;
+ else if (mode == DImode)
+ *total = alpha_rtx_cost_data[alpha_cpu].int_mult_di;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].int_mult_si;
+ return false;
+
+ case ASHIFT:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) <= 3)
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = alpha_rtx_cost_data[alpha_cpu].int_shift;
+ return false;
+
+ case IF_THEN_ELSE:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].int_cmov;
+ return false;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ if (!float_mode_p)
+ *total = COSTS_N_INSNS (70); /* ??? */
+ else if (mode == SFmode)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_div_sf;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_div_df;
+ return false;
+
+ case MEM:
+ *total = COSTS_N_INSNS (alpha_memory_latency);
+ return true;
+
+ case NEG:
+ if (! float_mode_p)
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case ABS:
+ if (! float_mode_p)
+ {
+ *total = COSTS_N_INSNS (1) + alpha_rtx_cost_data[alpha_cpu].int_cmov;
+ return false;
+ }
+ /* FALLTHRU */
+
+ case FLOAT:
+ case UNSIGNED_FLOAT:
+ case FIX:
+ case UNSIGNED_FIX:
+ case FLOAT_EXTEND:
+ case FLOAT_TRUNCATE:
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ return false;
+
+ default:
+ return false;
+ }
+}
+
/* REF is an alignable memory location. Place an aligned SImode
reference into *PALIGNED_MEM and the number of bits to shift into
*PBITNUM. SCRATCH is a free register for use in reloading out
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 24550f4d634..ae28dd2729d 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -112,9 +112,12 @@ Boston, MA 02111-1307, USA. */
mirrors this list, so changes to alpha.md must be made at the same time. */
enum processor_type
- {PROCESSOR_EV4, /* 2106[46]{a,} */
+{
+ PROCESSOR_EV4, /* 2106[46]{a,} */
PROCESSOR_EV5, /* 21164{a,pc,} */
- PROCESSOR_EV6}; /* 21264 */
+ PROCESSOR_EV6, /* 21264 */
+ PROCESSOR_MAX
+};
extern enum processor_type alpha_cpu;
@@ -1543,162 +1546,6 @@ do { \
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- If this is an 8-bit constant, return zero since it can be used
- nearly anywhere with no cost. If it is a valid operand for an
- ADD or AND, likewise return 0 if we know it will be used in that
- context. Otherwise, return 2 since it might be used there later.
- All other constants take at least two insns. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256) \
- return 0; \
- case CONST_DOUBLE: \
- if ((RTX) == CONST0_RTX (GET_MODE (RTX))) \
- return 0; \
- else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \
- || ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \
- return 0; \
- else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \
- return 2; \
- else \
- return COSTS_N_INSNS (2); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- }
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: case MINUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- } \
- else if (GET_CODE (XEXP (X, 0)) == MULT \
- && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \
- return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \
- + rtx_cost (XEXP (X, 1), OUTER_CODE)); \
- break; \
- case MULT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (6); \
- return COSTS_N_INSNS (23); \
- case PROCESSOR_EV5: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (12); \
- else \
- return COSTS_N_INSNS (8); \
- case PROCESSOR_EV6: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else \
- return COSTS_N_INSNS (7); \
- default: abort(); \
- } \
- case ASHIFT: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) <= 3) \
- break; \
- /* ... fall through ... */ \
- case ASHIFTRT: case LSHIFTRT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case IF_THEN_ELSE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case DIV: case UDIV: case MOD: case UMOD: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (34); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (63); \
- else \
- return COSTS_N_INSNS (70); \
- case PROCESSOR_EV5: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (15); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (22); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- case PROCESSOR_EV6: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (12); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (15); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- default: abort(); \
- } \
- case MEM: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- } \
- case NEG: case ABS: \
- if (! FLOAT_MODE_P (GET_MODE (X))) \
- break; \
- /* ... fall through ... */ \
- case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \
- case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- }
/* Control the assembler format that we output. */
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index c106b88e2cf..2048bd3e06e 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -96,6 +96,7 @@ static void arc_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void arc_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void arc_encode_section_info PARAMS ((tree, int));
static void arc_internal_label PARAMS ((FILE *, const char *, unsigned long));
+static bool arc_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -114,7 +115,10 @@ static void arc_internal_label PARAMS ((FILE *, const char *, unsigned long));
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
#undef TARGET_ASM_INTERNAL_LABEL
-#define TARGET_ASM_INTERNAL_LABEL arc_internal_label
+#define TARGET_ASM_INTERNAL_LABEL arc_internal_label
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS arc_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2376,3 +2380,61 @@ arc_internal_label (stream, prefix, labelno)
arc_ccfsm_at_label (prefix, labelno);
default_internal_label (stream, prefix, labelno);
}
+
+/* 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
+arc_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ /* Small integers are as cheap as registers. 4 byte values can
+ be fetched as immediate constants - let's give that the cost
+ of an extra insn. */
+ case CONST_INT:
+ if (SMALL_INT (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST_DOUBLE:
+ {
+ rtx high, low;
+ split_double (x, &high, &low);
+ *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
+ + !SMALL_INT (INTVAL (low)));
+ return true;
+ }
+
+ /* Encourage synth_mult to find a synthetic multiply when reasonable.
+ If we need more than 12 insns to do a multiply, then go out-of-line,
+ since the call overhead will be < 10% of the cost of the multiply. */
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (TARGET_SHIFTER)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ *total = COSTS_N_INSNS (16);
+ else
+ *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
+ return false;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 7739fa4cdad..4d7b6338cb0 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -995,34 +995,6 @@ arc_select_cc_mode (OP, X, Y)
/* Costs. */
-/* An insn is define to cost 4 "units", and we work from there.
- COSTS_N_INSNS (N) is defined as (N) * 4 - 2 so that seems reasonable.
- Some values are supposed to be defined relative to each other and thus
- aren't necessarily related to COSTS_N_INSNS. */
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-/* Small integers are as cheap as registers. 4 byte values can be fetched
- as immediate constants - let's give that the cost of an extra insn. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT : \
- if (SMALL_INT (INTVAL (X))) \
- return 0; \
- /* fall through */ \
- case CONST : \
- case LABEL_REF : \
- case SYMBOL_REF : \
- return 4; \
- case CONST_DOUBLE : \
- { \
- rtx high, low; \
- split_double (X, &high, &low); \
- return 4 * (!SMALL_INT (INTVAL (high)) \
- + !SMALL_INT (INTVAL (low))); \
- }
-
/* Compute the cost of an address. */
#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : arc_address_cost (ADDR))
@@ -1041,22 +1013,6 @@ arc_select_cc_mode (OP, X, Y)
expensive than reg->reg moves. */
#define BRANCH_COST 2
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable.
-
- If we need more than 12 insns to do a multiply, then go out-of-line,
- since the call overhead will be < 10% of the cost of the multiply. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ASHIFT : \
- case ASHIFTRT : \
- case LSHIFTRT : \
- if (TARGET_SHIFTER) \
- return COSTS_N_INSNS (1); \
- if (GET_CODE (XEXP ((X), 1)) != CONST_INT) \
- return COSTS_N_INSNS (16); \
- return COSTS_N_INSNS (INTVAL (XEXP ((X), 1)));
-
/* Nonzero if access to memory by bytes is slow and undesirable.
For RISC chips, it means that access to memory by bytes is no
better than access by words when possible, so grab a whole word
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index af0320e0eac..5fed1df3efc 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -57,7 +57,6 @@ extern int thumb_legitimate_address_p PARAMS ((enum machine_mode, rtx,
int));
extern int thumb_legitimate_offset_p PARAMS ((enum machine_mode,
HOST_WIDE_INT));
-extern int arm_rtx_costs PARAMS ((rtx, RTX_CODE, RTX_CODE));
extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index db27913b0d2..5bbe6acc909 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -140,6 +140,9 @@ static void arm_internal_label PARAMS ((FILE *, const char *, unsigned long));
static void arm_output_mi_thunk PARAMS ((FILE *, tree,
HOST_WIDE_INT,
HOST_WIDE_INT, tree));
+static int arm_rtx_costs_1 PARAMS ((rtx, enum rtx_code,
+ enum rtx_code));
+static bool arm_rtx_costs PARAMS ((rtx, int, int, int*));
#undef Hint
#undef Mmode
@@ -213,6 +216,9 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS arm_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -2909,8 +2915,8 @@ thumb_legitimate_offset_p (mode, val)
#define COSTS_N_INSNS(N) ((N) * 4 - 2)
#endif
-int
-arm_rtx_costs (x, code, outer)
+static inline int
+arm_rtx_costs_1 (x, code, outer)
rtx x;
enum rtx_code code;
enum rtx_code outer;
@@ -3294,6 +3300,16 @@ arm_rtx_costs (x, code, outer)
}
}
+static bool
+arm_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ *total = arm_rtx_costs_1 (x, code, outer_code);
+ return true;
+}
+
static int
arm_adjust_cost (insn, link, dep, cost)
rtx insn;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 2b205fc2092..c2afa4dc211 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2138,9 +2138,6 @@ typedef struct
( (X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
|| (X) == arg_pointer_rtx)
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- return arm_rtx_costs (X, CODE, OUTER_CODE);
-
/* Moves to and from memory are quite expensive */
#define MEMORY_MOVE_COST(M, CLASS, IN) \
(TARGET_ARM ? 10 : \
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 20841a72b70..b721b3e5a54 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -114,8 +114,6 @@ extern const char * output_reload_inhi PARAMS ((rtx insn, rtx *operands,
int *len));
extern const char * output_reload_insisf PARAMS ((rtx insn, rtx *operands,
int *len));
-extern int default_rtx_costs PARAMS ((rtx X, RTX_CODE code,
- RTX_CODE outer_code));
extern enum reg_class secondary_input_reload_class PARAMS ((enum reg_class,
enum machine_mode,
rtx));
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index fcfec615c91..037801243ba 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -71,6 +71,8 @@ static unsigned int avr_section_type_flags PARAMS ((tree, const char *, int));
static void avr_asm_out_ctor PARAMS ((rtx, int));
static void avr_asm_out_dtor PARAMS ((rtx, int));
+static int default_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
+static bool avr_rtx_costs PARAMS ((rtx, int, int, int *));
/* Allocate registers from r25 to r8 for parameters for function calls */
#define FIRST_CUM_REG 26
@@ -227,6 +229,8 @@ int avr_case_values_threshold = 30000;
#define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS avr_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -4978,7 +4982,7 @@ order_regs_for_local_alloc ()
/* Calculate the cost of X code of the expression in which it is contained,
found in OUTER_CODE */
-int
+static int
default_rtx_costs (X, code, outer_code)
rtx X;
enum rtx_code code;
@@ -5037,6 +5041,56 @@ default_rtx_costs (X, code, outer_code)
return cost;
}
+static bool
+avr_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ int cst;
+
+ switch (code)
+ {
+ case CONST_INT:
+ if (outer_code == PLUS
+ || outer_code == IOR
+ || outer_code == AND
+ || outer_code == MINUS
+ || outer_code == SET
+ || INTVAL (x) == 0)
+ {
+ *total = 2;
+ return true;
+ }
+ if (outer_code == COMPARE
+ && INTVAL (x) >= 0
+ && INTVAL (x) <= 255)
+ {
+ *total = 2;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = 4;
+ return true;
+
+ default:
+ cst = default_rtx_costs (x, code, outer_code);
+ if (cst > 0)
+ {
+ *total = cst;
+ return true;
+ }
+ else if (cst < 0)
+ *total += -cst;
+ return false;
+ }
+}
+
/* Calculate the cost of a memory address */
int
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 5309a0d5878..126a6fdb7b8 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -1521,59 +1521,6 @@ do { \
is a suitable definition for this macro on machines where anything
`CONSTANT_P' is valid. */
-#define CONST_COSTS(x,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (OUTER_CODE == PLUS \
- || OUTER_CODE == IOR \
- || OUTER_CODE == AND \
- || OUTER_CODE == MINUS \
- || OUTER_CODE == SET \
- || INTVAL (x) == 0) \
- return 2; \
- if (OUTER_CODE == COMPARE \
- && INTVAL (x) >= 0 \
- && INTVAL (x) <= 255) \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 4; \
- case CONST_DOUBLE: \
- return 4;
-
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define DEFAULT_RTX_COSTS(x, code, outer_code) \
-{ \
- int cst = default_rtx_costs (x, code, outer_code); \
- if (cst>0) \
- return cst; \
- else if (cst<0) \
- total += -cst; \
- break; \
-}
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained.
-
- This macro is optional; do not define it if the default cost
- assumptions are adequate for the target machine. */
-
#define ADDRESS_COST(ADDRESS) avr_address_cost (ADDRESS)
/* An expression giving the cost of an addressing mode that contains
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index 4fe50b22611..2d83a8c9b66 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -197,6 +197,7 @@ static void c4x_asm_named_section PARAMS ((const char *, unsigned int));
static int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static void c4x_encode_section_info PARAMS ((tree, int));
static void c4x_globalize_label PARAMS ((FILE *, const char *));
+static bool c4x_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_BYTE_OP
@@ -227,6 +228,9 @@ static void c4x_globalize_label PARAMS ((FILE *, const char *));
#undef TARGET_ASM_GLOBALIZE_LABEL
#define TARGET_ASM_GLOBALIZE_LABEL c4x_globalize_label
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS c4x_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Override command line options.
@@ -5062,3 +5066,98 @@ c4x_globalize_label (stream, name)
default_globalize_label (stream, name);
c4x_global_label (name);
}
+
+#define SHIFT_CODE_P(C) \
+ ((C) == ASHIFT || (C) == ASHIFTRT || (C) == LSHIFTRT)
+#define LOGICAL_CODE_P(C) \
+ ((C) == NOT || (C) == AND || (C) == IOR || (C) == XOR)
+
+/* 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
+c4x_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ HOST_WIDE_INT val;
+
+ switch (code)
+ {
+ /* Some small integers are effectively free for the C40. We should
+ also consider if we are using the small memory model. With
+ the big memory model we require an extra insn for a constant
+ loaded from memory. */
+
+ case CONST_INT:
+ val = INTVAL (x);
+ if (c4x_J_constant (x))
+ *total = 0;
+ else if (! TARGET_C3X
+ && outer_code == AND
+ && (val == 255 || val == 65535))
+ *total = 0;
+ else if (! TARGET_C3X
+ && (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
+ && (val == 16 || val == 24))
+ *total = 0;
+ else if (TARGET_C3X && SHIFT_CODE_P (outer_code))
+ *total = 3;
+ else if (LOGICAL_CODE_P (outer_code)
+ ? c4x_L_constant (x) : c4x_I_constant (x))
+ *total = 2;
+ else
+ *total = 4;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 4;
+ return true;
+
+ case CONST_DOUBLE:
+ if (c4x_H_constant (x))
+ *total = 2;
+ else if (GET_MODE (x) == QFmode)
+ *total = 4;
+ else
+ *total = 8;
+ return true;
+
+ /* ??? Note that we return true, rather than false so that rtx_cost
+ doesn't include the constant costs. Otherwise expand_mult will
+ think that it is cheaper to synthesize a multiply rather than to
+ use a multiply instruction. I think this is because the algorithm
+ synth_mult doesn't take into account the loading of the operands,
+ whereas the calculation of mult_cost does. */
+ case PLUS:
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case MULT:
+ *total = COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ || TARGET_MPYI ? 1 : 14);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ ? 15 : 50);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h
index c878112daa8..891ed4bf200 100644
--- a/gcc/config/c4x/c4x.h
+++ b/gcc/config/c4x/c4x.h
@@ -1461,103 +1461,10 @@ CUMULATIVE_ARGS;
/* Descripting Relative Cost of Operations. */
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE.
-
- Note that we return, rather than break so that rtx_cost doesn't
- include CONST_COSTS otherwise expand_mult will think that it is
- cheaper to synthesize a multiply rather than to use a multiply
- instruction. I think this is because the algorithm synth_mult
- doesn't take into account the loading of the operands, whereas the
- calculation of mult_cost does.
-*/
-
-
-#define RTX_COSTS(RTX, CODE, OUTER_CODE) \
- case PLUS: \
- case MINUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1); \
- case MULT: \
- return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \
- || TARGET_MPYI ? 1 : 14); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \
- ? 15 : 50);
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- An insn is assumed to cost 4 units.
- COSTS_N_INSNS (N) is defined as (N) * 4 - 2.
-
- Some small integers are effectively free for the C40. We should
- also consider if we are using the small memory model. With
- the big memory model we require an extra insn for a constant
- loaded from memory.
-
- This is used by expand_binop to decide whether to force a constant
- into a register. If the cost is greater than 2 and the constant
- is used within a short loop, it gets forced into a register.
- Ideally, there should be some weighting as to how mnay times it is used
- within the loop. */
-
-#define SHIFT_CODE_P(C) ((C) == ASHIFT || (C) == ASHIFTRT || (C) == LSHIFTRT)
-
-#define LOGICAL_CODE_P(C) ((C) == NOT || (C) == AND \
- || (C) == IOR || (C) == XOR)
-
-#define NON_COMMUTATIVE_CODE_P ((C) == MINUS || (C) == COMPARE)
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (c4x_J_constant (RTX)) \
- return 0; \
- if (! TARGET_C3X \
- && OUTER_CODE == AND \
- && GET_CODE (RTX) == CONST_INT \
- && (INTVAL (RTX) == 255 || INTVAL (RTX) == 65535)) \
- return 0; \
- if (! TARGET_C3X \
- && (OUTER_CODE == ASHIFTRT || OUTER_CODE == LSHIFTRT) \
- && GET_CODE (RTX) == CONST_INT \
- && (INTVAL (RTX) == 16 || INTVAL (RTX) == 24)) \
- return 0; \
- if (TARGET_C3X && SHIFT_CODE_P (OUTER_CODE)) \
- return 3; \
- if (LOGICAL_CODE_P (OUTER_CODE) \
- ? c4x_L_constant (RTX) : c4x_I_constant (RTX)) \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 4; \
- case CONST_DOUBLE: \
- if (c4x_H_constant (RTX)) \
- return 2; \
- if (GET_MODE (RTX) == QFmode) \
- return 4; \
- else \
- return 8;
-
/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. If the cost is
- approximated by the RTL complexity, including CONST_COSTS above, as
- is usually the case for CISC machines, this macro should not be defined.
- For aggressively RISCy machines, only one insn format is allowed, so
- this macro should be a constant. The value of this macro only matters
- for valid addresses. We handle the most common address without
- a call to c4x_address_cost. */
+ and/or execution delay of an insn using that address. The value of this
+ macro only matters for valid addresses. We handle the most common address
+ without a call to c4x_address_cost. */
#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : c4x_address_cost (ADDR))
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 0aeccc01636..6842dfebda0 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -2082,6 +2082,115 @@ cris_simple_epilogue ()
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
+cris_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ {
+ HOST_WIDE_INT val = INTVAL (x);
+ if (val == 0)
+ *total = 0;
+ else if (val < 32 && val >= -32)
+ *total = 1;
+ /* Eight or 16 bits are a word and cycle more expensive. */
+ else if (val <= 32767 && val >= -32768)
+ *total = 2;
+ /* A 32 bit constant (or very seldom, unsigned 16 bits) costs
+ another word. FIXME: This isn't linear to 16 bits. */
+ else
+ *total = 4;
+ return true;
+ }
+
+ case LABEL_REF:
+ *total = 6;
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ /* For PIC, we need a prefix (if it isn't already there),
+ and the PIC register. For a global PIC symbol, we also
+ need a read of the GOT. */
+ if (flag_pic)
+ if (cris_got_symbol (x))
+ *total = 2 + 4 + 6;
+ else
+ *total = 2 + 6;
+ else
+ *total = 6;
+ return true;
+
+ case CONST_DOUBLE:
+ if (x != CONST0_RTX (GET_MODE (x) == VOIDmode ? DImode : GET_MODE (x)))
+ *total = 12;
+ else
+ /* Make 0.0 cheap, else test-insns will not be used. */
+ *total = 0;
+ return true;
+
+ case MULT:
+ /* Identify values that are no powers of two. Powers of 2 are
+ taken care of already and those values should not be changed. */
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || exact_log2 (INTVAL (XEXP (x, 1)) < 0))
+ {
+ /* If we have a multiply insn, then the cost is between
+ 1 and 2 "fast" instructions. */
+ if (TARGET_HAS_MUL_INSNS)
+ {
+ *total = COSTS_N_INSNS (1) + COSTS_N_INSNS (1) / 2;
+ return true;
+ }
+
+ /* Estimate as 4 + 4 * #ofbits. */
+ *total = COSTS_N_INSNS (132);
+ return true;
+ }
+ return false;
+
+ case UDIV:
+ case MOD:
+ case UMOD:
+ case DIV:
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || exact_log2 (INTVAL (XEXP (X, 1)) < 0))
+ {
+ /* Estimate this as 4 + 8 * #of bits. */
+ *total = COSTS_N_INSNS (260);
+ return true;
+ }
+ return false;
+
+ case AND:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ /* Two constants may actually happen before optimization. */
+ && GET_CODE (XEXP (x, 0)) != CONST_INT
+ && !CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
+ {
+ *total = (rtx_cost (XEXP (x, 0), outer_code) + 2
+ + 2 * GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))));
+ return true;
+ }
+ return false;
+
+ case ZERO_EXTEND: case SIGN_EXTEND:
+ *total = rtx_cost (XEXP (x, 0), outer_code);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* The ADDRESS_COST worker. */
int
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index bd044f3a51a..38449c7bc81 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -1336,73 +1336,6 @@ struct cum_args {int regs;};
/* Node: Costs */
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) == 0) \
- return 0; \
- if (INTVAL (RTX) < 32 && INTVAL (RTX) >= -32) \
- return 1; \
- /* Eight or 16 bits are a word and cycle more expensive. */ \
- if (INTVAL (RTX) <= 32767 && INTVAL (RTX) >= -32768) \
- return 2; \
- /* A 32 bit constant (or very seldom, unsigned 16 bits) costs \
- another word. FIXME: This isn't linear to 16 bits. */ \
- return 4; \
- case LABEL_REF: \
- return 6; \
- case CONST: \
- case SYMBOL_REF: \
- /* For PIC, we need a prefix (if it isn't already there), \
- and the PIC register. For a global PIC symbol, we also need a \
- read of the GOT. */ \
- return \
- flag_pic ? (cris_got_symbol (RTX) ? (2 + 4 + 6) : (2 + 6)) : 6; \
- case CONST_DOUBLE: \
- if (RTX != CONST0_RTX (GET_MODE (RTX) == VOIDmode ? DImode \
- : GET_MODE (RTX))) \
- return 12; \
- /* Make 0.0 cheap, else test-insns will not be used. */ \
- return 0;
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT: \
- /* Identify values that are no powers of two. Powers of 2 are \
- taken care of already and those values should not be \
- changed. */ \
- if (GET_CODE (XEXP (X, 1)) != CONST_INT \
- || exact_log2 (INTVAL (XEXP (X, 1)) < 0)) \
- { \
- /* If we have a multiply insn, then the cost is between \
- 1 and 2 "fast" instructions. */ \
- if (TARGET_HAS_MUL_INSNS) \
- return COSTS_N_INSNS (1) + COSTS_N_INSNS (1) /2; \
- \
- /* Estimate as 4 + 4 * #ofbits. */ \
- return COSTS_N_INSNS (132); \
- } \
- break; \
- case UDIV: \
- case MOD: \
- case UMOD: \
- case DIV: \
- if (GET_CODE (XEXP (X, 1)) != CONST_INT \
- || exact_log2 (INTVAL (XEXP (X, 1)) < 0)) \
- /* Estimate this as 4 + 8 * #of bits. */ \
- return COSTS_N_INSNS (260); \
- \
- case AND: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- /* Two constants may actually happen before optimization. */ \
- && GET_CODE (XEXP (X, 0)) != CONST_INT \
- && !CONST_OK_FOR_LETTER_P (INTVAL (XEXP (X, 1)), 'I')) \
- return \
- rtx_cost (XEXP (X, 0), OUTER_CODE) + 2 \
- + 2 * GET_MODE_NUNITS (GET_MODE (XEXP (X, 0))); \
- \
- case ZERO_EXTEND: case SIGN_EXTEND: \
- /* Same as move. If embedded in other insn, cost is 0. */ \
- return rtx_cost (XEXP (X, 0), OUTER_CODE);
-
#define ADDRESS_COST(X) cris_address_cost (X)
/* FIXME: Need to define REGISTER_MOVE_COST when more register classes are
diff --git a/gcc/config/d30v/d30v.c b/gcc/config/d30v/d30v.c
index 4f282a80bcf..b3b72cd21cd 100644
--- a/gcc/config/d30v/d30v.c
+++ b/gcc/config/d30v/d30v.c
@@ -54,6 +54,7 @@ static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int d30v_issue_rate PARAMS ((void));
+static bool d30v_rtx_costs PARAMS ((rtx, int, int, int *));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
@@ -99,6 +100,9 @@ enum reg_class reg_class_from_letter[256];
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE d30v_issue_rate
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS d30v_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Sometimes certain combinations of command options do not make
@@ -3505,3 +3509,23 @@ d30v_return_addr ()
{
return get_hard_reg_initial_val (Pmode, GPR_LINK);
}
+
+static bool
+d30v_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case MULT:
+ *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
+ ? 1 : 2);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/d30v/d30v.h b/gcc/config/d30v/d30v.h
index 6fdbbd434d5..db0e120de28 100644
--- a/gcc/config/d30v/d30v.h
+++ b/gcc/config/d30v/d30v.h
@@ -2426,55 +2426,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. It must contain `case' labels for expression
- codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
- Each case must ultimately reach a `return' statement to return the relative
- cost of the use of that kind of constant value in an expression. The cost
- may depend on the precise value of the constant, which is available for
- examination in X, and the rtx code of the expression in which it is
- contained, found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained with
- `GET_CODE (X)'. */
-
-/* On the d30v, consider operatnds that fit in a short instruction very
- cheap. However, at this time, it causes cse to generate incorrect
- code, so disable it for now. */
-#if 0
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- if (IN_RANGE_P (INTVAL (X), 0, 31)) \
- return 0; \
- else if ((OUTER_CODE) == LEU && (OUTER_CODE) == LTU \
- && (OUTER_CODE) == GEU && (OUTER_CODE) == GTU) \
- return IN_RANGE_P (INTVAL (X), 32, 63) ? 0 : COSTS_N_INSNS (2); \
- else \
- return IN_RANGE_P (INTVAL (X), -31, -1) ? 0 : COSTS_N_INSNS (2); \
- case SYMBOL_REF: \
- case LABEL_REF: \
- case CONST: \
- return COSTS_N_INSNS (2); \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS ((GET_MODE (X) == SFmode) ? 2 : 4);
-#else
-#define CONST_COSTS(X, CODE, OUTER_CODE)
-#endif
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. This can be
- used, for example, to indicate how costly a multiply instruction is. In
- writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
- a cost equal to N fast instructions. OUTER_CODE is the code of the
- expression in which X is contained.
-
- This macro is optional; do not define it if the default cost assumptions are
- adequate for the target machine. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT: \
- return COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT \
- && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) \
- ? 1 : 2);
-
/* An expression giving the cost of an addressing mode that contains ADDRESS.
If not defined, the cost is computed from the ADDRESS expression and the
`CONST_COSTS' values.
diff --git a/gcc/config/dsp16xx/dsp16xx.c b/gcc/config/dsp16xx/dsp16xx.c
index 3b9f752914a..6d402bf6e3f 100644
--- a/gcc/config/dsp16xx/dsp16xx.c
+++ b/gcc/config/dsp16xx/dsp16xx.c
@@ -151,8 +151,10 @@ static const char *const lshift_right_asm_first[] =
static int reg_save_size PARAMS ((void));
static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-
+static bool dsp16xx_rtx_costs PARAMS ((rtx, int, int, int *));
+
/* Initialize the GCC target structure. */
+
#undef TARGET_ASM_BYTE_OP
#define TARGET_ASM_BYTE_OP "\tint\t"
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -165,6 +167,9 @@ static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epilogue
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS dsp16xx_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
int
@@ -2569,3 +2574,88 @@ signed_comparison_operator (op, mode)
return 0;
}
+
+static bool
+dsp16xx_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ *total = (unsigned HOST_WIDE_INT) INTVAL (x) < 65536 ? 0 : 2;
+ return true;
+
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case MEM:
+ *total = COSTS_N_INSNS (GET_MODE (x) == QImode ? 2 : 4);
+ return true;
+
+ case DIV:
+ case MOD:
+ *total = COSTS_N_INSNS (38);
+ return true;
+
+ case MULT:
+ if (GET_MODE (x) == QImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (38);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
+ {
+ *total = 1;
+ return false;
+ }
+ else
+ {
+ *total = COSTS_N_INSNS (38);
+ return true;
+ }
+
+ case NEG:
+ case NOT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT number = INTVAL (XEXP (x, 1));
+ if (number == 1 || number == 4 || number == 8
+ || number == 16)
+ *total = COSTS_N_INSNS (1);
+ else if (TARGET_BMU)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (num_1600_core_shifts (number));
+ return true;
+ }
+ break;
+ }
+
+ if (TARGET_BMU)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (15);
+ return true;
+}
diff --git a/gcc/config/dsp16xx/dsp16xx.h b/gcc/config/dsp16xx/dsp16xx.h
index fbbf50efec3..d80213a7a68 100644
--- a/gcc/config/dsp16xx/dsp16xx.h
+++ b/gcc/config/dsp16xx/dsp16xx.h
@@ -1431,76 +1431,6 @@ extern struct dsp16xx_frame_info current_frame_info;
/* DESCRIBING RELATIVE COSTS OF OPERATIONS */
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. */
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- return (unsigned) INTVAL (RTX) < 65536 ? 0 : 2; \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST: \
- return COSTS_N_INSNS (1); \
- \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (2);
-
-/* Like CONST_COSTS but applies to nonconstant RTL expressions.
- This can be used, for example to indicate how costly a multiply
- instruction is. */
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MEM: \
- return GET_MODE (X) == QImode ? COSTS_N_INSNS (2) : \
- COSTS_N_INSNS (4); \
- case DIV: \
- case MOD: \
- return COSTS_N_INSNS (38); \
- case MULT: \
- if (GET_MODE (X) == QImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (38); \
- case PLUS: \
- case MINUS: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
- { \
- return (1 + \
- rtx_cost (XEXP (X, 0), CODE) + \
- rtx_cost (XEXP (X, 1), CODE)); \
- } \
- else \
- return COSTS_N_INSNS (38); \
- \
- case AND: case IOR: case XOR: \
- return (1 + \
- rtx_cost (XEXP (X, 0), CODE) + \
- rtx_cost (XEXP (X, 1), CODE)); \
- \
- case NEG: case NOT: \
- return COSTS_N_INSNS (1); \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- if (GET_CODE (XEXP (X,1)) == CONST_INT) \
- { \
- int number = INTVAL(XEXP (X,1)); \
- if (number == 1 || number == 4 || number == 8 || \
- number == 16) \
- return COSTS_N_INSNS (1); \
- else \
- { \
- if (TARGET_BMU) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (num_1600_core_shifts(number)); \
- } \
- } \
- if (TARGET_BMU) \
- return COSTS_N_INSNS (1); \
- else \
- return COSTS_N_INSNS (15);
-
/* An expression giving the cost of an addressing mode that contains
address. */
#define ADDRESS_COST(ADDR) dsp16xx_address_cost (ADDR)
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index f1ad90b46ee..1c8f5668671 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -283,6 +283,7 @@ static rtx frv_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int)
static bool frv_in_small_data_p PARAMS ((tree));
static void frv_asm_output_mi_thunk
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+static bool frv_rtx_costs PARAMS ((rtx, int, int, int*));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
@@ -301,6 +302,8 @@ static void frv_asm_output_mi_thunk
#define TARGET_EXPAND_BUILTIN frv_expand_builtin
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS frv_rtx_costs
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
@@ -9788,3 +9791,65 @@ frv_in_small_data_p (decl)
return symbol_ref_small_data_p (XEXP (DECL_RTL (decl), 0))
&& size > 0 && size <= g_switch_value;
}
+
+static bool
+frv_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ /* Make 12 bit integers really cheap. */
+ if (IN_RANGE_P (INTVAL (x), -2048, 2047))
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case NOT:
+ case NEG:
+ case COMPARE:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE (x) == DImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case MULT:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (6); /* guess */
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (18);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index e7a481a728f..64aa29e72c2 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -2541,65 +2541,6 @@ __asm__("\n" \
/* Describing Relative Costs of Operations. */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. It must contain `case' labels for expression
- codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
- Each case must ultimately reach a `return' statement to return the relative
- cost of the use of that kind of constant value in an expression. The cost
- may depend on the precise value of the constant, which is available for
- examination in X, and the rtx code of the expression in which it is
- contained, found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained with
- `GET_CODE (X)'. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (2); \
- \
- case CONST_INT: \
- /* Make 12 bit integers really cheap */ \
- return IN_RANGE_P (INTVAL (X), -2048, 2047) ? 0 : COSTS_N_INSNS (2); \
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. This can be
- used, for example, to indicate how costly a multiply instruction is. In
- writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
- a cost equal to N fast instructions. OUTER_CODE is the code of the
- expression in which X is contained.
-
- This macro is optional; do not define it if the default cost assumptions are
- adequate for the target machine. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case PLUS: \
- case MINUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case NOT: \
- case NEG: \
- case COMPARE: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (1); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (3); /* guess */ \
- \
- case MULT: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (6); /* guess */ \
- \
- case DIV: \
- case UDIV: \
- return COSTS_N_INSNS (18);
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 4 is the default; other values are
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index f5a59d4b120..436ddb78837 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -34,9 +34,6 @@ extern unsigned int compute_a_shift_length PARAMS ((rtx, rtx *));
extern const char *emit_a_rotate PARAMS ((enum rtx_code, rtx *));
extern const char *output_simode_bld PARAMS ((int, rtx[]));
extern void print_operand_address PARAMS ((FILE *, rtx));
-extern int const_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
-extern int h8300_and_costs PARAMS ((rtx));
-extern int h8300_shift_costs PARAMS ((rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
extern int do_movsi PARAMS ((rtx[]));
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 23e334bd872..e59e87776f4 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -69,6 +69,10 @@ static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
static void h8300_encode_label PARAMS ((tree));
static void h8300_encode_section_info PARAMS ((tree, int));
static const char *h8300_strip_name_encoding PARAMS ((const char *));
+static int const_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
+static int h8300_and_costs PARAMS ((rtx));
+static int h8300_shift_costs PARAMS ((rtx));
+static bool h8300_rtx_costs PARAMS ((rtx, int, int, int *));
/* CPU_TYPE, says what cpu we're compiling for. */
int cpu_type;
@@ -113,6 +117,9 @@ const char *h8_push_op, *h8_pop_op, *h8_mov_op;
#undef TARGET_INSERT_ATTRIBUTES
#define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS h8300_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* See below where shifts are handled for explanation of this enum. */
@@ -1097,7 +1104,7 @@ function_arg (cum, mode, type, named)
/* Return the cost of the rtx R with code CODE. */
-int
+static int
const_costs (r, c, outer_code)
rtx r;
enum rtx_code c;
@@ -1144,7 +1151,7 @@ const_costs (r, c, outer_code)
}
}
-int
+static int
h8300_and_costs (x)
rtx x;
{
@@ -1164,7 +1171,7 @@ h8300_and_costs (x)
return compute_logical_op_length (GET_MODE (x), operands);
}
-int
+static int
h8300_shift_costs (x)
rtx x;
{
@@ -1181,6 +1188,49 @@ h8300_shift_costs (x)
operands[3] = x;
return compute_a_shift_length (NULL, operands);
}
+
+static bool
+h8300_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case AND:
+ *total = COSTS_N_INSNS (h8300_and_costs (x));
+ return true;
+
+ /* We say that MOD and DIV are so expensive because otherwise we'll
+ generate some really horrible code for division of a power of two. */
+ case MOD:
+ case DIV:
+ *total = 60;
+ return true;
+
+ case MULT:
+ *total = 20;
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (h8300_shift_costs (x));
+ return true;
+
+ case ROTATE:
+ case ROTATERT:
+ if (GET_MODE (x) == HImode)
+ *total = 2;
+ else
+ *total = 8;
+ return true;
+
+ default:
+ *total = const_costs (x, code, outer_code);
+ return true;
+ }
+}
/* Documentation for the machine specific operand escapes:
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index d6148f35fba..70e8b6601ee 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -1010,39 +1010,8 @@ struct cum_arg
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
LENGTH += h8300_adjust_insn_length (INSN, LENGTH);
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define DEFAULT_RTX_COSTS(RTX, CODE, OUTER_CODE) \
- return (const_costs (RTX, CODE, OUTER_CODE));
-
#define BRANCH_COST 0
-/* We say that MOD and DIV are so cheap because otherwise we'll
- generate some really horrible code for division of a power of two. */
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(RTX, CODE, OUTER_CODE) \
- case AND: \
- return COSTS_N_INSNS (h8300_and_costs (RTX)); \
- case MOD: \
- case DIV: \
- return 60; \
- case MULT: \
- return 20; \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (h8300_shift_costs (RTX)); \
- case ROTATE: \
- case ROTATERT: \
- if (GET_MODE (RTX) == HImode) return 2; \
- return 8;
-
/* Tell final.c how to eliminate redundant test instructions. */
/* Here we define machine-dependent flags and fields in cc_status
diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c
index 3db961a6170..e83fa7ad7f1 100644
--- a/gcc/config/i370/i370.c
+++ b/gcc/config/i370/i370.c
@@ -112,6 +112,7 @@ static int mvs_hash_alias PARAMS ((const char *));
#endif
static void i370_encode_section_info PARAMS ((tree, int));
static void i370_internal_label PARAMS ((FILE *, const char *, unsigned long));
+static bool i370_rtx_costs PARAMS ((rtx, int, int, int *));
/* ===================================================== */
/* defines and functions specific to the HLASM assembler */
@@ -317,6 +318,8 @@ static const unsigned char ebcasc[256] =
#define TARGET_ENCODE_SECTION_INFO i370_encode_section_info
#undef TARGET_ASM_INTERNAL_LABEL
#define TARGET_ASM_INTERNAL_LABEL i370_internal_label
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS i370_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -1613,3 +1616,35 @@ i370_internal_label (stream, prefix, labelno)
default_internal_label (stream, prefix, labelno);
}
+
+static bool
+i370_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if ((unsigned HOST_WIDE_INT) INTVAL (x) < 0xfff)
+ {
+ *total = 1;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 2;
+ return true;
+
+ case CONST_DOUBLE:
+ *total = 4;
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h
index 20117426740..61f296d71a5 100644
--- a/gcc/config/i370/i370.h
+++ b/gcc/config/i370/i370.h
@@ -901,21 +901,6 @@ enum reg_class
#define FUNCTION_MODE QImode
-/* Compute the cost of computing a constant rtl expression RTX whose
- rtx-code is CODE. The body of this macro is a portion of a switch
- statement. If the code is computed here, return it with a return
- statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX, CODE, OUTERCODE) \
- case CONST_INT: \
- if ((unsigned) INTVAL (RTX) < 0xfff) return 1; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 2; \
- case CONST_DOUBLE: \
- return 4;
-
/* A C statement (sans semicolon) to update the integer variable COST
based on the relationship between INSN that is dependent on
DEP_INSN through the dependence LINK. The default is to make no
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d963667d005..0f0a3a76282 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50,6 +50,14 @@ Boston, MA 02111-1307, USA. */
#define CHECK_STACK_LIMIT (-1)
#endif
+/* Return index of given mode in mult and division cost tables. */
+#define MODE_INDEX(mode) \
+ ((mode) == QImode ? 0 \
+ : (mode) == HImode ? 1 \
+ : (mode) == SImode ? 2 \
+ : (mode) == DImode ? 3 \
+ : 4)
+
/* Processor costs (relative to an add) */
static const
struct processor_costs size_cost = { /* costs for tunning for size */
@@ -872,6 +880,7 @@ static int ix86_value_regno PARAMS ((enum machine_mode));
static bool ix86_ms_bitfield_layout_p PARAMS ((tree));
static tree ix86_handle_struct_attribute PARAMS ((tree *, tree, tree, int, bool *));
static int extended_reg_mentioned_1 PARAMS ((rtx *, void *));
+static bool ix86_rtx_costs PARAMS ((rtx, int, int, int *));
#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
@@ -988,6 +997,9 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ix86_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Sometimes certain combinations of command options do not make
@@ -14458,6 +14470,257 @@ ix86_memory_move_cost (mode, class, in)
}
}
+/* 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
+ix86_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ enum machine_mode mode = GET_MODE (x);
+
+ switch (code)
+ {
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ if (TARGET_64BIT && !x86_64_sign_extended_value (x))
+ *total = 3;
+ else if (TARGET_64BIT && !x86_64_zero_extended_value (x))
+ *total = 2;
+ else if (flag_pic && SYMBOLIC_CONST (x))
+ *total = 1;
+ else
+ *total = 0;
+ return true;
+
+ case CONST_DOUBLE:
+ if (mode == VOIDmode)
+ *total = 0;
+ else
+ switch (standard_80387_constant_p (x))
+ {
+ case 1: /* 0.0 */
+ *total = 1;
+ break;
+ case 2: /* 1.0 */
+ *total = 2;
+ break;
+ default:
+ /* Start with (MEM (SYMBOL_REF)), since that's where
+ it'll probably end up. Add a penalty for size. */
+ *total = (COSTS_N_INSNS (1)
+ + (flag_pic != 0)
+ + (mode == SFmode ? 0 : mode == DFmode ? 1 : 2));
+ break;
+ }
+ return true;
+
+ case ZERO_EXTEND:
+ /* The zero extensions is often completely free on x86_64, so make
+ it as cheap as possible. */
+ if (TARGET_64BIT && mode == DImode
+ && GET_MODE (XEXP (x, 0)) == SImode)
+ *total = 1;
+ else if (TARGET_ZERO_EXTEND_WITH_AND)
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->movzx);
+ return false;
+
+ case SIGN_EXTEND:
+ *total = COSTS_N_INSNS (ix86_cost->movsx);
+ return false;
+
+ case ASHIFT:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (GET_MODE (XEXP (x, 0)) != DImode || TARGET_64BIT))
+ {
+ HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+ if (value == 1)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ return false;
+ }
+ if ((value == 2 || value == 3)
+ && !TARGET_DECOMPOSE_LEA
+ && ix86_cost->lea <= ix86_cost->shift_const)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ return false;
+ }
+ }
+ /* FALLTHRU */
+
+ case ROTATE:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case ROTATERT:
+ if (!TARGET_64BIT && GET_MODE (XEXP (x, 0)) == DImode)
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ if (INTVAL (XEXP (x, 1)) > 32)
+ *total = COSTS_N_INSNS(ix86_cost->shift_const + 2);
+ else
+ *total = COSTS_N_INSNS(ix86_cost->shift_const * 2);
+ }
+ else
+ {
+ if (GET_CODE (XEXP (x, 1)) == AND)
+ *total = COSTS_N_INSNS(ix86_cost->shift_var * 2);
+ else
+ *total = COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2);
+ }
+ }
+ else
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ *total = COSTS_N_INSNS (ix86_cost->shift_const);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->shift_var);
+ }
+ return false;
+
+ case MULT:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fmul);
+ else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+ int nbits;
+
+ for (nbits = 0; value != 0; value >>= 1)
+ nbits++;
+
+ *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ + nbits * ix86_cost->mult_bit);
+ }
+ else
+ {
+ /* This is arbitrary */
+ *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ + 7 * ix86_cost->mult_bit);
+ }
+ return false;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fdiv);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->divide[MODE_INDEX (mode)]);
+ return false;
+
+ case PLUS:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fadd);
+ else if (!TARGET_DECOMPOSE_LEA
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_BITSIZE (mode) <= GET_MODE_BITSIZE (Pmode))
+ {
+ if (GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
+ && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
+ && CONSTANT_P (XEXP (x, 1)))
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
+ if (val == 2 || val == 4 || val == 8)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+ *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
+ outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ else if (GET_CODE (XEXP (x, 0)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
+ if (val == 2 || val == 4 || val == 8)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ else if (GET_CODE (XEXP (x, 0)) == PLUS)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ /* FALLTHRU */
+
+ case MINUS:
+ if (FLOAT_MODE_P (mode))
+ {
+ *total = COSTS_N_INSNS (ix86_cost->fadd);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case AND:
+ case IOR:
+ case XOR:
+ if (!TARGET_64BIT && mode == DImode)
+ {
+ *total = (COSTS_N_INSNS (ix86_cost->add) * 2
+ + (rtx_cost (XEXP (x, 0), outer_code)
+ << (GET_MODE (XEXP (x, 0)) != DImode))
+ + (rtx_cost (XEXP (x, 1), outer_code)
+ << (GET_MODE (XEXP (x, 1)) != DImode)));
+ return true;
+ }
+ /* FALLTHRU */
+
+ case NEG:
+ if (FLOAT_MODE_P (mode))
+ {
+ *total = COSTS_N_INSNS (ix86_cost->fchs);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case NOT:
+ if (!TARGET_64BIT && mode == DImode)
+ *total = COSTS_N_INSNS (ix86_cost->add * 2);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ return false;
+
+ case FLOAT_EXTEND:
+ if (!TARGET_SSE_MATH || !VALID_SSE_REG_MODE (mode))
+ *total = 0;
+ return false;
+
+ case ABS:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fabs);
+ return false;
+
+ case SQRT:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fsqrt);
+ return false;
+
+ default:
+ return false;
+ }
+}
+
#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
static void
ix86_svr3_asm_out_constructor (symbol, priority)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b4359f1f8c6..32eb8ad6f6f 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2585,254 +2585,6 @@ do { \
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if (TARGET_64BIT && !x86_64_sign_extended_value (RTX)) \
- return 3; \
- if (TARGET_64BIT && !x86_64_zero_extended_value (RTX)) \
- return 2; \
- return flag_pic && SYMBOLIC_CONST (RTX) ? 1 : 0; \
- \
- case CONST_DOUBLE: \
- if (GET_MODE (RTX) == VOIDmode) \
- return 0; \
- switch (standard_80387_constant_p (RTX)) \
- { \
- case 1: /* 0.0 */ \
- return 1; \
- case 2: /* 1.0 */ \
- return 2; \
- default: \
- /* Start with (MEM (SYMBOL_REF)), since that's where \
- it'll probably end up. Add a penalty for size. */ \
- return (COSTS_N_INSNS (1) + (flag_pic != 0) \
- + (GET_MODE (RTX) == SFmode ? 0 \
- : GET_MODE (RTX) == DFmode ? 1 : 2)); \
- }
-
-/* Delete the definition here when TOPLEVEL_COSTS_N_INSNS gets added to cse.c */
-#define TOPLEVEL_COSTS_N_INSNS(N) \
- do { total = COSTS_N_INSNS (N); goto egress_rtx_costs; } while (0)
-
-/* Return index of given mode in mult and division cost tables. */
-#define MODE_INDEX(mode) \
- ((mode) == QImode ? 0 \
- : (mode) == HImode ? 1 \
- : (mode) == SImode ? 2 \
- : (mode) == DImode ? 3 \
- : 4)
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained.
-
- This macro is optional; do not define it if the default cost
- assumptions are adequate for the target machine. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ZERO_EXTEND: \
- /* The zero extensions is often completely free on x86_64, so make \
- it as cheap as possible. */ \
- if (TARGET_64BIT && GET_MODE (X) == DImode \
- && GET_MODE (XEXP (X, 0)) == SImode) \
- { \
- total = 1; goto egress_rtx_costs; \
- } \
- else \
- TOPLEVEL_COSTS_N_INSNS (TARGET_ZERO_EXTEND_WITH_AND ? \
- ix86_cost->add : ix86_cost->movzx); \
- break; \
- case SIGN_EXTEND: \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->movsx); \
- break; \
- case ASHIFT: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (GET_MODE (XEXP (X, 0)) != DImode || TARGET_64BIT)) \
- { \
- HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
- if (value == 1) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \
- if ((value == 2 || value == 3) \
- && !TARGET_DECOMPOSE_LEA \
- && ix86_cost->lea <= ix86_cost->shift_const) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->lea); \
- } \
- /* fall through */ \
- \
- case ROTATE: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ROTATERT: \
- if (!TARGET_64BIT && GET_MODE (XEXP (X, 0)) == DImode) \
- { \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- if (INTVAL (XEXP (X, 1)) > 32) \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const + 2); \
- else \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const * 2); \
- } \
- else \
- { \
- if (GET_CODE (XEXP (X, 1)) == AND) \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 2); \
- else \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2); \
- } \
- } \
- else \
- { \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_const); \
- else \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_var); \
- } \
- break; \
- \
- case MULT: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fmul); \
- else if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
- int nbits = 0; \
- \
- while (value != 0) \
- { \
- nbits++; \
- value >>= 1; \
- } \
- \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
- [MODE_INDEX (GET_MODE (X))] \
- + nbits * ix86_cost->mult_bit); \
- } \
- else /* This is arbitrary */ \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
- [MODE_INDEX (GET_MODE (X))] \
- + 7 * ix86_cost->mult_bit); \
- \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fdiv); \
- else \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->divide \
- [MODE_INDEX (GET_MODE (X))]); \
- break; \
- \
- case PLUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fadd); \
- else if (!TARGET_DECOMPOSE_LEA \
- && INTEGRAL_MODE_P (GET_MODE (X)) \
- && GET_MODE_BITSIZE (GET_MODE (X)) <= GET_MODE_BITSIZE (Pmode)) \
- { \
- if (GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == MULT \
- && GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 1)) == CONST_INT \
- && CONSTANT_P (XEXP (X, 1))) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 0), 0), 1));\
- if (val == 2 || val == 4 || val == 8) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 1), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (XEXP (XEXP (X, 0), 0), 0), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- else if (GET_CODE (XEXP (X, 0)) == MULT \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \
- if (val == 2 || val == 4 || val == 8) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 0), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- else if (GET_CODE (XEXP (X, 0)) == PLUS) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 0), (OUTER_CODE)) \
- + rtx_cost (XEXP (XEXP (X, 0), 1), (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- /* fall through */ \
- \
- case MINUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fadd); \
- /* fall through */ \
- \
- case AND: \
- case IOR: \
- case XOR: \
- if (!TARGET_64BIT && GET_MODE (X) == DImode) \
- return (COSTS_N_INSNS (ix86_cost->add) * 2 \
- + (rtx_cost (XEXP (X, 0), (OUTER_CODE)) \
- << (GET_MODE (XEXP (X, 0)) != DImode)) \
- + (rtx_cost (XEXP (X, 1), (OUTER_CODE)) \
- << (GET_MODE (XEXP (X, 1)) != DImode))); \
- /* fall through */ \
- \
- case NEG: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fchs); \
- /* fall through */ \
- \
- case NOT: \
- if (!TARGET_64BIT && GET_MODE (X) == DImode) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add * 2); \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \
- \
- case FLOAT_EXTEND: \
- if (!TARGET_SSE_MATH \
- || !VALID_SSE_REG_MODE (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (0); \
- break; \
- \
- case ABS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fabs); \
- break; \
- \
- case SQRT: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fsqrt); \
- break; \
- \
- egress_rtx_costs: \
- break;
-
-
/* An expression giving the cost of an addressing mode that contains
ADDRESS. If not defined, the cost is computed from the ADDRESS
expression and the `CONST_COSTS' values.
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index 08894aa46b1..35b72e25811 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -50,6 +50,7 @@ static void i960_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void i960_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void i960_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
+static bool i960_rtx_costs PARAMS ((rtx, int, int, int *));
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
@@ -107,6 +108,9 @@ static int ret_label = 0;
#undef TARGET_CAN_ASM_OUTPUT_MI_THUNK
#define TARGET_CAN_ASM_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS i960_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Override conflicting target switch options.
@@ -2856,3 +2860,52 @@ i960_output_mi_thunk (file, thunk, delta, vcall_offset, function)
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
}
+
+static bool
+i960_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ /* Constants that can be (non-ldconst) insn operands are cost 0.
+ Constants that can be non-ldconst operands in rare cases are cost 1.
+ Other constants have higher costs.
+
+ Must check for OUTER_CODE of SET for power2_operand, because
+ reload_cse_move2add calls us with OUTER_CODE of PLUS to decide
+ when to replace set with add. */
+
+ case CONST_INT:
+ if ((INTVAL (x) >= 0 && INTVAL (x) < 32)
+ || (outer_code == SET && power2_operand (x, VOIDmode)))
+ {
+ *total = 0;
+ return true;
+ }
+ else if (INTVAL (x) >= -31 && INTVAL (x) < 0)
+ {
+ *total = 1;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = (TARGET_C_SERIES ? 6 : 8);
+ return true;
+
+ case CONST_DOUBLE:
+ if (x == CONST0_RTX (DFmode) || x == CONST0_RTX (SFmode)
+ || x == CONST1_RTX (DFmode) || x == CONST1_RTX (SFmode))
+ *total = 1;
+ else
+ *total = 12;
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h
index 3b84d048dd8..534f5254dbd 100644
--- a/gcc/config/i960/i960.h
+++ b/gcc/config/i960/i960.h
@@ -1154,36 +1154,6 @@ extern struct rtx_def *i960_compare_op0, *i960_compare_op1;
#define TARGET_MEM_FUNCTIONS 1
#endif
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-/* Constants that can be (non-ldconst) insn operands are cost 0. Constants
- that can be non-ldconst operands in rare cases are cost 1. Other constants
- have higher costs. */
-
-/* Must check for OUTER_CODE of SET for power2_operand, because
- reload_cse_move2add calls us with OUTER_CODE of PLUS to decide when
- to replace set with add. */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- if ((INTVAL (RTX) >= 0 && INTVAL (RTX) < 32) \
- || (OUTER_CODE == SET && power2_operand (RTX, VOIDmode))) \
- return 0; \
- else if (INTVAL (RTX) >= -31 && INTVAL (RTX) < 0) \
- return 1; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return (TARGET_C_SERIES ? 6 : 8); \
- case CONST_DOUBLE: \
- if ((RTX) == CONST0_RTX (DFmode) || (RTX) == CONST0_RTX (SFmode) \
- || (RTX) == CONST1_RTX (DFmode) || (RTX) == CONST1_RTX (SFmode))\
- return 1; \
- return 12;
-
/* The i960 offers addressing modes which are "as cheap as a register".
See i960.c (or gcc.texinfo) for details. */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index c641e2d6128..9a671a9edee 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -147,6 +147,7 @@ static rtx gen_fr_spill_x PARAMS ((rtx, rtx, rtx));
static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));
static enum machine_mode hfa_element_mode PARAMS ((tree, int));
+static bool ia64_rtx_costs PARAMS ((rtx, int, int, int *));
static void fix_range PARAMS ((const char *));
static struct machine_function * ia64_init_machine_status PARAMS ((void));
static void emit_insn_group_barriers PARAMS ((FILE *, rtx));
@@ -314,6 +315,9 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ia64_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
@@ -3972,6 +3976,85 @@ ia64_print_operand (file, x, code)
return;
}
+/* 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. */
+/* ??? This is incomplete. */
+
+static bool
+ia64_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ switch (outer_code)
+ {
+ case SET:
+ *total = CONST_OK_FOR_J (INTVAL (x)) ? 0 : COSTS_N_INSNS (1);
+ return true;
+ case PLUS:
+ if (CONST_OK_FOR_I (INTVAL (x)))
+ *total = 0;
+ else if (CONST_OK_FOR_J (INTVAL (x)))
+ *total = 1;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ default:
+ if (CONST_OK_FOR_K (INTVAL (x)) || CONST_OK_FOR_L (INTVAL (x)))
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case MULT:
+ /* For multiplies wider than HImode, we have to go to the FPU,
+ which normally involves copies. Plus there's the latency
+ of the multiply itself, and the latency of the instructions to
+ transfer integer regs to FP regs. */
+ /* ??? Check for FP mode. */
+ if (GET_MODE_SIZE (GET_MODE (x)) > 2)
+ *total = COSTS_N_INSNS (10);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ /* We make divide expensive, so that divide-by-constant will be
+ optimized to a multiply. */
+ *total = COSTS_N_INSNS (60);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Calculate the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index fb51797b51f..425d451b8ab 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1673,62 +1673,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. */
-
-/* ??? This is incomplete. */
-
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- if ((X) == const0_rtx) \
- return 0; \
- switch (OUTER_CODE) \
- { \
- case SET: \
- return CONST_OK_FOR_J (INTVAL (X)) ? 0 : COSTS_N_INSNS (1); \
- case PLUS: \
- if (CONST_OK_FOR_I (INTVAL (X))) \
- return 0; \
- if (CONST_OK_FOR_J (INTVAL (X))) \
- return 1; \
- return COSTS_N_INSNS (1); \
- default: \
- if (CONST_OK_FOR_K (INTVAL (X)) || CONST_OK_FOR_L (INTVAL (X))) \
- return 0; \
- return COSTS_N_INSNS (1); \
- } \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (1); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- return COSTS_N_INSNS (3);
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT: \
- /* For multiplies wider than HImode, we have to go to the FPU, \
- which normally involves copies. Plus there's the latency \
- of the multiply itself, and the latency of the instructions to \
- transfer integer regs to FP regs. */ \
- if (GET_MODE_SIZE (GET_MODE (X)) > 2) \
- return COSTS_N_INSNS (10); \
- return COSTS_N_INSNS (2); \
- case PLUS: \
- case MINUS: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- /* We make divide expensive, so that divide-by-constant will be \
- optimized to a multiply. */ \
- return COSTS_N_INSNS (60);
-
/* An expression giving the cost of an addressing mode that contains ADDRESS.
If not defined, the cost is computed from the ADDRESS expression and the
`CONST_COSTS' values. */
diff --git a/gcc/config/ip2k/ip2k-protos.h b/gcc/config/ip2k/ip2k-protos.h
index 2ec040007a1..48c2c4a750e 100644
--- a/gcc/config/ip2k/ip2k-protos.h
+++ b/gcc/config/ip2k/ip2k-protos.h
@@ -43,7 +43,6 @@ extern int ip2k_address_cost PARAMS ((rtx));
extern int ip2k_extra_constraint PARAMS ((rtx, int));
extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode, rtx));
extern int adjust_insn_length PARAMS ((rtx insn, int len));
-extern int default_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
extern void asm_output_char PARAMS ((FILE *, rtx));
extern void asm_output_short PARAMS ((FILE *, rtx));
extern void asm_output_byte PARAMS ((FILE *, int));
diff --git a/gcc/config/ip2k/ip2k.c b/gcc/config/ip2k/ip2k.c
index 6b2bc33729c..cb1a0952c5f 100644
--- a/gcc/config/ip2k/ip2k.c
+++ b/gcc/config/ip2k/ip2k.c
@@ -78,6 +78,8 @@ static tree ip2k_handle_progmem_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree ip2k_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int,
bool *));
+static bool ip2k_rtx_costs PARAMS ((rtx, int, int, int *));
+
const struct attribute_spec ip2k_attribute_table[];
@@ -100,6 +102,9 @@ const struct attribute_spec ip2k_attribute_table[];
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ip2k_attribute_table
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ip2k_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Commands in the functions prologues in the compiled file. */
@@ -3273,23 +3278,34 @@ asm_file_end (file)
/* Cost functions. */
-/* Calculate the cost of X code of the expression in which it is contained,
- found in OUTER_CODE. */
+/* 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. */
-int
-default_rtx_costs (x, code, outer_code)
+static bool
+ip2k_rtx_costs (x, code, outer_code, total)
rtx x;
- enum rtx_code code;
- enum rtx_code outer_code;
+ int code, outer_code;
+ int *total;
{
enum machine_mode mode = GET_MODE (x);
int extra_cost = 0;
- int total;
switch (code)
{
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case LABEL_REF:
+ *total = 0;
+ return true;
+ case CONST:
+ case SYMBOL_REF:
+ *total = 8;
+ return true;
+
case MEM:
- return ip2k_address_cost (XEXP (x, 0));
+ *total = ip2k_address_cost (XEXP (x, 0));
+ return true;
case ROTATE:
case ROTATERT:
@@ -3311,45 +3327,47 @@ default_rtx_costs (x, code, outer_code)
/* Sign-preserving shifts require 2 extra instructions. */
if (code == ASHIFT)
cost += COSTS_N_INSNS (2);
- return cost;
+
+ *total = cost;
+ return true;
}
- total = rtx_cost (XEXP (x, 0), code);
- total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 8);
- return total;
+ *total = rtx_cost (XEXP (x, 0), code);
+ *total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 8);
+ return true;
case MINUS:
case PLUS:
case AND:
case XOR:
case IOR:
- total = rtx_cost (XEXP (x, 0), code)
- + rtx_cost (XEXP (x, 1), code);
- total += COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3);
- return total;
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3);
+ return false;
case MOD:
case DIV:
if (mode == QImode)
- return COSTS_N_INSNS (20);
- if (mode == HImode)
- return COSTS_N_INSNS (60);
+ *total = COSTS_N_INSNS (20);
+ else if (mode == HImode)
+ *total = COSTS_N_INSNS (60);
else if (mode == SImode)
- return COSTS_N_INSNS (180);
+ *total = COSTS_N_INSNS (180);
else
- return COSTS_N_INSNS (540);
+ *total = COSTS_N_INSNS (540);
+ return true;
case MULT:
/* These costs are OK, but should really handle subtle cases
where we're using sign or zero extended args as these are
*much* cheaper than those given below! */
if (mode == QImode)
- return COSTS_N_INSNS (4);
- if (mode == HImode)
- return COSTS_N_INSNS (12);
- if (mode == SImode)
- return COSTS_N_INSNS (36);
+ *total = COSTS_N_INSNS (4);
+ else if (mode == HImode)
+ *total = COSTS_N_INSNS (12);
+ else if (mode == SImode)
+ *total = COSTS_N_INSNS (36);
else
- return COSTS_N_INSNS (108);
+ *total = COSTS_N_INSNS (108);
+ return true;
case NEG:
case SIGN_EXTEND:
@@ -3359,20 +3377,25 @@ default_rtx_costs (x, code, outer_code)
case NOT:
case COMPARE:
case ABS:
- total = rtx_cost (XEXP (x, 0), code);
- return total + extra_cost + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 2);
+ *total = extra_cost + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 2);
+ return false;
case TRUNCATE:
case ZERO_EXTEND:
if (outer_code == SET)
- return rtx_cost (XEXP (x, 0), code)
- + COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3 / 2);
+ {
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) * 3 / 2);
+ return false;
+ }
else
- return -(COSTS_N_INSNS (GET_MODE_SIZE (mode)) / 2);
+ {
+ *total = -(COSTS_N_INSNS (GET_MODE_SIZE (mode)) / 2);
+ return true;
+ }
case IF_THEN_ELSE:
- return rtx_cost (XEXP (x, 0), code)
- + COSTS_N_INSNS (2);
+ *total = rtx_cost (XEXP (x, 0), code) + COSTS_N_INSNS (2);
+ return true;
case EQ:
case NE:
@@ -3384,11 +3407,12 @@ default_rtx_costs (x, code, outer_code)
case GT:
case LE:
case GE:
- return rtx_cost (XEXP (x, 0), code)
- + rtx_cost (XEXP (x, 1), code);
+ *total = 0;
+ return false;
default:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
}
}
diff --git a/gcc/config/ip2k/ip2k.h b/gcc/config/ip2k/ip2k.h
index a5b14c52025..c656e4a4bec 100644
--- a/gcc/config/ip2k/ip2k.h
+++ b/gcc/config/ip2k/ip2k.h
@@ -1765,44 +1765,6 @@ do { \
is a suitable definition for this macro on machines where anything
`CONSTANT_P' is valid. */
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- return 0; \
- case CONST: \
- return 8; \
- case LABEL_REF: \
- return 0; \
- case SYMBOL_REF: \
- return 8; \
- case CONST_DOUBLE: \
- return 0;
-
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- return default_rtx_costs ((X), (CODE), (OUTER_CODE))
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained.
-
- This macro is optional; do not define it if the default cost
- assumptions are adequate for the target machine. */
-
#define ADDRESS_COST(ADDRESS) ip2k_address_cost (ADDRESS)
/* An expression giving the cost of an addressing mode that contains
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index a004eedc053..6d4f2a30e1f 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -80,6 +80,7 @@ static void m32r_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT));
static void m32r_encode_section_info PARAMS ((tree, int));
static const char *m32r_strip_name_encoding PARAMS ((const char *));
static void init_idents PARAMS ((void));
+static bool m32r_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -113,6 +114,9 @@ static void init_idents PARAMS ((void));
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING m32r_strip_name_encoding
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS m32r_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Called by OVERRIDE_OPTIONS to initialize various things. */
@@ -1751,6 +1755,56 @@ m32r_variable_issue (stream, verbose, insn, how_many)
/* Cost functions. */
+static bool
+m32r_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ /* Small integers are as cheap as registers. 4 byte values can be
+ fetched as immediate constants - let's give that the cost of an
+ extra insn. */
+ case CONST_INT:
+ if (INT16_P (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST_DOUBLE:
+ {
+ rtx high, low;
+ split_double (x, &high, &low);
+ *total = COSTS_N_INSNS (!INT16_P (INTVAL (high))
+ + !INT16_P (INTVAL (low)));
+ return true;
+ }
+
+ case MULT:
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (10);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant.
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index ed36eb73fb3..22bf095f72c 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -1420,36 +1420,6 @@ do { \
/* Costs. */
-/* ??? I'm quite sure I don't understand enough of the subtleties involved
- in choosing the right numbers to use here, but there doesn't seem to be
- enough documentation on this. What I've done is define an insn to cost
- 4 "units" and work from there. COSTS_N_INSNS (N) is defined as (N) * 4 - 2
- so that seems reasonable. Some values are supposed to be defined relative
- to each other and thus aren't necessarily related to COSTS_N_INSNS. */
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-/* Small integers are as cheap as registers. 4 byte values can be fetched
- as immediate constants - let's give that the cost of an extra insn. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT : \
- if (INT16_P (INTVAL (X))) \
- return 0; \
- /* fall through */ \
- case CONST : \
- case LABEL_REF : \
- case SYMBOL_REF : \
- return 4; \
- case CONST_DOUBLE : \
- { \
- rtx high, low; \
- split_double (X, &high, &low); \
- return 4 * (!INT16_P (INTVAL (high)) \
- + !INT16_P (INTVAL (low))); \
- }
-
/* Compute the cost of an address. */
#define ADDRESS_COST(ADDR) m32r_address_cost (ADDR)
@@ -1469,21 +1439,6 @@ do { \
we define this as 1. Defining it as 2 had a heavy hit in fp-bit.c. */
#define BRANCH_COST ((TARGET_BRANCH_COST) ? 2 : 1)
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable.
-
- If we need more than 12 insns to do a multiply, then go out-of-line,
- since the call overhead will be < 10% of the cost of the multiply. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT : \
- return COSTS_N_INSNS (3); \
- case DIV : \
- case UDIV : \
- case MOD : \
- case UMOD : \
- return COSTS_N_INSNS (10);
-
/* Nonzero if access to memory by bytes is slow and undesirable.
For RISC chips, it means that access to memory by bytes is no
better than access by words when possible, so grab a whole word
diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h
index 7b1ca5654c8..2d78bed2f00 100644
--- a/gcc/config/m68hc11/m68hc11-protos.h
+++ b/gcc/config/m68hc11/m68hc11-protos.h
@@ -89,7 +89,6 @@ extern int m68hc11_memory_move_cost PARAMS((enum machine_mode, enum reg_class,
int));
extern int m68hc11_register_move_cost PARAMS((enum machine_mode,
enum reg_class, enum reg_class));
-extern int m68hc11_rtx_costs PARAMS((rtx, enum rtx_code, enum rtx_code));
extern int m68hc11_address_cost PARAMS((rtx));
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 57562e148a4..0a50c4cc2e6 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -68,6 +68,8 @@ static int register_indirect_p PARAMS((rtx, enum machine_mode, int));
static rtx m68hc11_expand_compare PARAMS((enum rtx_code, rtx, rtx));
static int must_parenthesize PARAMS ((rtx));
static int m68hc11_shift_cost PARAMS ((enum machine_mode, rtx, int));
+static int m68hc11_rtx_costs_1 PARAMS ((rtx, enum rtx_code, enum rtx_code));
+static bool m68hc11_rtx_costs PARAMS ((rtx, int, int, int *));
static int m68hc11_auto_inc_p PARAMS ((rtx));
static tree m68hc11_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bool *));
const struct attribute_spec m68hc11_attribute_table[];
@@ -229,6 +231,9 @@ static int nb_soft_regs;
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO m68hc11_encode_section_info
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS m68hc11_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
int
@@ -5335,8 +5340,8 @@ m68hc11_shift_cost (mode, x, shift)
return total;
}
-int
-m68hc11_rtx_costs (x, code, outer_code)
+static int
+m68hc11_rtx_costs_1 (x, code, outer_code)
rtx x;
enum rtx_code code;
enum rtx_code outer_code ATTRIBUTE_UNUSED;
@@ -5470,6 +5475,63 @@ m68hc11_rtx_costs (x, code, outer_code)
return COSTS_N_INSNS (4);
}
}
+
+static bool
+m68hc11_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ /* Constants are cheap. Moving them in registers must be avoided
+ because most instructions do not handle two register operands. */
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ /* Logical and arithmetic operations with a constant operand are
+ better because they are not supported with two registers. */
+ /* 'clr' is slow */
+ if (outer_code == SET && x == const0_rtx)
+ /* After reload, the reload_cse pass checks the cost to change
+ a SET into a PLUS. Make const0 cheap then. */
+ *total = 1 - reload_completed;
+ else
+ *total = 0;
+ return true;
+
+ if (outer_code == SET)
+ *total = 1 - reload_completed;
+
+ case ROTATE:
+ case ROTATERT:
+ case ASHIFT:
+ case LSHIFTRT:
+ case ASHIFTRT:
+ case MINUS:
+ case PLUS:
+ case AND:
+ case XOR:
+ case IOR:
+ case UDIV:
+ case DIV:
+ case MOD:
+ case MULT:
+ case NEG:
+ case SIGN_EXTEND:
+ case NOT:
+ case COMPARE:
+ case ZERO_EXTEND:
+ case IF_THEN_ELSE:
+ *total = m68hc11_rtx_costs_1 (x, code, outer_code);
+ return true;
+
+ default:
+ return false;
+ }
+}
/* print_options - called at the start of the code generation for a
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 346392174bc..8f3740cb27d 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1391,60 +1391,8 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
#define NOTICE_UPDATE_CC(EXP, INSN) \
m68hc11_notice_update_cc ((EXP), (INSN))
-/* Compute the cost of computing a constant rtl expression RTX whose rtx-code
- is CODE. The body of this macro is a portion of a switch statement. If
- the code is computed here, return it with a return statement. Otherwise,
- break from the switch.
-
- Constants are cheap. Moving them in registers must be avoided
- because most instructions do not handle two register operands. */
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- /* Logical and arithmetic operations with a constant */ \
- /* operand are better because they are not supported */ \
- /* with two registers. */ \
- /* 'clr' is slow */ \
- if ((OUTER_CODE) == SET && (RTX) == const0_rtx) \
- /* After reload, the reload_cse pass checks the cost */ \
- /* to change a SET into a PLUS. Make const0 cheap. */ \
- return 1 - reload_completed; \
- else \
- return 0; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if ((OUTER_CODE) == SET) \
- return 1 - reload_completed; \
- return 0; \
- case CONST_DOUBLE: \
- return 0;
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case ROTATE: \
- case ROTATERT: \
- case ASHIFT: \
- case LSHIFTRT: \
- case ASHIFTRT: \
- case MINUS: \
- case PLUS: \
- case AND: \
- case XOR: \
- case IOR: \
- case UDIV: \
- case DIV: \
- case MOD: \
- case MULT: \
- case NEG: \
- case SIGN_EXTEND: \
- case NOT: \
- case COMPARE: \
- case ZERO_EXTEND: \
- case IF_THEN_ELSE: \
- return m68hc11_rtx_costs (X, CODE, OUTER_CODE);
-
/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values. */
+ ADDRESS. */
#define ADDRESS_COST(RTX) m68hc11_address_cost (RTX)
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 72120ead37f..e0ffee80eb7 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -48,7 +48,6 @@ extern int strict_low_part_peephole_ok PARAMS ((enum machine_mode, rtx, rtx));
/* Functions from m68k.c used in macros. */
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int const_int_cost PARAMS ((rtx));
extern int standard_68881_constant_p PARAMS ((rtx));
extern int standard_sun_fpa_constant_p PARAMS ((rtx));
extern void print_operand_address PARAMS ((FILE *, rtx));
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index c7e0e5cdfad..cb94d232923 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -73,6 +73,8 @@ static void m68k_hp320_internal_label PARAMS ((FILE *, const char *, unsigned lo
static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static int m68k_save_reg PARAMS ((unsigned int));
+static int const_int_cost PARAMS ((rtx));
+static bool m68k_rtx_costs PARAMS ((rtx, int, int, int *));
/* Alignment to use for loops and jumps */
@@ -139,6 +141,9 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS m68k_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Sometimes certain combinations of command options do not make
@@ -1708,7 +1713,7 @@ const_method (constant)
return MOVL;
}
-int
+static int
const_int_cost (constant)
rtx constant;
{
@@ -1730,6 +1735,125 @@ const_int_cost (constant)
}
}
+static bool
+m68k_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ /* Constant zero is super cheap due to clr instruction. */
+ if (x == const0_rtx)
+ *total = 0;
+ else
+ *total = const_int_cost (x);
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 3;
+ return true;
+
+ case CONST_DOUBLE:
+ /* Make 0.0 cheaper than other floating constants to
+ encourage creating tstsf and tstdf insns. */
+ if (outer_code == COMPARE
+ && (x == CONST0_RTX (SFmode) || x == CONST0_RTX (DFmode)))
+ *total = 4;
+ else
+ *total = 5;
+ return true;
+
+ /* These are vaguely right for a 68020. */
+ /* The costs for long multiply have been adjusted to work properly
+ in synth_mult on the 68020, relative to an average of the time
+ for add and the time for shift, taking away a little more because
+ sometimes move insns are needed. */
+ /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
+#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : 13)
+#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
+#define DIVW_COST (TARGET_68020 ? 27 : 12)
+
+ case PLUS:
+ /* An lea costs about three times as much as a simple add. */
+ if (GET_MODE (x) == SImode
+ && GET_CODE (XEXP (x, 1)) == REG
+ && GET_CODE (XEXP (x, 0)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
+ || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
+ || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
+ *total = COSTS_N_INSNS (3); /* lea an@(dx:l:i),am */
+ return false;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (TARGET_68060)
+ {
+ *total = COSTS_N_INSNS(1);
+ return true;
+ }
+ if (! TARGET_68020)
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ if (INTVAL (XEXP (x, 1)) < 16)
+ *total = COSTS_N_INSNS (2) + INTVAL (XEXP (x, 1)) / 2;
+ else
+ /* We're using clrw + swap for these cases. */
+ *total = COSTS_N_INSNS (4) + (INTVAL (XEXP (x, 1)) - 16) / 2;
+ }
+ else
+ *total = COSTS_N_INSNS (10); /* worst case */
+ return true;
+ }
+ /* A shift by a big integer takes an extra instruction. */
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) == 16))
+ {
+ *total = COSTS_N_INSNS (2); /* clrw;swap */
+ return true;
+ }
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && !(INTVAL (XEXP (x, 1)) > 0
+ && INTVAL (XEXP (x, 1)) <= 8))
+ {
+ *total = COSTS_N_INSNS (3); /* lsr #i,dn */
+ return true;
+ }
+ return false;
+
+ case MULT:
+ if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
+ || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
+ && GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (MULW_COST);
+ else if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
+ *total = COSTS_N_INSNS (MULW_COST);
+ else
+ *total = COSTS_N_INSNS (MULL_COST);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ if (GET_MODE (x) == QImode || GET_MODE (x) == HImode)
+ *total = COSTS_N_INSNS (DIVW_COST); /* div.w */
+ else
+ *total = COSTS_N_INSNS (43); /* div.l */
+ return true;
+
+ default:
+ return false;
+ }
+}
+
const char *
output_move_const_into_data_reg (operands)
rtx *operands;
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 7d07a13a962..3ba717b064c 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -1520,96 +1520,6 @@ __transfer_from_trampoline () \
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- /* Constant zero is super cheap due to clr instruction. */ \
- if (RTX == const0_rtx) return 0; \
- /* if ((OUTER_CODE) == SET) */ \
- return const_int_cost(RTX); \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 3; \
- case CONST_DOUBLE: \
- /* Make 0.0 cheaper than other floating constants to \
- encourage creating tstsf and tstdf insns. */ \
- if ((OUTER_CODE) == COMPARE \
- && ((RTX) == CONST0_RTX (SFmode) \
- || (RTX) == CONST0_RTX (DFmode))) \
- return 4; \
- return 5;
-
-/* Compute the cost of various arithmetic operations.
- These are vaguely right for a 68020. */
-/* The costs for long multiply have been adjusted to
- work properly in synth_mult on the 68020,
- relative to an average of the time for add and the time for shift,
- taking away a little more because sometimes move insns are needed. */
-/* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
-#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : 13)
-#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
-#define DIVW_COST (TARGET_68020 ? 27 : 12)
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: \
- /* An lea costs about three times as much as a simple add. */ \
- if (GET_MODE (X) == SImode \
- && GET_CODE (XEXP (X, 1)) == REG \
- && GET_CODE (XEXP (X, 0)) == MULT \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && (INTVAL (XEXP (XEXP (X, 0), 1)) == 2 \
- || INTVAL (XEXP (XEXP (X, 0), 1)) == 4 \
- || INTVAL (XEXP (XEXP (X, 0), 1)) == 8)) \
- return COSTS_N_INSNS (3); /* lea an@(dx:l:i),am */ \
- break; \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- if (TARGET_68060) \
- return COSTS_N_INSNS(1); \
- if (! TARGET_68020) \
- { \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- if (INTVAL (XEXP (X, 1)) < 16) \
- return COSTS_N_INSNS (2) + INTVAL (XEXP (X, 1)) / 2; \
- else \
- /* We're using clrw + swap for these cases. */ \
- return COSTS_N_INSNS (4) + (INTVAL (XEXP (X, 1)) - 16) / 2; \
- } \
- return COSTS_N_INSNS (10); /* worst case */ \
- } \
- /* A shift by a big integer takes an extra instruction. */ \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) == 16)) \
- return COSTS_N_INSNS (2); /* clrw;swap */ \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && !(INTVAL (XEXP (X, 1)) > 0 \
- && INTVAL (XEXP (X, 1)) <= 8)) \
- return COSTS_N_INSNS (3); /* lsr #i,dn */ \
- break; \
- case MULT: \
- if ((GET_CODE (XEXP (X, 0)) == ZERO_EXTEND \
- || GET_CODE (XEXP (X, 0)) == SIGN_EXTEND) \
- && GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (MULW_COST); \
- if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \
- return COSTS_N_INSNS (MULW_COST); \
- else \
- return COSTS_N_INSNS (MULL_COST); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \
- return COSTS_N_INSNS (DIVW_COST); /* div.w */ \
- return COSTS_N_INSNS (43); /* div.l */
/* Tell final.c how to eliminate redundant test instructions. */
diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c
index 44ca220c4e1..5a8f26864e8 100644
--- a/gcc/config/m88k/m88k.c
+++ b/gcc/config/m88k/m88k.c
@@ -79,6 +79,7 @@ static void m88k_encode_section_info PARAMS ((tree, int));
#ifdef AS_BUG_DOT_LABELS
static void m88k_internal_label PARAMS ((FILE *, const char *, unsigned long));
#endif
+static bool m88k_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_BYTE_OP
@@ -111,6 +112,9 @@ static void m88k_internal_label PARAMS ((FILE *, const char *, unsigned long));
#define TARGET_ASM_INTERNAL_LABEL m88k_internal_label
#endif
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS m88k_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Determine what instructions are needed to manufacture the integer VALUE
@@ -3362,3 +3366,66 @@ m88k_internal_label (stream, prefix, labelno)
prefix, labelno, INTERNAL_ASM_OP, prefix, labelno);
}
#endif
+
+static bool
+m88k_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ /* We assume that any 16 bit integer can easily be recreated, so we
+ indicate 0 cost, in an attempt to get GCC not to optimize things
+ like comparison against a constant. */
+ case CONST_INT:
+ if (SMALL_INT (x))
+ *total = 0;
+ else if (SMALL_INTVAL (- INTVAL (x)))
+ *total = 2;
+ else if (classify_integer (SImode, INTVAL (x)) != m88k_oru_or)
+ *total = 4;
+ else
+ *total = 7;
+ return true;
+
+ case HIGH:
+ *total = 2;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ if (flag_pic)
+ *total = (flag_pic == 2) ? 11 : 8;
+ else
+ *total = 5;
+ return true;
+
+ /* The cost of CONST_DOUBLE is zero (if it can be placed in an insn, it
+ is as good as a register; since it can't be placed in any insn, it
+ won't do anything in cse, but it will cause expand_binop to pass the
+ constant to the define_expands). */
+ case CONST_DOUBLE:
+ *total = 0;
+ return true;
+
+ case MEM:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case MULT:
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (38);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/m88k/m88k.h b/gcc/config/m88k/m88k.h
index c702094f423..4001927e655 100644
--- a/gcc/config/m88k/m88k.h
+++ b/gcc/config/m88k/m88k.h
@@ -1504,39 +1504,6 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
state with CC_STATUS_INIT for now. */
#define CC_STATUS_INIT m88k_volatile_code = '\0'
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- We assume that any 16 bit integer can easily be recreated, so we
- indicate 0 cost, in an attempt to get GCC not to optimize things
- like comparison against a constant.
-
- The cost of CONST_DOUBLE is zero (if it can be placed in an insn, it
- is as good as a register; since it can't be placed in any insn, it
- won't do anything in cse, but it will cause expand_binop to pass the
- constant to the define_expands). */
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (SMALL_INT (RTX)) \
- return 0; \
- else if (SMALL_INTVAL (- INTVAL (RTX))) \
- return 2; \
- else if (classify_integer (SImode, INTVAL (RTX)) != m88k_oru_or) \
- return 4; \
- return 7; \
- case HIGH: \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if (flag_pic) \
- return (flag_pic == 2) ? 11 : 8; \
- return 5; \
- case CONST_DOUBLE: \
- return 0;
-
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant.
REG+REG is made slightly more expensive because it might keep
@@ -1549,19 +1516,6 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
GET_CODE (ADDR) != PLUS ? 4 : \
(REG_P (XEXP (ADDR, 0)) && REG_P (XEXP (ADDR, 1))) ? 2 : 1)
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MEM: \
- return COSTS_N_INSNS (2); \
- case MULT: \
- return COSTS_N_INSNS (3); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (38);
-
/* A C expressions returning the cost of moving data of MODE from a register
to or from memory. This is more costly than between registers. */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
diff --git a/gcc/config/mcore/mcore-protos.h b/gcc/config/mcore/mcore-protos.h
index 9910c3a5ec0..8b995811c51 100644
--- a/gcc/config/mcore/mcore-protos.h
+++ b/gcc/config/mcore/mcore-protos.h
@@ -61,9 +61,6 @@ extern int mcore_expand_insv PARAMS ((rtx *));
extern int mcore_modify_comparison PARAMS ((RTX_CODE));
extern void mcore_expand_block_move PARAMS ((rtx, rtx, rtx *));
extern void mcore_dependent_reorg PARAMS ((rtx));
-extern int mcore_const_costs PARAMS ((rtx, RTX_CODE));
-extern int mcore_and_cost PARAMS ((rtx));
-extern int mcore_ior_cost PARAMS ((rtx));
extern const char * mcore_output_andn PARAMS ((rtx, rtx *));
extern void mcore_print_operand_address PARAMS ((FILE *, rtx));
extern void mcore_print_operand PARAMS ((FILE *, rtx, int));
diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c
index dfe02828bfe..cb24e937f3e 100644
--- a/gcc/config/mcore/mcore.c
+++ b/gcc/config/mcore/mcore.c
@@ -141,6 +141,10 @@ static void mcore_asm_named_section PARAMS ((const char *,
static void mcore_unique_section PARAMS ((tree, int));
static void mcore_encode_section_info PARAMS ((tree, int));
static const char *mcore_strip_name_encoding PARAMS ((const char *));
+static int mcore_const_costs PARAMS ((rtx, RTX_CODE));
+static int mcore_and_cost PARAMS ((rtx));
+static int mcore_ior_cost PARAMS ((rtx));
+static bool mcore_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -164,6 +168,9 @@ static const char *mcore_strip_name_encoding PARAMS ((const char *));
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING mcore_strip_name_encoding
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS mcore_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Adjust the stack and return the number of bytes taken to do it. */
@@ -368,7 +375,7 @@ mcore_print_operand (stream, x, code)
/* What does a constant cost ? */
-int
+static int
mcore_const_costs (exp, code)
rtx exp;
enum rtx_code code;
@@ -399,7 +406,7 @@ mcore_const_costs (exp, code)
have been relaxed. We want to ensure that cse will cse relaxed immeds
out. Otherwise we'll get bad code (multiple reloads of the same const). */
-int
+static int
mcore_and_cost (x)
rtx x;
{
@@ -426,7 +433,7 @@ mcore_and_cost (x)
/* What does an or cost - see and_cost(). */
-int
+static int
mcore_ior_cost (x)
rtx x;
{
@@ -451,6 +458,48 @@ mcore_ior_cost (x)
return 5;
}
+static bool
+mcore_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ *total = mcore_const_costs (x, outer_code);
+ return true;
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 5;
+ return true;
+ case CONST_DOUBLE:
+ *total = 10;
+ return true;
+
+ case AND:
+ *total = COSTS_N_INSNS (mcore_and_cost (x));
+ return true;
+
+ case IOR:
+ *total = COSTS_N_INSNS (mcore_ior_cost (x));
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ case FLOAT:
+ case FIX:
+ *total = COSTS_N_INSNS (100);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Check to see if a comparison against a constant can be made more efficient
by incrementing/decrementing the constant to get one that is more efficient
to load. */
diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h
index bfa8271b8f7..42d2d45f974 100644
--- a/gcc/config/mcore/mcore.h
+++ b/gcc/config/mcore/mcore.h
@@ -1004,37 +1004,10 @@ extern const enum reg_class reg_class_from_letter[];
#define Pmode SImode
#define FUNCTION_MODE Pmode
-/* The relative costs of various types of constants. Note that cse.c defines
- REG = 1, SUBREG = 2, any node = (2 + sum of subnodes). */
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- return mcore_const_costs (RTX, OUTER_CODE); \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 5; \
- case CONST_DOUBLE: \
- return 10;
-
/* provide the cost for an address calculation.
All addressing modes cost the same on the MCore. */
#define ADDRESS_COST(RTX) 1
-/* Provide the cost of an rtl expression. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case AND: \
- return COSTS_N_INSNS (mcore_and_cost (X)); \
- case IOR: \
- return COSTS_N_INSNS (mcore_ior_cost (X)); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (100); \
- case FLOAT: \
- case FIX: \
- return 100;
-
/* Compute extra cost of moving data between one register class
and another. All register moves are cheap. */
#define REGISTER_MOVE_COST(MODE, SRCCLASS, DSTCLASS) 2
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b1408f19024..4dcf5248ab5 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -155,6 +155,8 @@ static void mips_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static int mips_use_dfa_pipeline_interface PARAMS ((void));
static void mips_encode_section_info PARAMS ((tree, int));
+static bool mips_rtx_costs PARAMS ((rtx, int, int, int *));
+
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@@ -670,6 +672,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_VALID_POINTER_MODE
#define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS mips_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2986,6 +2990,337 @@ mips_move_2words (operands, insn)
return ret;
}
+static bool
+mips_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ enum machine_mode mode = GET_MODE (x);
+
+ switch (code)
+ {
+ case CONST_INT:
+ if (! TARGET_MIPS16)
+ {
+ /* Always return 0, since we don't have different sized insns,
+ hence different costs according to Richard Kenner. */
+ *total = 0;
+ return true;
+ }
+
+ if (outer_code == SET)
+ {
+ if (INTVAL (x) >= 0 && INTVAL (x) < 0x100)
+ *total = 0;
+ else if ((INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
+ || (INTVAL (x) < 0 && INTVAL (x) > -0x100))
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+
+ /* A PLUS could be an address. We don't want to force an address
+ to use a register, so accept any signed 16 bit value without
+ complaint. */
+ if (outer_code == PLUS
+ && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
+ {
+ *total = 0;
+ return true;
+ }
+
+ /* A number between 1 and 8 inclusive is efficient for a shift.
+ Otherwise, we will need an extended instruction. */
+ if (outer_code == ASHIFT || outer_code == ASHIFTRT
+ || outer_code == LSHIFTRT)
+ {
+ if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
+ /* We can use cmpi for an xor with an unsigned 16 bit value. */
+ if (outer_code == XOR
+ && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
+ {
+ *total = 0;
+ return true;
+ }
+
+ /* We may be able to use slt or sltu for a comparison with a
+ signed 16 bit value. (The boundary conditions aren't quite
+ right, but this is just a heuristic anyhow.) */
+ if ((outer_code == LT || outer_code == LE
+ || outer_code == GE || outer_code == GT
+ || outer_code == LTU || outer_code == LEU
+ || outer_code == GEU || outer_code == GTU)
+ && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
+ {
+ *total = 0;
+ return true;
+ }
+
+ /* Equality comparisons with 0 are cheap. */
+ if ((outer_code == EQ || outer_code == NE)
+ && INTVAL (x) == 0)
+ return 0;
+
+ /* Otherwise, work out the cost to load the value into a
+ register. */
+ if (INTVAL (x) >= 0 && INTVAL (x) < 0x100)
+ *total = COSTS_N_INSNS (1);
+ else if ((INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
+ || (INTVAL (x) < 0 && INTVAL (x) > -0x100))
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case LABEL_REF:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST:
+ {
+ rtx offset = const0_rtx;
+ rtx symref = eliminate_constant_term (XEXP (x, 0), &offset);
+
+ if (TARGET_MIPS16 && mips16_gp_offset_p (x))
+ {
+ /* Treat this like a signed 16 bit CONST_INT. */
+ if (outer_code == PLUS)
+ *total = 0;
+ else if (outer_code == SET)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+
+ if (GET_CODE (symref) == LABEL_REF)
+ *total = COSTS_N_INSNS (2);
+ else if (GET_CODE (symref) != SYMBOL_REF)
+ *total = COSTS_N_INSNS (4);
+ else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
+
+ return true;
+ }
+
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
+ return true;
+
+ case CONST_DOUBLE:
+ {
+ rtx high, low;
+ if (TARGET_MIPS16)
+ {
+ *total = COSTS_N_INSNS (4);
+ return true;
+ }
+
+ split_double (x, &high, &low);
+ *total = COSTS_N_INSNS ((high == CONST0_RTX (GET_MODE (high))
+ || low == CONST0_RTX (GET_MODE (low)))
+ ? 2 : 4);
+ return true;
+ }
+
+ case MEM:
+ {
+ int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
+ if (simple_memory_operand (x, mode))
+ *total = COSTS_N_INSNS (num_words);
+ else
+ *total = COSTS_N_INSNS (2*num_words);
+ return true;
+ }
+
+ case FFS:
+ *total = COSTS_N_INSNS (6);
+ return true;
+
+ case NOT:
+ *total = COSTS_N_INSNS ((mode == DImode && !TARGET_64BIT) ? 2 : 1);
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ if (mode == DImode && !TARGET_64BIT)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ return false;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (mode == DImode && !TARGET_64BIT)
+ {
+ *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT)
+ ? 4 : 12);
+ return true;
+ }
+ return false;
+
+ case ABS:
+ if (mode == SFmode || mode == DFmode)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ if (mode == SFmode || mode == DFmode)
+ {
+ if (TUNE_MIPS3000 || TUNE_MIPS3900)
+ *total = COSTS_N_INSNS (2);
+ else if (TUNE_MIPS6000)
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = COSTS_N_INSNS (6);
+ return true;
+ }
+ if (mode == DImode && !TARGET_64BIT)
+ {
+ *total = COSTS_N_INSNS (4);
+ return true;
+ }
+ return false;
+
+ case NEG:
+ if (mode == DImode && !TARGET_64BIT)
+ {
+ *total = 4;
+ return true;
+ }
+ return false;
+
+ case MULT:
+ if (mode == SFmode)
+ {
+ if (TUNE_MIPS3000
+ || TUNE_MIPS3900
+ || TUNE_MIPS5000)
+ *total = COSTS_N_INSNS (4);
+ else if (TUNE_MIPS6000
+ || TUNE_MIPS5400
+ || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS (5);
+ else
+ *total = COSTS_N_INSNS (7);
+ return true;
+ }
+
+ if (mode == DFmode)
+ {
+ if (TUNE_MIPS3000
+ || TUNE_MIPS3900
+ || TUNE_MIPS5000)
+ *total = COSTS_N_INSNS (5);
+ else if (TUNE_MIPS6000
+ || TUNE_MIPS5400
+ || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS (6);
+ else
+ *total = COSTS_N_INSNS (8);
+ return true;
+ }
+
+ if (TUNE_MIPS3000)
+ *total = COSTS_N_INSNS (12);
+ else if (TUNE_MIPS3900)
+ *total = COSTS_N_INSNS (2);
+ else if (TUNE_MIPS5400 || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS ((mode == DImode) ? 4 : 3);
+ else if (TUNE_MIPS6000)
+ *total = COSTS_N_INSNS (17);
+ else if (TUNE_MIPS5000)
+ *total = COSTS_N_INSNS (5);
+ else
+ *total = COSTS_N_INSNS (10);
+ return true;
+
+ case DIV:
+ case MOD:
+ if (mode == SFmode)
+ {
+ if (TUNE_MIPS3000
+ || TUNE_MIPS3900)
+ *total = COSTS_N_INSNS (12);
+ else if (TUNE_MIPS6000)
+ *total = COSTS_N_INSNS (15);
+ else if (TUNE_MIPS5400 || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS (30);
+ else
+ *total = COSTS_N_INSNS (23);
+ return true;
+ }
+
+ if (mode == DFmode)
+ {
+ if (TUNE_MIPS3000
+ || TUNE_MIPS3900)
+ *total = COSTS_N_INSNS (19);
+ else if (TUNE_MIPS5400 || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS (59);
+ else if (TUNE_MIPS6000)
+ *total = COSTS_N_INSNS (16);
+ else
+ *total = COSTS_N_INSNS (36);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case UDIV:
+ case UMOD:
+ if (TUNE_MIPS3000
+ || TUNE_MIPS3900)
+ *total = COSTS_N_INSNS (35);
+ else if (TUNE_MIPS6000)
+ *total = COSTS_N_INSNS (38);
+ else if (TUNE_MIPS5000)
+ *total = COSTS_N_INSNS (36);
+ else if (TUNE_MIPS5400 || TUNE_MIPS5500)
+ *total = COSTS_N_INSNS ((mode == SImode) ? 42 : 74);
+ else
+ *total = COSTS_N_INSNS (69);
+ return true;
+
+ case SIGN_EXTEND:
+ /* A sign extend from SImode to DImode in 64 bit mode is often
+ zero instructions, because the result can often be used
+ directly by another instruction; we'll call it one. */
+ if (TARGET_64BIT && mode == DImode
+ && GET_MODE (XEXP (x, 0)) == SImode)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case ZERO_EXTEND:
+ if (TARGET_64BIT && mode == DImode
+ && GET_MODE (XEXP (x, 0)) == SImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 61a6b0db735..696aff2be2f 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3385,316 +3385,6 @@ typedef struct mips_args {
#define FUNCTION_MODE (Pmode == DImode ? DImode : SImode)
-/* A part of a C `switch' statement that describes the relative
- costs of constant RTL expressions. It must contain `case'
- labels for expression codes `const_int', `const', `symbol_ref',
- `label_ref' and `const_double'. Each case must ultimately reach
- a `return' statement to return the relative cost of the use of
- that kind of constant value in an expression. The cost may
- depend on the precise value of the constant, which is available
- for examination in X.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define CONST_COSTS(X,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (! TARGET_MIPS16) \
- { \
- /* Always return 0, since we don't have different sized \
- instructions, hence different costs according to Richard \
- Kenner */ \
- return 0; \
- } \
- if ((OUTER_CODE) == SET) \
- { \
- if (INTVAL (X) >= 0 && INTVAL (X) < 0x100) \
- return 0; \
- else if ((INTVAL (X) >= 0 && INTVAL (X) < 0x10000) \
- || (INTVAL (X) < 0 && INTVAL (X) > -0x100)) \
- return COSTS_N_INSNS (1); \
- else \
- return COSTS_N_INSNS (2); \
- } \
- /* A PLUS could be an address. We don't want to force an address \
- to use a register, so accept any signed 16 bit value without \
- complaint. */ \
- if ((OUTER_CODE) == PLUS \
- && INTVAL (X) >= -0x8000 && INTVAL (X) < 0x8000) \
- return 0; \
- /* A number between 1 and 8 inclusive is efficient for a shift. \
- Otherwise, we will need an extended instruction. */ \
- if ((OUTER_CODE) == ASHIFT || (OUTER_CODE) == ASHIFTRT \
- || (OUTER_CODE) == LSHIFTRT) \
- { \
- if (INTVAL (X) >= 1 && INTVAL (X) <= 8) \
- return 0; \
- return COSTS_N_INSNS (1); \
- } \
- /* We can use cmpi for an xor with an unsigned 16 bit value. */ \
- if ((OUTER_CODE) == XOR \
- && INTVAL (X) >= 0 && INTVAL (X) < 0x10000) \
- return 0; \
- /* We may be able to use slt or sltu for a comparison with a \
- signed 16 bit value. (The boundary conditions aren't quite \
- right, but this is just a heuristic anyhow.) */ \
- if (((OUTER_CODE) == LT || (OUTER_CODE) == LE \
- || (OUTER_CODE) == GE || (OUTER_CODE) == GT \
- || (OUTER_CODE) == LTU || (OUTER_CODE) == LEU \
- || (OUTER_CODE) == GEU || (OUTER_CODE) == GTU) \
- && INTVAL (X) >= -0x8000 && INTVAL (X) < 0x8000) \
- return 0; \
- /* Equality comparisons with 0 are cheap. */ \
- if (((OUTER_CODE) == EQ || (OUTER_CODE) == NE) \
- && INTVAL (X) == 0) \
- return 0; \
- \
- /* Otherwise, work out the cost to load the value into a \
- register. */ \
- if (INTVAL (X) >= 0 && INTVAL (X) < 0x100) \
- return COSTS_N_INSNS (1); \
- else if ((INTVAL (X) >= 0 && INTVAL (X) < 0x10000) \
- || (INTVAL (X) < 0 && INTVAL (X) > -0x100)) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (3); \
- \
- case LABEL_REF: \
- return COSTS_N_INSNS (2); \
- \
- case CONST: \
- { \
- rtx offset = const0_rtx; \
- rtx symref = eliminate_constant_term (XEXP (X, 0), &offset); \
- \
- if (TARGET_MIPS16 && mips16_gp_offset_p (X)) \
- { \
- /* Treat this like a signed 16 bit CONST_INT. */ \
- if ((OUTER_CODE) == PLUS) \
- return 0; \
- else if ((OUTER_CODE) == SET) \
- return COSTS_N_INSNS (1); \
- else \
- return COSTS_N_INSNS (2); \
- } \
- \
- if (GET_CODE (symref) == LABEL_REF) \
- return COSTS_N_INSNS (2); \
- \
- if (GET_CODE (symref) != SYMBOL_REF) \
- return COSTS_N_INSNS (4); \
- \
- /* let's be paranoid.... */ \
- if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767) \
- return COSTS_N_INSNS (2); \
- \
- return COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2); \
- } \
- \
- case SYMBOL_REF: \
- return COSTS_N_INSNS (SYMBOL_REF_FLAG (X) ? 1 : 2); \
- \
- case CONST_DOUBLE: \
- { \
- rtx high, low; \
- if (TARGET_MIPS16) \
- return COSTS_N_INSNS (4); \
- split_double (X, &high, &low); \
- return COSTS_N_INSNS ((high == CONST0_RTX (GET_MODE (high)) \
- || low == CONST0_RTX (GET_MODE (low))) \
- ? 2 : 4); \
- }
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast instructions.
-
- This macro is optional; do not define it if the default cost
- assumptions are adequate for the target machine.
-
- If -mdebugd is used, change the multiply cost to 2, so multiply by
- a constant isn't converted to a series of shifts. This helps
- strength reduction, and also makes it easier to identify what the
- compiler is doing. */
-
-/* ??? Fix this to be right for the R8000. */
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MEM: \
- { \
- int num_words = (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ? 2 : 1; \
- if (simple_memory_operand (X, GET_MODE (X))) \
- return COSTS_N_INSNS (num_words); \
- \
- return COSTS_N_INSNS (2*num_words); \
- } \
- \
- case FFS: \
- return COSTS_N_INSNS (6); \
- \
- case NOT: \
- return COSTS_N_INSNS ((GET_MODE (X) == DImode && !TARGET_64BIT) ? 2 : 1); \
- \
- case AND: \
- case IOR: \
- case XOR: \
- if (GET_MODE (X) == DImode && !TARGET_64BIT) \
- return COSTS_N_INSNS (2); \
- \
- break; \
- \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- if (GET_MODE (X) == DImode && !TARGET_64BIT) \
- return COSTS_N_INSNS ((GET_CODE (XEXP (X, 1)) == CONST_INT) ? 4 : 12); \
- \
- break; \
- \
- case ABS: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode || xmode == DFmode) \
- return COSTS_N_INSNS (1); \
- \
- return COSTS_N_INSNS (4); \
- } \
- \
- case PLUS: \
- case MINUS: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode || xmode == DFmode) \
- { \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
- return COSTS_N_INSNS (2); \
- else if (TUNE_MIPS6000) \
- return COSTS_N_INSNS (3); \
- else \
- return COSTS_N_INSNS (6); \
- } \
- \
- if (xmode == DImode && !TARGET_64BIT) \
- return COSTS_N_INSNS (4); \
- \
- break; \
- } \
- \
- case NEG: \
- if (GET_MODE (X) == DImode && !TARGET_64BIT) \
- return 4; \
- \
- break; \
- \
- case MULT: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- { \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900 \
- || TUNE_MIPS5000) \
- return COSTS_N_INSNS (4); \
- else if (TUNE_MIPS6000 \
- || TUNE_MIPS5400 \
- || TUNE_MIPS5500) \
- return COSTS_N_INSNS (5); \
- else \
- return COSTS_N_INSNS (7); \
- } \
- \
- if (xmode == DFmode) \
- { \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900 \
- || TUNE_MIPS5000) \
- return COSTS_N_INSNS (5); \
- else if (TUNE_MIPS6000 \
- || TUNE_MIPS5400 \
- || TUNE_MIPS5500) \
- return COSTS_N_INSNS (6); \
- else \
- return COSTS_N_INSNS (8); \
- } \
- \
- if (TUNE_MIPS3000) \
- return COSTS_N_INSNS (12); \
- else if (TUNE_MIPS3900) \
- return COSTS_N_INSNS (2); \
- else if (TUNE_MIPS5400 || TUNE_MIPS5500) \
- return COSTS_N_INSNS ((xmode == DImode) ? 4 : 3); \
- else if (TUNE_MIPS6000) \
- return COSTS_N_INSNS (17); \
- else if (TUNE_MIPS5000) \
- return COSTS_N_INSNS (5); \
- else \
- return COSTS_N_INSNS (10); \
- } \
- \
- case DIV: \
- case MOD: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- { \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
- return COSTS_N_INSNS (12); \
- else if (TUNE_MIPS6000) \
- return COSTS_N_INSNS (15); \
- else if (TUNE_MIPS5400 || TUNE_MIPS5500) \
- return COSTS_N_INSNS (30); \
- else \
- return COSTS_N_INSNS (23); \
- } \
- \
- if (xmode == DFmode) \
- { \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
- return COSTS_N_INSNS (19); \
- else if (TUNE_MIPS5400 || TUNE_MIPS5500) \
- return COSTS_N_INSNS (59); \
- else if (TUNE_MIPS6000) \
- return COSTS_N_INSNS (16); \
- else \
- return COSTS_N_INSNS (36); \
- } \
- } \
- /* fall through */ \
- \
- case UDIV: \
- case UMOD: \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
- return COSTS_N_INSNS (35); \
- else if (TUNE_MIPS6000) \
- return COSTS_N_INSNS (38); \
- else if (TUNE_MIPS5000) \
- return COSTS_N_INSNS (36); \
- else if (TUNE_MIPS5400 || TUNE_MIPS5500) \
- return COSTS_N_INSNS ((GET_MODE (X) == SImode) ? 42 : 74); \
- else \
- return COSTS_N_INSNS (69); \
- \
- case SIGN_EXTEND: \
- /* A sign extend from SImode to DImode in 64 bit mode is often \
- zero instructions, because the result can often be used \
- directly by another instruction; we'll call it one. */ \
- if (TARGET_64BIT && GET_MODE (X) == DImode \
- && GET_MODE (XEXP (X, 0)) == SImode) \
- return COSTS_N_INSNS (1); \
- else \
- return COSTS_N_INSNS (2); \
- \
- case ZERO_EXTEND: \
- if (TARGET_64BIT && GET_MODE (X) == DImode \
- && GET_MODE (XEXP (X, 0)) == SImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (1);
-
/* An expression giving the cost of an addressing mode that
contains ADDRESS. If not defined, the cost is computed from the
form of the ADDRESS expression and the `CONST_COSTS' values.
diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h
index fb3705a403c..e6c22f093f9 100644
--- a/gcc/config/mmix/mmix-protos.h
+++ b/gcc/config/mmix/mmix-protos.h
@@ -109,8 +109,6 @@ extern void mmix_setup_frame_addresses PARAMS ((void));
/* Needs to be ifdef:d for sake of enum rtx_code. */
extern enum machine_mode mmix_select_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
extern void mmix_canonicalize_comparison PARAMS ((enum rtx_code *, rtx *, rtx *));
-extern int mmix_rtx_cost_recalculated
- PARAMS ((rtx, enum rtx_code, enum rtx_code, int *));
extern int mmix_valid_comparison PARAMS ((enum rtx_code, enum machine_mode, rtx));
extern rtx mmix_gen_compare_reg PARAMS ((enum rtx_code, rtx, rtx));
#endif
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index db4bb4c1e54..b8cc2fbd2b9 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -134,6 +134,8 @@ static void mmix_target_asm_function_epilogue
PARAMS ((FILE *, HOST_WIDE_INT));
static void mmix_asm_output_mi_thunk
PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+static bool mmix_rtx_costs
+ PARAMS ((rtx, int, int, int *));
/* Target structure macros. Listed by node. See `Using and Porting GCC'
@@ -171,6 +173,9 @@ static void mmix_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS mmix_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Functions that are expansions for target macros.
@@ -1189,19 +1194,19 @@ mmix_reversible_cc_mode (mode)
return mode != CC_FPmode;
}
-/* DEFAULT_RTX_COSTS. */
+/* TARGET_RTX_COSTS. */
-int
-mmix_rtx_cost_recalculated (x, code, outer_code, costp)
+static bool
+mmix_rtx_costs (x, code, outer_code, total)
rtx x ATTRIBUTE_UNUSED;
- RTX_CODE code ATTRIBUTE_UNUSED;
- RTX_CODE outer_code ATTRIBUTE_UNUSED;
- int *costp ATTRIBUTE_UNUSED;
+ int code ATTRIBUTE_UNUSED;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total ATTRIBUTE_UNUSED;
{
/* For the time being, this is just a stub and we'll accept the
generic calculations, until we can do measurements, at least.
Say we did not modify any calculated costs. */
- return 0;
+ return false;
}
/* ADDRESS_COST. */
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index 562c39e1ef3..7549f590cdc 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -881,15 +881,6 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
/* Node: Costs */
-/* This one takes on both the RTX_COSTS and CONST_COSTS tasks. */
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- { \
- int mmix_rtx_cost; \
- if (mmix_rtx_cost_recalculated (X, CODE, OUTER_CODE, \
- &mmix_rtx_cost)) \
- return mmix_rtx_cost; \
- }
-
#define ADDRESS_COST(ADDRESS) mmix_address_cost (ADDRESS)
/* The special registers can only move to and from general regs, and we
diff --git a/gcc/config/mn10200/mn10200.c b/gcc/config/mn10200/mn10200.c
index 39a378d3285..4116c016e55 100644
--- a/gcc/config/mn10200/mn10200.c
+++ b/gcc/config/mn10200/mn10200.c
@@ -65,6 +65,7 @@ rtx zero_dreg;
rtx zero_areg;
static void count_tst_insns PARAMS ((int *));
+static bool mn10200_rtx_costs PARAMS ((rtx, int, int, int *));
/* Note whether or not we need an out of line epilogue. */
static int out_of_line_epilogue;
@@ -73,6 +74,9 @@ static int out_of_line_epilogue;
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS mn10200_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Indicate this file was compiled by gcc and what optimization
@@ -1600,3 +1604,59 @@ extendpsi_operand (op, mode)
&& XEXP (op, 0) == stack_pointer_rtx
&& general_operand (XEXP (op, 1), VOIDmode)));
}
+
+static bool
+mn10200_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ /* Zeros are extremely cheap. */
+ if (INTVAL (x) == 0)
+ *total = 0;
+ /* If it fits in 8 bits, then it's still relatively cheap. */
+ else if (INT_8_BITS (INTVAL (x)))
+ *total = 1;
+ /* This is the "base" cost, includes constants where either the
+ upper or lower 16bits are all zeros. */
+ else if (INT_16_BITS (INTVAL (x))
+ || (INTVAL (x) & 0xffff) == 0
+ || (INTVAL (x) & 0xffff0000) == 0)
+ *total = 2;
+ else
+ *total = 4;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ /* These are more costly than a CONST_INT, but we can relax them,
+ so they're less costly than a CONST_DOUBLE. */
+ *total = 6;
+ return true;
+
+ case CONST_DOUBLE:
+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
+ so their cost is very high. */
+ *total = 8;
+ return true;
+
+ /* ??? This probably needs more work. The definitions below were first
+ taken from the H8 port, then tweaked slightly to improve code density
+ on various sample codes. */
+ case MOD:
+ case DIV:
+ *total = 8;
+ return true;
+
+ case MULT:
+ *total = (GET_MODE (x) == SImode ? 20 : 8);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/mn10200/mn10200.h b/gcc/config/mn10200/mn10200.h
index 112b90d866b..58099cb5887 100644
--- a/gcc/config/mn10200/mn10200.h
+++ b/gcc/config/mn10200/mn10200.h
@@ -730,55 +730,10 @@ struct cum_arg { int nbytes; };
addresses generally makes code worse due to register pressure. */
#define NO_FUNCTION_CSE
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- /* Zeros are extremely cheap. */ \
- if (INTVAL (RTX) == 0) \
- return 0; \
- /* If it fits in 8 bits, then it's still relatively cheap. */ \
- if (INT_8_BITS (INTVAL (RTX))) \
- return 1; \
- /* This is the "base" cost, includes constants where either the \
- upper or lower 16bits are all zeros. */ \
- if (INT_16_BITS (INTVAL (RTX)) \
- || (INTVAL (RTX) & 0xffff) == 0 \
- || (INTVAL (RTX) & 0xffff0000) == 0) \
- return 2; \
- return 4; \
- /* These are more costly than a CONST_INT, but we can relax them, \
- so they're less costly than a CONST_DOUBLE. */ \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 6; \
- /* We don't optimize CONST_DOUBLEs well nor do we relax them well, \
- so their cost is very high. */ \
- case CONST_DOUBLE: \
- return 8;
-
/* Make moves between different classes more expensive than moves
within the same class. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) (CLASS1 != CLASS2 ? 4 : 2)
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE.
-
- ?!? This probably needs more work. The definitions below were first
- taken from the H8 port, then tweaked slightly to improve code density
- on various sample codes. */
-
-#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
- case MOD: \
- case DIV: \
- return 8; \
- case MULT: \
- return (GET_MODE (RTX) == SImode ? 20 : 8);
-
/* Nonzero if access to memory by bytes or half words is no faster
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index 578ba644033..7f524ae134c 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -53,11 +53,18 @@ Boston, MA 02111-1307, USA. */
+ 4 * regs_ever_live[7] \
+ 16 * (regs_ever_live[14] || regs_ever_live[15] \
|| regs_ever_live[16] || regs_ever_live[17]))
+
+
+static bool mn10300_rtx_costs PARAMS ((rtx, int, int, int *));
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS mn10300_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
void
@@ -1324,3 +1331,54 @@ mn10300_address_cost (x, unsig)
}
}
+
+static bool
+mn10300_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ /* Zeros are extremely cheap. */
+ if (INTVAL (x) == 0 && outer_code == SET)
+ *total = 0;
+ /* If it fits in 8 bits, then it's still relatively cheap. */
+ else if (INT_8_BITS (INTVAL (x)))
+ *total = 1;
+ /* This is the "base" cost, includes constants where either the
+ upper or lower 16bits are all zeros. */
+ else if (INT_16_BITS (INTVAL (x))
+ || (INTVAL (x) & 0xffff) == 0
+ || (INTVAL (x) & 0xffff0000) == 0)
+ *total = 2;
+ else
+ *total = 4;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ /* These are more costly than a CONST_INT, but we can relax them,
+ so they're less costly than a CONST_DOUBLE. */
+ *total = 6;
+ return true;
+
+ case CONST_DOUBLE:
+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
+ so their cost is very high. */
+ *total = 8;
+ return true;
+
+ /* ??? This probably needs more work. */
+ case MOD:
+ case DIV:
+ case MULT:
+ *total = 8;
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 73a355f2790..67dc1ebee3f 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -800,37 +800,6 @@ struct cum_arg {int nbytes; };
#define CC_NO_CARRY CC_NO_OVERFLOW
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- /* Zeros are extremely cheap. */ \
- if (INTVAL (RTX) == 0 && OUTER_CODE == SET) \
- return 0; \
- /* If it fits in 8 bits, then it's still relatively cheap. */ \
- if (INT_8_BITS (INTVAL (RTX))) \
- return 1; \
- /* This is the "base" cost, includes constants where either the \
- upper or lower 16bits are all zeros. */ \
- if (INT_16_BITS (INTVAL (RTX)) \
- || (INTVAL (RTX) & 0xffff) == 0 \
- || (INTVAL (RTX) & 0xffff0000) == 0) \
- return 2; \
- return 4; \
- /* These are more costly than a CONST_INT, but we can relax them, \
- so they're less costly than a CONST_DOUBLE. */ \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 6; \
- /* We don't optimize CONST_DOUBLEs well nor do we relax them well, \
- so their cost is very high. */ \
- case CONST_DOUBLE: \
- return 8;
-
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
((CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS) && \
@@ -845,19 +814,6 @@ struct cum_arg {int nbytes; };
#define ADDRESS_COST(X) mn10300_address_cost((X), 0)
-/* A crude cut at RTX_COSTS for the MN10300. */
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
- case UMOD: \
- case UDIV: \
- case MOD: \
- case DIV: \
- return 8; \
- case MULT: \
- return 8;
-
/* Nonzero if access to memory by bytes or half words is no faster
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c
index 4e861132fcb..58650c4c924 100644
--- a/gcc/config/ns32k/ns32k.c
+++ b/gcc/config/ns32k/ns32k.c
@@ -72,6 +72,7 @@ const struct attribute_spec ns32k_attribute_table[];
static void ns32k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void ns32k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void ns32k_encode_section_info PARAMS ((tree, int));
+static bool ns32k_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -92,6 +93,9 @@ static void ns32k_encode_section_info PARAMS ((tree, int));
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO ns32k_encode_section_info
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ns32k_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Generate the assembly code for function entry. FILE is a stdio
@@ -490,6 +494,38 @@ hard_regno_mode_ok (regno, mode)
return 0;
}
+static bool
+ns32k_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if (INTVAL (x) <= 7 && INTVAL (x) >= -8)
+ *total = 0;
+ else if (INTVAL (x) < 0x2000 && INTVAL (x) >= -0x2000)
+ *total = 1;
+ else
+ *total = 3;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 3;
+ return true;
+
+ case CONST_DOUBLE:
+ *total = 5;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
int register_move_cost (CLASS1, CLASS2)
enum reg_class CLASS1;
enum reg_class CLASS2;
diff --git a/gcc/config/ns32k/ns32k.h b/gcc/config/ns32k/ns32k.h
index 8e648989fb1..36c23f2640f 100644
--- a/gcc/config/ns32k/ns32k.h
+++ b/gcc/config/ns32k/ns32k.h
@@ -1166,22 +1166,6 @@ __transfer_from_trampoline () \
#define ADDRESS_COST(RTX) calc_address_cost (RTX)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) <= 7 && INTVAL (RTX) >= -8) return 0; \
- if (INTVAL (RTX) < 0x2000 && INTVAL (RTX) >= -0x2000) \
- return 1; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 3; \
- case CONST_DOUBLE: \
- return 5;
/* Tell final.c how to eliminate redundant test instructions. */
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 2821d463501..9b2f98ef041 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -97,6 +97,7 @@ hppa_fpstore_bypass_p (out_insn, in_insn)
#endif
#endif
+static bool hppa_rtx_costs PARAMS ((rtx, int, int, int *));
static inline rtx force_mode PARAMS ((enum machine_mode, rtx));
static void pa_combine_instructions PARAMS ((rtx));
static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
@@ -220,6 +221,9 @@ static size_t n_deferred_plabels = 0;
#define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor
#endif
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS hppa_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
void
@@ -1315,6 +1319,87 @@ hppa_address_cost (X)
return 4;
}
+/* 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
+hppa_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if (INTVAL (x) == 0)
+ *total = 0;
+ else if (INT_14_BITS (x))
+ *total = 1;
+ else
+ *total = 2;
+ return true;
+
+ case HIGH:
+ *total = 2;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 4;
+ return true;
+
+ case CONST_DOUBLE:
+ if ((x == CONST0_RTX (DFmode) || x == CONST0_RTX (SFmode))
+ && outer_code != SET)
+ *total = 0;
+ else
+ *total = 8;
+ return true;
+
+ case MULT:
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ *total = COSTS_N_INSNS (3);
+ else if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
+ *total = COSTS_N_INSNS (8);
+ else
+ *total = COSTS_N_INSNS (20);
+ return true;
+
+ case DIV:
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ {
+ *total = COSTS_N_INSNS (14);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (60);
+ return true;
+
+ case PLUS: /* this includes shNadd insns */
+ case MINUS:
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Ensure mode of ORIG, a REG rtx, is MODE. Returns either ORIG or a
new rtx with the correct mode. */
static inline rtx
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 2361ba4368c..8be8d88e3a0 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1595,28 +1595,6 @@ do { \
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) == 0) return 0; \
- if (INT_14_BITS (RTX)) return 1; \
- case HIGH: \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 4; \
- case CONST_DOUBLE: \
- if ((RTX == CONST0_RTX (DFmode) || RTX == CONST0_RTX (SFmode)) \
- && OUTER_CODE != SET) \
- return 0; \
- else \
- return 8;
-
#define ADDRESS_COST(RTX) \
(GET_CODE (RTX) == REG ? 1 : hppa_address_cost (RTX))
@@ -1636,34 +1614,6 @@ do { \
: FP_REG_CLASS_P (CLASS2) && ! FP_REG_CLASS_P (CLASS1) ? 16 \
: 2)
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MULT: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (3); \
- return (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT) \
- ? COSTS_N_INSNS (8) : COSTS_N_INSNS (20); \
- case DIV: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (14); \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (60); \
- case PLUS: /* this includes shNadd insns */ \
- case MINUS: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (3); \
- return COSTS_N_INSNS (1); \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1);
-
/* Adjust the cost of branches. */
#define BRANCH_COST (pa_cpu == PROCESSOR_8000 ? 2 : 1)
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index d2f25ca6a29..23150965151 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -59,6 +59,7 @@ static const char *singlemove_string PARAMS ((rtx *));
static bool pdp11_assemble_integer PARAMS ((rtx, unsigned int, int));
static void pdp11_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void pdp11_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+static bool pdp11_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_BYTE_OP
@@ -80,6 +81,9 @@ static void pdp11_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
#undef TARGET_ASM_CLOSE_PAREN
#define TARGET_ASM_CLOSE_PAREN "]"
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS pdp11_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Nonzero if OP is a valid second operand for an arithmetic insn. */
@@ -1015,6 +1019,116 @@ register_move_cost(c1, c2)
return move_costs[(int)c1][(int)c2];
}
+static bool
+pdp11_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ /* Twice as expensive as REG. */
+ *total = 2;
+ return true;
+
+ case CONST_DOUBLE:
+ /* Twice (or 4 times) as expensive as 16 bit. */
+ *total = 4;
+ return true;
+
+ case MULT:
+ /* ??? There is something wrong in MULT because MULT is not
+ as cheap as total = 2 even if we can shift! */
+ /* If optimizing for size make mult etc cheap, but not 1, so when
+ in doubt the faster insn is chosen. */
+ if (optimize_size)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (11);
+ return false;
+
+ case DIV:
+ if (optimize_size)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (25);
+ return false;
+
+ case MOD:
+ if (optimize_size)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (26);
+ return false;
+
+ case ABS:
+ /* Equivalent to length, so same for optimize_size. */
+ *total = COSTS_N_INSNS (3);
+ return false;
+
+ case ZERO_EXTEND:
+ /* Only used for qi->hi. */
+ *total = COSTS_N_INSNS (1);
+ return false;
+
+ case SIGN_EXTEND:
+ if (GET_MODE (x) == HImode)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (6);
+ else
+ *total = COSTS_N_INSNS (2);
+ return false;
+
+ case ASHIFT:
+ case LSHIFTRT:
+ case ASHIFTRT:
+ if (optimize_size)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE (x) == QImode)
+ {
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ *total = COSTS_N_INSNS (8); /* worst case */
+ else
+ *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
+ }
+ else if (GET_MODE (x) == HImode)
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ if (abs (INTVAL (XEXP (x, 1))) == 1)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
+ }
+ else
+ *total = COSTS_N_INSNS (10); /* worst case */
+ }
+ else if (GET_MODE (x) == SImode)
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
+ else /* worst case */
+ *total = COSTS_N_INSNS (18);
+ }
+ return false;
+
+ default:
+ return false;
+ }
+}
+
const char *
output_jump(pos, neg, length)
const char *pos, *neg;
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index f9eb3f0e96a..147b6ba67ce 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -934,28 +934,6 @@ extern int may_call_alloca;
but a CALL with constant address is cheap. */
/* #define NO_FUNCTION_CSE */
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- -1, 0, 1 are cheaper for add, sub ...
-*/
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL(RTX) == 0 \
- || INTVAL(RTX) == -1 \
- || INTVAL(RTX) == 1) \
- return 0; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- /* twice as expensive as REG */ \
- return 2; \
- case CONST_DOUBLE: \
- /* twice (or 4 times) as expensive as 16 bit */ \
- return 4;
/* cost of moving one register class to another */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
@@ -1212,89 +1190,6 @@ JMP FUNCTION 0x0058 0x0000 <- FUNCTION
} \
}
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE.
-
- we don't say how expensive SImode is - pretty expensive!!!
-
- there is something wrong in MULT because MULT is not
- as cheap as total = 2 even if we can shift!
-
- if optimizing for size make mult etc cheap, but not 1, so when
- in doubt the faster insn is chosen.
-*/
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MULT: \
- if (optimize_size) \
- total = COSTS_N_INSNS(2); \
- else \
- total = COSTS_N_INSNS (11); \
- break; \
- case DIV: \
- if (optimize_size) \
- total = COSTS_N_INSNS(2); \
- else \
- total = COSTS_N_INSNS (25); \
- break; \
- case MOD: \
- if (optimize_size) \
- total = COSTS_N_INSNS(2); \
- else \
- total = COSTS_N_INSNS (26); \
- break; \
- case ABS: \
- /* equivalent to length, so same for optimize_size */ \
- total = COSTS_N_INSNS (3); \
- break; \
- case ZERO_EXTEND: \
- /* only used for: qi->hi */ \
- total = COSTS_N_INSNS(1); \
- break; \
- case SIGN_EXTEND: \
- if (GET_MODE(X) == HImode) \
- total = COSTS_N_INSNS(1); \
- else if (GET_MODE(X) == SImode) \
- total = COSTS_N_INSNS(6); \
- else \
- total = COSTS_N_INSNS(2); \
- break; \
- /* case LSHIFT: */ \
- case ASHIFT: \
- case LSHIFTRT: \
- case ASHIFTRT: \
- if (optimize_size) \
- total = COSTS_N_INSNS(1); \
- else if (GET_MODE(X) == QImode) \
- { \
- if (GET_CODE(XEXP (X,1)) != CONST_INT) \
- total = COSTS_N_INSNS(8); /* worst case */ \
- else \
- total = COSTS_N_INSNS(INTVAL(XEXP (X,1))); \
- } \
- else if (GET_MODE(X) == HImode) \
- { \
- if (GET_CODE(XEXP (X,1)) == CONST_INT) \
- { \
- if (abs (INTVAL (XEXP (X, 1))) == 1) \
- total = COSTS_N_INSNS(1); \
- else \
- total = COSTS_N_INSNS(2.5 + 0.5 *INTVAL(XEXP(X,1))); \
- } \
- else /* worst case */ \
- total = COSTS_N_INSNS (10); \
- } \
- else if (GET_MODE(X) == SImode) \
- { \
- if (GET_CODE(XEXP (X,1)) == CONST_INT) \
- total = COSTS_N_INSNS(2.5 + 0.5 *INTVAL(XEXP(X,1))); \
- else /* worst case */ \
- total = COSTS_N_INSNS(18); \
- } \
- break;
-
-
/* there is no point in avoiding branches on a pdp,
since branches are really cheap - I just want to find out
how much difference the BRANCH_COST macro makes in code */
diff --git a/gcc/config/romp/romp.c b/gcc/config/romp/romp.c
index dc9761c7113..36e8b54b160 100644
--- a/gcc/config/romp/romp.c
+++ b/gcc/config/romp/romp.c
@@ -59,6 +59,7 @@ static void romp_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void romp_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static void romp_encode_section_info PARAMS ((tree, int));
+static bool romp_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
@@ -69,6 +70,8 @@ static void romp_encode_section_info PARAMS ((tree, int));
#define TARGET_ASM_SELECT_RTX_SECTION romp_select_rtx_section
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO romp_encode_section_info
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS romp_rtx_costs
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2099,3 +2102,66 @@ romp_encode_section_info (decl, first)
if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
}
+
+static bool
+romp_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (x)
+ {
+ case CONST_INT:
+ if ((outer_code == IOR && exact_log2 (INTVAL (x)) >= 0)
+ || (outer_code == AND && exact_log2 (~INTVAL (x)) >= 0)
+ || ((outer_code == PLUS || outer_code == MINUS)
+ && (unsigned HOST_WIDE_INT) (INTVAL (x) + 15) < 31)
+ || (outer_code == SET && (unsigned HOST_WIDE_INT) INTVAL (x) < 16))
+ *total = 0;
+ else if ((unsigned HOST_WIDE_INT) (INTVAL (x) + 0x8000) < 0x10000
+ || (INTVAL (x) & 0xffff0000) == 0)
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ if (current_function_operand (x, Pmode))
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST_DOUBLE:
+ if (x == CONST0_RTX (GET_MODE (x)))
+ *total = 2;
+ else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ *total = COSTS_N_INSNS (5)
+ else
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case MEM:
+ *total = current_function_operand (x, Pmode) ? 0 : COSTS_N_INSNS (2);
+ return true;
+
+ case MULT:
+ if (TARGET_IN_LINE_MUL && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT)
+ *total = COSTS_N_INSNS (19);
+ else
+ *total = COSTS_N_INSNS (25);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (45);
+ return true;
+
+ default:
+ return false;
+ }
+}
diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h
index e659f8c8b04..16b543dfa80 100644
--- a/gcc/config/romp/romp.h
+++ b/gcc/config/romp/romp.h
@@ -1162,50 +1162,6 @@ struct rt_cargs {int gregs, fregs; };
/* #define SHIFT_COUNT_TRUNCATED */
-/* Compute the cost of computing a constant rtl expression RTX whose
- rtx-code is CODE, contained within an expression of code OUTER_CODE.
- The body of this macro is a portion of a switch statement. If the
- code is computed here, return it with a return statement. Otherwise,
- break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (((OUTER_CODE) == IOR && exact_log2 (INTVAL (RTX)) >= 0) \
- || ((OUTER_CODE) == AND && exact_log2 (~INTVAL (RTX)) >= 0) \
- || (((OUTER_CODE) == PLUS || (OUTER_CODE) == MINUS) \
- && (unsigned int) (INTVAL (RTX) + 15) < 31) \
- || ((OUTER_CODE) == SET && (unsigned int) INTVAL (RTX) < 16))\
- return 0; \
- return ((unsigned int) (INTVAL(RTX) + 0x8000) < 0x10000 \
- || (INTVAL (RTX) & 0xffff0000) == 0) ? 0 : COSTS_N_INSNS (2);\
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if (current_function_operand (RTX, Pmode)) return 0; \
- return COSTS_N_INSNS (2); \
- case CONST_DOUBLE: \
- if ((RTX) == CONST0_RTX (GET_MODE (RTX))) return 2; \
- return ((GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT) \
- ? COSTS_N_INSNS (5) : COSTS_N_INSNS (4));
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE.
-
- References to our own data area are really references to r14, so they
- are very cheap. Multiples and divides are very expensive. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MEM: \
- return current_function_operand (X, Pmode) ? 0 : COSTS_N_INSNS (2); \
- case MULT: \
- return (TARGET_IN_LINE_MUL && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT)\
- ? COSTS_N_INSNS (19) : COSTS_N_INSNS (25); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (45);
-
/* Compute the cost of an address. This is meant to approximate the size
and/or execution delay of an insn using that address. If the cost is
approximated by the RTL complexity, including CONST_COSTS above, as
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b51ad91167b..69fda814afb 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -227,6 +227,7 @@ static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *,
static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
ATTRIBUTE_UNUSED;
static bool rs6000_binds_local_p PARAMS ((tree));
+static bool rs6000_rtx_costs PARAMS ((rtx, int, int, int *));
static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int rs6000_adjust_priority PARAMS ((rtx, int));
static int rs6000_issue_rate PARAMS ((void));
@@ -404,6 +405,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS rs6000_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Override command line options. Mostly we process the processor
@@ -13230,6 +13234,210 @@ rs6000_binds_local_p (decl)
return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
}
+/* 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
+rs6000_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ /* On the RS/6000, if it is valid in the insn, it is free.
+ So this always returns 0. */
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ case HIGH:
+ *total = 0;
+ return true;
+
+ case PLUS:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
+ + 0x8000) >= 0x10000)
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case MULT:
+ if (optimize_size)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ case PROCESSOR_PPC405:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12));
+ return true;
+
+ case PROCESSOR_RIOS2:
+ case PROCESSOR_MPCCORE:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (5);
+ return true;
+
+ case PROCESSOR_PPC603:
+ case PROCESSOR_PPC7400:
+ case PROCESSOR_PPC750:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (4)
+ : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC403:
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC8540:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ case PROCESSOR_POWER4:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case DIV:
+ case MOD:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case UDIV:
+ case UMOD:
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_RIOS2:
+ *total = COSTS_N_INSNS (13);
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (65)
+ : COSTS_N_INSNS (67));
+ return true;
+
+ case PROCESSOR_MPCCORE:
+ *total = COSTS_N_INSNS (6);
+ return true;
+
+ case PROCESSOR_PPC403:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ case PROCESSOR_PPC405:
+ *total = COSTS_N_INSNS (35);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (36);
+ return true;
+
+ case PROCESSOR_PPC603:
+ *total = COSTS_N_INSNS (37);
+ return true;
+
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (20);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ case PROCESSOR_POWER4:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (21)
+ : COSTS_N_INSNS (37));
+ return true;
+
+ case PROCESSOR_PPC750:
+ case PROCESSOR_PPC8540:
+ case PROCESSOR_PPC7400:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = COSTS_N_INSNS (23);
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case FFS:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case MEM:
+ /* MEM should be slightly more expensive than (plus (reg) (const)) */
+ *total = 5;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 80d5321c172..71288817dc5 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2291,139 +2291,6 @@ do { \
#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- On the RS/6000, if it is valid in the insn, it is free. So this
- always returns 0. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- case HIGH: \
- return 0;
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) \
- + 0x8000) >= 0x10000) \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case AND: \
- case IOR: \
- case XOR: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0 \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case MULT: \
- if (optimize_size) \
- return COSTS_N_INSNS (2); \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- case PROCESSOR_PPC405: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- case PROCESSOR_RS64A: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12)); \
- case PROCESSOR_RIOS2: \
- case PROCESSOR_MPCCORE: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (5); \
- case PROCESSOR_PPC603: \
- case PROCESSOR_PPC7400: \
- case PROCESSOR_PPC750: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC7450: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (4) \
- : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC403: \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC8540: \
- return COSTS_N_INSNS (4); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- case PROCESSOR_POWER4: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- } \
- case DIV: \
- case MOD: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
- return COSTS_N_INSNS (2); \
- /* otherwise fall through to normal divide. */ \
- case UDIV: \
- case UMOD: \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_RIOS2: \
- return COSTS_N_INSNS (13); \
- case PROCESSOR_RS64A: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (65) \
- : COSTS_N_INSNS (67)); \
- case PROCESSOR_MPCCORE: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_PPC403: \
- return COSTS_N_INSNS (33); \
- case PROCESSOR_PPC405: \
- return COSTS_N_INSNS (35); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (36); \
- case PROCESSOR_PPC603: \
- return COSTS_N_INSNS (37); \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (20); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- case PROCESSOR_POWER4: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (21) \
- : COSTS_N_INSNS (37)); \
- case PROCESSOR_PPC750: \
- case PROCESSOR_PPC8540: \
- case PROCESSOR_PPC7400: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_PPC7450: \
- return COSTS_N_INSNS (23); \
- } \
- case FFS: \
- return COSTS_N_INSNS (4); \
- case MEM: \
- /* MEM should be slightly more expensive than (plus (reg) (const)) */ \
- return 5;
-
/* Compute the cost of an address. This is meant to approximate the size
and/or execution delay of an insn using that address. If the cost is
approximated by the RTL complexity, including CONST_COSTS above, as
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
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index b9ea747c963..066f2cf3670 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -812,72 +812,6 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
/* Relative costs of operations. */
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-/* 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). */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST: \
- if ((GET_CODE (XEXP (RTX, 0)) == MINUS) && \
- (GET_CODE (XEXP (XEXP (RTX, 0), 1)) != CONST_INT)) \
- return 1000; \
- case CONST_INT: \
- if ((OUTER_CODE == PLUS) && \
- ((INTVAL (RTX) > 32767) || \
- (INTVAL (RTX) < -32768))) \
- return COSTS_N_INSNS (3); \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return 0; \
-
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case PLUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case MINUS: \
- case NEG: \
- case NOT: \
- return COSTS_N_INSNS (1); \
- case MULT: \
- if (GET_MODE (XEXP (X, 0)) == DImode) \
- return COSTS_N_INSNS (40); \
- else \
- return COSTS_N_INSNS (7); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (33);
-
-
/* An expression giving the cost of an addressing mode that contains
ADDRESS. If not defined, the cost is computed from the ADDRESS
expression and the `CONST_COSTS' values. */
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 5e37a48446b..535fb30687a 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -56,10 +56,6 @@ extern int expand_block_move PARAMS ((rtx *));
extern int prepare_move_operands PARAMS ((rtx[], enum machine_mode mode));
extern void from_compare PARAMS ((rtx *, int));
extern int shift_insns_rtx PARAMS ((rtx));
-extern int shiftcosts PARAMS ((rtx));
-extern int addsubcosts PARAMS ((rtx));
-extern int andcosts PARAMS ((rtx));
-extern int multcosts PARAMS ((rtx));
extern void gen_ashift PARAMS ((int, int, rtx));
extern void gen_ashift_hi PARAMS ((int, int, rtx));
extern void gen_shifty_op PARAMS ((int, rtx *));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index dbebd24fd6f..93e7978c020 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -214,7 +214,11 @@ static void sh_media_init_builtins PARAMS ((void));
static rtx sh_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static int flow_dependent_p PARAMS ((rtx, rtx));
static void flow_dependent_p_1 PARAMS ((rtx, rtx, void *));
-
+static int shiftcosts PARAMS ((rtx));
+static int andcosts PARAMS ((rtx));
+static int addsubcosts PARAMS ((rtx));
+static int multcosts PARAMS ((rtx));
+static bool sh_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -266,6 +270,9 @@ static void flow_dependent_p_1 PARAMS ((rtx, rtx, void *));
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL sh_function_ok_for_sibcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS sh_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Print the operand address in x to the stream. */
@@ -1274,7 +1281,7 @@ shift_insns_rtx (insn)
/* Return the cost of a shift. */
-int
+static inline int
shiftcosts (x)
rtx x;
{
@@ -1314,7 +1321,7 @@ shiftcosts (x)
/* Return the cost of an AND operation. */
-int
+static inline int
andcosts (x)
rtx x;
{
@@ -1354,7 +1361,7 @@ andcosts (x)
/* Return the cost of an addition or a subtraction. */
-int
+static inline int
addsubcosts (x)
rtx x;
{
@@ -1395,7 +1402,7 @@ addsubcosts (x)
}
/* Return the cost of a multiply. */
-int
+static inline int
multcosts (x)
rtx x ATTRIBUTE_UNUSED;
{
@@ -1421,6 +1428,101 @@ multcosts (x)
return 20;
}
+/* 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
+sh_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code, *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if (TARGET_SHMEDIA)
+ {
+ if (INTVAL (x) == 0)
+ *total = 0;
+ else if (outer_code == AND && and_operand ((x), DImode))
+ *total = 0;
+ else if ((outer_code == IOR || outer_code == XOR
+ || outer_code == PLUS)
+ && CONST_OK_FOR_P (INTVAL (x)))
+ *total = 0;
+ else if (CONST_OK_FOR_J (INTVAL (x)))
+ *total = COSTS_N_INSNS (outer_code != SET);
+ else if (CONST_OK_FOR_J (INTVAL (x) >> 16))
+ *total = COSTS_N_INSNS (2);
+ else if (CONST_OK_FOR_J ((INTVAL (x) >> 16) >> 16))
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = COSTS_N_INSNS (4);
+ return true;
+ }
+ if (CONST_OK_FOR_I (INTVAL (x)))
+ *total = 0;
+ else if ((outer_code == AND || outer_code == IOR || outer_code == XOR)
+ && CONST_OK_FOR_L (INTVAL (x)))
+ *total = 1;
+ else
+ *total = 8;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ if (TARGET_SHMEDIA64)
+ *total = COSTS_N_INSNS (4);
+ else if (TARGET_SHMEDIA32)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = 5;
+ return true;
+
+ case CONST_DOUBLE:
+ if (TARGET_SHMEDIA)
+ *total = COSTS_N_INSNS (4);
+ else
+ *total = 10;
+ return true;
+
+ case PLUS:
+ *total = COSTS_N_INSNS (addsubcosts (x));
+ return true;
+
+ case AND:
+ *total = COSTS_N_INSNS (andcosts (x));
+ return true;
+
+ case MULT:
+ *total = COSTS_N_INSNS (multcosts (x));
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (shiftcosts (x));
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (20);
+ return true;
+
+ case FLOAT:
+ case FIX:
+ *total = 100;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
/* Code to expand a shift. */
void
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index b92c747f02c..7213933ad36 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2690,70 +2690,6 @@ while (0)
#define Pmode (TARGET_SHMEDIA64 ? DImode : SImode)
#define FUNCTION_MODE Pmode
-/* The relative costs of various types of constants. */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- if (TARGET_SHMEDIA) \
- { \
- if (INTVAL (RTX) == 0) \
- return 0; \
- if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
- return 0; \
- if (((OUTER_CODE) == IOR || (OUTER_CODE) == XOR \
- || (OUTER_CODE) == PLUS) \
- && CONST_OK_FOR_P (INTVAL (RTX))) \
- return 0; \
- if (CONST_OK_FOR_J (INTVAL (RTX))) \
- return COSTS_N_INSNS ((OUTER_CODE) != SET); \
- else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
- return COSTS_N_INSNS (2); \
- else if (CONST_OK_FOR_J ((INTVAL (RTX) >> 16) >> 16)) \
- return COSTS_N_INSNS (3); \
- else \
- return COSTS_N_INSNS (4); \
- } \
- if (CONST_OK_FOR_I (INTVAL (RTX))) \
- return 0; \
- else if (((OUTER_CODE) == AND || (OUTER_CODE) == IOR || (OUTER_CODE) == XOR) \
- && CONST_OK_FOR_L (INTVAL (RTX))) \
- return 1; \
- else \
- return 8; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if (TARGET_SHMEDIA64) \
- return COSTS_N_INSNS (4); \
- if (TARGET_SHMEDIA32) \
- return COSTS_N_INSNS (2); \
- return 5; \
- case CONST_DOUBLE: \
- if (TARGET_SHMEDIA) \
- return COSTS_N_INSNS (4); \
- else \
- return 10;
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case PLUS: \
- return COSTS_N_INSNS (addsubcosts (X)); \
- case AND: \
- return COSTS_N_INSNS (andcosts (X)); \
- case MULT: \
- return COSTS_N_INSNS (multcosts (X)); \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (shiftcosts (X)); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (20); \
- case FLOAT: \
- case FIX: \
- return 100;
-
/* The multiply insn on the SH1 and the divide insns on the SH1 and SH2
are actually function calls with some special constraints on arguments
and register usage.
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 0aa6e58f7da..31e0a2ccc6c 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -120,7 +120,6 @@ extern char *sparc_v8plus_shift PARAMS ((rtx *, rtx, const char *));
extern int sparc_check_64 PARAMS ((rtx, rtx));
extern rtx gen_df_reg PARAMS ((rtx, int));
extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
-extern int sparc_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
#endif /* RTX_CODE */
#endif /* __SPARC_PROTOS_H__ */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index aed7e4b79d5..a769ca9d2e7 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -181,6 +181,7 @@ static void sparc_encode_section_info PARAMS ((tree, int));
static bool sparc_function_ok_for_sibcall PARAMS ((tree, tree));
static void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
+static bool sparc_rtx_costs PARAMS ((rtx, int, int, int *));
/* Option handling. */
@@ -252,6 +253,9 @@ enum processor_type sparc_cpu;
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS sparc_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Validate and override various options, and do some machine dependent
@@ -8156,10 +8160,10 @@ sparc_extra_constraint_check (op, c, strict)
??? scheduler description. Some day, teach genautomata to output
??? the latencies and then CSE will just use that. */
-int
-sparc_rtx_costs (x, code, outer_code)
+static bool
+sparc_rtx_costs (x, code, outer_code, total)
rtx x;
- enum rtx_code code, outer_code;
+ int code, outer_code, *total;
{
switch (code)
{
@@ -8173,50 +8177,61 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case SQRT:
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
else
- return COSTS_N_INSNS (29);
+ *total = COSTS_N_INSNS (29);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (63);
+ *total = COSTS_N_INSNS (63);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
+ return true;
default:
- return COSTS_N_INSNS (30);
+ *total = COSTS_N_INSNS (30);
+ return true;
}
case COMPARE:
@@ -8226,18 +8241,22 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
@@ -8245,7 +8264,8 @@ sparc_rtx_costs (x, code, outer_code)
??? all UltraSPARC processors because the result
??? can be bypassed to a branch in the same group. */
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case MULT:
if (FLOAT_MODE_P (GET_MODE (x)))
@@ -8254,20 +8274,25 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
default:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
}
}
@@ -8304,20 +8329,28 @@ sparc_rtx_costs (x, code, outer_code)
Since we do not play any such tricks currently the
safest thing to do is report the worst case latency. */
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ {
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ return true;
+ }
/* Multiply latency on Ultra-III, fortunately, is constant. */
if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return COSTS_N_INSNS (6);
+ {
+ *total = COSTS_N_INSNS (6);
+ return true;
+ }
if (sparc_cpu == PROCESSOR_HYPERSPARC
|| sparc_cpu == PROCESSOR_SPARCLITE86X)
- return COSTS_N_INSNS (17);
+ {
+ *total = COSTS_N_INSNS (17);
+ return true;
+ }
- return (TARGET_HARD_MUL
- ? COSTS_N_INSNS (5)
- : COSTS_N_INSNS (25));
+ *total = (TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25));
+ return true;
case DIV:
case UDIV:
@@ -8329,57 +8362,67 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
else
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
+ return true;
case PROCESSOR_SUPERSPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (6);
+ *total = COSTS_N_INSNS (6);
else
- return COSTS_N_INSNS (9);
+ *total = COSTS_N_INSNS (9);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (8);
+ *total = COSTS_N_INSNS (8);
else
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
default:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
}
}
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
- if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
- return COSTS_N_INSNS (25);
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
+ else if (sparc_cpu == PROCESSOR_ULTRASPARC3)
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
+ else
+ *total = COSTS_N_INSNS (25);
+ return true;
case IF_THEN_ELSE:
/* Conditional moves. */
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (FLOAT_MODE_P (GET_MODE (x)))
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case MEM:
@@ -8390,9 +8433,10 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (outer_code == ZERO_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (outer_code == ZERO_EXTEND)
@@ -8400,75 +8444,87 @@ sparc_rtx_costs (x, code, outer_code)
if (GET_MODE (x) == QImode
|| GET_MODE (x) == HImode
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
}
else
{
/* This handles sign extension (3 cycles)
and everything else (2 cycles). */
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
}
+ return true;
case PROCESSOR_SUPERSPARC:
if (FLOAT_MODE_P (GET_MODE (x))
|| outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_TSC701:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case CONST_INT:
if (INTVAL (x) < 0x1000 && INTVAL (x) >= -0x1000)
- return 0;
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
- /* fallthru */
case HIGH:
- return 2;
+ *total = 2;
+ return true;
case CONST:
case LABEL_REF:
case SYMBOL_REF:
- return 4;
+ *total = 4;
+ return true;
case CONST_DOUBLE:
- if (GET_MODE (x) == DImode)
- if ((XINT (x, 3) == 0
- && (unsigned) XINT (x, 2) < 0x1000)
- || (XINT (x, 3) == -1
- && XINT (x, 2) < 0
- && XINT (x, 2) >= -0x1000))
- return 0;
- return 8;
+ if (GET_MODE (x) == DImode
+ && ((XINT (x, 3) == 0
+ && (unsigned HOST_WIDE_INT) XINT (x, 2) < 0x1000)
+ || (XINT (x, 3) == -1
+ && XINT (x, 2) < 0
+ && XINT (x, 2) >= -0x1000)))
+ *total = 0;
+ else
+ *total = 8;
+ return true;
default:
- abort();
- };
+ return false;
+ }
}
/* If we are referencing a function make the SYMBOL_REF special. In
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index ab000da6a6e..95a97d240ca 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -2608,27 +2608,6 @@ do { \
: (sparc_cpu == PROCESSOR_ULTRASPARC3 \
? 9 : 3))
-/* The cases that RTX_COSTS handles. */
-
-#define RTX_COSTS_CASES \
-case PLUS: case MINUS: case ABS: case NEG: \
-case FLOAT: case UNSIGNED_FLOAT: \
-case FIX: case UNSIGNED_FIX: \
-case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
-case SQRT: \
-case COMPARE: case IF_THEN_ELSE: \
-case MEM: \
-case MULT: case DIV: case UDIV: case MOD: case UMOD: \
-case CONST_INT: case HIGH: case CONST: \
-case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- RTX_COSTS_CASES \
- return sparc_rtx_costs(X,CODE,OUTER_CODE);
-
#define ADDRESS_COST(RTX) 1
#define PREFETCH_BLOCK \
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index 4d98ea7bf85..7a034626dd9 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -57,6 +57,7 @@ static void xstormy16_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
static void xstormy16_init_builtins PARAMS ((void));
static rtx xstormy16_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+static bool xstormy16_rtx_costs PARAMS ((rtx, int, int, int *));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
@@ -97,6 +98,47 @@ inequality_operator (op, mode)
return comparison_operator (op, mode) && ! equality_operator (op, mode);
}
+/* 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
+xstormy16_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ if (INTVAL (x) < 16 && INTVAL (x) >= 0)
+ *total = COSTS_N_INSNS (1) / 2;
+ else if (INTVAL (x) < 256 && INTVAL (x) >= 0)
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST_DOUBLE:
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ *total = COSTS_N_INSNS(2);
+ return true;
+
+ case MULT:
+ *total = COSTS_N_INSNS (35 + 6);
+ return true;
+ case DIV:
+ *total = COSTS_N_INSNS (51 - 6);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
/* Branches are handled as follows:
1. HImode compare-and-branches. The machine supports these
@@ -2165,4 +2207,7 @@ xstormy16_expand_builtin(exp, target, subtarget, mode, ignore)
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS xstormy16_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h
index 30f34a4748c..b8a90c49f47 100644
--- a/gcc/config/stormy16/stormy16.h
+++ b/gcc/config/stormy16/stormy16.h
@@ -2197,43 +2197,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. It must contain `case' labels for expression
- codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
- Each case must ultimately reach a `return' statement to return the relative
- cost of the use of that kind of constant value in an expression. The cost
- may depend on the precise value of the constant, which is available for
- examination in X, and the rtx code of the expression in which it is
- contained, found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained with
- `GET_CODE (X)'. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (X) < 16 && INTVAL (X) >= 0) \
- return COSTS_N_INSNS (1)/2; \
- if (INTVAL (X) < 256 && INTVAL (X) >= 0) \
- return COSTS_N_INSNS (1); \
- case CONST_DOUBLE: \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- return COSTS_N_INSNS(2);
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. This can be
- used, for example, to indicate how costly a multiply instruction is. In
- writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
- a cost equal to N fast instructions. OUTER_CODE is the code of the
- expression in which X is contained.
-
- This macro is optional; do not define it if the default cost assumptions are
- adequate for the target machine. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT: \
- return COSTS_N_INSNS (35 + 6); \
- case DIV: \
- return COSTS_N_INSNS (51 - 6);
-
/* An expression giving the cost of an addressing mode that contains ADDRESS.
If not defined, the cost is computed from the ADDRESS expression and the
`CONST_COSTS' values.
diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h
index d618aeae26b..296b6722dde 100644
--- a/gcc/config/v850/v850-protos.h
+++ b/gcc/config/v850/v850-protos.h
@@ -46,7 +46,6 @@ extern int v850_output_addr_const_extra PARAMS ((FILE *, rtx));
extern rtx v850_return_addr PARAMS ((int));
extern void print_operand PARAMS ((FILE *, rtx, int ));
extern void print_operand_address PARAMS ((FILE *, rtx));
-extern int const_costs PARAMS ((rtx, enum rtx_code));
extern const char *output_move_double PARAMS ((rtx *));
extern const char *output_move_single PARAMS ((rtx *));
extern void v850_reorg PARAMS ((rtx));
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index dcbb644ae2a..f16114ec6c9 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -51,6 +51,8 @@
/* Function prototypes for stupid compilers: */
static void const_double_split PARAMS ((rtx, HOST_WIDE_INT *, HOST_WIDE_INT *));
static int const_costs_int PARAMS ((HOST_WIDE_INT, int));
+static int const_costs PARAMS ((rtx, enum rtx_code));
+static bool v850_rtx_costs PARAMS ((rtx, int, int, int *));
static void substitute_ep_register PARAMS ((rtx, rtx, int, int, rtx *, rtx *));
static int ep_memory_offset PARAMS ((enum machine_mode, int));
static void v850_set_data_area PARAMS ((tree, v850_data_area));
@@ -105,6 +107,9 @@ static int v850_interrupt_p = FALSE;
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING v850_strip_name_encoding
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS v850_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Sometimes certain combinations of command options do not make
@@ -322,7 +327,7 @@ const_costs_int (value, zero_cost)
return 4;
}
-int
+static int
const_costs (r, c)
rtx r;
enum rtx_code c;
@@ -354,6 +359,55 @@ const_costs (r, c)
}
}
+static bool
+v850_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code ATTRIBUTE_UNUSED, *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ *total = COSTS_N_INSNS (const_costs (x, code));
+ return true;
+
+ case MOD:
+ case DIV:
+ case UMOD:
+ case UDIV:
+ if (TARGET_V850E && optimize_size)
+ *total = 6;
+ else
+ *total = 60;
+ return true;
+
+ case MULT:
+ if (TARGET_V850E
+ && ( GET_MODE (x) == SImode
+ || GET_MODE (x) == HImode
+ || GET_MODE (x) == QImode))
+ {
+ if (GET_CODE (XEXP (x, 1)) == REG)
+ *total = 4;
+ else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ if (CONST_OK_FOR_O (INTVAL (XEXP (x, 1))))
+ *total = 6;
+ else if (CONST_OK_FOR_K (INTVAL (XEXP (x, 1))))
+ *total = 10;
+ }
+ }
+ else
+ *total = 20;
+ return true;
+
+ default:
+ return false;
+ }
+}
/* Print operand X using operand code CODE to assembly language output file
FILE. */
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 29c992176d1..447e247ea36 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -1025,64 +1025,6 @@ do { \
#define CC_NO_CARRY CC_NO_OVERFLOW
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- case CONST_DOUBLE: \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- { \
- int _zxy = const_costs(RTX, CODE); \
- return (_zxy) ? COSTS_N_INSNS (_zxy) : 0; \
- }
-
-/* A crude cut at RTX_COSTS for the V850. */
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE.
-
- There aren't DImode MOD, DIV or MULT operations, so call them
- very expensive. Everything else is pretty much a constant cost. */
-
-#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
- case MOD: \
- case DIV: \
- case UMOD: \
- case UDIV: \
- if (TARGET_V850E && optimize_size) \
- return 6; \
- return 60; \
- case MULT: \
- if (TARGET_V850E \
- && ( GET_MODE (RTX) == SImode \
- || GET_MODE (RTX) == HImode \
- || GET_MODE (RTX) == QImode)) \
- { \
- if (GET_CODE (XEXP (RTX, 1)) == REG) \
- return 4; \
- else if (GET_CODE (XEXP (RTX, 1)) == CONST_INT) \
- { \
- if (CONST_OK_FOR_O (INTVAL (XEXP (RTX, 1)))) \
- return 6; \
- else if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1)))) \
- return 10; \
- } \
- } \
- return 20;
-
/* All addressing modes have the same cost on the V850 series. */
#define ADDRESS_COST(ADDR) 1
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 422b936567f..9bff82b15e8 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -45,6 +45,8 @@ static int follows_p PARAMS ((rtx, rtx));
static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
+static int vax_rtx_costs_1 PARAMS ((rtx, enum rtx_code, enum rtx_code));
+static bool vax_rtx_costs PARAMS ((rtx, int, int, int *));
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -58,6 +60,9 @@ static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS vax_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Set global variables as needed for the options enabled. */
@@ -482,16 +487,15 @@ vax_address_cost (addr)
return reg + indexed + indir + offset + predec;
}
-
/* Cost of an expression on a VAX. This version has costs tuned for the
CVAX chip (found in the VAX 3 series) with comments for variations on
other models. */
-int
-vax_rtx_cost (x)
+static int
+vax_rtx_costs_1 (x, code, outer_code)
register rtx x;
+ enum rtx_code code, outer_code;
{
- register enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
register int c;
int i = 0; /* may be modified in switch */
@@ -499,6 +503,40 @@ vax_rtx_cost (x)
switch (code)
{
+ /* On a VAX, constants from 0..63 are cheap because they can use the
+ 1 byte literal constant format. compare to -1 should be made cheap
+ so that decrement-and-branch insns can be formed more easily (if
+ the value -1 is copied to a register some decrement-and-branch
+ patterns will not match). */
+ case CONST_INT:
+ if (INTVAL (x) == 0)
+ return 0;
+ if (outer_code == AND)
+ return ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
+ if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077)
+ return 1;
+ if (outer_code == COMPARE && INTVAL (x) == -1)
+ return 1;
+ if (outer_code == PLUS && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)
+ return 1;
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ return 3;
+
+ case CONST_DOUBLE:
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ return vax_float_literal (x) ? 5 : 8;
+ else
+ return (((CONST_DOUBLE_HIGH (x) == 0
+ && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
+ || (outer_code == PLUS
+ && CONST_DOUBLE_HIGH (x) == -1 \
+ && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
+ ? 2 : 5);
+
case POST_INC:
return 2;
case PRE_DEC:
@@ -617,7 +655,6 @@ vax_rtx_cost (x)
break;
}
-
/* Now look inside the expression. Operands which are not registers or
short constants add to the cost.
@@ -678,6 +715,16 @@ vax_rtx_cost (x)
}
return c;
}
+
+static bool
+vax_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ *total = vax_rtx_costs_1 (x, code, outer_code);
+ return true;
+}
/* Return 1 if insn A follows B. */
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index f3f1e465961..e2a1d95e13d 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -848,49 +848,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
#define TARGET_FLOAT_FORMAT VAX_FLOAT_FORMAT
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-/* On a VAX, constants from 0..63 are cheap because they can use the
- 1 byte literal constant format. compare to -1 should be made cheap
- so that decrement-and-branch insns can be formed more easily (if
- the value -1 is copied to a register some decrement-and-branch patterns
- will not match). */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) == 0) return 0; \
- if ((OUTER_CODE) == AND) \
- return ((unsigned) ~INTVAL (RTX) <= 077) ? 1 : 2; \
- if ((unsigned) INTVAL (RTX) <= 077) return 1; \
- if ((OUTER_CODE) == COMPARE && INTVAL (RTX) == -1) \
- return 1; \
- if ((OUTER_CODE) == PLUS && (unsigned) -INTVAL (RTX) <= 077)\
- return 1; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 3; \
- case CONST_DOUBLE: \
- if (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT) \
- return vax_float_literal (RTX) ? 5 : 8; \
- else \
- return (((CONST_DOUBLE_HIGH (RTX) == 0 \
- && (unsigned) CONST_DOUBLE_LOW (RTX) < 64) \
- || ((OUTER_CODE) == PLUS \
- && CONST_DOUBLE_HIGH (RTX) == -1 \
- && (unsigned)-CONST_DOUBLE_LOW (RTX) < 64)) \
- ? 2 : 5);
-
-#define RTX_COSTS(RTX,CODE,OUTER_CODE) case FIX: case FLOAT: \
- case MULT: case DIV: case UDIV: case MOD: case UMOD: \
- case ASHIFT: case LSHIFTRT: case ASHIFTRT: \
- case ROTATE: case ROTATERT: case PLUS: case MINUS: case IOR: \
- case XOR: case AND: case NEG: case NOT: case ZERO_EXTRACT: \
- case SIGN_EXTRACT: case MEM: return vax_rtx_cost(RTX)
-
#define ADDRESS_COST(RTX) (1 + (GET_CODE (RTX) == REG ? 0 : vax_address_cost(RTX)))
/* Specify the cost of a branch insn; roughly the number of extra insns that
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index c0d0ab0780d..645ad1adbfd 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -204,6 +204,7 @@ static unsigned int xtensa_multibss_section_type_flags
static void xtensa_select_rtx_section
PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
static void xtensa_encode_section_info PARAMS ((tree, int));
+static bool xtensa_rtx_costs PARAMS ((rtx, int, int, int *));
static rtx frame_size_const;
static int current_function_arg_words;
@@ -240,6 +241,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO xtensa_encode_section_info
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS xtensa_rtx_costs
+
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2838,4 +2842,216 @@ xtensa_encode_section_info (decl, first)
SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 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
+xtensa_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code, outer_code;
+ int *total;
+{
+ switch (code)
+ {
+ case CONST_INT:
+ switch (outer_code)
+ {
+ case SET:
+ if (xtensa_simm12b (INTVAL (x)))
+ {
+ *total = 4;
+ return true;
+ }
+ break;
+ case PLUS:
+ if (xtensa_simm8 (INTVAL (x))
+ || xtensa_simm8x256 (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ break;
+ case AND:
+ if (xtensa_mask_immediate (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ break;
+ case COMPARE:
+ if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ break;
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case ROTATE:
+ case ROTATERT:
+ /* no way to tell if X is the 2nd operand so be conservative */
+ default: break;
+ }
+ if (xtensa_simm12b (INTVAL (x)))
+ *total = 5;
+ else
+ *total = 6;
+ return true;
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = 5;
+ return true;
+
+ case CONST_DOUBLE:
+ *total = 7;
+ return true;
+
+ case MEM:
+ {
+ int num_words =
+ (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ? 2 : 1;
+
+ if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
+ *total = COSTS_N_INSNS (num_words);
+ else
+ *total = COSTS_N_INSNS (2*num_words);
+ return true;
+ }
+
+ case FFS:
+ *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
+ return true;
+
+ case NOT:
+ *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ if (GET_MODE (x) == DImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (GET_MODE (x) == DImode)
+ *total = COSTS_N_INSNS (50);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case ABS:
+ {
+ enum machine_mode xmode = GET_MODE (x);
+ if (xmode == SFmode)
+ *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
+ else if (xmode == DFmode)
+ *total = COSTS_N_INSNS (50);
+ else
+ *total = COSTS_N_INSNS (4);
+ return true;
+ }
+
+ case PLUS:
+ case MINUS:
+ {
+ enum machine_mode xmode = GET_MODE (x);
+ if (xmode == SFmode)
+ *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
+ else if (xmode == DFmode || xmode == DImode)
+ *total = COSTS_N_INSNS (50);
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
+ case NEG:
+ *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
+ return true;
+
+ case MULT:
+ {
+ enum machine_mode xmode = GET_MODE (x);
+ if (xmode == SFmode)
+ *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
+ else if (xmode == DFmode || xmode == DImode)
+ *total = COSTS_N_INSNS (50);
+ else if (TARGET_MUL32)
+ *total = COSTS_N_INSNS (4);
+ else if (TARGET_MAC16)
+ *total = COSTS_N_INSNS (16);
+ else if (TARGET_MUL16)
+ *total = COSTS_N_INSNS (12);
+ else
+ *total = COSTS_N_INSNS (50);
+ return true;
+ }
+
+ case DIV:
+ case MOD:
+ {
+ enum machine_mode xmode = GET_MODE (x);
+ if (xmode == SFmode)
+ {
+ *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
+ return true;
+ }
+ else if (xmode == DFmode)
+ {
+ *total = COSTS_N_INSNS (50);
+ return true;
+ }
+ }
+ /* fall through */
+
+ case UDIV:
+ case UMOD:
+ {
+ enum machine_mode xmode = GET_MODE (x);
+ if (xmode == DImode)
+ *total = COSTS_N_INSNS (50);
+ else if (TARGET_DIV32)
+ *total = COSTS_N_INSNS (32);
+ else
+ *total = COSTS_N_INSNS (50);
+ return true;
+ }
+
+ case SQRT:
+ if (GET_MODE (x) == SFmode)
+ *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
+ else
+ *total = COSTS_N_INSNS (50);
+ return true;
+
+ case SMIN:
+ case UMIN:
+ case SMAX:
+ case UMAX:
+ *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
+ return true;
+
+ case SIGN_EXTRACT:
+ case SIGN_EXTEND:
+ *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
+ return true;
+
+ case ZERO_EXTRACT:
+ case ZERO_EXTEND:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
#include "gt-xtensa.h"
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index d51b6795a34..3ae66f1240e 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -1281,153 +1281,6 @@ typedef struct xtensa_args {
indexing purposes) so give the MEM rtx a words's mode. */
#define FUNCTION_MODE SImode
-/* Xtensa constant costs. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- switch (OUTER_CODE) \
- { \
- case SET: \
- if (xtensa_simm12b (INTVAL (X))) return 4; \
- break; \
- case PLUS: \
- if (xtensa_simm8 (INTVAL (X))) return 0; \
- if (xtensa_simm8x256 (INTVAL (X))) return 0; \
- break; \
- case AND: \
- if (xtensa_mask_immediate (INTVAL (X))) return 0; \
- break; \
- case COMPARE: \
- if ((INTVAL (X) == 0) || xtensa_b4const (INTVAL (X))) return 0; \
- break; \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ROTATE: \
- case ROTATERT: \
- /* no way to tell if X is the 2nd operand so be conservative */ \
- default: break; \
- } \
- if (xtensa_simm12b (INTVAL (X))) return 5; \
- return 6; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 5; \
- case CONST_DOUBLE: \
- return 7;
-
-/* Costs of various Xtensa operations. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MEM: \
- { \
- int num_words = \
- (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ? 2 : 1; \
- if (memory_address_p (GET_MODE (X), XEXP ((X), 0))) \
- return COSTS_N_INSNS (num_words); \
- \
- return COSTS_N_INSNS (2*num_words); \
- } \
- \
- case FFS: \
- return COSTS_N_INSNS (TARGET_NSA ? 5 : 50); \
- \
- case NOT: \
- return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 3 : 2); \
- \
- case AND: \
- case IOR: \
- case XOR: \
- if (GET_MODE (X) == DImode) return COSTS_N_INSNS (2); \
- return COSTS_N_INSNS (1); \
- \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- if (GET_MODE (X) == DImode) return COSTS_N_INSNS (50); \
- return COSTS_N_INSNS (1); \
- \
- case ABS: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); \
- if (xmode == DFmode) \
- return COSTS_N_INSNS (50); \
- return COSTS_N_INSNS (4); \
- } \
- \
- case PLUS: \
- case MINUS: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); \
- if (xmode == DFmode || xmode == DImode) \
- return COSTS_N_INSNS (50); \
- return COSTS_N_INSNS (1); \
- } \
- \
- case NEG: \
- return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 4 : 2); \
- \
- case MULT: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50); \
- if (xmode == DFmode || xmode == DImode) \
- return COSTS_N_INSNS (50); \
- if (TARGET_MUL32) \
- return COSTS_N_INSNS (4); \
- if (TARGET_MAC16) \
- return COSTS_N_INSNS (16); \
- if (TARGET_MUL16) \
- return COSTS_N_INSNS (12); \
- return COSTS_N_INSNS (50); \
- } \
- \
- case DIV: \
- case MOD: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == SFmode) \
- return COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50); \
- if (xmode == DFmode) \
- return COSTS_N_INSNS (50); \
- } \
- /* fall through */ \
- \
- case UDIV: \
- case UMOD: \
- { \
- enum machine_mode xmode = GET_MODE (X); \
- if (xmode == DImode) \
- return COSTS_N_INSNS (50); \
- if (TARGET_DIV32) \
- return COSTS_N_INSNS (32); \
- return COSTS_N_INSNS (50); \
- } \
- \
- case SQRT: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50); \
- return COSTS_N_INSNS (50); \
- \
- case SMIN: \
- case UMIN: \
- case SMAX: \
- case UMAX: \
- return COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50); \
- \
- case SIGN_EXTRACT: \
- case SIGN_EXTEND: \
- return COSTS_N_INSNS (TARGET_SEXT ? 1 : 2); \
- \
- case ZERO_EXTRACT: \
- case ZERO_EXTEND: \
- return COSTS_N_INSNS (1);
-
-
/* An expression giving the cost of an addressing mode that
contains ADDRESS. */
#define ADDRESS_COST(ADDR) 1
diff --git a/gcc/cse.c b/gcc/cse.c
index e2a04e59398..84210babcbd 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -41,6 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "timevar.h"
#include "except.h"
+#include "target.h"
/* The basic idea of common subexpression elimination is to go
through the code, keeping a record of expressions that would
@@ -832,7 +833,7 @@ rtx_cost (x, outer_code)
return 0;
/* Compute the default costs of certain things.
- Note that RTX_COSTS can override the defaults. */
+ Note that targetm.rtx_costs can override the defaults. */
code = GET_CODE (x);
switch (code)
@@ -867,17 +868,9 @@ rtx_cost (x, outer_code)
+ GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
break;
-#ifdef RTX_COSTS
- RTX_COSTS (x, code, outer_code);
-#endif
-#ifdef CONST_COSTS
- CONST_COSTS (x, code, outer_code);
-#endif
-
default:
-#ifdef DEFAULT_RTX_COSTS
- DEFAULT_RTX_COSTS (x, code, outer_code);
-#endif
+ if ((*targetm.rtx_costs) (x, code, outer_code, &total))
+ return total;
break;
}
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4646985a957..84dc1de0c15 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5264,49 +5264,6 @@ These macros let you describe the relative speed of various operations
on the target machine.
@table @code
-@findex CONST_COSTS
-@item CONST_COSTS (@var{x}, @var{code}, @var{outer_code})
-A part of a C @code{switch} statement that describes the relative costs
-of constant RTL expressions. It must contain @code{case} labels for
-expression codes @code{const_int}, @code{const}, @code{symbol_ref},
-@code{label_ref} and @code{const_double}. Each case must ultimately
-reach a @code{return} statement to return the relative cost of the use
-of that kind of constant value in an expression. The cost may depend on
-the precise value of the constant, which is available for examination in
-@var{x}, and the rtx code of the expression in which it is contained,
-found in @var{outer_code}.
-
-@var{code} is the expression code---redundant, since it can be
-obtained with @code{GET_CODE (@var{x})}.
-
-@findex RTX_COSTS
-@findex COSTS_N_INSNS
-@item RTX_COSTS (@var{x}, @var{code}, @var{outer_code})
-Like @code{CONST_COSTS} but applies to nonconstant RTL expressions.
-This can be used, for example, to indicate how costly a multiply
-instruction is. In writing this macro, you can use the construct
-@code{COSTS_N_INSNS (@var{n})} to specify a cost equal to @var{n} fast
-instructions. @var{outer_code} is the code of the expression in which
-@var{x} is contained.
-
-This macro is optional; do not define it if the default cost assumptions
-are adequate for the target machine.
-
-@findex DEFAULT_RTX_COSTS
-@item DEFAULT_RTX_COSTS (@var{x}, @var{code}, @var{outer_code})
-This macro, if defined, is called for any case not handled by the
-@code{RTX_COSTS} or @code{CONST_COSTS} macros. This eliminates the need
-to put case labels into the macro, but the code, or any functions it
-calls, must assume that the RTL in @var{x} could be of any type that has
-not already been handled. The arguments are the same as for
-@code{RTX_COSTS}, and the macro should execute a return statement giving
-the cost of any RTL expressions that it can handle. The default cost
-calculation is used for any RTL for which this macro does not return a
-value.
-
-This macro is optional; do not define it if the default cost assumptions
-are adequate for the target machine.
-
@findex ADDRESS_COST
@item ADDRESS_COST (@var{address})
An expression giving the cost of an addressing mode that contains
@@ -5551,6 +5508,27 @@ itself with an explicit address than to call an address kept in a
register.
@end table
+@deftypefn {Target Hook} bool TARGET_RTX_COSTS (rtx @var{x}, int @var{code}, int @var{outer_code}, int *@var{total})
+This target hook describes the relative costs of RTL expressions.
+
+The cost may depend on the precise form of the expression, which is
+available for examination in @var{x}, and the rtx code of the expression
+in which it is contained, found in @var{outer_code}. @var{code} is the
+expression code---redundant, since it can be obtained with
+@code{GET_CODE (@var{x})}.
+
+In implementing this hook, you can use the construct
+@code{COSTS_N_INSNS (@var{n})} to specify a cost equal to @var{n} fast
+instructions.
+
+On entry to the hook, @code{*@var{total}} contains a default estimate
+for the cost of the expression. The hook should modify this value as
+necessary.
+
+The hook returns true when all subexpressions of @var{x} have been
+processed, and false when @code{rtx_cost} should recurse.
+@end deftypefn
+
@node Scheduling
@section Adjusting the Instruction Scheduler
diff --git a/gcc/hooks.c b/gcc/hooks.c
index a80ead0c3e0..59117167665 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -131,3 +131,14 @@ hook_bool_rtx_false (a)
{
return false;
}
+
+bool
+hook_bool_rtx_int_int_intp_false (a, b, c, d)
+ rtx a ATTRIBUTE_UNUSED;
+ int b ATTRIBUTE_UNUSED;
+ int c ATTRIBUTE_UNUSED;
+ int *d ATTRIBUTE_UNUSED;
+{
+ return false;
+}
+
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 26f87dfe1a8..954f2181ead 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -29,6 +29,7 @@ bool hook_bool_tree_hwi_hwi_tree_false
bool hook_bool_tree_hwi_hwi_tree_true
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
bool hook_bool_rtx_false PARAMS ((rtx));
+bool hook_bool_rtx_int_int_intp_false PARAMS ((rtx, int, int, int *));
void hook_void_tree_int PARAMS ((tree, int));
void hook_void_void PARAMS ((void));
diff --git a/gcc/system.h b/gcc/system.h
index da78a59714b..6858d30f049 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -613,7 +613,7 @@ typedef char _Bool;
ASM_OUTPUT_DESTRUCTOR SIGNED_CHAR_SPEC MAX_CHAR_TYPE_SIZE \
WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \
ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL \
- ASM_OUTPUT_MI_THUNK
+ ASM_OUTPUT_MI_THUNK CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 0cf463b9ce5..a6f13579215 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -262,6 +262,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
#define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
+/* #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false */
#ifndef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P hook_bool_tree_false
@@ -295,6 +296,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_ENCODE_SECTION_INFO, \
TARGET_STRIP_NAME_ENCODING, \
TARGET_VALID_POINTER_MODE, \
+ TARGET_RTX_COSTS, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
diff --git a/gcc/target.h b/gcc/target.h
index 770830079c1..933da66b526 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -311,7 +311,16 @@ struct gcc_target
/* Undo the effects of encode_section_info on the symbol string. */
const char * (* strip_name_encoding) PARAMS ((const char *));
+ /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))). */
bool (* valid_pointer_mode) PARAMS ((enum machine_mode mode));
+
+ /* 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. */
+ /* Note that CODE and OUTER_CODE ought to be RTX_CODE, but that's
+ not necessarily defined at this point. */
+ bool (* rtx_costs) PARAMS ((rtx x, int code, int outer_code, int *total));
+
/* Leave the boolean fields at the end. */
/* True if arbitrary sections are supported. */