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: upstream/5.3.0~8430 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81d1eb9df766795dd1d5439c65eb61cbee824b72;p=platform%2Fupstream%2Flinaro-gcc.git [AArch64 costs 10/18] Improve costs for sign/zero extend operations gcc/ * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost ZERO_EXTEND and SIGN_EXTEND better. 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 e648140..38a66e7 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 6b20d4a..76ef7ce 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -5281,21 +5281,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: