From: jgreenhalgh Date: Fri, 16 May 2014 09:01:28 +0000 (+0000) Subject: [AArch64 costs 10/18] Improve costs for sign/zero extend operations X-Git-Tag: accepted/tizen/3.0.2015.q2/common/20150615.160009~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dfbbddad198d908c7d738b8b6476237294808af2;p=platform%2Fupstream%2Fgcc49.git [AArch64 costs 10/18] Improve costs for sign/zero extend operations git cherry-pick 81d1eb9 gcc/ * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost ZERO_EXTEND and SIGN_EXTEND better. Change-Id: Ifa42bd83302971230562416fa1e948977d824ba5 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210502 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2eef3cf..fdb5795 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2014-05-16 James Greenhalgh Philipp Tomsich + * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost + ZERO_EXTEND and SIGN_EXTEND better. + +2014-05-16 James Greenhalgh + Philipp Tomsich + * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for logical operations. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b2e615c..a56cb88 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -5213,21 +5213,62 @@ cost_minus: return false; case ZERO_EXTEND: - if ((GET_MODE (x) == DImode - && GET_MODE (XEXP (x, 0)) == SImode) - || GET_CODE (XEXP (x, 0)) == MEM) + + op0 = XEXP (x, 0); + /* If a value is written in SI mode, then zero extended to DI + mode, the operation will in general be free as a write to + a 'w' register implicitly zeroes the upper bits of an 'x' + register. However, if this is + + (set (reg) (zero_extend (reg))) + + we must cost the explicit register move. */ + if (mode == DImode + && GET_MODE (op0) == SImode + && outer == SET) + { + int op_cost = rtx_cost (XEXP (x, 0), ZERO_EXTEND, 0, speed); + + if (!op_cost && speed) + /* MOV. */ + *cost += extra_cost->alu.extend; + else + /* Free, the cost is that of the SI mode operation. */ + *cost = op_cost; + + return true; + } + else if (MEM_P (XEXP (x, 0))) { - *cost += rtx_cost (XEXP (x, 0), ZERO_EXTEND, 0, speed); + /* All loads can zero extend to any size for free. */ + *cost = rtx_cost (XEXP (x, 0), ZERO_EXTEND, param, speed); return true; } + + /* UXTB/UXTH. */ + if (speed) + *cost += extra_cost->alu.extend; + return false; case SIGN_EXTEND: - if (GET_CODE (XEXP (x, 0)) == MEM) + if (MEM_P (XEXP (x, 0))) { - *cost += rtx_cost (XEXP (x, 0), SIGN_EXTEND, 0, speed); + /* LDRSH. */ + if (speed) + { + rtx address = XEXP (XEXP (x, 0), 0); + *cost += extra_cost->ldst.load_sign_extend; + + *cost += + COSTS_N_INSNS (aarch64_address_cost (address, mode, + 0, speed)); + } return true; } + + if (speed) + *cost += extra_cost->alu.extend; return false; case ROTATE: