Patchwork Add an operand number argument to rtx_cost

login
register
mail settings
Submitter Richard Sandiford
Date Aug. 15, 2011, 3:15 p.m.
Message ID <m3ei0mu2nb.fsf@richards-thinkpad.stglab.manchester.uk.ibm.com>
Download mbox | patch
Permalink /patch/110052/
State New
Headers show

Comments

Richard Sandiford - Aug. 15, 2011, 3:15 p.m.
rtx_cost knows that the expression under test (X) is an operand to an
expression of a particular code (OUTER_CODE).  However, nothing says
which operand it actually is.  This can make a difference for
non-commutative binary operations.  E.g. shifts by 1 are often
cheaper than shifts of 1.

The patch below makes this information available.  I'm planning on
using this parameter to provide costs of lvalues as well as rvalues,
but that's a separate patch.

In the backend patches, I've avoided propagating the extra parameter
to subroutines unless it would be used.  I've also passed the original
operand number to recursive calls wherever the original code is passed
to recursive calls.  This includes expressions of the form:

   rtx_cost (A, outer_code, speed_p) + rtx_cost (B, outer_code, speed_p)

where A and B are subrtxes of X.  Since X is exactly one operand,
it seems odd to sum two costs with the same outer code like this,
but I left it be.

I notice that score defines an rtx cost function but doesn't
actually use it.  Again, I've not fixed that here.

avr.c:final_prescan_insn passes a SET rtx to rtx_cost (with an
outer code of INSN).  This is only used for debugging, so I passed
an arbitrary opno here.  (I didn't pass the opno of PATTERN because
that could easily change in future.)

Tested on x86_64-linux-gnu.  Also tested by compiling cc1 for:

        alpha-linux-gnu arm-linux-gnueabi avr-rtems bfin-elf cris-elf
        fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
        lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
        microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
        hppa64-hp-hpux11.23 pdp11 picochip-elf powerpc-linux-gnu
        powerpc-eabispe rx-elf s390-linux-gnu score-elf sh-linux-gnu
        sparc-linux-gnu spu-elf xstormy16-elf v850-elf vax-netbsdelf
        xtensa-elf

and checking that (a) there were no new warnings and (b) that the
-O2 and -Os output for gcc.dg and gcc.c-torture didn't change.
OK to install?

Richard


gcc/
	* doc/tm.texi.in (TARGET_RTX_COSTS): Add an opno paramter.
	* doc/tm.texi: Regenerate.
	* target.def (rtx_costs): Add an opno parameter.
	* hooks.h (hook_bool_rtx_int_int_intp_bool_false): Replace with...
	(hook_bool_rtx_int_int_int_intp_bool_false): ...this.
	* hooks.c (hook_bool_rtx_int_int_intp_bool_false): Replace with...
	(hook_bool_rtx_int_int_int_intp_bool_false): ...this.
	* cse.c (COST_IN): Add an opno parameter.
	(notreg_cost): Likewise.  Update call to rtx_cost.
	(COST, fold_rtx): Update accordingly.
	* dojump.c (prefer_and_bit_test): Update call to rtx_cost.
	* expmed.c (emit_store_flag): Likewise.
	* optabs.c (avoid_expensive_constant): Add an opno parameter.
	Update call to rtx_cost.
	(expand_binop_directly, expand_binop): Likewise.
	(expand_twoval_binop, prepare_cmp_insn): Likewise.
	* rtl.h (rtx_cost, get_full_rtx_cost): Add opno parameters.
	(set_src_cost, get_full_set_src_cost): Update accordingly.
	* rtlanal.c (rtx_cost): Add an opno parameter.  Update call
	to target hook.
	(get_full_rtx_cost): Add an opno paramter.  Update calls to rtx_cost.
	(default_adress_cost): Update calls to rtx_cost.

	* config/alpha/alpha.c (alpha_rtx_costs): Add an opno parameter and
	adjust any recursive rtx-cost calls.
	* config/avr/avr.c (avr_operand_rtx_cost, avr_rtx_costs): Likewise.
	* config/bfin/bfin.c (bfin_rtx_costs): Likewise.
	* config/c6x/c6x.c (c6x_rtx_costs): Likewise.
	* config/cris/cris.c (cris_rtx_costs): Likewise.
	* config/frv/frv.c (frv_rtx_costs): Likewise.
	* config/h8300/h8300.c (h8300_rtx_costs): Likewise.
	* config/i386/i386.c (ix86_rtx_costs): Likewise.
	* config/ia64/ia64.c (ia64_rtx_costs): Likewise.
	* config/iq2000/iq2000.c (iq2000_rtx_costs): Likewise.
	* config/lm32/lm32.c (lm32_rtx_costs): Likewise.
	* config/m32c/m32c.c (m32c_rtx_costs): Likewise.
	* config/m32r/m32r.c (m32r_rtx_costs): Likewise.
	* config/m68k/m68k.c (m68k_rtx_costs): Likewise.
	* config/mcore/mcore.c (mcore_rtx_costs): Likewise.
	* config/mep/mep.c (mep_rtx_cost): Likewise.
	* config/microblaze/microblaze.c (microblaze_rtx_costs): Likewise.
	* config/mips/mips.c (mips_binary_cost): Update call to rtx_cost.
	(mips_zero_extend_cost): Add an opno parameter.
	* config/mmix/mmix.c (mmix_rtx_costs): Likewise.
	* config/mn10300/mn10300.c (mn10300_address_cost): Update call
	to rtx_cost.
	(mn10300_rtx_costs): Add an opno parameter and adjust any recursive
	rtx-cost calls.
	* config/pa/pa.c (hppa_rtx_costs): Likewise.
	* config/pdp11/pdp11.c (pdp11_rtx_costs): Likewise.
	* config/picochip/picochip.c (picochip_rtx_costs): Likewise.
	* config/rs6000/rs6000.c (rs6000_rtx_costs): Likewise.
	(rs6000_debug_rtx_costs): Likewise.
	* config/s390/s390.c (s390_rtx_costs): Likewise.
	* config/score/score-protos.h (score_rtx_costs): Likewise.
	* config/score/score.c (score_rtx_costs): Likewise.
	* config/sh/sh.c (andcosts): Update call to rtx_cost.
	(sh_rtx_costs): Add an opno parameter.
	* config/sparc/sparc.c (sparc_rtx_costs): Likewise.
	* config/spu/spu.c (spu_rtx_costs): Likewise.
	* config/stormy16/stormy16.c (xstormy16_rtx_costs): Likewise.
	* config/v850/v850.c (v850_rtx_costs): Likewise.
	* config/vax/vax.c (vax_rtx_costs): Likewise.
	* config/xtensa/xtensa.c (xtensa_rtx_costs): Likewise.
Richard Guenther - Aug. 15, 2011, 3:24 p.m.
On Mon, Aug 15, 2011 at 5:15 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> rtx_cost knows that the expression under test (X) is an operand to an
> expression of a particular code (OUTER_CODE).  However, nothing says
> which operand it actually is.  This can make a difference for
> non-commutative binary operations.  E.g. shifts by 1 are often
> cheaper than shifts of 1.
>
> The patch below makes this information available.  I'm planning on
> using this parameter to provide costs of lvalues as well as rvalues,
> but that's a separate patch.
>
> In the backend patches, I've avoided propagating the extra parameter
> to subroutines unless it would be used.  I've also passed the original
> operand number to recursive calls wherever the original code is passed
> to recursive calls.  This includes expressions of the form:
>
>   rtx_cost (A, outer_code, speed_p) + rtx_cost (B, outer_code, speed_p)
>
> where A and B are subrtxes of X.  Since X is exactly one operand,
> it seems odd to sum two costs with the same outer code like this,
> but I left it be.
>
> I notice that score defines an rtx cost function but doesn't
> actually use it.  Again, I've not fixed that here.
>
> avr.c:final_prescan_insn passes a SET rtx to rtx_cost (with an
> outer code of INSN).  This is only used for debugging, so I passed
> an arbitrary opno here.  (I didn't pass the opno of PATTERN because
> that could easily change in future.)
>
> Tested on x86_64-linux-gnu.  Also tested by compiling cc1 for:
>
>        alpha-linux-gnu arm-linux-gnueabi avr-rtems bfin-elf cris-elf
>        fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
>        lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
>        microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
>        hppa64-hp-hpux11.23 pdp11 picochip-elf powerpc-linux-gnu
>        powerpc-eabispe rx-elf s390-linux-gnu score-elf sh-linux-gnu
>        sparc-linux-gnu spu-elf xstormy16-elf v850-elf vax-netbsdelf
>        xtensa-elf
>
> and checking that (a) there were no new warnings and (b) that the
> -O2 and -Os output for gcc.dg and gcc.c-torture didn't change.
> OK to install?

Can you add to the documentation that operands are counted from zero?
I suppose lvalues will be SET, 0 then, right?

THe patch looks ok to me but please leave others (esp. target maintainers)
time to comment.

Thanks,
Richard.

> Richard
>
>
> gcc/
>        * doc/tm.texi.in (TARGET_RTX_COSTS): Add an opno paramter.
>        * doc/tm.texi: Regenerate.
>        * target.def (rtx_costs): Add an opno parameter.
>        * hooks.h (hook_bool_rtx_int_int_intp_bool_false): Replace with...
>        (hook_bool_rtx_int_int_int_intp_bool_false): ...this.
>        * hooks.c (hook_bool_rtx_int_int_intp_bool_false): Replace with...
>        (hook_bool_rtx_int_int_int_intp_bool_false): ...this.
>        * cse.c (COST_IN): Add an opno parameter.
>        (notreg_cost): Likewise.  Update call to rtx_cost.
>        (COST, fold_rtx): Update accordingly.
>        * dojump.c (prefer_and_bit_test): Update call to rtx_cost.
>        * expmed.c (emit_store_flag): Likewise.
>        * optabs.c (avoid_expensive_constant): Add an opno parameter.
>        Update call to rtx_cost.
>        (expand_binop_directly, expand_binop): Likewise.
>        (expand_twoval_binop, prepare_cmp_insn): Likewise.
>        * rtl.h (rtx_cost, get_full_rtx_cost): Add opno parameters.
>        (set_src_cost, get_full_set_src_cost): Update accordingly.
>        * rtlanal.c (rtx_cost): Add an opno parameter.  Update call
>        to target hook.
>        (get_full_rtx_cost): Add an opno paramter.  Update calls to rtx_cost.
>        (default_adress_cost): Update calls to rtx_cost.
>
>        * config/alpha/alpha.c (alpha_rtx_costs): Add an opno parameter and
>        adjust any recursive rtx-cost calls.
>        * config/avr/avr.c (avr_operand_rtx_cost, avr_rtx_costs): Likewise.
>        * config/bfin/bfin.c (bfin_rtx_costs): Likewise.
>        * config/c6x/c6x.c (c6x_rtx_costs): Likewise.
>        * config/cris/cris.c (cris_rtx_costs): Likewise.
>        * config/frv/frv.c (frv_rtx_costs): Likewise.
>        * config/h8300/h8300.c (h8300_rtx_costs): Likewise.
>        * config/i386/i386.c (ix86_rtx_costs): Likewise.
>        * config/ia64/ia64.c (ia64_rtx_costs): Likewise.
>        * config/iq2000/iq2000.c (iq2000_rtx_costs): Likewise.
>        * config/lm32/lm32.c (lm32_rtx_costs): Likewise.
>        * config/m32c/m32c.c (m32c_rtx_costs): Likewise.
>        * config/m32r/m32r.c (m32r_rtx_costs): Likewise.
>        * config/m68k/m68k.c (m68k_rtx_costs): Likewise.
>        * config/mcore/mcore.c (mcore_rtx_costs): Likewise.
>        * config/mep/mep.c (mep_rtx_cost): Likewise.
>        * config/microblaze/microblaze.c (microblaze_rtx_costs): Likewise.
>        * config/mips/mips.c (mips_binary_cost): Update call to rtx_cost.
>        (mips_zero_extend_cost): Add an opno parameter.
>        * config/mmix/mmix.c (mmix_rtx_costs): Likewise.
>        * config/mn10300/mn10300.c (mn10300_address_cost): Update call
>        to rtx_cost.
>        (mn10300_rtx_costs): Add an opno parameter and adjust any recursive
>        rtx-cost calls.
>        * config/pa/pa.c (hppa_rtx_costs): Likewise.
>        * config/pdp11/pdp11.c (pdp11_rtx_costs): Likewise.
>        * config/picochip/picochip.c (picochip_rtx_costs): Likewise.
>        * config/rs6000/rs6000.c (rs6000_rtx_costs): Likewise.
>        (rs6000_debug_rtx_costs): Likewise.
>        * config/s390/s390.c (s390_rtx_costs): Likewise.
>        * config/score/score-protos.h (score_rtx_costs): Likewise.
>        * config/score/score.c (score_rtx_costs): Likewise.
>        * config/sh/sh.c (andcosts): Update call to rtx_cost.
>        (sh_rtx_costs): Add an opno parameter.
>        * config/sparc/sparc.c (sparc_rtx_costs): Likewise.
>        * config/spu/spu.c (spu_rtx_costs): Likewise.
>        * config/stormy16/stormy16.c (xstormy16_rtx_costs): Likewise.
>        * config/v850/v850.c (v850_rtx_costs): Likewise.
>        * config/vax/vax.c (vax_rtx_costs): Likewise.
>        * config/xtensa/xtensa.c (xtensa_rtx_costs): Likewise.
>
> Index: gcc/doc/tm.texi.in
> ===================================================================
> --- gcc/doc/tm.texi.in  2011-08-15 15:22:59.485479486 +0100
> +++ gcc/doc/tm.texi.in  2011-08-15 15:23:01.746475059 +0100
> @@ -6357,9 +6357,9 @@ Define this macro if a non-short-circuit
>  This target hook describes the relative costs of RTL expressions.
>
>  The cost may depend on the precise form of the expression, which is
> -available for examination in @var{x}, and the rtx code of the expression
> -in which it is contained, found in @var{outer_code}.  @var{code} is the
> -expression code---redundant, since it can be obtained with
> +available for examination in @var{x}, and the fact that @var{x} appears
> +as operand @var{opno} of an expression with rtx code @var{outer_code}.
> +@var{code} is the expression code---redundant, since it can be obtained with
>  @code{GET_CODE (@var{x})}.
>
>  In implementing this hook, you can use the construct
> Index: gcc/target.def
> ===================================================================
> --- gcc/target.def      2011-08-15 15:22:59.478479500 +0100
> +++ gcc/target.def      2011-08-15 15:24:31.311298899 +0100
> @@ -1645,8 +1645,8 @@ DEFHOOKPOD
>  DEFHOOK
>  (rtx_costs,
>  "",
> - bool, (rtx x, int code, int outer_code, int *total, bool speed),
> - hook_bool_rtx_int_int_intp_bool_false)
> + bool, (rtx x, int code, int outer_code, int opno, int *total, bool speed),
> + hook_bool_rtx_int_int_int_intp_bool_false)
>
>  /* Compute the cost of X, used as an address.  Never called with
>    invalid addresses.  */
> Index: gcc/hooks.h
> ===================================================================
> --- gcc/hooks.h 2011-05-03 08:45:55.000000000 +0100
> +++ gcc/hooks.h 2011-08-15 15:26:34.079055149 +0100
> @@ -53,7 +53,8 @@ extern bool hook_bool_const_tree_hwi_hwi
>  extern bool hook_bool_rtx_false (rtx);
>  extern bool hook_bool_rtx_int_false (rtx, int);
>  extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
> -extern bool hook_bool_rtx_int_int_intp_bool_false (rtx, int, int, int *, bool);
> +extern bool hook_bool_rtx_int_int_int_intp_bool_false (rtx, int, int, int,
> +                                                      int *, bool);
>  extern bool hook_bool_tree_tree_false (tree, tree);
>  extern bool hook_bool_tree_tree_true (tree, tree);
>  extern bool hook_bool_tree_bool_false (tree, bool);
> Index: gcc/hooks.c
> ===================================================================
> --- gcc/hooks.c 2011-05-03 08:45:55.000000000 +0100
> +++ gcc/hooks.c 2011-08-15 15:24:56.510249081 +0100
> @@ -267,11 +267,12 @@ hook_bool_uintp_uintp_false (unsigned in
>  }
>
>  bool
> -hook_bool_rtx_int_int_intp_bool_false (rtx a ATTRIBUTE_UNUSED,
> -                                      int b ATTRIBUTE_UNUSED,
> -                                      int c ATTRIBUTE_UNUSED,
> -                                      int *d ATTRIBUTE_UNUSED,
> -                                      bool speed_p ATTRIBUTE_UNUSED)
> +hook_bool_rtx_int_int_int_intp_bool_false (rtx a ATTRIBUTE_UNUSED,
> +                                          int b ATTRIBUTE_UNUSED,
> +                                          int c ATTRIBUTE_UNUSED,
> +                                          int d ATTRIBUTE_UNUSED,
> +                                          int *e ATTRIBUTE_UNUSED,
> +                                          bool speed_p ATTRIBUTE_UNUSED)
>  {
>   return false;
>  }
> Index: gcc/cse.c
> ===================================================================
> --- gcc/cse.c   2011-08-15 15:22:59.485479486 +0100
> +++ gcc/cse.c   2011-08-15 15:23:01.633475279 +0100
> @@ -475,8 +475,8 @@ #define CHEAP_REGNO(N)                                                      \
>    || (HARD_REGISTER_NUM_P (N)                                         \
>        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
>
> -#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET))
> -#define COST_IN(X,OUTER) (REG_P (X) ? 0 : notreg_cost (X, OUTER))
> +#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET, 1))
> +#define COST_IN(X, OUTER, OPNO) (REG_P (X) ? 0 : notreg_cost (X, OUTER, OPNO))
>
>  /* Get the number of times this register has been updated in this
>    basic block.  */
> @@ -552,7 +552,7 @@ struct cse_basic_block_data
>  static sbitmap cse_visited_basic_blocks;
>
>  static bool fixed_base_plus_p (rtx x);
> -static int notreg_cost (rtx, enum rtx_code);
> +static int notreg_cost (rtx, enum rtx_code, int);
>  static int approx_reg_cost_1 (rtx *, void *);
>  static int approx_reg_cost (rtx);
>  static int preferable (int, int, int, int);
> @@ -752,7 +752,7 @@ preferable (int cost_a, int regcost_a, i
>    from COST macro to keep it simple.  */
>
>  static int
> -notreg_cost (rtx x, enum rtx_code outer)
> +notreg_cost (rtx x, enum rtx_code outer, int opno)
>  {
>   return ((GET_CODE (x) == SUBREG
>           && REG_P (SUBREG_REG (x))
> @@ -764,7 +764,7 @@ notreg_cost (rtx x, enum rtx_code outer)
>           && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (x),
>                                             GET_MODE (SUBREG_REG (x))))
>          ? 0
> -         : rtx_cost (x, outer, optimize_this_for_speed_p) * 2);
> +         : rtx_cost (x, outer, opno, optimize_this_for_speed_p) * 2);
>  }
>
>
> @@ -3296,7 +3296,7 @@ fold_rtx (rtx x, rtx insn)
>           argument.  */
>        if (const_arg != 0
>            && const_arg != folded_arg
> -           && COST_IN (const_arg, code) <= COST_IN (folded_arg, code)
> +           && COST_IN (const_arg, code, i) <= COST_IN (folded_arg, code, i)
>
>            /* It's not safe to substitute the operand of a conversion
>               operator with a constant, as the conversion's identity
> Index: gcc/dojump.c
> ===================================================================
> --- gcc/dojump.c        2011-08-15 15:22:59.484479488 +0100
> +++ gcc/dojump.c        2011-08-15 15:23:01.753475045 +0100
> @@ -144,6 +144,8 @@ static GTY(()) rtx shift_test;
>  static bool
>  prefer_and_bit_test (enum machine_mode mode, int bitnum)
>  {
> +  bool speed_p;
> +
>   if (and_test == 0)
>     {
>       /* Set up rtxes for the two variations.  Use NULL as a placeholder
> @@ -168,8 +170,9 @@ prefer_and_bit_test (enum machine_mode m
>                                                 mode);
>   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
>
> -  return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
> -         <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
> +  speed_p = optimize_insn_for_speed_p ();
> +  return (rtx_cost (and_test, IF_THEN_ELSE, 0, speed_p)
> +         <= rtx_cost (shift_test, IF_THEN_ELSE, 0, speed_p));
>  }
>
>  /* Subroutine of do_jump, dealing with exploded comparisons of the type
> Index: gcc/expmed.c
> ===================================================================
> --- gcc/expmed.c        2011-08-15 15:22:59.484479488 +0100
> +++ gcc/expmed.c        2011-08-15 15:23:01.755475041 +0100
> @@ -5431,7 +5431,7 @@ emit_store_flag (rtx target, enum rtx_co
>
>          /* For the reverse comparison, use either an addition or a XOR.  */
>           if (want_add
> -             && rtx_cost (GEN_INT (normalizep), PLUS,
> +             && rtx_cost (GEN_INT (normalizep), PLUS, 1,
>                           optimize_insn_for_speed_p ()) == 0)
>            {
>              tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
> @@ -5442,7 +5442,7 @@ emit_store_flag (rtx target, enum rtx_co
>                                     target, 0, OPTAB_WIDEN);
>            }
>           else if (!want_add
> -                  && rtx_cost (trueval, XOR,
> +                  && rtx_cost (trueval, XOR, 1,
>                                optimize_insn_for_speed_p ()) == 0)
>            {
>              tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
> @@ -5535,7 +5535,7 @@ emit_store_flag (rtx target, enum rtx_co
>
>       /* Again, for the reverse comparison, use either an addition or a XOR.  */
>       if (want_add
> -         && rtx_cost (GEN_INT (normalizep), PLUS,
> +         && rtx_cost (GEN_INT (normalizep), PLUS, 1,
>                       optimize_insn_for_speed_p ()) == 0)
>        {
>          tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
> @@ -5545,7 +5545,7 @@ emit_store_flag (rtx target, enum rtx_co
>                                GEN_INT (normalizep), target, 0, OPTAB_WIDEN);
>        }
>       else if (!want_add
> -              && rtx_cost (trueval, XOR,
> +              && rtx_cost (trueval, XOR, 1,
>                            optimize_insn_for_speed_p ()) == 0)
>        {
>          tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
> Index: gcc/optabs.c
> ===================================================================
> --- gcc/optabs.c        2011-08-15 15:22:59.484479488 +0100
> +++ gcc/optabs.c        2011-08-15 15:23:01.760475031 +0100
> @@ -1204,21 +1204,21 @@ commutative_optab_p (optab binoptab)
>          || binoptab == umul_highpart_optab);
>  }
>
> -/* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
> +/* X is to be used in mode MODE as operand OPN to BINOPTAB.  If we're
>    optimizing, and if the operand is a constant that costs more than
>    1 instruction, force the constant into a register and return that
>    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
>
>  static rtx
>  avoid_expensive_constant (enum machine_mode mode, optab binoptab,
> -                         rtx x, bool unsignedp)
> +                         int opn, rtx x, bool unsignedp)
>  {
>   bool speed = optimize_insn_for_speed_p ();
>
>   if (mode != VOIDmode
>       && optimize
>       && CONSTANT_P (x)
> -      && rtx_cost (x, binoptab->code, speed) > set_src_cost (x, speed))
> +      && rtx_cost (x, binoptab->code, opn, speed) > set_src_cost (x, speed))
>     {
>       if (CONST_INT_P (x))
>        {
> @@ -1265,9 +1265,9 @@ expand_binop_directly (enum machine_mode
>     }
>
>   /* If we are optimizing, force expensive constants into a register.  */
> -  xop0 = avoid_expensive_constant (xmode0, binoptab, xop0, unsignedp);
> +  xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
>   if (!shift_optab_p (binoptab))
> -    xop1 = avoid_expensive_constant (xmode1, binoptab, xop1, unsignedp);
> +    xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
>
>   /* In case the insn wants input operands in modes different from
>      those of the actual operands, convert the operands.  It would
> @@ -1479,10 +1479,10 @@ expand_binop (enum machine_mode mode, op
>                && mclass == MODE_INT)
>              {
>                no_extend = 1;
> -               xop0 = avoid_expensive_constant (mode, binoptab,
> +               xop0 = avoid_expensive_constant (mode, binoptab, 0,
>                                                 xop0, unsignedp);
>                if (binoptab != ashl_optab)
> -                 xop1 = avoid_expensive_constant (mode, binoptab,
> +                 xop1 = avoid_expensive_constant (mode, binoptab, 1,
>                                                   xop1, unsignedp);
>              }
>
> @@ -2216,8 +2216,8 @@ expand_twoval_binop (optab binoptab, rtx
>       rtx xop0 = op0, xop1 = op1;
>
>       /* If we are optimizing, force expensive constants into a register.  */
> -      xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
> -      xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
> +      xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
> +      xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
>
>       create_fixed_operand (&ops[0], targ0);
>       create_convert_operand_from (&ops[1], op0, mode, unsignedp);
> @@ -3790,12 +3790,12 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx
>
>   /* If we are optimizing, force expensive constants into a register.  */
>   if (CONSTANT_P (x) && optimize
> -      && (rtx_cost (x, COMPARE, optimize_insn_for_speed_p ())
> +      && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
>           > COSTS_N_INSNS (1)))
>     x = force_reg (mode, x);
>
>   if (CONSTANT_P (y) && optimize
> -      && (rtx_cost (y, COMPARE, optimize_insn_for_speed_p ())
> +      && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
>           > COSTS_N_INSNS (1)))
>     y = force_reg (mode, y);
>
> Index: gcc/rtl.h
> ===================================================================
> --- gcc/rtl.h   2011-08-15 15:22:59.477479502 +0100
> +++ gcc/rtl.h   2011-08-15 15:23:01.765475021 +0100
> @@ -1196,9 +1196,10 @@ costs_add_n_insns (struct full_rtx_costs
>  }
>
>  extern void init_rtlanal (void);
> -extern int rtx_cost (rtx, enum rtx_code, bool);
> +extern int rtx_cost (rtx, enum rtx_code, int, bool);
>  extern int address_cost (rtx, enum machine_mode, addr_space_t, bool);
> -extern void get_full_rtx_cost (rtx, enum rtx_code, struct full_rtx_costs *);
> +extern void get_full_rtx_cost (rtx, enum rtx_code, int,
> +                              struct full_rtx_costs *);
>  extern unsigned int subreg_lsb (const_rtx);
>  extern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode,
>                                  unsigned int);
> @@ -1225,7 +1226,7 @@ extern int low_bitmask_len (enum machine
>  static inline int
>  set_src_cost (rtx x, bool speed_p)
>  {
> -  return rtx_cost (x, SET, speed_p);
> +  return rtx_cost (x, SET, 1, speed_p);
>  }
>
>  /* Like set_src_cost, but return both the speed and size costs in C.  */
> @@ -1233,7 +1234,7 @@ set_src_cost (rtx x, bool speed_p)
>  static inline void
>  get_full_set_src_cost (rtx x, struct full_rtx_costs *c)
>  {
> -  get_full_rtx_cost (x, SET, c);
> +  get_full_rtx_cost (x, SET, 1, c);
>  }
>  #endif
>
> Index: gcc/rtlanal.c
> ===================================================================
> --- gcc/rtlanal.c       2011-08-15 15:22:59.484479488 +0100
> +++ gcc/rtlanal.c       2011-08-15 15:23:01.768475015 +0100
> @@ -3674,11 +3674,12 @@ label_is_jump_target_p (const_rtx label,
>    Another is in rtl generation, to pick the cheapest way to multiply.
>    Other uses like the latter are expected in the future.
>
> -   SPEED parameter specify whether costs optimized for speed or size should
> +   X appears as operand OPNO in an expression with code OUTER_CODE.
> +   SPEED specifies whether costs optimized for speed or size should
>    be returned.  */
>
>  int
> -rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED, bool speed)
> +rtx_cost (rtx x, enum rtx_code outer_code, int opno, bool speed)
>  {
>   int i, j;
>   enum rtx_code code;
> @@ -3726,7 +3727,7 @@ rtx_cost (rtx x, enum rtx_code outer_cod
>       break;
>
>     default:
> -      if (targetm.rtx_costs (x, code, outer_code, &total, speed))
> +      if (targetm.rtx_costs (x, code, outer_code, opno, &total, speed))
>        return total;
>       break;
>     }
> @@ -3737,22 +3738,23 @@ rtx_cost (rtx x, enum rtx_code outer_cod
>   fmt = GET_RTX_FORMAT (code);
>   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
>     if (fmt[i] == 'e')
> -      total += rtx_cost (XEXP (x, i), code, speed);
> +      total += rtx_cost (XEXP (x, i), code, i, speed);
>     else if (fmt[i] == 'E')
>       for (j = 0; j < XVECLEN (x, i); j++)
> -       total += rtx_cost (XVECEXP (x, i, j), code, speed);
> +       total += rtx_cost (XVECEXP (x, i, j), code, i, speed);
>
>   return total;
>  }
>
>  /* Fill in the structure C with information about both speed and size rtx
> -   costs for X, with outer code OUTER.  */
> +   costs for X, which is operand OPNO in an expression with code OUTER.  */
>
>  void
> -get_full_rtx_cost (rtx x, enum rtx_code outer, struct full_rtx_costs *c)
> +get_full_rtx_cost (rtx x, enum rtx_code outer, int opno,
> +                  struct full_rtx_costs *c)
>  {
> -  c->speed = rtx_cost (x, outer, true);
> -  c->size = rtx_cost (x, outer, false);
> +  c->speed = rtx_cost (x, outer, opno, true);
> +  c->size = rtx_cost (x, outer, opno, false);
>  }
>
>
> @@ -3780,7 +3782,7 @@ address_cost (rtx x, enum machine_mode m
>  int
>  default_address_cost (rtx x, bool speed)
>  {
> -  return rtx_cost (x, MEM, speed);
> +  return rtx_cost (x, MEM, 0, speed);
>  }
>
>
> Index: gcc/config/alpha/alpha.c
> ===================================================================
> --- gcc/config/alpha/alpha.c    2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/alpha/alpha.c    2011-08-15 15:23:01.456475626 +0100
> @@ -1154,7 +1154,7 @@ alpha_legitimize_reload_address (rtx x,
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -alpha_rtx_costs (rtx x, int code, int outer_code, int *total,
> +alpha_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
>                 bool speed)
>  {
>   enum machine_mode mode = GET_MODE (x);
> @@ -1222,9 +1222,9 @@ alpha_rtx_costs (rtx x, int code, int ou
>               && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
>        {
>          *total = (rtx_cost (XEXP (XEXP (x, 0), 0),
> -                             (enum rtx_code) outer_code, speed)
> +                             (enum rtx_code) outer_code, opno, speed)
>                    + rtx_cost (XEXP (x, 1),
> -                               (enum rtx_code) outer_code, speed)
> +                               (enum rtx_code) outer_code, opno, speed)
>                    + COSTS_N_INSNS (1));
>          return true;
>        }
> Index: gcc/config/avr/avr.c
> ===================================================================
> --- gcc/config/avr/avr.c        2011-08-15 15:22:59.480479496 +0100
> +++ gcc/config/avr/avr.c        2011-08-15 15:23:01.459475620 +0100
> @@ -89,8 +89,9 @@ static void avr_asm_out_ctor (rtx, int);
>  static void avr_asm_out_dtor (rtx, int);
>  static int avr_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
>  static int avr_memory_move_cost (enum machine_mode, reg_class_t, bool);
> -static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code, bool);
> -static bool avr_rtx_costs (rtx, int, int, int *, bool);
> +static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
> +                                int, bool);
> +static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
>  static int avr_address_cost (rtx, bool);
>  static bool avr_return_in_memory (const_tree, const_tree);
>  static struct machine_function * avr_init_machine_status (void);
> @@ -1640,7 +1641,8 @@ final_prescan_insn (rtx insn, rtx *opera
>                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
>       else
>         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
> -                 rtx_cost (PATTERN (insn), INSN, optimize_insn_for_speed_p()));
> +                 rtx_cost (PATTERN (insn), INSN, 0,
> +                          optimize_insn_for_speed_p()));
>     }
>  }
>
> @@ -5300,7 +5302,7 @@ avr_memory_move_cost (enum machine_mode
>
>  static int
>  avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
> -                     bool speed)
> +                     int opno, bool speed)
>  {
>   enum rtx_code code = GET_CODE (x);
>   int total;
> @@ -5320,7 +5322,7 @@ avr_operand_rtx_cost (rtx x, enum machin
>     }
>
>   total = 0;
> -  avr_rtx_costs (x, code, outer, &total, speed);
> +  avr_rtx_costs (x, code, outer, opno, &total, speed);
>   return total;
>  }
>
> @@ -5330,8 +5332,8 @@ avr_operand_rtx_cost (rtx x, enum machin
>    case, *TOTAL contains the cost result.  */
>
>  static bool
> -avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
> -              bool speed)
> +avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
> +              int opno ATTRIBUTE_UNUSED, int *total, bool speed)
>  {
>   enum rtx_code code = (enum rtx_code) codearg;
>   enum machine_mode mode = GET_MODE (x);
> @@ -5371,7 +5373,7 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case ABS:
> @@ -5385,24 +5387,24 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case NOT:
>       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case ZERO_EXTEND:
>       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
>                              - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case SIGN_EXTEND:
>       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
>                              - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case PLUS:
> @@ -5411,14 +5413,15 @@ avr_rtx_costs (rtx x, int codearg, int o
>        case QImode:
>          *total = COSTS_N_INSNS (1);
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
> -           *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +           *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>          break;
>
>        case HImode:
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (2);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
>            *total = COSTS_N_INSNS (1);
> @@ -5430,7 +5433,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (4);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
>            *total = COSTS_N_INSNS (1);
> @@ -5441,22 +5445,22 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case MINUS:
>     case AND:
>     case IOR:
>       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
> -          *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>       return true;
>
>     case XOR:
>       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> -      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>       return true;
>
>     case MULT:
> @@ -5546,8 +5550,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> -      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>       return true;
>
>     case DIV:
> @@ -5558,8 +5562,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>        *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
>       else
>        return false;
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> -      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>       return true;
>
>     case ROTATE:
> @@ -5594,7 +5598,7 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case ASHIFT:
> @@ -5604,7 +5608,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 4 : 17);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            {
> @@ -5633,7 +5638,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5670,7 +5676,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
> @@ -5678,7 +5685,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5702,14 +5710,15 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case ASHIFTRT:
> @@ -5719,7 +5728,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 4 : 17);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            {
> @@ -5739,7 +5749,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5775,7 +5786,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
> @@ -5783,7 +5795,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5807,14 +5820,15 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case LSHIFTRT:
> @@ -5824,7 +5838,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 4 : 17);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            {
> @@ -5842,7 +5857,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5881,7 +5897,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 5 : 41);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
> @@ -5889,7 +5906,8 @@ avr_rtx_costs (rtx x, int codearg, int o
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
>            {
>              *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                             speed);
>            }
>          else
>            switch (INTVAL (XEXP (x, 1)))
> @@ -5913,14 +5931,15 @@ avr_rtx_costs (rtx x, int codearg, int o
>                break;
>              default:
>                *total = COSTS_N_INSNS (!speed ? 7 : 113);
> -               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
> +                                               speed);
>              }
>          break;
>
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case COMPARE:
> @@ -5929,13 +5948,13 @@ avr_rtx_costs (rtx x, int codearg, int o
>        case QImode:
>          *total = COSTS_N_INSNS (1);
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
> -           *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +           *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>          break;
>
>         case HImode:
>          *total = COSTS_N_INSNS (2);
>          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
> -            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>          else if (INTVAL (XEXP (x, 1)) != 0)
>            *total += COSTS_N_INSNS (1);
>           break;
> @@ -5943,7 +5962,7 @@ avr_rtx_costs (rtx x, int codearg, int o
>         case SImode:
>           *total = COSTS_N_INSNS (4);
>           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
> -            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
> +            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>          else if (INTVAL (XEXP (x, 1)) != 0)
>            *total += COSTS_N_INSNS (3);
>           break;
> @@ -5951,7 +5970,7 @@ avr_rtx_costs (rtx x, int codearg, int o
>        default:
>          return false;
>        }
> -      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
> +      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>       return true;
>
>     case TRUNCATE:
> Index: gcc/config/bfin/bfin.c
> ===================================================================
> --- gcc/config/bfin/bfin.c      2011-08-15 15:22:59.484479488 +0100
> +++ gcc/config/bfin/bfin.c      2011-08-15 15:23:01.464475610 +0100
> @@ -2779,7 +2779,8 @@ bfin_legitimate_constant_p (enum machine
>  }
>
>  static bool
> -bfin_rtx_costs (rtx x, int code_i, int outer_code_i, int *total, bool speed)
> +bfin_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total,
> +               bool speed)
>  {
>   enum rtx_code code = (enum rtx_code) code_i;
>   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
> @@ -2829,8 +2830,8 @@ bfin_rtx_costs (rtx x, int code_i, int o
>              if (val == 2 || val == 4)
>                {
>                  *total = cost2;
> -                 *total += rtx_cost (XEXP (op0, 0), outer_code, speed);
> -                 *total += rtx_cost (op1, outer_code, speed);
> +                 *total += rtx_cost (XEXP (op0, 0), outer_code, opno, speed);
> +                 *total += rtx_cost (op1, outer_code, opno, speed);
>                  return true;
>                }
>            }
> @@ -2849,10 +2850,10 @@ bfin_rtx_costs (rtx x, int code_i, int o
>          *total = 6 * cost2;
>          if (GET_CODE (op1) != CONST_INT
>              || !satisfies_constraint_Ks7 (op1))
> -           *total += rtx_cost (op1, PLUS, speed);
> +           *total += rtx_cost (op1, PLUS, 1, speed);
>          if (GET_CODE (op0) != REG
>              && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
> -           *total += rtx_cost (op0, PLUS, speed);
> +           *total += rtx_cost (op0, PLUS, 0, speed);
>        }
>       return true;
>
> @@ -2875,7 +2876,7 @@ bfin_rtx_costs (rtx x, int code_i, int o
>       op1 = XEXP (x, 1);
>       if (GET_CODE (op0) != REG
>          && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
> -       *total += rtx_cost (op0, code, speed);
> +       *total += rtx_cost (op0, code, 0, speed);
>
>       return true;
>
> @@ -2900,7 +2901,7 @@ bfin_rtx_costs (rtx x, int code_i, int o
>
>       if (GET_CODE (op0) != REG
>          && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
> -       *total += rtx_cost (op0, code, speed);
> +       *total += rtx_cost (op0, code, 0, speed);
>
>       if (GET_MODE (x) == DImode)
>        {
> @@ -2914,12 +2915,12 @@ bfin_rtx_costs (rtx x, int code_i, int o
>       if (code == AND)
>        {
>          if (! rhs_andsi3_operand (XEXP (x, 1), SImode))
> -           *total += rtx_cost (XEXP (x, 1), code, speed);
> +           *total += rtx_cost (XEXP (x, 1), code, 1, speed);
>        }
>       else
>        {
>          if (! regorlog2_operand (XEXP (x, 1), SImode))
> -           *total += rtx_cost (XEXP (x, 1), code, speed);
> +           *total += rtx_cost (XEXP (x, 1), code, 1, speed);
>        }
>
>       return true;
> @@ -2959,10 +2960,10 @@ bfin_rtx_costs (rtx x, int code_i, int o
>
>          if (GET_CODE (op0) != REG
>              && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
> -           *total += rtx_cost (op0, MULT, speed);
> +           *total += rtx_cost (op0, MULT, 0, speed);
>          if (GET_CODE (op1) != REG
>              && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
> -           *total += rtx_cost (op1, MULT, speed);
> +           *total += rtx_cost (op1, MULT, 1, speed);
>        }
>       return true;
>
> Index: gcc/config/c6x/c6x.c
> ===================================================================
> --- gcc/config/c6x/c6x.c        2011-08-15 15:22:59.481479494 +0100
> +++ gcc/config/c6x/c6x.c        2011-08-15 15:23:01.467475604 +0100
> @@ -4772,7 +4772,8 @@ shift_p (rtx x, enum rtx_code code, int
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -c6x_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
> +c6x_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
> +              bool speed)
>  {
>   int cost2 = COSTS_N_INSNS (1);
>   rtx op0, op1;
> @@ -4826,8 +4827,8 @@ c6x_rtx_costs (rtx x, int code, int oute
>                *total = COSTS_N_INSNS (2);
>              else
>                *total = COSTS_N_INSNS (12);
> -             *total += rtx_cost (XEXP (op0, 0), code0, speed);
> -             *total += rtx_cost (XEXP (op1, 0), code1, speed);
> +             *total += rtx_cost (XEXP (op0, 0), code0, 0, speed);
> +             *total += rtx_cost (XEXP (op1, 0), code1, 0, speed);
>              return true;
>            }
>        }
> @@ -4855,8 +4856,8 @@ c6x_rtx_costs (rtx x, int code, int oute
>              || INTVAL (XEXP (op0, 1)) == 4
>              || (code == PLUS && INTVAL (XEXP (op0, 1)) == 8)))
>        {
> -         *total += rtx_cost (XEXP (op0, 0), ASHIFT, speed);
> -         *total += rtx_cost (op1, (enum rtx_code)code, speed);
> +         *total += rtx_cost (XEXP (op0, 0), ASHIFT, 0, speed);
> +         *total += rtx_cost (op1, (enum rtx_code) code, 1, speed);
>          return true;
>        }
>       return false;
> @@ -4926,10 +4927,10 @@ c6x_rtx_costs (rtx x, int code, int oute
>
>       if (GET_CODE (op0) != REG
>          && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
> -       *total += rtx_cost (op0, MULT, speed);
> +       *total += rtx_cost (op0, MULT, 0, speed);
>       if (op1 && GET_CODE (op1) != REG
>          && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
> -       *total += rtx_cost (op1, MULT, speed);
> +       *total += rtx_cost (op1, MULT, 1, speed);
>       return true;
>
>     case UDIV:
> @@ -4947,7 +4948,8 @@ c6x_rtx_costs (rtx x, int code, int oute
>          && XEXP (op0, 1) == const0_rtx
>          && rtx_equal_p (XEXP (x, 1), XEXP (op0, 0)))
>        {
> -         *total = rtx_cost (XEXP (x, 1), (enum rtx_code)outer_code, speed);
> +         *total = rtx_cost (XEXP (x, 1), (enum rtx_code) outer_code,
> +                            opno, speed);
>          return false;
>        }
>       return false;
> Index: gcc/config/cris/cris.c
> ===================================================================
> --- gcc/config/cris/cris.c      2011-08-15 15:22:59.478479500 +0100
> +++ gcc/config/cris/cris.c      2011-08-15 15:23:01.471475596 +0100
> @@ -123,7 +123,7 @@ static void cris_init_libfuncs (void);
>
>  static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
>  static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool);
> -static bool cris_rtx_costs (rtx, int, int, int *, bool);
> +static bool cris_rtx_costs (rtx, int, int, int, int *, bool);
>  static int cris_address_cost (rtx, bool);
>  static bool cris_pass_by_reference (cumulative_args_t, enum machine_mode,
>                                    const_tree, bool);
> @@ -1777,7 +1777,7 @@ cris_expand_return (bool on_stack)
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -cris_rtx_costs (rtx x, int code, int outer_code, int *total,
> +cris_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
>                bool speed)
>  {
>   switch (code)
> @@ -1871,7 +1871,8 @@ cris_rtx_costs (rtx x, int code, int out
>           && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
>        {
>          *total
> -           = (rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed) + 2
> +           = (rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code,
> +                        opno, speed) + 2
>               + 2 * GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))));
>          return true;
>        }
> @@ -1883,7 +1884,7 @@ cris_rtx_costs (rtx x, int code, int out
>       /* fall through */
>
>     case ZERO_EXTEND: case SIGN_EXTEND:
> -      *total = rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed);
> +      *total = rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, opno, speed);
>       return true;
>
>     default:
> Index: gcc/config/frv/frv.c
> ===================================================================
> --- gcc/config/frv/frv.c        2011-08-15 15:22:59.484479488 +0100
> +++ gcc/config/frv/frv.c        2011-08-15 15:23:01.477475585 +0100
> @@ -364,7 +364,8 @@ static void frv_setup_incoming_varargs
>                                                 tree, int *, int);
>  static rtx frv_expand_builtin_saveregs         (void);
>  static void frv_expand_builtin_va_start                (tree, rtx);
> -static bool frv_rtx_costs                      (rtx, int, int, int*, bool);
> +static bool frv_rtx_costs                      (rtx, int, int, int, int*,
> +                                                bool);
>  static int frv_register_move_cost              (enum machine_mode,
>                                                 reg_class_t, reg_class_t);
>  static int frv_memory_move_cost                        (enum machine_mode,
> @@ -9496,6 +9497,7 @@ frv_in_small_data_p (const_tree decl)
>  frv_rtx_costs (rtx x,
>                int code ATTRIBUTE_UNUSED,
>                int outer_code ATTRIBUTE_UNUSED,
> +              int opno ATTRIBUTE_UNUSED,
>                int *total,
>               bool speed ATTRIBUTE_UNUSED)
>  {
> Index: gcc/config/h8300/h8300.c
> ===================================================================
> --- gcc/config/h8300/h8300.c    2011-08-15 15:22:59.478479500 +0100
> +++ gcc/config/h8300/h8300.c    2011-08-15 15:23:01.484475572 +0100
> @@ -1174,7 +1174,8 @@ h8300_shift_costs (rtx x)
>  /* Worker function for TARGET_RTX_COSTS.  */
>
>  static bool
> -h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
> +h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                int *total, bool speed)
>  {
>   if (TARGET_H8300SX && outer_code == MEM)
>     {
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c      2011-08-15 15:22:59.480479496 +0100
> +++ gcc/config/i386/i386.c      2011-08-15 15:23:01.501475538 +0100
> @@ -28825,7 +28825,8 @@ ix86_modes_tieable_p (enum machine_mode
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -ix86_rtx_costs (rtx x, int code, int outer_code_i, int *total, bool speed)
> +ix86_rtx_costs (rtx x, int code, int outer_code_i, int opno, int *total,
> +               bool speed)
>  {
>   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
>   enum machine_mode mode = GET_MODE (x);
> @@ -28949,18 +28950,18 @@ ix86_rtx_costs (rtx x, int code, int out
>         /* ??? SSE scalar/vector cost should be used here.  */
>         /* ??? Bald assumption that fma has the same cost as fmul.  */
>         *total = cost->fmul;
> -       *total += rtx_cost (XEXP (x, 1), FMA, speed);
> +       *total += rtx_cost (XEXP (x, 1), FMA, 1, speed);
>
>         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
>        sub = XEXP (x, 0);
>        if (GET_CODE (sub) == NEG)
>          sub = XEXP (sub, 0);
> -       *total += rtx_cost (sub, FMA, speed);
> +       *total += rtx_cost (sub, FMA, 0, speed);
>
>        sub = XEXP (x, 2);
>        if (GET_CODE (sub) == NEG)
>          sub = XEXP (sub, 0);
> -       *total += rtx_cost (sub, FMA, speed);
> +       *total += rtx_cost (sub, FMA, 2, speed);
>        return true;
>       }
>
> @@ -29022,7 +29023,8 @@ ix86_rtx_costs (rtx x, int code, int out
>
>          *total = (cost->mult_init[MODE_INDEX (mode)]
>                    + nbits * cost->mult_bit
> -                   + rtx_cost (op0, outer_code, speed) + rtx_cost (op1, outer_code, speed));
> +                   + rtx_cost (op0, outer_code, opno, speed)
> +                   + rtx_cost (op1, outer_code, opno, speed));
>
>           return true;
>        }
> @@ -29056,10 +29058,11 @@ ix86_rtx_costs (rtx x, int code, int out
>              if (val == 2 || val == 4 || val == 8)
>                {
>                  *total = cost->lea;
> -                 *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code, speed);
> +                 *total += rtx_cost (XEXP (XEXP (x, 0), 1),
> +                                     outer_code, opno, speed);
>                  *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
> -                                     outer_code, speed);
> -                 *total += rtx_cost (XEXP (x, 1), outer_code, speed);
> +                                     outer_code, opno, speed);
> +                 *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
>                  return true;
>                }
>            }
> @@ -29070,17 +29073,20 @@ ix86_rtx_costs (rtx x, int code, int out
>              if (val == 2 || val == 4 || val == 8)
>                {
>                  *total = cost->lea;
> -                 *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed);
> -                 *total += rtx_cost (XEXP (x, 1), outer_code, speed);
> +                 *total += rtx_cost (XEXP (XEXP (x, 0), 0),
> +                                     outer_code, opno, speed);
> +                 *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
>                  return true;
>                }
>            }
>          else if (GET_CODE (XEXP (x, 0)) == PLUS)
>            {
>              *total = cost->lea;
> -             *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed);
> -             *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code, speed);
> -             *total += rtx_cost (XEXP (x, 1), outer_code, speed);
> +             *total += rtx_cost (XEXP (XEXP (x, 0), 0),
> +                                 outer_code, opno, speed);
> +             *total += rtx_cost (XEXP (XEXP (x, 0), 1),
> +                                 outer_code, opno, speed);
> +             *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
>              return true;
>            }
>        }
> @@ -29112,9 +29118,9 @@ ix86_rtx_costs (rtx x, int code, int out
>       if (!TARGET_64BIT && mode == DImode)
>        {
>          *total = (cost->add * 2
> -                   + (rtx_cost (XEXP (x, 0), outer_code, speed)
> +                   + (rtx_cost (XEXP (x, 0), outer_code, opno, speed)
>                       << (GET_MODE (XEXP (x, 0)) != DImode))
> -                   + (rtx_cost (XEXP (x, 1), outer_code, speed)
> +                   + (rtx_cost (XEXP (x, 1), outer_code, opno, speed)
>                       << (GET_MODE (XEXP (x, 1)) != DImode)));
>          return true;
>        }
> @@ -29156,8 +29162,8 @@ ix86_rtx_costs (rtx x, int code, int out
>          /* This kind of construct is implemented using test[bwl].
>             Treat it as if we had an AND.  */
>          *total = (cost->add
> -                   + rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed)
> -                   + rtx_cost (const1_rtx, outer_code, speed));
> +                   + rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, opno, speed)
> +                   + rtx_cost (const1_rtx, outer_code, opno, speed));
>          return true;
>        }
>       return false;
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> --- gcc/config/ia64/ia64.c      2011-08-15 15:22:59.481479494 +0100
> +++ gcc/config/ia64/ia64.c      2011-08-15 15:23:01.517475507 +0100
> @@ -217,7 +217,7 @@ static int ia64_register_move_cost (enum
>                                     reg_class_t);
>  static int ia64_memory_move_cost (enum machine_mode mode, reg_class_t,
>                                  bool);
> -static bool ia64_rtx_costs (rtx, int, int, int *, bool);
> +static bool ia64_rtx_costs (rtx, int, int, int, int *, bool);
>  static int ia64_unspec_may_trap_p (const_rtx, unsigned);
>  static void fix_range (const char *);
>  static struct machine_function * ia64_init_machine_status (void);
> @@ -5244,8 +5244,8 @@ ia64_print_operand (FILE * file, rtx x,
>  /* ??? This is incomplete.  */
>
>  static bool
> -ia64_rtx_costs (rtx x, int code, int outer_code, int *total,
> -               bool speed ATTRIBUTE_UNUSED)
> +ia64_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/iq2000/iq2000.c
> ===================================================================
> --- gcc/config/iq2000/iq2000.c  2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/iq2000/iq2000.c  2011-08-15 15:23:01.522475498 +0100
> @@ -151,7 +151,7 @@ static bool iq2000_return_in_memory   (c
>  static void iq2000_setup_incoming_varargs (cumulative_args_t,
>                                           enum machine_mode, tree, int *,
>                                           int);
> -static bool iq2000_rtx_costs          (rtx, int, int, int *, bool);
> +static bool iq2000_rtx_costs          (rtx, int, int, int, int *, bool);
>  static int  iq2000_address_cost       (rtx, bool);
>  static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
>  static rtx  iq2000_legitimize_address (rtx, rtx, enum machine_mode);
> @@ -3285,7 +3285,8 @@ iq2000_legitimize_address (rtx xinsn, rt
>
>
>  static bool
> -iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
> +iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +                 int opno ATTRIBUTE_UNUSED, int * total,
>                  bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
> Index: gcc/config/lm32/lm32.c
> ===================================================================
> --- gcc/config/lm32/lm32.c      2011-08-15 15:22:59.480479496 +0100
> +++ gcc/config/lm32/lm32.c      2011-08-15 15:23:01.526475489 +0100
> @@ -68,8 +68,8 @@ static bool lm32_in_small_data_p (const_
>  static void lm32_setup_incoming_varargs (cumulative_args_t cum,
>                                         enum machine_mode mode, tree type,
>                                         int *pretend_size, int no_rtl);
> -static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total,
> -                           bool speed);
> +static bool lm32_rtx_costs (rtx x, int code, int outer_code, int opno,
> +                           int *total, bool speed);
>  static bool lm32_can_eliminate (const int, const int);
>  static bool
>  lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
> @@ -928,7 +928,8 @@ nonpic_symbol_mentioned_p (rtx x)
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -lm32_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
> +lm32_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed)
>  {
>   enum machine_mode mode = GET_MODE (x);
>   bool small_mode;
> Index: gcc/config/m32c/m32c.c
> ===================================================================
> --- gcc/config/m32c/m32c.c      2011-08-15 15:22:59.481479494 +0100
> +++ gcc/config/m32c/m32c.c      2011-08-15 15:23:01.528475485 +0100
> @@ -2421,8 +2421,8 @@ m32c_memory_move_cost (enum machine_mode
>  #undef TARGET_RTX_COSTS
>  #define TARGET_RTX_COSTS m32c_rtx_costs
>  static bool
> -m32c_rtx_costs (rtx x, int code, int outer_code, int *total,
> -               bool speed ATTRIBUTE_UNUSED)
> +m32c_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/m32r/m32r.c
> ===================================================================
> --- gcc/config/m32r/m32r.c      2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/m32r/m32r.c      2011-08-15 15:23:01.531475479 +0100
> @@ -84,7 +84,7 @@ static bool m32r_function_value_regno_p
>  static void m32r_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
>                                         tree, int *, int);
>  static void init_idents (void);
> -static bool m32r_rtx_costs (rtx, int, int, int *, bool speed);
> +static bool m32r_rtx_costs (rtx, int, int, int, int *, bool speed);
>  static int m32r_memory_move_cost (enum machine_mode, reg_class_t, bool);
>  static bool m32r_pass_by_reference (cumulative_args_t, enum machine_mode,
>                                    const_tree, bool);
> @@ -1356,7 +1356,8 @@ m32r_memory_move_cost (enum machine_mode
>  }
>
>  static bool
> -m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
> +m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +               int opno ATTRIBUTE_UNUSED, int *total,
>                bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
> Index: gcc/config/m68k/m68k.c
> ===================================================================
> --- gcc/config/m68k/m68k.c      2011-08-15 15:22:59.481479494 +0100
> +++ gcc/config/m68k/m68k.c      2011-08-15 15:23:01.535475471 +0100
> @@ -150,7 +150,7 @@ static bool m68k_save_reg (unsigned int
>  static bool m68k_ok_for_sibcall_p (tree, tree);
>  static bool m68k_tls_symbol_p (rtx);
>  static rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
> -static bool m68k_rtx_costs (rtx, int, int, int *, bool);
> +static bool m68k_rtx_costs (rtx, int, int, int, int *, bool);
>  #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
>  static bool m68k_return_in_memory (const_tree, const_tree);
>  #endif
> @@ -2765,8 +2765,8 @@ const_int_cost (HOST_WIDE_INT i)
>  }
>
>  static bool
> -m68k_rtx_costs (rtx x, int code, int outer_code, int *total,
> -               bool speed ATTRIBUTE_UNUSED)
> +m68k_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/mcore/mcore.c
> ===================================================================
> --- gcc/config/mcore/mcore.c    2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/mcore/mcore.c    2011-08-15 15:23:01.538475465 +0100
> @@ -121,7 +121,8 @@ static const char *mcore_strip_name_enco
>  static int        mcore_const_costs                    (rtx, RTX_CODE);
>  static int        mcore_and_cost                       (rtx);
>  static int        mcore_ior_cost                       (rtx);
> -static bool       mcore_rtx_costs              (rtx, int, int, int *, bool);
> +static bool       mcore_rtx_costs              (rtx, int, int, int,
> +                                                int *, bool);
>  static void       mcore_external_libcall       (rtx);
>  static bool       mcore_return_in_memory       (const_tree, const_tree);
>  static int        mcore_arg_partial_bytes       (cumulative_args_t,
> @@ -508,8 +509,8 @@ mcore_ior_cost (rtx x)
>  }
>
>  static bool
> -mcore_rtx_costs (rtx x, int code, int outer_code, int * total,
> -                bool speed ATTRIBUTE_UNUSED)
> +mcore_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                int * total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/mep/mep.c
> ===================================================================
> --- gcc/config/mep/mep.c        2011-08-15 15:22:59.478479500 +0100
> +++ gcc/config/mep/mep.c        2011-08-15 15:23:01.541475459 +0100
> @@ -211,7 +211,7 @@ static void mep_move_ready_insn (rtx *,
>  static int mep_sched_reorder (FILE *, int, rtx *, int *, int);
>  static rtx mep_make_bundle (rtx, rtx);
>  static void mep_bundle_insns (rtx);
> -static bool mep_rtx_cost (rtx, int, int, int *, bool);
> +static bool mep_rtx_cost (rtx, int, int, int, int *, bool);
>  static int mep_address_cost (rtx, bool);
>  static void mep_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
>                                        tree, int *, int);
> @@ -7261,7 +7261,9 @@ mep_expand_binary_intrinsic (int ATTRIBU
>  }
>
>  static bool
> -mep_rtx_cost (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total, bool ATTRIBUTE_UNUSED speed_t)
> +mep_rtx_cost (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +             int opno ATTRIBUTE_UNUSED, int *total,
> +             bool ATTRIBUTE_UNUSED speed_t)
>  {
>   switch (code)
>     {
> Index: gcc/config/microblaze/microblaze.c
> ===================================================================
> --- gcc/config/microblaze/microblaze.c  2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/microblaze/microblaze.c  2011-08-15 15:23:01.545475451 +0100
> @@ -861,7 +861,8 @@ microblaze_expand_block_move (rtx dest,
>  }
>
>  static bool
> -microblaze_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
> +microblaze_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +                     int opno ATTRIBUTE_UNUSED, int *total,
>                      bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
> Index: gcc/config/mips/mips.c
> ===================================================================
> --- gcc/config/mips/mips.c      2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/mips/mips.c      2011-08-15 15:23:01.550475442 +0100
> @@ -3334,7 +3334,7 @@ mips_binary_cost (rtx x, int single_cost
>     cost = single_cost;
>   return (cost
>          + set_src_cost (XEXP (x, 0), speed)
> -         + rtx_cost (XEXP (x, 1), GET_CODE (x), speed));
> +         + rtx_cost (XEXP (x, 1), GET_CODE (x), 1, speed));
>  }
>
>  /* Return the cost of floating-point multiplications of mode MODE.  */
> @@ -3404,7 +3404,8 @@ mips_zero_extend_cost (enum machine_mode
>  /* Implement TARGET_RTX_COSTS.  */
>
>  static bool
> -mips_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
> +mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed)
>  {
>   enum machine_mode mode = GET_MODE (x);
>   bool float_mode_p = FLOAT_MODE_P (mode);
> Index: gcc/config/mmix/mmix.c
> ===================================================================
> --- gcc/config/mmix/mmix.c      2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/mmix/mmix.c      2011-08-15 15:23:01.557475429 +0100
> @@ -140,7 +140,7 @@ static void mmix_reorg (void);
>   (cumulative_args_t, enum machine_mode, tree, int *, int);
>  static void mmix_file_start (void);
>  static void mmix_file_end (void);
> -static bool mmix_rtx_costs (rtx, int, int, int *, bool);
> +static bool mmix_rtx_costs (rtx, int, int, int, int *, bool);
>  static int mmix_register_move_cost (enum machine_mode,
>                                    reg_class_t, reg_class_t);
>  static rtx mmix_struct_value_rtx (tree, int);
> @@ -1229,6 +1229,7 @@ mmix_reversible_cc_mode (enum machine_mo
>  mmix_rtx_costs (rtx x ATTRIBUTE_UNUSED,
>                int code ATTRIBUTE_UNUSED,
>                int outer_code ATTRIBUTE_UNUSED,
> +               int opno ATTRIBUTE_UNUSED,
>                int *total ATTRIBUTE_UNUSED,
>                bool speed ATTRIBUTE_UNUSED)
>  {
> Index: gcc/config/mn10300/mn10300.c
> ===================================================================
> --- gcc/config/mn10300/mn10300.c        2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/mn10300/mn10300.c        2011-08-15 15:23:01.560475423 +0100
> @@ -2182,7 +2182,7 @@ mn10300_address_cost (rtx x, bool speed)
>       return speed ? 2 : 6;
>
>     default:
> -      return rtx_cost (x, MEM, speed);
> +      return rtx_cost (x, MEM, 0, speed);
>     }
>  }
>
> @@ -2296,7 +2296,8 @@ mn10300_memory_move_cost (enum machine_m
>    to represent cycles.  Size-relative costs are in bytes.  */
>
>  static bool
> -mn10300_rtx_costs (rtx x, int code, int outer_code, int *ptotal, bool speed)
> +mn10300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                  int *ptotal, bool speed)
>  {
>   /* This value is used for SYMBOL_REF etc where we want to pretend
>      we have a full 32-bit constant.  */
> @@ -2387,7 +2388,7 @@ mn10300_rtx_costs (rtx x, int code, int
>          i = INTVAL (XEXP (x, 1));
>          if (i == 1 || i == 4)
>            {
> -             total = 1 + rtx_cost (XEXP (x, 0), PLUS, speed);
> +             total = 1 + rtx_cost (XEXP (x, 0), PLUS, 0, speed);
>              goto alldone;
>            }
>        }
> Index: gcc/config/pa/pa.c
> ===================================================================
> --- gcc/config/pa/pa.c  2011-08-15 15:22:59.484479488 +0100
> +++ gcc/config/pa/pa.c  2011-08-15 15:23:01.565475413 +0100
> @@ -92,7 +92,7 @@ static void fix_range (const char *);
>  static int hppa_register_move_cost (enum machine_mode mode, reg_class_t,
>                                    reg_class_t);
>  static int hppa_address_cost (rtx, bool);
> -static bool hppa_rtx_costs (rtx, int, int, int *, bool);
> +static bool hppa_rtx_costs (rtx, int, int, int, int *, bool);
>  static inline rtx force_mode (enum machine_mode, rtx);
>  static void pa_reorg (void);
>  static void pa_combine_instructions (void);
> @@ -1411,8 +1411,8 @@ hppa_address_cost (rtx X,
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -hppa_rtx_costs (rtx x, int code, int outer_code, int *total,
> -               bool speed ATTRIBUTE_UNUSED)
> +hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/pdp11/pdp11.c
> ===================================================================
> --- gcc/config/pdp11/pdp11.c    2011-08-15 15:22:59.481479494 +0100
> +++ gcc/config/pdp11/pdp11.c    2011-08-15 15:23:01.569475405 +0100
> @@ -141,7 +141,7 @@ decode_pdp11_d (const struct real_format
>
>  static const char *singlemove_string (rtx *);
>  static bool pdp11_assemble_integer (rtx, unsigned int, int);
> -static bool pdp11_rtx_costs (rtx, int, int, int *, bool);
> +static bool pdp11_rtx_costs (rtx, int, int, int, int *, bool);
>  static bool pdp11_return_in_memory (const_tree, const_tree);
>  static rtx pdp11_function_value (const_tree, const_tree, bool);
>  static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
> @@ -888,7 +888,8 @@ pdp11_register_move_cost (enum machine_m
>  }
>
>  static bool
> -pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
> +pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +                int opno ATTRIBUTE_UNUSED, int *total,
>                 bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
> Index: gcc/config/picochip/picochip.c
> ===================================================================
> --- gcc/config/picochip/picochip.c      2011-08-15 15:22:59.478479500 +0100
> +++ gcc/config/picochip/picochip.c      2011-08-15 15:23:01.573475397 +0100
> @@ -101,7 +101,8 @@ int picochip_sched_reorder (FILE * file,
>  void picochip_init_builtins (void);
>  rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
>
> -bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed);
> +bool picochip_rtx_costs (rtx x, int code, int outer_code, int opno,
> +                        int* total, bool speed);
>  bool picochip_return_in_memory(const_tree type,
>                               const_tree fntype ATTRIBUTE_UNUSED);
>  bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
> @@ -3741,7 +3742,8 @@ gen_SImode_mem(rtx opnd1,rtx opnd2)
>  }
>
>  bool
> -picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed)
> +picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +                   int opno ATTRIBUTE_UNUSED, int* total, bool speed)
>  {
>
>   int localTotal = 0;
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> --- gcc/config/rs6000/rs6000.c  2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/rs6000/rs6000.c  2011-08-15 15:23:01.583475377 +0100
> @@ -948,8 +948,8 @@ static int rs6000_variable_issue (FILE *
>  static int rs6000_register_move_cost (enum machine_mode,
>                                      reg_class_t, reg_class_t);
>  static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
> -static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
> -static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
> +static bool rs6000_rtx_costs (rtx, int, int, int, int *, bool);
> +static bool rs6000_debug_rtx_costs (rtx, int, int, int, int *, bool);
>  static int rs6000_debug_address_cost (rtx, bool);
>  static int rs6000_adjust_cost (rtx, rtx, rtx, int);
>  static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
> @@ -25730,8 +25730,8 @@ rs6000_xcoff_file_end (void)
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
> -                 bool speed)
> +rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                 int *total, bool speed)
>  {
>   enum machine_mode mode = GET_MODE (x);
>
> @@ -26074,17 +26074,18 @@ rs6000_rtx_costs (rtx x, int code, int o
>  /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost.  */
>
>  static bool
> -rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
> +rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
>                        bool speed)
>  {
> -  bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
> +  bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed);
>
>   fprintf (stderr,
>           "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
> -          "total = %d, speed = %s, x:\n",
> +          "opno = %d, total = %d, speed = %s, x:\n",
>           ret ? "complete" : "scan inner",
>           GET_RTX_NAME (code),
>           GET_RTX_NAME (outer_code),
> +          opno,
>           *total,
>           speed ? "true" : "false");
>
> Index: gcc/config/s390/s390.c
> ===================================================================
> --- gcc/config/s390/s390.c      2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/s390/s390.c      2011-08-15 15:23:01.595475353 +0100
> @@ -2374,8 +2374,8 @@ s390_memory_move_cost (enum machine_mode
>    of the superexpression of x.  */
>
>  static bool
> -s390_rtx_costs (rtx x, int code, int outer_code, int *total,
> -               bool speed ATTRIBUTE_UNUSED)
> +s390_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +               int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> @@ -2480,9 +2480,9 @@ s390_rtx_costs (rtx x, int code, int out
>       /* Negate in the third argument is free: FMSUB.  */
>       if (GET_CODE (XEXP (x, 2)) == NEG)
>        {
> -         *total += (rtx_cost (XEXP (x, 0), FMA, speed)
> -                    + rtx_cost (XEXP (x, 1), FMA, speed)
> -                    + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, speed));
> +         *total += (rtx_cost (XEXP (x, 0), FMA, 0, speed)
> +                    + rtx_cost (XEXP (x, 1), FMA, 1, speed)
> +                    + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, 2, speed));
>          return true;
>        }
>       return false;
> Index: gcc/config/score/score-protos.h
> ===================================================================
> --- gcc/config/score/score-protos.h     2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/score/score-protos.h     2011-08-15 15:23:01.599475347 +0100
> @@ -73,7 +73,8 @@ extern const char * score_select (rtx *o
>  extern const char * score_output_casesi (rtx *operands);
>  extern const char * score_rpush (rtx *ops);
>  extern const char * score_rpop (rtx *ops);
> -extern bool score_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed);
> +extern bool score_rtx_costs (rtx x, int code, int outer_code, int opno,
> +                            int *total, bool speed);
>
>  #ifdef RTX_CODE
>  extern enum machine_mode score_select_cc_mode (enum rtx_code op, rtx x, rtx y);
> Index: gcc/config/score/score.c
> ===================================================================
> --- gcc/config/score/score.c    2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/score/score.c    2011-08-15 15:27:35.663931901 +0100
> @@ -1074,7 +1074,8 @@ score_address_insns (rtx x, enum machine
>
>  /* Implement TARGET_RTX_COSTS macro.  */
>  bool
> -score_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed ATTRIBUTE_UNUSED)
> +score_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
>
> Index: gcc/config/sh/sh.c
> ===================================================================
> --- gcc/config/sh/sh.c  2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/sh/sh.c  2011-08-15 15:23:01.604475337 +0100
> @@ -247,7 +247,7 @@ static int addsubcosts (rtx);
>  static int multcosts (rtx);
>  static bool unspec_caller_rtx_p (rtx);
>  static bool sh_cannot_copy_insn_p (rtx);
> -static bool sh_rtx_costs (rtx, int, int, int *, bool);
> +static bool sh_rtx_costs (rtx, int, int, int, int *, bool);
>  static int sh_address_cost (rtx, bool);
>  static int sh_pr_n_sets (void);
>  static rtx sh_allocate_initial_value (rtx);
> @@ -2849,7 +2849,7 @@ andcosts (rtx x)
>          || satisfies_constraint_J16 (XEXP (x, 1)))
>        return 1;
>       else
> -       return 1 + rtx_cost (XEXP (x, 1), AND, !optimize_size);
> +       return 1 + rtx_cost (XEXP (x, 1), AND, 1, !optimize_size);
>     }
>
>   /* These constants are single cycle extu.[bw] instructions.  */
> @@ -2949,8 +2949,8 @@ multcosts (rtx x ATTRIBUTE_UNUSED)
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -sh_rtx_costs (rtx x, int code, int outer_code, int *total,
> -             bool speed ATTRIBUTE_UNUSED)
> +sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +             int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/sparc/sparc.c
> ===================================================================
> --- gcc/config/sparc/sparc.c    2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/sparc/sparc.c    2011-08-15 15:23:01.611475323 +0100
> @@ -428,7 +428,7 @@ static const char *get_some_local_dynami
>  static int get_some_local_dynamic_name_1 (rtx *, void *);
>  static int sparc_register_move_cost (enum machine_mode,
>                                     reg_class_t, reg_class_t);
> -static bool sparc_rtx_costs (rtx, int, int, int *, bool);
> +static bool sparc_rtx_costs (rtx, int, int, int, int *, bool);
>  static rtx sparc_function_value (const_tree, const_tree, bool);
>  static rtx sparc_libcall_value (enum machine_mode, const_rtx);
>  static bool sparc_function_value_regno_p (const unsigned int);
> @@ -9414,8 +9414,8 @@ sparc_fold_builtin (tree fndecl, int n_a
>    ??? the latencies and then CSE will just use that.  */
>
>  static bool
> -sparc_rtx_costs (rtx x, int code, int outer_code, int *total,
> -                bool speed ATTRIBUTE_UNUSED)
> +sparc_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
>   bool float_mode_p = FLOAT_MODE_P (mode);
> Index: gcc/config/spu/spu.c
> ===================================================================
> --- gcc/config/spu/spu.c        2011-08-15 15:22:59.479479498 +0100
> +++ gcc/config/spu/spu.c        2011-08-15 15:23:01.616475314 +0100
> @@ -203,7 +203,7 @@ static int mem_is_padded_component_ref (
>  static int reg_aligned_for_addr (rtx x);
>  static bool spu_assemble_integer (rtx x, unsigned int size, int aligned_p);
>  static void spu_asm_globalize_label (FILE * file, const char *name);
> -static bool spu_rtx_costs (rtx x, int code, int outer_code,
> +static bool spu_rtx_costs (rtx x, int code, int outer_code, int opno,
>                           int *total, bool speed);
>  static bool spu_function_ok_for_sibcall (tree decl, tree exp);
>  static void spu_init_libfuncs (void);
> @@ -5415,7 +5415,8 @@ spu_asm_globalize_label (FILE * file, co
>  }
>
>  static bool
> -spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
> +spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> +              int opno ATTRIBUTE_UNUSED, int *total,
>               bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
> Index: gcc/config/stormy16/stormy16.c
> ===================================================================
> --- gcc/config/stormy16/stormy16.c      2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/stormy16/stormy16.c      2011-08-15 15:23:01.620475305 +0100
> @@ -57,7 +57,7 @@ static void xstormy16_asm_output_mi_thun
>
>  static void xstormy16_init_builtins (void);
>  static rtx xstormy16_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
> -static bool xstormy16_rtx_costs (rtx, int, int, int *, bool);
> +static bool xstormy16_rtx_costs (rtx, int, int, int, int *, bool);
>  static int xstormy16_address_cost (rtx, bool);
>  static bool xstormy16_return_in_memory (const_tree, const_tree);
>
> @@ -69,7 +69,8 @@ static GTY(()) section *bss100_section;
>
>  static bool
>  xstormy16_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
> -                    int *total, bool speed ATTRIBUTE_UNUSED)
> +                    int opno ATTRIBUTE_UNUSED, int *total,
> +                    bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
> Index: gcc/config/v850/v850.c
> ===================================================================
> --- gcc/config/v850/v850.c      2011-08-15 15:22:59.482479492 +0100
> +++ gcc/config/v850/v850.c      2011-08-15 15:23:01.623475299 +0100
> @@ -310,6 +310,7 @@ const_costs (rtx r, enum rtx_code c)
>  v850_rtx_costs (rtx x,
>                 int codearg,
>                 int outer_code ATTRIBUTE_UNUSED,
> +               int opno ATTRIBUTE_UNUSED,
>                 int * total, bool speed)
>  {
>   enum rtx_code code = (enum rtx_code) codearg;
> Index: gcc/config/vax/vax.c
> ===================================================================
> --- gcc/config/vax/vax.c        2011-08-15 15:22:59.483479490 +0100
> +++ gcc/config/vax/vax.c        2011-08-15 15:23:01.624475297 +0100
> @@ -54,7 +54,7 @@ static void vax_output_mi_thunk (FILE *,
>                                 HOST_WIDE_INT, tree);
>  static int vax_address_cost_1 (rtx);
>  static int vax_address_cost (rtx, bool);
> -static bool vax_rtx_costs (rtx, int, int, int *, bool);
> +static bool vax_rtx_costs (rtx, int, int, int, int *, bool);
>  static rtx vax_function_arg (cumulative_args_t, enum machine_mode,
>                             const_tree, bool);
>  static void vax_function_arg_advance (cumulative_args_t, enum machine_mode,
> @@ -745,8 +745,8 @@ vax_address_cost (rtx x, bool speed ATTR
>    costs on a per cpu basis.  */
>
>  static bool
> -vax_rtx_costs (rtx x, int code, int outer_code, int *total,
> -              bool speed ATTRIBUTE_UNUSED)
> +vax_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +              int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   enum machine_mode mode = GET_MODE (x);
>   int i = 0;                              /* may be modified in switch */
> Index: gcc/config/xtensa/xtensa.c
> ===================================================================
> --- gcc/config/xtensa/xtensa.c  2011-08-15 15:22:59.480479496 +0100
> +++ gcc/config/xtensa/xtensa.c  2011-08-15 15:23:01.629475287 +0100
> @@ -136,7 +136,7 @@ static unsigned int xtensa_multibss_sect
>                                                        int) ATTRIBUTE_UNUSED;
>  static section *xtensa_select_rtx_section (enum machine_mode, rtx,
>                                           unsigned HOST_WIDE_INT);
> -static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
> +static bool xtensa_rtx_costs (rtx, int, int, int, int *, bool);
>  static int xtensa_register_move_cost (enum machine_mode, reg_class_t,
>                                      reg_class_t);
>  static int xtensa_memory_move_cost (enum machine_mode, reg_class_t, bool);
> @@ -3342,8 +3342,8 @@ xtensa_memory_move_cost (enum machine_mo
>    scanned.  In either case, *TOTAL contains the cost result.  */
>
>  static bool
> -xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
> -                 bool speed ATTRIBUTE_UNUSED)
> +xtensa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
> +                 int *total, bool speed ATTRIBUTE_UNUSED)
>  {
>   switch (code)
>     {
>
Richard Sandiford - Aug. 15, 2011, 3:34 p.m.
Richard Guenther <richard.guenther@gmail.com> writes:
> On Mon, Aug 15, 2011 at 5:15 PM, Richard Sandiford
> <richard.sandiford@linaro.org> wrote:
>> rtx_cost knows that the expression under test (X) is an operand to an
>> expression of a particular code (OUTER_CODE).  However, nothing says
>> which operand it actually is.  This can make a difference for
>> non-commutative binary operations.  E.g. shifts by 1 are often
>> cheaper than shifts of 1.
>>
>> The patch below makes this information available.  I'm planning on
>> using this parameter to provide costs of lvalues as well as rvalues,
>> but that's a separate patch.
>>
>> In the backend patches, I've avoided propagating the extra parameter
>> to subroutines unless it would be used.  I've also passed the original
>> operand number to recursive calls wherever the original code is passed
>> to recursive calls.  This includes expressions of the form:
>>
>>   rtx_cost (A, outer_code, speed_p) + rtx_cost (B, outer_code, speed_p)
>>
>> where A and B are subrtxes of X.  Since X is exactly one operand,
>> it seems odd to sum two costs with the same outer code like this,
>> but I left it be.
>>
>> I notice that score defines an rtx cost function but doesn't
>> actually use it.  Again, I've not fixed that here.
>>
>> avr.c:final_prescan_insn passes a SET rtx to rtx_cost (with an
>> outer code of INSN).  This is only used for debugging, so I passed
>> an arbitrary opno here.  (I didn't pass the opno of PATTERN because
>> that could easily change in future.)
>>
>> Tested on x86_64-linux-gnu.  Also tested by compiling cc1 for:
>>
>>        alpha-linux-gnu arm-linux-gnueabi avr-rtems bfin-elf cris-elf
>>        fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
>>        lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
>>        microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
>>        hppa64-hp-hpux11.23 pdp11 picochip-elf powerpc-linux-gnu
>>        powerpc-eabispe rx-elf s390-linux-gnu score-elf sh-linux-gnu
>>        sparc-linux-gnu spu-elf xstormy16-elf v850-elf vax-netbsdelf
>>        xtensa-elf
>>
>> and checking that (a) there were no new warnings and (b) that the
>> -O2 and -Os output for gcc.dg and gcc.c-torture didn't change.
>> OK to install?
>
> Can you add to the documentation that operands are counted from zero?

Sure.  How about:

  The cost may depend on the precise form of the expression, which is
  available for examination in @var{x}, and the fact that @var{x} appears
  as operand @var{opno} of an expression with rtx code @var{outer_code}.
  That is, the hook can assume that there is some rtx @var{y} such
  that @samp{GET_CODE (@var{y}) == @var{outer_code}) and such that
  either (a) @samp{XEXP (@var{y}, @var{opno}) == @var{x}} or
  (b) @samp{XVEC (@var{y}, @var{opno})} contains @var{x}.

  @var{code} is @var{x}'s expression code---redundant, since it can be
  obtained with @code{GET_CODE (@var{x})}.

> I suppose lvalues will be SET, 0 then, right?

I think it'd be easier to have negative opno mean "lvalue".  The problem
is that things like zero_extend can be used as either lvalues or rvalues,
so if you're taking the cost of the operand of a zero_extend, you need to
know more than the operand number itself (which is always 0).

But that's for another day...

> THe patch looks ok to me but please leave others (esp. target maintainers)
> time to comment.

Thanks.  I'll hold off till Thursday morning UK time.

Richard
Richard Guenther - Aug. 15, 2011, 3:38 p.m.
On Mon, Aug 15, 2011 at 5:34 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Richard Guenther <richard.guenther@gmail.com> writes:
>> On Mon, Aug 15, 2011 at 5:15 PM, Richard Sandiford
>> <richard.sandiford@linaro.org> wrote:
>>> rtx_cost knows that the expression under test (X) is an operand to an
>>> expression of a particular code (OUTER_CODE).  However, nothing says
>>> which operand it actually is.  This can make a difference for
>>> non-commutative binary operations.  E.g. shifts by 1 are often
>>> cheaper than shifts of 1.
>>>
>>> The patch below makes this information available.  I'm planning on
>>> using this parameter to provide costs of lvalues as well as rvalues,
>>> but that's a separate patch.
>>>
>>> In the backend patches, I've avoided propagating the extra parameter
>>> to subroutines unless it would be used.  I've also passed the original
>>> operand number to recursive calls wherever the original code is passed
>>> to recursive calls.  This includes expressions of the form:
>>>
>>>   rtx_cost (A, outer_code, speed_p) + rtx_cost (B, outer_code, speed_p)
>>>
>>> where A and B are subrtxes of X.  Since X is exactly one operand,
>>> it seems odd to sum two costs with the same outer code like this,
>>> but I left it be.
>>>
>>> I notice that score defines an rtx cost function but doesn't
>>> actually use it.  Again, I've not fixed that here.
>>>
>>> avr.c:final_prescan_insn passes a SET rtx to rtx_cost (with an
>>> outer code of INSN).  This is only used for debugging, so I passed
>>> an arbitrary opno here.  (I didn't pass the opno of PATTERN because
>>> that could easily change in future.)
>>>
>>> Tested on x86_64-linux-gnu.  Also tested by compiling cc1 for:
>>>
>>>        alpha-linux-gnu arm-linux-gnueabi avr-rtems bfin-elf cris-elf
>>>        fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
>>>        lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
>>>        microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
>>>        hppa64-hp-hpux11.23 pdp11 picochip-elf powerpc-linux-gnu
>>>        powerpc-eabispe rx-elf s390-linux-gnu score-elf sh-linux-gnu
>>>        sparc-linux-gnu spu-elf xstormy16-elf v850-elf vax-netbsdelf
>>>        xtensa-elf
>>>
>>> and checking that (a) there were no new warnings and (b) that the
>>> -O2 and -Os output for gcc.dg and gcc.c-torture didn't change.
>>> OK to install?
>>
>> Can you add to the documentation that operands are counted from zero?
>
> Sure.  How about:
>
>  The cost may depend on the precise form of the expression, which is
>  available for examination in @var{x}, and the fact that @var{x} appears
>  as operand @var{opno} of an expression with rtx code @var{outer_code}.
>  That is, the hook can assume that there is some rtx @var{y} such
>  that @samp{GET_CODE (@var{y}) == @var{outer_code}) and such that
>  either (a) @samp{XEXP (@var{y}, @var{opno}) == @var{x}} or
>  (b) @samp{XVEC (@var{y}, @var{opno})} contains @var{x}.
>
>  @var{code} is @var{x}'s expression code---redundant, since it can be
>  obtained with @code{GET_CODE (@var{x})}.

Yes, that looks good to me.

Thanks,
Richard.

Patch

Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	2011-08-15 15:22:59.485479486 +0100
+++ gcc/doc/tm.texi.in	2011-08-15 15:23:01.746475059 +0100
@@ -6357,9 +6357,9 @@  Define this macro if a non-short-circuit
 This target hook describes the relative costs of RTL expressions.
 
 The cost may depend on the precise form of the expression, which is
-available for examination in @var{x}, and the rtx code of the expression
-in which it is contained, found in @var{outer_code}.  @var{code} is the
-expression code---redundant, since it can be obtained with
+available for examination in @var{x}, and the fact that @var{x} appears
+as operand @var{opno} of an expression with rtx code @var{outer_code}.
+@var{code} is the expression code---redundant, since it can be obtained with
 @code{GET_CODE (@var{x})}.
 
 In implementing this hook, you can use the construct
Index: gcc/target.def
===================================================================
--- gcc/target.def	2011-08-15 15:22:59.478479500 +0100
+++ gcc/target.def	2011-08-15 15:24:31.311298899 +0100
@@ -1645,8 +1645,8 @@  DEFHOOKPOD
 DEFHOOK
 (rtx_costs,
  "",
- bool, (rtx x, int code, int outer_code, int *total, bool speed),
- hook_bool_rtx_int_int_intp_bool_false)
+ bool, (rtx x, int code, int outer_code, int opno, int *total, bool speed),
+ hook_bool_rtx_int_int_int_intp_bool_false)
 
 /* Compute the cost of X, used as an address.  Never called with
    invalid addresses.  */
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h	2011-05-03 08:45:55.000000000 +0100
+++ gcc/hooks.h	2011-08-15 15:26:34.079055149 +0100
@@ -53,7 +53,8 @@  extern bool hook_bool_const_tree_hwi_hwi
 extern bool hook_bool_rtx_false (rtx);
 extern bool hook_bool_rtx_int_false (rtx, int);
 extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
-extern bool hook_bool_rtx_int_int_intp_bool_false (rtx, int, int, int *, bool);
+extern bool hook_bool_rtx_int_int_int_intp_bool_false (rtx, int, int, int,
+						       int *, bool);
 extern bool hook_bool_tree_tree_false (tree, tree);
 extern bool hook_bool_tree_tree_true (tree, tree);
 extern bool hook_bool_tree_bool_false (tree, bool);
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c	2011-05-03 08:45:55.000000000 +0100
+++ gcc/hooks.c	2011-08-15 15:24:56.510249081 +0100
@@ -267,11 +267,12 @@  hook_bool_uintp_uintp_false (unsigned in
 }
 
 bool
-hook_bool_rtx_int_int_intp_bool_false (rtx a ATTRIBUTE_UNUSED,
-				       int b ATTRIBUTE_UNUSED,
-				       int c ATTRIBUTE_UNUSED,
-				       int *d ATTRIBUTE_UNUSED,
-				       bool speed_p ATTRIBUTE_UNUSED)
+hook_bool_rtx_int_int_int_intp_bool_false (rtx a ATTRIBUTE_UNUSED,
+					   int b ATTRIBUTE_UNUSED,
+					   int c ATTRIBUTE_UNUSED,
+					   int d ATTRIBUTE_UNUSED,
+					   int *e ATTRIBUTE_UNUSED,
+					   bool speed_p ATTRIBUTE_UNUSED)
 {
   return false;
 }
Index: gcc/cse.c
===================================================================
--- gcc/cse.c	2011-08-15 15:22:59.485479486 +0100
+++ gcc/cse.c	2011-08-15 15:23:01.633475279 +0100
@@ -475,8 +475,8 @@  #define CHEAP_REGNO(N)							\
    || (HARD_REGISTER_NUM_P (N)						\
        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
 
-#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET))
-#define COST_IN(X,OUTER) (REG_P (X) ? 0 : notreg_cost (X, OUTER))
+#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET, 1))
+#define COST_IN(X, OUTER, OPNO) (REG_P (X) ? 0 : notreg_cost (X, OUTER, OPNO))
 
 /* Get the number of times this register has been updated in this
    basic block.  */
@@ -552,7 +552,7 @@  struct cse_basic_block_data
 static sbitmap cse_visited_basic_blocks;
 
 static bool fixed_base_plus_p (rtx x);
-static int notreg_cost (rtx, enum rtx_code);
+static int notreg_cost (rtx, enum rtx_code, int);
 static int approx_reg_cost_1 (rtx *, void *);
 static int approx_reg_cost (rtx);
 static int preferable (int, int, int, int);
@@ -752,7 +752,7 @@  preferable (int cost_a, int regcost_a, i
    from COST macro to keep it simple.  */
 
 static int
-notreg_cost (rtx x, enum rtx_code outer)
+notreg_cost (rtx x, enum rtx_code outer, int opno)
 {
   return ((GET_CODE (x) == SUBREG
 	   && REG_P (SUBREG_REG (x))
@@ -764,7 +764,7 @@  notreg_cost (rtx x, enum rtx_code outer)
 	   && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (x),
 					     GET_MODE (SUBREG_REG (x))))
 	  ? 0
-	  : rtx_cost (x, outer, optimize_this_for_speed_p) * 2);
+	  : rtx_cost (x, outer, opno, optimize_this_for_speed_p) * 2);
 }
 
 
@@ -3296,7 +3296,7 @@  fold_rtx (rtx x, rtx insn)
 	   argument.  */
 	if (const_arg != 0
 	    && const_arg != folded_arg
-	    && COST_IN (const_arg, code) <= COST_IN (folded_arg, code)
+	    && COST_IN (const_arg, code, i) <= COST_IN (folded_arg, code, i)
 
 	    /* It's not safe to substitute the operand of a conversion
 	       operator with a constant, as the conversion's identity
Index: gcc/dojump.c
===================================================================
--- gcc/dojump.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/dojump.c	2011-08-15 15:23:01.753475045 +0100
@@ -144,6 +144,8 @@  static GTY(()) rtx shift_test;
 static bool
 prefer_and_bit_test (enum machine_mode mode, int bitnum)
 {
+  bool speed_p;
+
   if (and_test == 0)
     {
       /* Set up rtxes for the two variations.  Use NULL as a placeholder
@@ -168,8 +170,9 @@  prefer_and_bit_test (enum machine_mode m
 						 mode);
   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
 
-  return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
-	  <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
+  speed_p = optimize_insn_for_speed_p ();
+  return (rtx_cost (and_test, IF_THEN_ELSE, 0, speed_p)
+	  <= rtx_cost (shift_test, IF_THEN_ELSE, 0, speed_p));
 }
 
 /* Subroutine of do_jump, dealing with exploded comparisons of the type
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/expmed.c	2011-08-15 15:23:01.755475041 +0100
@@ -5431,7 +5431,7 @@  emit_store_flag (rtx target, enum rtx_co
 
 	  /* For the reverse comparison, use either an addition or a XOR.  */
           if (want_add
-	      && rtx_cost (GEN_INT (normalizep), PLUS,
+	      && rtx_cost (GEN_INT (normalizep), PLUS, 1,
 			   optimize_insn_for_speed_p ()) == 0)
 	    {
 	      tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
@@ -5442,7 +5442,7 @@  emit_store_flag (rtx target, enum rtx_co
 				     target, 0, OPTAB_WIDEN);
 	    }
           else if (!want_add
-	           && rtx_cost (trueval, XOR,
+	           && rtx_cost (trueval, XOR, 1,
 			        optimize_insn_for_speed_p ()) == 0)
 	    {
 	      tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
@@ -5535,7 +5535,7 @@  emit_store_flag (rtx target, enum rtx_co
 
       /* Again, for the reverse comparison, use either an addition or a XOR.  */
       if (want_add
-	  && rtx_cost (GEN_INT (normalizep), PLUS,
+	  && rtx_cost (GEN_INT (normalizep), PLUS, 1,
 		       optimize_insn_for_speed_p ()) == 0)
 	{
 	  tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
@@ -5545,7 +5545,7 @@  emit_store_flag (rtx target, enum rtx_co
 				GEN_INT (normalizep), target, 0, OPTAB_WIDEN);
 	}
       else if (!want_add
-	       && rtx_cost (trueval, XOR,
+	       && rtx_cost (trueval, XOR, 1,
 			    optimize_insn_for_speed_p ()) == 0)
 	{
 	  tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/optabs.c	2011-08-15 15:23:01.760475031 +0100
@@ -1204,21 +1204,21 @@  commutative_optab_p (optab binoptab)
 	  || binoptab == umul_highpart_optab);
 }
 
-/* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
+/* X is to be used in mode MODE as operand OPN to BINOPTAB.  If we're
    optimizing, and if the operand is a constant that costs more than
    1 instruction, force the constant into a register and return that
    register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
 
 static rtx
 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
-			  rtx x, bool unsignedp)
+			  int opn, rtx x, bool unsignedp)
 {
   bool speed = optimize_insn_for_speed_p ();
 
   if (mode != VOIDmode
       && optimize
       && CONSTANT_P (x)
-      && rtx_cost (x, binoptab->code, speed) > set_src_cost (x, speed))
+      && rtx_cost (x, binoptab->code, opn, speed) > set_src_cost (x, speed))
     {
       if (CONST_INT_P (x))
 	{
@@ -1265,9 +1265,9 @@  expand_binop_directly (enum machine_mode
     }
 
   /* If we are optimizing, force expensive constants into a register.  */
-  xop0 = avoid_expensive_constant (xmode0, binoptab, xop0, unsignedp);
+  xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
   if (!shift_optab_p (binoptab))
-    xop1 = avoid_expensive_constant (xmode1, binoptab, xop1, unsignedp);
+    xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
 
   /* In case the insn wants input operands in modes different from
      those of the actual operands, convert the operands.  It would
@@ -1479,10 +1479,10 @@  expand_binop (enum machine_mode mode, op
 		&& mclass == MODE_INT)
 	      {
 		no_extend = 1;
-		xop0 = avoid_expensive_constant (mode, binoptab,
+		xop0 = avoid_expensive_constant (mode, binoptab, 0,
 						 xop0, unsignedp);
 		if (binoptab != ashl_optab)
-		  xop1 = avoid_expensive_constant (mode, binoptab,
+		  xop1 = avoid_expensive_constant (mode, binoptab, 1,
 						   xop1, unsignedp);
 	      }
 
@@ -2216,8 +2216,8 @@  expand_twoval_binop (optab binoptab, rtx
       rtx xop0 = op0, xop1 = op1;
 
       /* If we are optimizing, force expensive constants into a register.  */
-      xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
-      xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
+      xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
+      xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
 
       create_fixed_operand (&ops[0], targ0);
       create_convert_operand_from (&ops[1], op0, mode, unsignedp);
@@ -3790,12 +3790,12 @@  prepare_cmp_insn (rtx x, rtx y, enum rtx
 
   /* If we are optimizing, force expensive constants into a register.  */
   if (CONSTANT_P (x) && optimize
-      && (rtx_cost (x, COMPARE, optimize_insn_for_speed_p ())
+      && (rtx_cost (x, COMPARE, 0, optimize_insn_for_speed_p ())
           > COSTS_N_INSNS (1)))
     x = force_reg (mode, x);
 
   if (CONSTANT_P (y) && optimize
-      && (rtx_cost (y, COMPARE, optimize_insn_for_speed_p ())
+      && (rtx_cost (y, COMPARE, 1, optimize_insn_for_speed_p ())
           > COSTS_N_INSNS (1)))
     y = force_reg (mode, y);
 
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2011-08-15 15:22:59.477479502 +0100
+++ gcc/rtl.h	2011-08-15 15:23:01.765475021 +0100
@@ -1196,9 +1196,10 @@  costs_add_n_insns (struct full_rtx_costs
 }
 
 extern void init_rtlanal (void);
-extern int rtx_cost (rtx, enum rtx_code, bool);
+extern int rtx_cost (rtx, enum rtx_code, int, bool);
 extern int address_cost (rtx, enum machine_mode, addr_space_t, bool);
-extern void get_full_rtx_cost (rtx, enum rtx_code, struct full_rtx_costs *);
+extern void get_full_rtx_cost (rtx, enum rtx_code, int,
+			       struct full_rtx_costs *);
 extern unsigned int subreg_lsb (const_rtx);
 extern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode,
 				  unsigned int);
@@ -1225,7 +1226,7 @@  extern int low_bitmask_len (enum machine
 static inline int
 set_src_cost (rtx x, bool speed_p)
 {
-  return rtx_cost (x, SET, speed_p);
+  return rtx_cost (x, SET, 1, speed_p);
 }
 
 /* Like set_src_cost, but return both the speed and size costs in C.  */
@@ -1233,7 +1234,7 @@  set_src_cost (rtx x, bool speed_p)
 static inline void
 get_full_set_src_cost (rtx x, struct full_rtx_costs *c)
 {
-  get_full_rtx_cost (x, SET, c);
+  get_full_rtx_cost (x, SET, 1, c);
 }
 #endif
 
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/rtlanal.c	2011-08-15 15:23:01.768475015 +0100
@@ -3674,11 +3674,12 @@  label_is_jump_target_p (const_rtx label,
    Another is in rtl generation, to pick the cheapest way to multiply.
    Other uses like the latter are expected in the future.
 
-   SPEED parameter specify whether costs optimized for speed or size should
+   X appears as operand OPNO in an expression with code OUTER_CODE.
+   SPEED specifies whether costs optimized for speed or size should
    be returned.  */
 
 int
-rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED, bool speed)
+rtx_cost (rtx x, enum rtx_code outer_code, int opno, bool speed)
 {
   int i, j;
   enum rtx_code code;
@@ -3726,7 +3727,7 @@  rtx_cost (rtx x, enum rtx_code outer_cod
       break;
 
     default:
-      if (targetm.rtx_costs (x, code, outer_code, &total, speed))
+      if (targetm.rtx_costs (x, code, outer_code, opno, &total, speed))
 	return total;
       break;
     }
@@ -3737,22 +3738,23 @@  rtx_cost (rtx x, enum rtx_code outer_cod
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     if (fmt[i] == 'e')
-      total += rtx_cost (XEXP (x, i), code, speed);
+      total += rtx_cost (XEXP (x, i), code, i, speed);
     else if (fmt[i] == 'E')
       for (j = 0; j < XVECLEN (x, i); j++)
-	total += rtx_cost (XVECEXP (x, i, j), code, speed);
+	total += rtx_cost (XVECEXP (x, i, j), code, i, speed);
 
   return total;
 }
 
 /* Fill in the structure C with information about both speed and size rtx
-   costs for X, with outer code OUTER.  */
+   costs for X, which is operand OPNO in an expression with code OUTER.  */
 
 void
-get_full_rtx_cost (rtx x, enum rtx_code outer, struct full_rtx_costs *c)
+get_full_rtx_cost (rtx x, enum rtx_code outer, int opno,
+		   struct full_rtx_costs *c)
 {
-  c->speed = rtx_cost (x, outer, true);
-  c->size = rtx_cost (x, outer, false);
+  c->speed = rtx_cost (x, outer, opno, true);
+  c->size = rtx_cost (x, outer, opno, false);
 }
 
 
@@ -3780,7 +3782,7 @@  address_cost (rtx x, enum machine_mode m
 int
 default_address_cost (rtx x, bool speed)
 {
-  return rtx_cost (x, MEM, speed);
+  return rtx_cost (x, MEM, 0, speed);
 }
 
 
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/alpha/alpha.c	2011-08-15 15:23:01.456475626 +0100
@@ -1154,7 +1154,7 @@  alpha_legitimize_reload_address (rtx x,
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-alpha_rtx_costs (rtx x, int code, int outer_code, int *total,
+alpha_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
 		 bool speed)
 {
   enum machine_mode mode = GET_MODE (x);
@@ -1222,9 +1222,9 @@  alpha_rtx_costs (rtx x, int code, int ou
 	       && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
 	{
 	  *total = (rtx_cost (XEXP (XEXP (x, 0), 0),
-			      (enum rtx_code) outer_code, speed)
+			      (enum rtx_code) outer_code, opno, speed)
 		    + rtx_cost (XEXP (x, 1),
-				(enum rtx_code) outer_code, speed)
+				(enum rtx_code) outer_code, opno, speed)
 		    + COSTS_N_INSNS (1));
 	  return true;
 	}
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	2011-08-15 15:22:59.480479496 +0100
+++ gcc/config/avr/avr.c	2011-08-15 15:23:01.459475620 +0100
@@ -89,8 +89,9 @@  static void avr_asm_out_ctor (rtx, int);
 static void avr_asm_out_dtor (rtx, int);
 static int avr_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
 static int avr_memory_move_cost (enum machine_mode, reg_class_t, bool);
-static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code, bool);
-static bool avr_rtx_costs (rtx, int, int, int *, bool);
+static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
+				 int, bool);
+static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
 static int avr_address_cost (rtx, bool);
 static bool avr_return_in_memory (const_tree, const_tree);
 static struct machine_function * avr_init_machine_status (void);
@@ -1640,7 +1641,8 @@  final_prescan_insn (rtx insn, rtx *opera
                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
       else
         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
-                 rtx_cost (PATTERN (insn), INSN, optimize_insn_for_speed_p()));
+                 rtx_cost (PATTERN (insn), INSN, 0,
+			   optimize_insn_for_speed_p()));
     }
 }
 
@@ -5300,7 +5302,7 @@  avr_memory_move_cost (enum machine_mode 
 
 static int
 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
-		      bool speed)
+		      int opno, bool speed)
 {
   enum rtx_code code = GET_CODE (x);
   int total;
@@ -5320,7 +5322,7 @@  avr_operand_rtx_cost (rtx x, enum machin
     }
 
   total = 0;
-  avr_rtx_costs (x, code, outer, &total, speed);
+  avr_rtx_costs (x, code, outer, opno, &total, speed);
   return total;
 }
 
@@ -5330,8 +5332,8 @@  avr_operand_rtx_cost (rtx x, enum machin
    case, *TOTAL contains the cost result.  */
 
 static bool
-avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
-	       bool speed)
+avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
+	       int opno ATTRIBUTE_UNUSED, int *total, bool speed)
 {
   enum rtx_code code = (enum rtx_code) codearg;
   enum machine_mode mode = GET_MODE (x);
@@ -5371,7 +5373,7 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case ABS:
@@ -5385,24 +5387,24 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case NOT:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case ZERO_EXTEND:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case SIGN_EXTEND:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case PLUS:
@@ -5411,14 +5413,15 @@  avr_rtx_costs (rtx x, int codearg, int o
 	case QImode:
 	  *total = COSTS_N_INSNS (1);
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
 	  break;
 
 	case HImode:
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (2);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
 	    *total = COSTS_N_INSNS (1);
@@ -5430,7 +5433,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (4);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
 	    *total = COSTS_N_INSNS (1);
@@ -5441,22 +5445,22 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case MINUS:
     case AND:
     case IOR:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-          *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
 
     case XOR:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
-      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
 
     case MULT:
@@ -5546,8 +5550,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
-      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
 
     case DIV:
@@ -5558,8 +5562,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
       else
 	return false;
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
-      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
 
     case ROTATE:
@@ -5594,7 +5598,7 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;    
 
     case ASHIFT:
@@ -5604,7 +5608,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    {
@@ -5633,7 +5638,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5670,7 +5676,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
@@ -5678,7 +5685,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5702,14 +5710,15 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case ASHIFTRT:
@@ -5719,7 +5728,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    {
@@ -5739,7 +5749,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5775,7 +5786,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
@@ -5783,7 +5795,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5807,14 +5820,15 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case LSHIFTRT:
@@ -5824,7 +5838,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    {
@@ -5842,7 +5857,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5881,7 +5897,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
-	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
@@ -5889,7 +5906,8 @@  avr_rtx_costs (rtx x, int codearg, int o
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    {
 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
-	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+					      speed);
 	    }
 	  else
 	    switch (INTVAL (XEXP (x, 1)))
@@ -5913,14 +5931,15 @@  avr_rtx_costs (rtx x, int codearg, int o
 		break;
 	      default:
 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
+						speed);
 	      }
 	  break;
 
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case COMPARE:
@@ -5929,13 +5948,13 @@  avr_rtx_costs (rtx x, int codearg, int o
 	case QImode:
 	  *total = COSTS_N_INSNS (1);
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
 	  break;
 
         case HImode:
 	  *total = COSTS_N_INSNS (2);
 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
 	  else if (INTVAL (XEXP (x, 1)) != 0)
 	    *total += COSTS_N_INSNS (1);
           break;
@@ -5943,7 +5962,7 @@  avr_rtx_costs (rtx x, int codearg, int o
         case SImode:
           *total = COSTS_N_INSNS (4);
           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
-            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
+            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
 	  else if (INTVAL (XEXP (x, 1)) != 0)
 	    *total += COSTS_N_INSNS (3);
           break;
@@ -5951,7 +5970,7 @@  avr_rtx_costs (rtx x, int codearg, int o
 	default:
 	  return false;
 	}
-      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
+      *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case TRUNCATE:
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/config/bfin/bfin.c	2011-08-15 15:23:01.464475610 +0100
@@ -2779,7 +2779,8 @@  bfin_legitimate_constant_p (enum machine
 }
 
 static bool
-bfin_rtx_costs (rtx x, int code_i, int outer_code_i, int *total, bool speed)
+bfin_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total,
+		bool speed)
 {
   enum rtx_code code = (enum rtx_code) code_i;
   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
@@ -2829,8 +2830,8 @@  bfin_rtx_costs (rtx x, int code_i, int o
 	      if (val == 2 || val == 4)
 		{
 		  *total = cost2;
-		  *total += rtx_cost (XEXP (op0, 0), outer_code, speed);
-		  *total += rtx_cost (op1, outer_code, speed);
+		  *total += rtx_cost (XEXP (op0, 0), outer_code, opno, speed);
+		  *total += rtx_cost (op1, outer_code, opno, speed);
 		  return true;
 		}
 	    }
@@ -2849,10 +2850,10 @@  bfin_rtx_costs (rtx x, int code_i, int o
 	  *total = 6 * cost2;
 	  if (GET_CODE (op1) != CONST_INT
 	      || !satisfies_constraint_Ks7 (op1))
-	    *total += rtx_cost (op1, PLUS, speed);
+	    *total += rtx_cost (op1, PLUS, 1, speed);
 	  if (GET_CODE (op0) != REG
 	      && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
-	    *total += rtx_cost (op0, PLUS, speed);
+	    *total += rtx_cost (op0, PLUS, 0, speed);
 	}
       return true;
 
@@ -2875,7 +2876,7 @@  bfin_rtx_costs (rtx x, int code_i, int o
       op1 = XEXP (x, 1);
       if (GET_CODE (op0) != REG
 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
-	*total += rtx_cost (op0, code, speed);
+	*total += rtx_cost (op0, code, 0, speed);
 
       return true;
 	  
@@ -2900,7 +2901,7 @@  bfin_rtx_costs (rtx x, int code_i, int o
 
       if (GET_CODE (op0) != REG
 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
-	*total += rtx_cost (op0, code, speed);
+	*total += rtx_cost (op0, code, 0, speed);
 
       if (GET_MODE (x) == DImode)
 	{
@@ -2914,12 +2915,12 @@  bfin_rtx_costs (rtx x, int code_i, int o
       if (code == AND)
 	{
 	  if (! rhs_andsi3_operand (XEXP (x, 1), SImode))
-	    *total += rtx_cost (XEXP (x, 1), code, speed);
+	    *total += rtx_cost (XEXP (x, 1), code, 1, speed);
 	}
       else
 	{
 	  if (! regorlog2_operand (XEXP (x, 1), SImode))
-	    *total += rtx_cost (XEXP (x, 1), code, speed);
+	    *total += rtx_cost (XEXP (x, 1), code, 1, speed);
 	}
 
       return true;
@@ -2959,10 +2960,10 @@  bfin_rtx_costs (rtx x, int code_i, int o
 
 	  if (GET_CODE (op0) != REG
 	      && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
-	    *total += rtx_cost (op0, MULT, speed);
+	    *total += rtx_cost (op0, MULT, 0, speed);
 	  if (GET_CODE (op1) != REG
 	      && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
-	    *total += rtx_cost (op1, MULT, speed);
+	    *total += rtx_cost (op1, MULT, 1, speed);
 	}
       return true;
 
Index: gcc/config/c6x/c6x.c
===================================================================
--- gcc/config/c6x/c6x.c	2011-08-15 15:22:59.481479494 +0100
+++ gcc/config/c6x/c6x.c	2011-08-15 15:23:01.467475604 +0100
@@ -4772,7 +4772,8 @@  shift_p (rtx x, enum rtx_code code, int 
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-c6x_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+c6x_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
+	       bool speed)
 {
   int cost2 = COSTS_N_INSNS (1);
   rtx op0, op1;
@@ -4826,8 +4827,8 @@  c6x_rtx_costs (rtx x, int code, int oute
 		*total = COSTS_N_INSNS (2);
 	      else
 		*total = COSTS_N_INSNS (12);
-	      *total += rtx_cost (XEXP (op0, 0), code0, speed);
-	      *total += rtx_cost (XEXP (op1, 0), code1, speed);
+	      *total += rtx_cost (XEXP (op0, 0), code0, 0, speed);
+	      *total += rtx_cost (XEXP (op1, 0), code1, 0, speed);
 	      return true;
 	    }
 	}
@@ -4855,8 +4856,8 @@  c6x_rtx_costs (rtx x, int code, int oute
 	      || INTVAL (XEXP (op0, 1)) == 4
 	      || (code == PLUS && INTVAL (XEXP (op0, 1)) == 8)))
 	{
-	  *total += rtx_cost (XEXP (op0, 0), ASHIFT, speed);
-	  *total += rtx_cost (op1, (enum rtx_code)code, speed);
+	  *total += rtx_cost (XEXP (op0, 0), ASHIFT, 0, speed);
+	  *total += rtx_cost (op1, (enum rtx_code) code, 1, speed);
 	  return true;
 	}
       return false;
@@ -4926,10 +4927,10 @@  c6x_rtx_costs (rtx x, int code, int oute
 
       if (GET_CODE (op0) != REG
 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
-	*total += rtx_cost (op0, MULT, speed);
+	*total += rtx_cost (op0, MULT, 0, speed);
       if (op1 && GET_CODE (op1) != REG
 	  && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
-	*total += rtx_cost (op1, MULT, speed);
+	*total += rtx_cost (op1, MULT, 1, speed);
       return true;
 
     case UDIV:
@@ -4947,7 +4948,8 @@  c6x_rtx_costs (rtx x, int code, int oute
 	  && XEXP (op0, 1) == const0_rtx
 	  && rtx_equal_p (XEXP (x, 1), XEXP (op0, 0)))
 	{
-	  *total = rtx_cost (XEXP (x, 1), (enum rtx_code)outer_code, speed);
+	  *total = rtx_cost (XEXP (x, 1), (enum rtx_code) outer_code,
+			     opno, speed);
 	  return false;
 	}
       return false;
Index: gcc/config/cris/cris.c
===================================================================
--- gcc/config/cris/cris.c	2011-08-15 15:22:59.478479500 +0100
+++ gcc/config/cris/cris.c	2011-08-15 15:23:01.471475596 +0100
@@ -123,7 +123,7 @@  static void cris_init_libfuncs (void);
 
 static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
 static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool);
-static bool cris_rtx_costs (rtx, int, int, int *, bool);
+static bool cris_rtx_costs (rtx, int, int, int, int *, bool);
 static int cris_address_cost (rtx, bool);
 static bool cris_pass_by_reference (cumulative_args_t, enum machine_mode,
 				    const_tree, bool);
@@ -1777,7 +1777,7 @@  cris_expand_return (bool on_stack)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-cris_rtx_costs (rtx x, int code, int outer_code, int *total,
+cris_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
 		bool speed)
 {
   switch (code)
@@ -1871,7 +1871,8 @@  cris_rtx_costs (rtx x, int code, int out
           && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
 	{
 	  *total
-	    = (rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed) + 2
+	    = (rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code,
+			 opno, speed) + 2
 	       + 2 * GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))));
 	  return true;
 	}
@@ -1883,7 +1884,7 @@  cris_rtx_costs (rtx x, int code, int out
       /* fall through */
 
     case ZERO_EXTEND: case SIGN_EXTEND:
-      *total = rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed);
+      *total = rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, opno, speed);
       return true;
 
     default:
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/config/frv/frv.c	2011-08-15 15:23:01.477475585 +0100
@@ -364,7 +364,8 @@  static void frv_setup_incoming_varargs		
 						 tree, int *, int);
 static rtx frv_expand_builtin_saveregs		(void);
 static void frv_expand_builtin_va_start		(tree, rtx);
-static bool frv_rtx_costs			(rtx, int, int, int*, bool);
+static bool frv_rtx_costs			(rtx, int, int, int, int*,
+						 bool);
 static int frv_register_move_cost		(enum machine_mode,
 						 reg_class_t, reg_class_t);
 static int frv_memory_move_cost			(enum machine_mode,
@@ -9496,6 +9497,7 @@  frv_in_small_data_p (const_tree decl)
 frv_rtx_costs (rtx x,
                int code ATTRIBUTE_UNUSED,
                int outer_code ATTRIBUTE_UNUSED,
+	       int opno ATTRIBUTE_UNUSED,
                int *total,
 	       bool speed ATTRIBUTE_UNUSED)
 {
Index: gcc/config/h8300/h8300.c
===================================================================
--- gcc/config/h8300/h8300.c	2011-08-15 15:22:59.478479500 +0100
+++ gcc/config/h8300/h8300.c	2011-08-15 15:23:01.484475572 +0100
@@ -1174,7 +1174,8 @@  h8300_shift_costs (rtx x)
 /* Worker function for TARGET_RTX_COSTS.  */
 
 static bool
-h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		 int *total, bool speed)
 {
   if (TARGET_H8300SX && outer_code == MEM)
     {
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2011-08-15 15:22:59.480479496 +0100
+++ gcc/config/i386/i386.c	2011-08-15 15:23:01.501475538 +0100
@@ -28825,7 +28825,8 @@  ix86_modes_tieable_p (enum machine_mode 
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-ix86_rtx_costs (rtx x, int code, int outer_code_i, int *total, bool speed)
+ix86_rtx_costs (rtx x, int code, int outer_code_i, int opno, int *total,
+		bool speed)
 {
   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   enum machine_mode mode = GET_MODE (x);
@@ -28949,18 +28950,18 @@  ix86_rtx_costs (rtx x, int code, int out
         /* ??? SSE scalar/vector cost should be used here.  */
         /* ??? Bald assumption that fma has the same cost as fmul.  */
         *total = cost->fmul;
-	*total += rtx_cost (XEXP (x, 1), FMA, speed);
+	*total += rtx_cost (XEXP (x, 1), FMA, 1, speed);
 
         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
 	sub = XEXP (x, 0);
 	if (GET_CODE (sub) == NEG)
 	  sub = XEXP (sub, 0);
-	*total += rtx_cost (sub, FMA, speed);
+	*total += rtx_cost (sub, FMA, 0, speed);
 
 	sub = XEXP (x, 2);
 	if (GET_CODE (sub) == NEG)
 	  sub = XEXP (sub, 0);
-	*total += rtx_cost (sub, FMA, speed);
+	*total += rtx_cost (sub, FMA, 2, speed);
 	return true;
       }
 
@@ -29022,7 +29023,8 @@  ix86_rtx_costs (rtx x, int code, int out
 
   	  *total = (cost->mult_init[MODE_INDEX (mode)]
 		    + nbits * cost->mult_bit
-	            + rtx_cost (op0, outer_code, speed) + rtx_cost (op1, outer_code, speed));
+	            + rtx_cost (op0, outer_code, opno, speed)
+		    + rtx_cost (op1, outer_code, opno, speed));
 
           return true;
 	}
@@ -29056,10 +29058,11 @@  ix86_rtx_costs (rtx x, int code, int out
 	      if (val == 2 || val == 4 || val == 8)
 		{
 		  *total = cost->lea;
-		  *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code, speed);
+		  *total += rtx_cost (XEXP (XEXP (x, 0), 1),
+				      outer_code, opno, speed);
 		  *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
-				      outer_code, speed);
-		  *total += rtx_cost (XEXP (x, 1), outer_code, speed);
+				      outer_code, opno, speed);
+		  *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
 		  return true;
 		}
 	    }
@@ -29070,17 +29073,20 @@  ix86_rtx_costs (rtx x, int code, int out
 	      if (val == 2 || val == 4 || val == 8)
 		{
 		  *total = cost->lea;
-		  *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed);
-		  *total += rtx_cost (XEXP (x, 1), outer_code, speed);
+		  *total += rtx_cost (XEXP (XEXP (x, 0), 0),
+				      outer_code, opno, speed);
+		  *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
 		  return true;
 		}
 	    }
 	  else if (GET_CODE (XEXP (x, 0)) == PLUS)
 	    {
 	      *total = cost->lea;
-	      *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed);
-	      *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code, speed);
-	      *total += rtx_cost (XEXP (x, 1), outer_code, speed);
+	      *total += rtx_cost (XEXP (XEXP (x, 0), 0),
+				  outer_code, opno, speed);
+	      *total += rtx_cost (XEXP (XEXP (x, 0), 1),
+				  outer_code, opno, speed);
+	      *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
 	      return true;
 	    }
 	}
@@ -29112,9 +29118,9 @@  ix86_rtx_costs (rtx x, int code, int out
       if (!TARGET_64BIT && mode == DImode)
 	{
 	  *total = (cost->add * 2
-		    + (rtx_cost (XEXP (x, 0), outer_code, speed)
+		    + (rtx_cost (XEXP (x, 0), outer_code, opno, speed)
 		       << (GET_MODE (XEXP (x, 0)) != DImode))
-		    + (rtx_cost (XEXP (x, 1), outer_code, speed)
+		    + (rtx_cost (XEXP (x, 1), outer_code, opno, speed)
 	               << (GET_MODE (XEXP (x, 1)) != DImode)));
 	  return true;
 	}
@@ -29156,8 +29162,8 @@  ix86_rtx_costs (rtx x, int code, int out
 	  /* This kind of construct is implemented using test[bwl].
 	     Treat it as if we had an AND.  */
 	  *total = (cost->add
-		    + rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed)
-		    + rtx_cost (const1_rtx, outer_code, speed));
+		    + rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, opno, speed)
+		    + rtx_cost (const1_rtx, outer_code, opno, speed));
 	  return true;
 	}
       return false;
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	2011-08-15 15:22:59.481479494 +0100
+++ gcc/config/ia64/ia64.c	2011-08-15 15:23:01.517475507 +0100
@@ -217,7 +217,7 @@  static int ia64_register_move_cost (enum
                                     reg_class_t);
 static int ia64_memory_move_cost (enum machine_mode mode, reg_class_t,
 				  bool);
-static bool ia64_rtx_costs (rtx, int, int, int *, bool);
+static bool ia64_rtx_costs (rtx, int, int, int, int *, bool);
 static int ia64_unspec_may_trap_p (const_rtx, unsigned);
 static void fix_range (const char *);
 static struct machine_function * ia64_init_machine_status (void);
@@ -5244,8 +5244,8 @@  ia64_print_operand (FILE * file, rtx x, 
 /* ??? This is incomplete.  */
 
 static bool
-ia64_rtx_costs (rtx x, int code, int outer_code, int *total,
-		bool speed ATTRIBUTE_UNUSED)
+ia64_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/iq2000/iq2000.c	2011-08-15 15:23:01.522475498 +0100
@@ -151,7 +151,7 @@  static bool iq2000_return_in_memory   (c
 static void iq2000_setup_incoming_varargs (cumulative_args_t,
 					   enum machine_mode, tree, int *,
 					   int);
-static bool iq2000_rtx_costs          (rtx, int, int, int *, bool);
+static bool iq2000_rtx_costs          (rtx, int, int, int, int *, bool);
 static int  iq2000_address_cost       (rtx, bool);
 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
 static rtx  iq2000_legitimize_address (rtx, rtx, enum machine_mode);
@@ -3285,7 +3285,8 @@  iq2000_legitimize_address (rtx xinsn, rt
 
 
 static bool
-iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
+iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+		  int opno ATTRIBUTE_UNUSED, int * total,
 		  bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
Index: gcc/config/lm32/lm32.c
===================================================================
--- gcc/config/lm32/lm32.c	2011-08-15 15:22:59.480479496 +0100
+++ gcc/config/lm32/lm32.c	2011-08-15 15:23:01.526475489 +0100
@@ -68,8 +68,8 @@  static bool lm32_in_small_data_p (const_
 static void lm32_setup_incoming_varargs (cumulative_args_t cum,
 					 enum machine_mode mode, tree type,
 					 int *pretend_size, int no_rtl);
-static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total,
-			    bool speed);
+static bool lm32_rtx_costs (rtx x, int code, int outer_code, int opno,
+			    int *total, bool speed);
 static bool lm32_can_eliminate (const int, const int);
 static bool
 lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
@@ -928,7 +928,8 @@  nonpic_symbol_mentioned_p (rtx x)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-lm32_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+lm32_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed)
 {
   enum machine_mode mode = GET_MODE (x);
   bool small_mode;
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	2011-08-15 15:22:59.481479494 +0100
+++ gcc/config/m32c/m32c.c	2011-08-15 15:23:01.528475485 +0100
@@ -2421,8 +2421,8 @@  m32c_memory_move_cost (enum machine_mode
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS m32c_rtx_costs
 static bool
-m32c_rtx_costs (rtx x, int code, int outer_code, int *total,
-		bool speed ATTRIBUTE_UNUSED)
+m32c_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/m32r/m32r.c
===================================================================
--- gcc/config/m32r/m32r.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/m32r/m32r.c	2011-08-15 15:23:01.531475479 +0100
@@ -84,7 +84,7 @@  static bool m32r_function_value_regno_p 
 static void m32r_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
 					 tree, int *, int);
 static void init_idents (void);
-static bool m32r_rtx_costs (rtx, int, int, int *, bool speed);
+static bool m32r_rtx_costs (rtx, int, int, int, int *, bool speed);
 static int m32r_memory_move_cost (enum machine_mode, reg_class_t, bool);
 static bool m32r_pass_by_reference (cumulative_args_t, enum machine_mode,
 				    const_tree, bool);
@@ -1356,7 +1356,8 @@  m32r_memory_move_cost (enum machine_mode
 }
 
 static bool
-m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
+m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+		int opno ATTRIBUTE_UNUSED, int *total,
 		bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	2011-08-15 15:22:59.481479494 +0100
+++ gcc/config/m68k/m68k.c	2011-08-15 15:23:01.535475471 +0100
@@ -150,7 +150,7 @@  static bool m68k_save_reg (unsigned int 
 static bool m68k_ok_for_sibcall_p (tree, tree);
 static bool m68k_tls_symbol_p (rtx);
 static rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
-static bool m68k_rtx_costs (rtx, int, int, int *, bool);
+static bool m68k_rtx_costs (rtx, int, int, int, int *, bool);
 #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
 static bool m68k_return_in_memory (const_tree, const_tree);
 #endif
@@ -2765,8 +2765,8 @@  const_int_cost (HOST_WIDE_INT i)
 }
 
 static bool
-m68k_rtx_costs (rtx x, int code, int outer_code, int *total,
-		bool speed ATTRIBUTE_UNUSED)
+m68k_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/mcore/mcore.c	2011-08-15 15:23:01.538475465 +0100
@@ -121,7 +121,8 @@  static const char *mcore_strip_name_enco
 static int        mcore_const_costs            	(rtx, RTX_CODE);
 static int        mcore_and_cost               	(rtx);
 static int        mcore_ior_cost               	(rtx);
-static bool       mcore_rtx_costs		(rtx, int, int, int *, bool);
+static bool       mcore_rtx_costs		(rtx, int, int, int,
+						 int *, bool);
 static void       mcore_external_libcall	(rtx);
 static bool       mcore_return_in_memory	(const_tree, const_tree);
 static int        mcore_arg_partial_bytes       (cumulative_args_t,
@@ -508,8 +509,8 @@  mcore_ior_cost (rtx x)
 }
 
 static bool
-mcore_rtx_costs (rtx x, int code, int outer_code, int * total,
-		 bool speed ATTRIBUTE_UNUSED)
+mcore_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		 int * total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/mep/mep.c
===================================================================
--- gcc/config/mep/mep.c	2011-08-15 15:22:59.478479500 +0100
+++ gcc/config/mep/mep.c	2011-08-15 15:23:01.541475459 +0100
@@ -211,7 +211,7 @@  static void mep_move_ready_insn (rtx *, 
 static int mep_sched_reorder (FILE *, int, rtx *, int *, int);
 static rtx mep_make_bundle (rtx, rtx);
 static void mep_bundle_insns (rtx);
-static bool mep_rtx_cost (rtx, int, int, int *, bool);
+static bool mep_rtx_cost (rtx, int, int, int, int *, bool);
 static int mep_address_cost (rtx, bool);
 static void mep_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
 					tree, int *, int);
@@ -7261,7 +7261,9 @@  mep_expand_binary_intrinsic (int ATTRIBU
 }
 
 static bool
-mep_rtx_cost (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total, bool ATTRIBUTE_UNUSED speed_t)
+mep_rtx_cost (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+	      int opno ATTRIBUTE_UNUSED, int *total,
+	      bool ATTRIBUTE_UNUSED speed_t)
 {
   switch (code)
     {
Index: gcc/config/microblaze/microblaze.c
===================================================================
--- gcc/config/microblaze/microblaze.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/microblaze/microblaze.c	2011-08-15 15:23:01.545475451 +0100
@@ -861,7 +861,8 @@  microblaze_expand_block_move (rtx dest, 
 }
 
 static bool
-microblaze_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total, 
+microblaze_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+		      int opno ATTRIBUTE_UNUSED, int *total,
 		      bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/mips/mips.c	2011-08-15 15:23:01.550475442 +0100
@@ -3334,7 +3334,7 @@  mips_binary_cost (rtx x, int single_cost
     cost = single_cost;
   return (cost
 	  + set_src_cost (XEXP (x, 0), speed)
-	  + rtx_cost (XEXP (x, 1), GET_CODE (x), speed));
+	  + rtx_cost (XEXP (x, 1), GET_CODE (x), 1, speed));
 }
 
 /* Return the cost of floating-point multiplications of mode MODE.  */
@@ -3404,7 +3404,8 @@  mips_zero_extend_cost (enum machine_mode
 /* Implement TARGET_RTX_COSTS.  */
 
 static bool
-mips_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed)
 {
   enum machine_mode mode = GET_MODE (x);
   bool float_mode_p = FLOAT_MODE_P (mode);
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/mmix/mmix.c	2011-08-15 15:23:01.557475429 +0100
@@ -140,7 +140,7 @@  static void mmix_reorg (void);
   (cumulative_args_t, enum machine_mode, tree, int *, int);
 static void mmix_file_start (void);
 static void mmix_file_end (void);
-static bool mmix_rtx_costs (rtx, int, int, int *, bool);
+static bool mmix_rtx_costs (rtx, int, int, int, int *, bool);
 static int mmix_register_move_cost (enum machine_mode,
 				    reg_class_t, reg_class_t);
 static rtx mmix_struct_value_rtx (tree, int);
@@ -1229,6 +1229,7 @@  mmix_reversible_cc_mode (enum machine_mo
 mmix_rtx_costs (rtx x ATTRIBUTE_UNUSED,
 		int code ATTRIBUTE_UNUSED,
 		int outer_code ATTRIBUTE_UNUSED,
+		int opno ATTRIBUTE_UNUSED,
 		int *total ATTRIBUTE_UNUSED,
 		bool speed ATTRIBUTE_UNUSED)
 {
Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/mn10300/mn10300.c	2011-08-15 15:23:01.560475423 +0100
@@ -2182,7 +2182,7 @@  mn10300_address_cost (rtx x, bool speed)
       return speed ? 2 : 6;
 
     default:
-      return rtx_cost (x, MEM, speed);
+      return rtx_cost (x, MEM, 0, speed);
     }
 }
 
@@ -2296,7 +2296,8 @@  mn10300_memory_move_cost (enum machine_m
    to represent cycles.  Size-relative costs are in bytes.  */
 
 static bool
-mn10300_rtx_costs (rtx x, int code, int outer_code, int *ptotal, bool speed)
+mn10300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		   int *ptotal, bool speed)
 {
   /* This value is used for SYMBOL_REF etc where we want to pretend
      we have a full 32-bit constant.  */
@@ -2387,7 +2388,7 @@  mn10300_rtx_costs (rtx x, int code, int 
 	  i = INTVAL (XEXP (x, 1));
 	  if (i == 1 || i == 4)
 	    {
-	      total = 1 + rtx_cost (XEXP (x, 0), PLUS, speed);
+	      total = 1 + rtx_cost (XEXP (x, 0), PLUS, 0, speed);
 	      goto alldone;
 	    }
 	}
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	2011-08-15 15:22:59.484479488 +0100
+++ gcc/config/pa/pa.c	2011-08-15 15:23:01.565475413 +0100
@@ -92,7 +92,7 @@  static void fix_range (const char *);
 static int hppa_register_move_cost (enum machine_mode mode, reg_class_t,
 				    reg_class_t);
 static int hppa_address_cost (rtx, bool);
-static bool hppa_rtx_costs (rtx, int, int, int *, bool);
+static bool hppa_rtx_costs (rtx, int, int, int, int *, bool);
 static inline rtx force_mode (enum machine_mode, rtx);
 static void pa_reorg (void);
 static void pa_combine_instructions (void);
@@ -1411,8 +1411,8 @@  hppa_address_cost (rtx X,
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-hppa_rtx_costs (rtx x, int code, int outer_code, int *total,
-		bool speed ATTRIBUTE_UNUSED)
+hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	2011-08-15 15:22:59.481479494 +0100
+++ gcc/config/pdp11/pdp11.c	2011-08-15 15:23:01.569475405 +0100
@@ -141,7 +141,7 @@  decode_pdp11_d (const struct real_format
 
 static const char *singlemove_string (rtx *);
 static bool pdp11_assemble_integer (rtx, unsigned int, int);
-static bool pdp11_rtx_costs (rtx, int, int, int *, bool);
+static bool pdp11_rtx_costs (rtx, int, int, int, int *, bool);
 static bool pdp11_return_in_memory (const_tree, const_tree);
 static rtx pdp11_function_value (const_tree, const_tree, bool);
 static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
@@ -888,7 +888,8 @@  pdp11_register_move_cost (enum machine_m
 }
 
 static bool
-pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
+pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+		 int opno ATTRIBUTE_UNUSED, int *total,
 		 bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
Index: gcc/config/picochip/picochip.c
===================================================================
--- gcc/config/picochip/picochip.c	2011-08-15 15:22:59.478479500 +0100
+++ gcc/config/picochip/picochip.c	2011-08-15 15:23:01.573475397 +0100
@@ -101,7 +101,8 @@  int picochip_sched_reorder (FILE * file,
 void picochip_init_builtins (void);
 rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 
-bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed);
+bool picochip_rtx_costs (rtx x, int code, int outer_code, int opno,
+			 int* total, bool speed);
 bool picochip_return_in_memory(const_tree type,
                               const_tree fntype ATTRIBUTE_UNUSED);
 bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
@@ -3741,7 +3742,8 @@  gen_SImode_mem(rtx opnd1,rtx opnd2)
 }
 
 bool
-picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed)
+picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+		    int opno ATTRIBUTE_UNUSED, int* total, bool speed)
 {
 
   int localTotal = 0;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/rs6000/rs6000.c	2011-08-15 15:23:01.583475377 +0100
@@ -948,8 +948,8 @@  static int rs6000_variable_issue (FILE *
 static int rs6000_register_move_cost (enum machine_mode,
 				      reg_class_t, reg_class_t);
 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
-static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
-static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
+static bool rs6000_rtx_costs (rtx, int, int, int, int *, bool);
+static bool rs6000_debug_rtx_costs (rtx, int, int, int, int *, bool);
 static int rs6000_debug_address_cost (rtx, bool);
 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
@@ -25730,8 +25730,8 @@  rs6000_xcoff_file_end (void)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
-		  bool speed)
+rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		  int *total, bool speed)
 {
   enum machine_mode mode = GET_MODE (x);
 
@@ -26074,17 +26074,18 @@  rs6000_rtx_costs (rtx x, int code, int o
 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost.  */
 
 static bool
-rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
+rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total,
 			bool speed)
 {
-  bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
+  bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed);
 
   fprintf (stderr,
 	   "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
-	   "total = %d, speed = %s, x:\n",
+	   "opno = %d, total = %d, speed = %s, x:\n",
 	   ret ? "complete" : "scan inner",
 	   GET_RTX_NAME (code),
 	   GET_RTX_NAME (outer_code),
+	   opno,
 	   *total,
 	   speed ? "true" : "false");
 
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/s390/s390.c	2011-08-15 15:23:01.595475353 +0100
@@ -2374,8 +2374,8 @@  s390_memory_move_cost (enum machine_mode
    of the superexpression of x.  */
 
 static bool
-s390_rtx_costs (rtx x, int code, int outer_code, int *total,
-		bool speed ATTRIBUTE_UNUSED)
+s390_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
@@ -2480,9 +2480,9 @@  s390_rtx_costs (rtx x, int code, int out
       /* Negate in the third argument is free: FMSUB.  */
       if (GET_CODE (XEXP (x, 2)) == NEG)
 	{
-	  *total += (rtx_cost (XEXP (x, 0), FMA, speed)
-		     + rtx_cost (XEXP (x, 1), FMA, speed)
-		     + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, speed));
+	  *total += (rtx_cost (XEXP (x, 0), FMA, 0, speed)
+		     + rtx_cost (XEXP (x, 1), FMA, 1, speed)
+		     + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, 2, speed));
 	  return true;
 	}
       return false;
Index: gcc/config/score/score-protos.h
===================================================================
--- gcc/config/score/score-protos.h	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/score/score-protos.h	2011-08-15 15:23:01.599475347 +0100
@@ -73,7 +73,8 @@  extern const char * score_select (rtx *o
 extern const char * score_output_casesi (rtx *operands);
 extern const char * score_rpush (rtx *ops);
 extern const char * score_rpop (rtx *ops);
-extern bool score_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed);
+extern bool score_rtx_costs (rtx x, int code, int outer_code, int opno,
+			     int *total, bool speed);
 
 #ifdef RTX_CODE
 extern enum machine_mode score_select_cc_mode (enum rtx_code op, rtx x, rtx y);
Index: gcc/config/score/score.c
===================================================================
--- gcc/config/score/score.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/score/score.c	2011-08-15 15:27:35.663931901 +0100
@@ -1074,7 +1074,8 @@  score_address_insns (rtx x, enum machine
 
 /* Implement TARGET_RTX_COSTS macro.  */
 bool
-score_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed ATTRIBUTE_UNUSED)
+score_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		 int *total, bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
 
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/sh/sh.c	2011-08-15 15:23:01.604475337 +0100
@@ -247,7 +247,7 @@  static int addsubcosts (rtx);
 static int multcosts (rtx);
 static bool unspec_caller_rtx_p (rtx);
 static bool sh_cannot_copy_insn_p (rtx);
-static bool sh_rtx_costs (rtx, int, int, int *, bool);
+static bool sh_rtx_costs (rtx, int, int, int, int *, bool);
 static int sh_address_cost (rtx, bool);
 static int sh_pr_n_sets (void);
 static rtx sh_allocate_initial_value (rtx);
@@ -2849,7 +2849,7 @@  andcosts (rtx x)
 	  || satisfies_constraint_J16 (XEXP (x, 1)))
 	return 1;
       else
-	return 1 + rtx_cost (XEXP (x, 1), AND, !optimize_size);
+	return 1 + rtx_cost (XEXP (x, 1), AND, 1, !optimize_size);
     }
 
   /* These constants are single cycle extu.[bw] instructions.  */
@@ -2949,8 +2949,8 @@  multcosts (rtx x ATTRIBUTE_UNUSED)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-sh_rtx_costs (rtx x, int code, int outer_code, int *total,
-	      bool speed ATTRIBUTE_UNUSED)
+sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+	      int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/sparc/sparc.c	2011-08-15 15:23:01.611475323 +0100
@@ -428,7 +428,7 @@  static const char *get_some_local_dynami
 static int get_some_local_dynamic_name_1 (rtx *, void *);
 static int sparc_register_move_cost (enum machine_mode,
 				     reg_class_t, reg_class_t);
-static bool sparc_rtx_costs (rtx, int, int, int *, bool);
+static bool sparc_rtx_costs (rtx, int, int, int, int *, bool);
 static rtx sparc_function_value (const_tree, const_tree, bool);
 static rtx sparc_libcall_value (enum machine_mode, const_rtx);
 static bool sparc_function_value_regno_p (const unsigned int);
@@ -9414,8 +9414,8 @@  sparc_fold_builtin (tree fndecl, int n_a
    ??? the latencies and then CSE will just use that.  */
 
 static bool
-sparc_rtx_costs (rtx x, int code, int outer_code, int *total,
-		 bool speed ATTRIBUTE_UNUSED)
+sparc_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		 int *total, bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
   bool float_mode_p = FLOAT_MODE_P (mode);
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	2011-08-15 15:22:59.479479498 +0100
+++ gcc/config/spu/spu.c	2011-08-15 15:23:01.616475314 +0100
@@ -203,7 +203,7 @@  static int mem_is_padded_component_ref (
 static int reg_aligned_for_addr (rtx x);
 static bool spu_assemble_integer (rtx x, unsigned int size, int aligned_p);
 static void spu_asm_globalize_label (FILE * file, const char *name);
-static bool spu_rtx_costs (rtx x, int code, int outer_code,
+static bool spu_rtx_costs (rtx x, int code, int outer_code, int opno,
 			   int *total, bool speed);
 static bool spu_function_ok_for_sibcall (tree decl, tree exp);
 static void spu_init_libfuncs (void);
@@ -5415,7 +5415,8 @@  spu_asm_globalize_label (FILE * file, co
 }
 
 static bool
-spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
+spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+	       int opno ATTRIBUTE_UNUSED, int *total,
 	       bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/stormy16/stormy16.c	2011-08-15 15:23:01.620475305 +0100
@@ -57,7 +57,7 @@  static void xstormy16_asm_output_mi_thun
 
 static void xstormy16_init_builtins (void);
 static rtx xstormy16_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-static bool xstormy16_rtx_costs (rtx, int, int, int *, bool);
+static bool xstormy16_rtx_costs (rtx, int, int, int, int *, bool);
 static int xstormy16_address_cost (rtx, bool);
 static bool xstormy16_return_in_memory (const_tree, const_tree);
 
@@ -69,7 +69,8 @@  static GTY(()) section *bss100_section;
 
 static bool
 xstormy16_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
-		     int *total, bool speed ATTRIBUTE_UNUSED)
+		     int opno ATTRIBUTE_UNUSED, int *total,
+		     bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
Index: gcc/config/v850/v850.c
===================================================================
--- gcc/config/v850/v850.c	2011-08-15 15:22:59.482479492 +0100
+++ gcc/config/v850/v850.c	2011-08-15 15:23:01.623475299 +0100
@@ -310,6 +310,7 @@  const_costs (rtx r, enum rtx_code c)
 v850_rtx_costs (rtx x,
                 int codearg,
                 int outer_code ATTRIBUTE_UNUSED,
+		int opno ATTRIBUTE_UNUSED,
                 int * total, bool speed)
 {
   enum rtx_code code = (enum rtx_code) codearg;
Index: gcc/config/vax/vax.c
===================================================================
--- gcc/config/vax/vax.c	2011-08-15 15:22:59.483479490 +0100
+++ gcc/config/vax/vax.c	2011-08-15 15:23:01.624475297 +0100
@@ -54,7 +54,7 @@  static void vax_output_mi_thunk (FILE *,
 				 HOST_WIDE_INT, tree);
 static int vax_address_cost_1 (rtx);
 static int vax_address_cost (rtx, bool);
-static bool vax_rtx_costs (rtx, int, int, int *, bool);
+static bool vax_rtx_costs (rtx, int, int, int, int *, bool);
 static rtx vax_function_arg (cumulative_args_t, enum machine_mode,
 			     const_tree, bool);
 static void vax_function_arg_advance (cumulative_args_t, enum machine_mode,
@@ -745,8 +745,8 @@  vax_address_cost (rtx x, bool speed ATTR
    costs on a per cpu basis.  */
 
 static bool
-vax_rtx_costs (rtx x, int code, int outer_code, int *total,
-	       bool speed ATTRIBUTE_UNUSED)
+vax_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+	       int *total, bool speed ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode = GET_MODE (x);
   int i = 0;				   /* may be modified in switch */
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	2011-08-15 15:22:59.480479496 +0100
+++ gcc/config/xtensa/xtensa.c	2011-08-15 15:23:01.629475287 +0100
@@ -136,7 +136,7 @@  static unsigned int xtensa_multibss_sect
 							int) ATTRIBUTE_UNUSED;
 static section *xtensa_select_rtx_section (enum machine_mode, rtx,
 					   unsigned HOST_WIDE_INT);
-static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
+static bool xtensa_rtx_costs (rtx, int, int, int, int *, bool);
 static int xtensa_register_move_cost (enum machine_mode, reg_class_t,
 				      reg_class_t);
 static int xtensa_memory_move_cost (enum machine_mode, reg_class_t, bool);
@@ -3342,8 +3342,8 @@  xtensa_memory_move_cost (enum machine_mo
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
-		  bool speed ATTRIBUTE_UNUSED)
+xtensa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+		  int *total, bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {