OSDN Git Service

* Makefile.in (cse.o): Depend on TARGET_H.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Jan 2003 04:46:33 +0000 (04:46 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Jan 2003 04:46:33 +0000 (04:46 +0000)
* 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

92 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/c4x/c4x.c
gcc/config/c4x/c4x.h
gcc/config/cris/cris.c
gcc/config/cris/cris.h
gcc/config/d30v/d30v.c
gcc/config/d30v/d30v.h
gcc/config/dsp16xx/dsp16xx.c
gcc/config/dsp16xx/dsp16xx.h
gcc/config/frv/frv.c
gcc/config/frv/frv.h
gcc/config/h8300/h8300-protos.h
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.h
gcc/config/i370/i370.c
gcc/config/i370/i370.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i960/i960.c
gcc/config/i960/i960.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ip2k/ip2k-protos.h
gcc/config/ip2k/ip2k.c
gcc/config/ip2k/ip2k.h
gcc/config/m32r/m32r.c
gcc/config/m32r/m32r.h
gcc/config/m68hc11/m68hc11-protos.h
gcc/config/m68hc11/m68hc11.c
gcc/config/m68hc11/m68hc11.h
gcc/config/m68k/m68k-protos.h
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.h
gcc/config/m88k/m88k.c
gcc/config/m88k/m88k.h
gcc/config/mcore/mcore-protos.h
gcc/config/mcore/mcore.c
gcc/config/mcore/mcore.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mmix/mmix-protos.h
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.h
gcc/config/mn10200/mn10200.c
gcc/config/mn10200/mn10200.h
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.h
gcc/config/ns32k/ns32k.c
gcc/config/ns32k/ns32k.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pdp11/pdp11.c
gcc/config/pdp11/pdp11.h
gcc/config/romp/romp.c
gcc/config/romp/romp.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/stormy16/stormy16.c
gcc/config/stormy16/stormy16.h
gcc/config/v850/v850-protos.h
gcc/config/v850/v850.c
gcc/config/v850/v850.h
gcc/config/vax/vax.c
gcc/config/vax/vax.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/cse.c
gcc/doc/tm.texi
gcc/hooks.c
gcc/hooks.h
gcc/system.h
gcc/target-def.h
gcc/target.h

index 7e899b3..5bb0bad 100644 (file)
@@ -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.
 
index 4cb7de2..d75db8f 100644 (file)
@@ -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
index cc5c9f2..d10396e 100644 (file)
@@ -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;
 \f
 /* Parse target option strings.  */
@@ -2474,6 +2527,150 @@ alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
   return NULL_RTX;
 }
 \f
+/* 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;
+    }
+}
+\f
 /* 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
index 24550f4..ae28dd2 100644 (file)
@@ -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();                                        \
-      }
 \f
 /* Control the assembler format that we output.  */
 
index c106b88..2048bd3 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
@@ -2376,3 +2380,61 @@ arc_internal_label (stream, prefix, labelno)
   arc_ccfsm_at_label (prefix, labelno);
   default_internal_label (stream, prefix, labelno);
 }
+\f
+/* 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;
+    }
+}
index 7739fa4..4d7b633 100644 (file)
@@ -995,34 +995,6 @@ arc_select_cc_mode (OP, X, Y)
 \f
 /* 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
index af0320e..5fed1df 100644 (file)
@@ -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));
 
index db27913..5bbe6ac 100644 (file)
@@ -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;
 \f
 /* 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;
index 2b205fc..c2afa4d 100644 (file)
@@ -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 :                                   \
index 20841a7..b721b3e 100644 (file)
@@ -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));
index fcfec61..0378012 100644 (file)
@@ -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;
 \f
@@ -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
index 5309a0d..126a6fd 100644 (file)
@@ -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
index 4fe50b2..2d83a8c 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* Override command line options.
@@ -5062,3 +5066,98 @@ c4x_globalize_label (stream, name)
   default_globalize_label (stream, name);
   c4x_global_label (name);
 }
+\f
+#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;
+    }
+}
index c878112..891ed4b 100644 (file)
@@ -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))
 
index 0aeccc0..6842dfe 100644 (file)
@@ -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
index bd044f3..38449c7 100644 (file)
@@ -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
index 4f282a8..b3b72cd 100644 (file)
@@ -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;
 \f
 /* 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);
 }
+\f
+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;
+    }
+}
index 6fdbbd4..db0e120 100644 (file)
@@ -2426,55 +2426,6 @@ do {                                                                     \
 \f
 /* 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.
index 3b9f752..6d402bf 100644 (file)
@@ -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 *));
+\f
 /* 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;
 }
+\f
+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;
+}
index fbbf50e..d80213a 100644 (file)
@@ -1431,76 +1431,6 @@ extern struct dsp16xx_frame_info current_frame_info;
 \f
 /* 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)
index f1ad90b..1c8f566 100644 (file)
@@ -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*));
 \f
 /* 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;
 }
+\f
+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;
+    }
+}
index e7a481a..64aa29e 100644 (file)
@@ -2541,65 +2541,6 @@ __asm__("\n"                                                             \
 \f
 /* 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
index f5a59d4..436ddb7 100644 (file)
@@ -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[]));
index 23e334b..e59e877 100644 (file)
@@ -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;
 \f
 /* See below where shifts are handled for explanation of this enum.  */
@@ -1097,7 +1104,7 @@ function_arg (cum, mode, type, named)
 \f
 /* 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;
+    }
+}
 \f
 /* Documentation for the machine specific operand escapes:
 
index d6148f3..70e8b66 100644 (file)
@@ -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
index 3db961a..e83fa7a 100644 (file)
@@ -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;
 \f
@@ -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;
+    }
+}
index 2011742..61f296d 100644 (file)
@@ -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
index d963667..0f0a3a7 100644 (file)
@@ -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;
 \f
 /* 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)
index b4359f1..32eb8ad 100644 (file)
@@ -2585,254 +2585,6 @@ do {                                                    \
    so give the MEM rtx a byte's mode.  */
 #define FUNCTION_MODE QImode
 \f
-/* 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.
index 08894aa..35b72e2 100644 (file)
@@ -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;
 \f
 /* 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;
+    }
+}
index 3b84d04..534f525 100644 (file)
@@ -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.  */
 
index c641e2d..9a671a9 100644 (file)
@@ -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;
 \f
 /* 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;
 }
 \f
+/* 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.  */
 
index fb51797..425d451 100644 (file)
@@ -1673,62 +1673,6 @@ do {                                                                     \
 \f
 /* 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.  */
index 2ec0400..48c2c4a 100644 (file)
@@ -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));
index 6b2bc33..cb1a095 100644 (file)
@@ -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;
     }
 }
 
index a5b14c5..c656e4a 100644 (file)
@@ -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
index a004eed..6d4f2a3 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
@@ -1751,6 +1755,56 @@ m32r_variable_issue (stream, verbose, insn, how_many)
 \f
 /* 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.
 
index ed36eb7..22bf095 100644 (file)
@@ -1420,36 +1420,6 @@ do {                                                                     \
 \f
 /* 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
index 7b1ca56..2d78bed 100644 (file)
@@ -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));
 
 
index 57562e1..0a50c4c 100644 (file)
@@ -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;
 \f
 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;
+    }
+}
 \f
 
 /* print_options - called at the start of the code generation for a
index 3463921..8f3740c 100644 (file)
@@ -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)
 
index 72120ea..e0ffee8 100644 (file)
@@ -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));
index c7e0e5c..cb94d23 100644 (file)
@@ -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 *));
 \f
 
 /* 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;
 \f
 /* 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;
index 7d07a13..3ba717b 100644 (file)
@@ -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 */
 \f
 /* Tell final.c how to eliminate redundant test instructions.  */
 
index 44ca220..5a8f268 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* 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;
+    }
+}
index c702094..4001927 100644 (file)
@@ -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
index 9910c3a..8b99581 100644 (file)
@@ -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));
index dfe0282..cb24e93 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* 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.  */
index bfa8271..42d2d45 100644 (file)
@@ -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
index b1408f1..4dcf524 100644 (file)
@@ -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;
 \f
@@ -2986,6 +2990,337 @@ mips_move_2words (operands, insn)
   return ret;
 }
 \f
+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.  */
 
index 61a6b0d..696aff2 100644 (file)
@@ -3385,316 +3385,6 @@ typedef struct mips_args {
 #define FUNCTION_MODE (Pmode == DImode ? DImode : SImode)
 
 \f
-/* 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.
index fb3705a..e6c22f0 100644 (file)
@@ -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
index db4bb4c..b8cc2fb 100644 (file)
@@ -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.  */
index 562c39e..7549f59 100644 (file)
@@ -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
index 39a378d..4116c01 100644 (file)
@@ -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;
 \f
 /* 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)));
 }
+\f
+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;
+    }
+}
index 112b90d..58099cb 100644 (file)
@@ -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
index 578ba64..7f524ae 100644 (file)
@@ -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 *));
+
 \f
 /* 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;
 \f
 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;
+    }
+}
index 73a355f..67dc1eb 100644 (file)
@@ -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
index 4e86113..58650c4 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* 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;
index 8e64898..36c23f2 100644 (file)
@@ -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;
 \f
 /* Tell final.c how to eliminate redundant test instructions.  */
 
index 2821d46..9b2f98e 100644 (file)
@@ -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;
 \f
 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
index 2361ba4..8be8d88 100644 (file)
@@ -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)
 
index d2f25ca..2315096 100644 (file)
@@ -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 *));
 \f
 /* 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;
 \f
 /* 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;
index f9eb3f0..147b6ba 100644 (file)
@@ -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 sw