OSDN Git Service

Add vcond/vcondu patterns to sparc backend.
[pf3gnuchains/gcc-fork.git] / gcc / regcprop.c
index bf34115..b0f0343 100644 (file)
@@ -418,10 +418,9 @@ maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
 
       offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0)
                + (BYTES_BIG_ENDIAN ? byteoffset : 0));
-      return gen_rtx_raw_REG (new_mode,
-                             regno + subreg_regno_offset (regno, orig_mode,
-                                                          offset,
-                                                          new_mode));
+      regno += subreg_regno_offset (regno, orig_mode, offset, new_mode);
+      if (HARD_REGNO_MODE_OK (regno, new_mode))
+       return gen_rtx_raw_REG (new_mode, regno);
     }
   return NULL_RTX;
 }
@@ -825,6 +824,14 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
              if (hard_regno_nregs[regno][mode]
                  > hard_regno_nregs[regno][vd->e[regno].mode])
                goto no_move_special_case;
+
+             /* And likewise, if we are narrowing on big endian the transformation
+                is also invalid.  */
+             if (hard_regno_nregs[regno][mode]
+                 < hard_regno_nregs[regno][vd->e[regno].mode]
+                 && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
+                     ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+               goto no_move_special_case;
            }
 
          /* If the destination is also a register, try to find a source
@@ -841,6 +848,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
                  changed = true;
                  goto did_replacement;
                }
+             /* We need to re-extract as validate_change clobbers
+                recog_data.  */
+             extract_insn (insn);
+             if (! constrain_operands (1))
+               fatal_insn_not_found (insn);
+             preprocess_constraints ();
            }
 
          /* Otherwise, try all valid registers and see if its valid.  */
@@ -863,6 +876,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
                      changed = true;
                      goto did_replacement;
                    }
+                 /* We need to re-extract as validate_change clobbers
+                    recog_data.  */
+                 extract_insn (insn);
+                 if (! constrain_operands (1))
+                   fatal_insn_not_found (insn);
+                 preprocess_constraints ();
                }
            }
        }
@@ -1188,7 +1207,7 @@ struct rtl_opt_pass pass_cprop_hardreg =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func | TODO_df_finish
+  TODO_df_finish
   | TODO_verify_rtl_sharing            /* todo_flags_finish */
  }
 };