From: olegendo Date: Sat, 15 Sep 2012 13:24:30 +0000 (+0000) Subject: * config/sh/sh.c (sh_rtx_costs): Add handling of MEM, SIGN_EXTEND, X-Git-Tag: upstream/4.9.2~10619 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b9a94d1609c2d0bf6dafae9457ddb32d661a9bca;p=platform%2Fupstream%2Flinaro-gcc.git * config/sh/sh.c (sh_rtx_costs): Add handling of MEM, SIGN_EXTEND, ZERO_EXTEND and PARALLEL cases. (sh_address_cost): Correct rtx parsing and tweak cost estimations. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191342 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4330b3..ae8bf34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-09-15 Oleg Endo + + * config/sh/sh.c (sh_rtx_costs): Add handling of MEM, SIGN_EXTEND, + ZERO_EXTEND and PARALLEL cases. + (sh_address_cost): Correct rtx parsing and tweak cost estimations. + 2012-09-14 Sandra Loosemore * doc/tm.texi.in (Stack Arguments): Update obsolete references diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 7f8ded0..b54bf2f 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -3196,6 +3196,78 @@ sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, } return false; + /* The cost of a mem access is mainly the cost of the address mode. */ + case MEM: + *total = sh_address_cost (XEXP (x, 0), GET_MODE (x), MEM_ADDR_SPACE (x), + true); + return true; + + /* The cost of a sign or zero extend depends on whether the source is a + reg or a mem. In case of a mem take the address into acount. */ + case SIGN_EXTEND: + if (REG_P (XEXP (x, 0))) + { + *total = COSTS_N_INSNS (1); + return true; + } + if (MEM_P (XEXP (x, 0))) + { + *total = sh_address_cost (XEXP (XEXP (x, 0), 0), + GET_MODE (XEXP (x, 0)), + MEM_ADDR_SPACE (XEXP (x, 0)), true); + return true; + } + return false; + + case ZERO_EXTEND: + if (REG_P (XEXP (x, 0))) + { + *total = COSTS_N_INSNS (1); + return true; + } + else if (TARGET_SH2A && MEM_P (XEXP (x, 0)) + && (GET_MODE (XEXP (x, 0)) == QImode + || GET_MODE (XEXP (x, 0)) == HImode)) + { + /* Handle SH2A's movu.b and movu.w insn. */ + *total = sh_address_cost (XEXP (XEXP (x, 0), 0), + GET_MODE (XEXP (x, 0)), + MEM_ADDR_SPACE (XEXP (x, 0)), true); + return true; + } + return false; + + /* mems for SFmode and DFmode can be inside a parallel due to + the way the fpscr is handled. */ + case PARALLEL: + for (int i = 0; i < XVECLEN (x, 0); i++) + { + rtx xx = XVECEXP (x, 0, i); + if (GET_CODE (xx) == SET && MEM_P (XEXP (xx, 0))) + { + *total = sh_address_cost (XEXP (XEXP (xx, 0), 0), + GET_MODE (XEXP (xx, 0)), + MEM_ADDR_SPACE (XEXP (xx, 0)), true); + return true; + } + if (GET_CODE (xx) == SET && MEM_P (XEXP (xx, 1))) + { + *total = sh_address_cost (XEXP (XEXP (xx, 1), 0), + GET_MODE (XEXP (xx, 1)), + MEM_ADDR_SPACE (XEXP (xx, 1)), true); + return true; + } + } + + if (sh_1el_vec (x, VOIDmode)) + *total = outer_code != SET; + else if (sh_rep_vec (x, VOIDmode)) + *total = ((GET_MODE_UNIT_SIZE (GET_MODE (x)) + 3) / 4 + + (outer_code != SET)); + else + *total = COSTS_N_INSNS (3) + (outer_code != SET); + return true; + case CONST_INT: if (TARGET_SHMEDIA) { @@ -3271,7 +3343,10 @@ sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, else *total = 10; return true; + case CONST_VECTOR: + /* FIXME: This looks broken. Only the last statement has any effect. + Probably this could be folded with the PARALLEL case? */ if (x == CONST0_RTX (GET_MODE (x))) *total = 0; else if (sh_1el_vec (x, VOIDmode)) @@ -3339,15 +3414,6 @@ sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (20); return true; - case PARALLEL: - if (sh_1el_vec (x, VOIDmode)) - *total = outer_code != SET; - if (sh_rep_vec (x, VOIDmode)) - *total = ((GET_MODE_UNIT_SIZE (GET_MODE (x)) + 3) / 4 - + (outer_code != SET)); - *total = COSTS_N_INSNS (3) + (outer_code != SET); - return true; - case FLOAT: case FIX: *total = 100; @@ -3430,36 +3496,47 @@ disp_addr_displacement (rtx x) /* Compute the cost of an address. */ static int -sh_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED, +sh_address_cost (rtx x, enum machine_mode mode, addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED) { + /* Simple reg, post-inc, pre-dec addressing. */ + if (REG_P (x) || GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC) + return 1; + /* 'reg + disp' addressing. */ - if (satisfies_constraint_Sdd (x)) + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))) { - const HOST_WIDE_INT offset = disp_addr_displacement (x); - const enum machine_mode mode = GET_MODE (x); + const HOST_WIDE_INT offset = INTVAL (XEXP (x, 1)); + + if (offset == 0) + return 1; - /* The displacement would fit into a 2 byte move insn. */ + /* The displacement would fit into a 2 byte move insn. + HImode and QImode loads/stores with displacement put pressure on + R0 which will most likely require another reg copy. Thus account + a higher cost for that. */ if (offset > 0 && offset <= max_mov_insn_displacement (mode, false)) - return 0; + return (mode == HImode || mode == QImode) ? 2 : 1; /* The displacement would fit into a 4 byte move insn (SH2A). */ if (TARGET_SH2A && offset > 0 && offset <= max_mov_insn_displacement (mode, true)) - return 1; + return 2; /* The displacement is probably out of range and will require extra calculations. */ - return 2; + return 3; } /* 'reg + reg' addressing. Account a slightly higher cost because of increased pressure on R0. */ if (GET_CODE (x) == PLUS && ! CONSTANT_P (XEXP (x, 1)) && ! TARGET_SHMEDIA) - return 1; + return 3; - return 0; + /* Not sure what it is - probably expensive. */ + return 10; } /* Code to expand a shift. */