OSDN Git Service

Implement interleave via permutation.
[pf3gnuchains/gcc-fork.git] / gcc / expmed.c
index 8349b6f..b3e6d6d 100644 (file)
@@ -47,9 +47,15 @@ struct target_expmed *this_target_expmed = &default_target_expmed;
 
 static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
                                   unsigned HOST_WIDE_INT,
-                                  unsigned HOST_WIDE_INT, rtx);
+                                  unsigned HOST_WIDE_INT,
+                                  unsigned HOST_WIDE_INT,
+                                  unsigned HOST_WIDE_INT,
+                                  rtx);
 static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
-                                  unsigned HOST_WIDE_INT, rtx);
+                                  unsigned HOST_WIDE_INT,
+                                  unsigned HOST_WIDE_INT,
+                                  unsigned HOST_WIDE_INT,
+                                  rtx);
 static rtx extract_fixed_bit_field (enum machine_mode, rtx,
                                    unsigned HOST_WIDE_INT,
                                    unsigned HOST_WIDE_INT,
@@ -190,7 +196,7 @@ init_expmed (void)
   for (speed = 0; speed < 2; speed++)
     {
       crtl->maybe_hot_insn_p = speed;
-      zero_cost[speed] = rtx_cost (const0_rtx, SET, speed);
+      zero_cost[speed] = set_src_cost (const0_rtx, speed);
 
       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
           mode != VOIDmode;
@@ -211,15 +217,15 @@ init_expmed (void)
          PUT_MODE (&all.shift_sub0, mode);
          PUT_MODE (&all.shift_sub1, mode);
 
-         add_cost[speed][mode] = rtx_cost (&all.plus, SET, speed);
-         neg_cost[speed][mode] = rtx_cost (&all.neg, SET, speed);
-         mul_cost[speed][mode] = rtx_cost (&all.mult, SET, speed);
-         sdiv_cost[speed][mode] = rtx_cost (&all.sdiv, SET, speed);
-         udiv_cost[speed][mode] = rtx_cost (&all.udiv, SET, speed);
+         add_cost[speed][mode] = set_src_cost (&all.plus, speed);
+         neg_cost[speed][mode] = set_src_cost (&all.neg, speed);
+         mul_cost[speed][mode] = set_src_cost (&all.mult, speed);
+         sdiv_cost[speed][mode] = set_src_cost (&all.sdiv, speed);
+         udiv_cost[speed][mode] = set_src_cost (&all.udiv, speed);
 
-         sdiv_pow2_cheap[speed][mode] = (rtx_cost (&all.sdiv_32, SET, speed)
+         sdiv_pow2_cheap[speed][mode] = (set_src_cost (&all.sdiv_32, speed)
                                          <= 2 * add_cost[speed][mode]);
-         smod_pow2_cheap[speed][mode] = (rtx_cost (&all.smod_32, SET, speed)
+         smod_pow2_cheap[speed][mode] = (set_src_cost (&all.smod_32, speed)
                                          <= 4 * add_cost[speed][mode]);
 
          wider_mode = GET_MODE_WIDER_MODE (mode);
@@ -231,9 +237,9 @@ init_expmed (void)
              XEXP (&all.wide_lshr, 1) = GEN_INT (GET_MODE_BITSIZE (mode));
 
              mul_widen_cost[speed][wider_mode]
-               = rtx_cost (&all.wide_mult, SET, speed);
+               = set_src_cost (&all.wide_mult, speed);
              mul_highpart_cost[speed][mode]
-               = rtx_cost (&all.wide_trunc, SET, speed);
+               = set_src_cost (&all.wide_trunc, speed);
            }
 
          shift_cost[speed][mode][0] = 0;
@@ -246,10 +252,13 @@ init_expmed (void)
              XEXP (&all.shift, 1) = cint[m];
              XEXP (&all.shift_mult, 1) = pow2[m];
 
-             shift_cost[speed][mode][m] = rtx_cost (&all.shift, SET, speed);
-             shiftadd_cost[speed][mode][m] = rtx_cost (&all.shift_add, SET, speed);
-             shiftsub0_cost[speed][mode][m] = rtx_cost (&all.shift_sub0, SET, speed);
-             shiftsub1_cost[speed][mode][m] = rtx_cost (&all.shift_sub1, SET, speed);
+             shift_cost[speed][mode][m] = set_src_cost (&all.shift, speed);
+             shiftadd_cost[speed][mode][m] = set_src_cost (&all.shift_add,
+                                                           speed);
+             shiftsub0_cost[speed][mode][m] = set_src_cost (&all.shift_sub0,
+                                                            speed);
+             shiftsub1_cost[speed][mode][m] = set_src_cost (&all.shift_sub1,
+                                                            speed);
            }
        }
     }
@@ -333,7 +342,10 @@ mode_for_extraction (enum extraction_pattern pattern, int opno)
 
 static bool
 store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
-                  unsigned HOST_WIDE_INT bitnum, enum machine_mode fieldmode,
+                  unsigned HOST_WIDE_INT bitnum,
+                  unsigned HOST_WIDE_INT bitregion_start,
+                  unsigned HOST_WIDE_INT bitregion_end,
+                  enum machine_mode fieldmode,
                   rtx value, bool fallback_p)
 {
   unsigned int unit
@@ -455,6 +467,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 
   /* We may be accessing data outside the field, which means
      we can alias adjacent data.  */
+  /* ?? not always for C++0x memory model ?? */
   if (MEM_P (op0))
     {
       op0 = shallow_copy_rtx (op0);
@@ -547,7 +560,9 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 
          if (!store_bit_field_1 (op0, MIN (BITS_PER_WORD,
                                            bitsize - i * BITS_PER_WORD),
-                                 bitnum + bit_offset, word_mode,
+                                 bitnum + bit_offset,
+                                 bitregion_start, bitregion_end,
+                                 word_mode,
                                  value_word, fallback_p))
            {
              delete_insns_since (last);
@@ -605,6 +620,10 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       && GET_MODE (value) != BLKmode
       && bitsize > 0
       && GET_MODE_BITSIZE (op_mode) >= bitsize
+      /* Do not use insv for volatile bitfields when
+         -fstrict-volatile-bitfields is in effect.  */
+      && !(MEM_P (op0) && MEM_VOLATILE_P (op0)
+          && flag_strict_volatile_bitfields > 0)
       && ! ((REG_P (op0) || GET_CODE (op0) == SUBREG)
            && (bitsize + bitpos > GET_MODE_BITSIZE (op_mode))))
     {
@@ -644,19 +663,21 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
          copy_back = true;
        }
 
-      /* On big-endian machines, we count bits from the most significant.
-        If the bit field insn does not, we must invert.  */
-
-      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
-       xbitpos = unit - bitsize - xbitpos;
-
       /* We have been counting XBITPOS within UNIT.
         Count instead within the size of the register.  */
-      if (BITS_BIG_ENDIAN && !MEM_P (xop0))
+      if (BYTES_BIG_ENDIAN && !MEM_P (xop0))
        xbitpos += GET_MODE_BITSIZE (op_mode) - unit;
 
       unit = GET_MODE_BITSIZE (op_mode);
 
+      /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count
+         "backwards" from the size of the unit we are inserting into.
+        Otherwise, we count bits from the most significant on a
+        BYTES/BITS_BIG_ENDIAN machine.  */
+
+      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
+       xbitpos = unit - bitsize - xbitpos;
+
       /* Convert VALUE to op_mode (which insv insn wants) in VALUE1.  */
       value1 = value;
       if (GET_MODE (value) != op_mode)
@@ -710,6 +731,10 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
   if (HAVE_insv && MEM_P (op0))
     {
       enum machine_mode bestmode;
+      unsigned HOST_WIDE_INT maxbits = MAX_FIXED_MODE_SIZE;
+
+      if (bitregion_end)
+       maxbits = bitregion_end - bitregion_start + 1;
 
       /* Get the mode to use for inserting into this field.  If OP0 is
         BLKmode, get the smallest mode consistent with the alignment. If
@@ -717,9 +742,12 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
         mode. Otherwise, use the smallest mode containing the field.  */
 
       if (GET_MODE (op0) == BLKmode
+         || GET_MODE_BITSIZE (GET_MODE (op0)) > maxbits
          || (op_mode != MAX_MACHINE_MODE
              && GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (op_mode)))
-       bestmode = get_best_mode (bitsize, bitnum, MEM_ALIGN (op0),
+       bestmode = get_best_mode  (bitsize, bitnum,
+                                 bitregion_start, bitregion_end,
+                                 MEM_ALIGN (op0),
                                  (op_mode == MAX_MACHINE_MODE
                                   ? VOIDmode : op_mode),
                                  MEM_VOLATILE_P (op0));
@@ -748,6 +776,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
             the unit.  */
          tempreg = copy_to_reg (xop0);
          if (store_bit_field_1 (tempreg, bitsize, xbitpos,
+                                bitregion_start, bitregion_end,
                                 fieldmode, orig_value, false))
            {
              emit_move_insn (xop0, tempreg);
@@ -760,21 +789,59 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
   if (!fallback_p)
     return false;
 
-  store_fixed_bit_field (op0, offset, bitsize, bitpos, value);
+  store_fixed_bit_field (op0, offset, bitsize, bitpos,
+                        bitregion_start, bitregion_end, value);
   return true;
 }
 
 /* Generate code to store value from rtx VALUE
    into a bit-field within structure STR_RTX
    containing BITSIZE bits starting at bit BITNUM.
+
+   BITREGION_START is bitpos of the first bitfield in this region.
+   BITREGION_END is the bitpos of the ending bitfield in this region.
+   These two fields are 0, if the C++ memory model does not apply,
+   or we are not interested in keeping track of bitfield regions.
+
    FIELDMODE is the machine-mode of the FIELD_DECL node for this field.  */
 
 void
 store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
-                unsigned HOST_WIDE_INT bitnum, enum machine_mode fieldmode,
+                unsigned HOST_WIDE_INT bitnum,
+                unsigned HOST_WIDE_INT bitregion_start,
+                unsigned HOST_WIDE_INT bitregion_end,
+                enum machine_mode fieldmode,
                 rtx value)
 {
-  if (!store_bit_field_1 (str_rtx, bitsize, bitnum, fieldmode, value, true))
+  /* Under the C++0x memory model, we must not touch bits outside the
+     bit region.  Adjust the address to start at the beginning of the
+     bit region.  */
+  if (MEM_P (str_rtx)
+      && bitregion_start > 0)
+    {
+      enum machine_mode bestmode;
+      enum machine_mode op_mode;
+      unsigned HOST_WIDE_INT offset;
+
+      op_mode = mode_for_extraction (EP_insv, 3);
+      if (op_mode == MAX_MACHINE_MODE)
+       op_mode = VOIDmode;
+
+      offset = bitregion_start / BITS_PER_UNIT;
+      bitnum -= bitregion_start;
+      bitregion_end -= bitregion_start;
+      bitregion_start = 0;
+      bestmode = get_best_mode (bitsize, bitnum,
+                               bitregion_start, bitregion_end,
+                               MEM_ALIGN (str_rtx),
+                               op_mode,
+                               MEM_VOLATILE_P (str_rtx));
+      str_rtx = adjust_address (str_rtx, bestmode, offset);
+    }
+
+  if (!store_bit_field_1 (str_rtx, bitsize, bitnum,
+                         bitregion_start, bitregion_end,
+                         fieldmode, value, true))
     gcc_unreachable ();
 }
 \f
@@ -790,7 +857,10 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 static void
 store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
                       unsigned HOST_WIDE_INT bitsize,
-                      unsigned HOST_WIDE_INT bitpos, rtx value)
+                      unsigned HOST_WIDE_INT bitpos,
+                      unsigned HOST_WIDE_INT bitregion_start,
+                      unsigned HOST_WIDE_INT bitregion_end,
+                      rtx value)
 {
   enum machine_mode mode;
   unsigned int total_bits = BITS_PER_WORD;
@@ -811,12 +881,19 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
       /* Special treatment for a bit field split across two registers.  */
       if (bitsize + bitpos > BITS_PER_WORD)
        {
-         store_split_bit_field (op0, bitsize, bitpos, value);
+         store_split_bit_field (op0, bitsize, bitpos,
+                                bitregion_start, bitregion_end,
+                                value);
          return;
        }
     }
   else
     {
+      unsigned HOST_WIDE_INT maxbits = MAX_FIXED_MODE_SIZE;
+
+      if (bitregion_end)
+       maxbits = bitregion_end - bitregion_start + 1;
+
       /* Get the proper mode to use for this field.  We want a mode that
         includes the entire field.  If such a mode would be larger than
         a word, we won't be doing the extraction the normal way.
@@ -829,10 +906,12 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
 
       if (MEM_VOLATILE_P (op0)
           && GET_MODE_BITSIZE (GET_MODE (op0)) > 0
+         && GET_MODE_BITSIZE (GET_MODE (op0)) <= maxbits
          && flag_strict_volatile_bitfields > 0)
        mode = GET_MODE (op0);
       else
        mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
+                             bitregion_start, bitregion_end,
                              MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
 
       if (mode == VOIDmode)
@@ -840,7 +919,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
          /* The only way this should occur is if the field spans word
             boundaries.  */
          store_split_bit_field (op0, bitsize, bitpos + offset * BITS_PER_UNIT,
-                                value);
+                                bitregion_start, bitregion_end, value);
          return;
        }
 
