diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2012-05-08 18:01:54 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2012-05-08 18:01:54 +0200 |
commit | 3f3dcbb39347539a29ce245aa428ae73641f15c1 (patch) | |
tree | a40065ca6cb615fdce51b1384c4817e9e6c0a376 /gcc | |
parent | bcc708fcdc60c6b4485b1796ac1ba61c5f56b0b3 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 55 |
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: |