aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2012-05-08 18:01:54 +0200
committerUros Bizjak <uros@gcc.gnu.org>2012-05-08 18:01:54 +0200
commit3f3dcbb39347539a29ce245aa428ae73641f15c1 (patch)
treea40065ca6cb615fdce51b1384c4817e9e6c0a376
parentbcc708fcdc60c6b4485b1796ac1ba61c5f56b0b3 (diff)
downloadgcc-3f3dcbb39347539a29ce245aa428ae73641f15c1.zip
gcc-3f3dcbb39347539a29ce245aa428ae73641f15c1.tar.gz
gcc-3f3dcbb39347539a29ce245aa428ae73641f15c1.tar.bz2
re PR target/53250 ([SH] ICE: in change_address_1, at emit-rtl.c:2018)
PR target/53250 * config/i386/i386.c (ix86_set_reg_reg_cost): New function. (ix86_rtx_costs): Handle SET. From-SVN: r187289
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c55
2 files changed, 62 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e933f4e..d2994e4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ecf4d6e..6bb64e0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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: