From: Uros Bizjak Date: Tue, 8 May 2012 16:01:54 +0000 (+0200) Subject: re PR target/53250 ([SH] ICE: in change_address_1, at emit-rtl.c:2018) X-Git-Tag: misc/gccgo-go1_1_2~3028 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f3dcbb39347539a29ce245aa428ae73641f15c1;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e933f4e0cd99..d2994e437b84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-05-08 Uros Bizjak + + PR target/53250 + * config/i386/i386.c (ix86_set_reg_reg_cost): New function. + (ix86_rtx_costs): Handle SET. + 2012-05-08 Michael Matz * 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 ecf4d6e9922c..6bb64e085232 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: