]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/53250 ([SH] ICE: in change_address_1, at emit-rtl.c:2018)
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 8 May 2012 16:01:54 +0000 (18:01 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 8 May 2012 16:01:54 +0000 (18:01 +0200)
PR target/53250
* config/i386/i386.c (ix86_set_reg_reg_cost): New function.
(ix86_rtx_costs): Handle SET.

From-SVN: r187289

gcc/ChangeLog
gcc/config/i386/i386.c

index e933f4e0cd9982e088958a3d34a9ed14028a7839..d2994e437b844f071f213732fcc03185b0abd3ab 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-08  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/53250
+       * config/i386/i386.c (ix86_set_reg_reg_cost): New function.
+       (ix86_rtx_costs): Handle SET.
+
 2012-05-08  Michael Matz  <matz@suse.de>
 
        * basic-block.h (struct rtl_bb_info): Remove visited member and
@@ -15,8 +21,7 @@
        (fixup_fallthru_exit_predecessor): Ditto.
        (cfg_layout_duplicate_bb): Ditto.
        * combine.c (update_cfg_for_uncondjump): Adjust.
-       * bb-reorder.c (struct bbro_basic_block_data_def): Add visited
-       member.
+       * bb-reorder.c (struct bbro_basic_block_data_def): Add visited member.
        (bb_visited_trace): New accessor.
        (mark_bb_visited): Move in front.
        (rotate_loop): Use bb_visited_trace.
index ecf4d6e9922c245b0f5551f02e7a4695f672feff..6bb64e085232f61fde4307375d3215ffd000a195 100644 (file)
@@ -31861,6 +31861,52 @@ ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
   return false;
 }
 
+/* Return the cost of moving between two registers of mode MODE.  */
+
+static int
+ix86_set_reg_reg_cost (enum machine_mode mode)
+{
+  unsigned int units = UNITS_PER_WORD;
+
+  switch (GET_MODE_CLASS (mode))
+    {
+    default:
+      break;
+
+    case MODE_CC:
+      units = GET_MODE_SIZE (CCmode);
+      break;
+
+    case MODE_FLOAT:
+      if ((TARGET_SSE2 && mode == TFmode)
+         || (TARGET_80387 && mode == XFmode)
+         || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
+         || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
+       units = GET_MODE_SIZE (mode);
+      break;
+
+    case MODE_COMPLEX_FLOAT:
+      if ((TARGET_SSE2 && mode == TCmode)
+         || (TARGET_80387 && mode == XCmode)
+         || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
+         || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
+       units = GET_MODE_SIZE (mode);
+      break;
+
+    case MODE_VECTOR_INT:
+    case MODE_VECTOR_FLOAT:
+      if ((TARGET_AVX && VALID_AVX256_REG_MODE (mode))
+         || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
+         || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
+         || (TARGET_MMX && VALID_MMX_REG_MODE (mode)))
+       units = GET_MODE_SIZE (mode);
+    }
+
+  /* Return the cost of moving between two registers of mode MODE,
+     assuming that the move will be in pieces of at most UNITS bytes.  */
+  return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
+}
+
 /* Compute a (partial) cost for rtx X.  Return true if the complete
    cost has been computed, and false if subexpressions should be
    scanned.  In either case, *TOTAL contains the cost result.  */
@@ -31875,6 +31921,15 @@ ix86_rtx_costs (rtx x, int code, int outer_code_i, int opno, int *total,
 
   switch (code)
     {
+    case SET:
+      if (register_operand (SET_DEST (x), VOIDmode)
+         && reg_or_0_operand (SET_SRC (x), VOIDmode))
+       {
+         *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
+         return true;
+       }
+      return false;
+
     case CONST_INT:
     case CONST:
     case LABEL_REF: