OSDN Git Service

* df-core.c (df_bb_regno_last_use_find): Do not look for dataflow
[pf3gnuchains/gcc-fork.git] / gcc / expmed.c
index 31b8241..89ae78d 100644 (file)
@@ -636,7 +636,9 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       && bitsize > 0
       && GET_MODE_BITSIZE (op_mode) >= bitsize
       && ! ((REG_P (op0) || GET_CODE (op0) == SUBREG)
-           && (bitsize + bitpos > GET_MODE_BITSIZE (op_mode))))
+           && (bitsize + bitpos > GET_MODE_BITSIZE (op_mode)))
+      && insn_data[CODE_FOR_insv].operand[1].predicate (GEN_INT (bitsize),
+                                                       VOIDmode))
     {
       int xbitpos = bitpos;
       rtx value1;
@@ -922,7 +924,12 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
 
   if (! all_one)
     {
-      temp = expand_binop (mode, and_optab, op0,
+      /* Don't try and keep the intermediate in memory, if we need to
+        perform both a bit-wise AND and a bit-wise IOR (except when
+        we're optimizing for size).  */
+      if (MEM_P (subtarget) && !all_zero && !optimize_size)
+       subtarget = force_reg (mode, subtarget);
+      temp = expand_binop (mode, and_optab, subtarget,
                           mask_rtx (mode, bitpos, bitsize, 1),
                           subtarget, 1, OPTAB_LIB_WIDEN);
       subtarget = temp;