@@ -960,7 +1039,10 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
 
 static void
 store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
-                      unsigned HOST_WIDE_INT bitpos, rtx value)
+                      unsigned HOST_WIDE_INT bitpos,
+                      unsigned HOST_WIDE_INT bitregion_start,
+                      unsigned HOST_WIDE_INT bitregion_end,
+                      rtx value)
 {
   unsigned int unit;
   unsigned int bitsdone = 0;
@@ -1075,7 +1157,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
         it is just an out-of-bounds access.  Ignore it.  */
       if (word != const0_rtx)
        store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT, thissize,
-                              thispos, part);
+                              thispos, bitregion_start, bitregion_end, part);
       bitsdone += thissize;
     }
 }
@@ -1431,6 +1513,10 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
   if (ext_mode != MAX_MACHINE_MODE
       && bitsize > 0
       && GET_MODE_BITSIZE (ext_mode) >= bitsize
+      /* Do not use extv/extzv for volatile bitfields when
+         -fstrict-volatile-bitfields is in effect.  */
+      && !(MEM_P (op0) && MEM_VOLATILE_P (op0)
+          && flag_strict_volatile_bitfields > 0)
       /* If op0 is a register, we need it in EXT_MODE to make it
         acceptable to the format of ext(z)v.  */
       && !(GET_CODE (op0) == SUBREG && GET_MODE (op0) != ext_mode)
@@ -1452,17 +1538,20 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
        /* Get ref to first byte containing part of the field.  */
        xop0 = adjust_address (xop0, byte_mode, xoffset);
 
-      /* On big-endian machines, we count bits from the most significant.
-        If the bit field insn does not, we must invert.  */
-      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
-       xbitpos = unit - bitsize - xbitpos;
-
       /* Now convert from counting within UNIT to counting in EXT_MODE.  */
-      if (BITS_BIG_ENDIAN && !MEM_P (xop0))
+      if (BYTES_BIG_ENDIAN && !MEM_P (xop0))
        xbitpos += GET_MODE_BITSIZE (ext_mode) - unit;
 
       unit = GET_MODE_BITSIZE (ext_mode);
 
+      /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count
+         "backwards" from the size of the unit we are extracting from.
+        Otherwise, we count bits from the most significant on a
+        BYTES/BITS_BIG_ENDIAN machine.  */
+
+      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
+       xbitpos = unit - bitsize - xbitpos;
+
       if (xtarget == 0)
        xtarget = xspec_target = gen_reg_rtx (tmode);
 
@@ -1515,7 +1604,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       if (GET_MODE (op0) == BLKmode
          || (ext_mode != MAX_MACHINE_MODE
              && GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (ext_mode)))
-       bestmode = get_best_mode (bitsize, bitnum, MEM_ALIGN (op0),
+       bestmode = get_best_mode (bitsize, bitnum, 0, 0, MEM_ALIGN (op0),
                                  (ext_mode == MAX_MACHINE_MODE
                                   ? VOIDmode : ext_mode),
                                  MEM_VOLATILE_P (op0));
@@ -1641,7 +1730,7 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
            mode = tmode;
        }
       else
-       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
+       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, 0, 0,
                              MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0));
 
       if (mode == VOIDmode)
@@ -2090,7 +2179,7 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
   if (code == LSHIFT_EXPR
       && CONST_INT_P (op1)
       && INTVAL (op1) > 0
-      && INTVAL (op1) < GET_MODE_BITSIZE (mode)
+      && INTVAL (op1) < GET_MODE_PRECISION (mode)
       && INTVAL (op1) < MAX_BITS_PER_WORD
       && shift_cost[speed][mode][INTVAL (op1)] > INTVAL (op1) * add_cost[speed][mode]
       && shift_cost[speed][mode][INTVAL (op1)] != MAX_COST)
@@ -2146,7 +2235,7 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
              else
                other_amount
                  = simplify_gen_binary (MINUS, GET_MODE (op1),
-                                        GEN_INT (GET_MODE_BITSIZE (mode)),
+                                        GEN_INT (GET_MODE_PRECISION (mode)),
                                         op1);
 
              shifted = force_reg (mode, shifted);
@@ -3004,8 +3093,9 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
                 result is interpreted as an unsigned coefficient.
                 Exclude cost of op0 from max_cost to match the cost
                 calculation of the synth_mult.  */
-             max_cost = rtx_cost (gen_rtx_MULT (mode, fake_reg, op1), SET, speed)
-                        - neg_cost[speed][mode];
+             max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1),
+                                       speed)
+                         - neg_cost[speed][mode]);
              if (max_cost > 0
                  && choose_mult_variant (mode, -INTVAL (op1), &algorithm,
                                          &variant, max_cost))
@@ -3048,7 +3138,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
 
          /* Exclude cost of op0 from max_cost to match the cost
             calculation of the synth_mult.  */
-         max_cost = rtx_cost (gen_rtx_MULT (mode, fake_reg, op1), SET, speed);
+         max_cost = set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), speed);
          if (choose_mult_variant (mode, coeff, &algorithm, &variant,
                                   max_cost))
            return expand_mult_const (mode, op0, coeff, target,
@@ -3112,7 +3202,7 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
                                this_optab == umul_widen_optab))
       && CONST_INT_P (cop1)
       && (INTVAL (cop1) >= 0
-         || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
+         || HWI_COMPUTABLE_MODE_P (mode)))
     {
       HOST_WIDE_INT coeff = INTVAL (cop1);
       int max_cost;
@@ -3377,7 +3467,7 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
 
   /* Try widening multiplication.  */
   moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
-  if (optab_handler (moptab, wider_mode) != CODE_FOR_nothing
+  if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
       && mul_widen_cost[speed][wider_mode] < max_cost)
     {
       tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
@@ -3414,7 +3504,7 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
 
   /* Try widening multiplication of opposite signedness, and adjust.  */
   moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
-  if (optab_handler (moptab, wider_mode) != CODE_FOR_nothing
+  if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
       && size - 1 < BITS_PER_WORD
       && (mul_widen_cost[speed][wider_mode] + 2 * shift_cost[speed][mode][size-1]
          + 4 * add_cost[speed][mode] < max_cost))
@@ -3459,7 +3549,7 @@ expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
 
   gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
   /* We can't support modes wider than HOST_BITS_PER_INT.  */
-  gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT);
+  gcc_assert (HWI_COMPUTABLE_MODE_P (mode));
 
   cnst1 = INTVAL (op1) & GET_MODE_MASK (mode);
 
@@ -3537,7 +3627,8 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
 
          temp = gen_rtx_LSHIFTRT (mode, result, shift);
          if (optab_handler (lshr_optab, mode) == CODE_FOR_nothing
-             || rtx_cost (temp, SET, optimize_insn_for_speed_p ()) > COSTS_N_INSNS (2))
+             || (set_src_cost (temp, optimize_insn_for_speed_p ())
+                 > COSTS_N_INSNS (2)))
            {
              temp = expand_binop (mode, xor_optab, op0, signmask,
                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
@@ -5353,7 +5444,7 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
          /* 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,
@@ -5364,7 +5455,7 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
                                     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,
@@ -5457,7 +5548,7 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
       /* 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,
@@ -5467,7 +5558,7 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
                                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,