From 17a5981f15c6b7451f03d0e10d87e4500902bb2b Mon Sep 17 00:00:00 2001 From: ktkachov Date: Thu, 30 Apr 2015 16:59:50 +0000 Subject: [PATCH] [AArch64] Properly handle mvn-register and add EON+shift pattern and cost appropriately * config/aarch64/aarch64.md (*eor_one_cmpl_3_alt): New pattern. (*eor_one_cmpl_sidi3_alt_ze): Likewise. * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle MVN-shift appropriately. Handle alternative EON form. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222637 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/config/aarch64/aarch64.c | 38 +++++++++++++++++++++++++++++++++++--- gcc/config/aarch64/aarch64.md | 26 ++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40d71fcbd12..a4569bbc075 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-04-30 Kyrylo Tkachov + + * config/aarch64/aarch64.md + (*eor_one_cmpl_3_alt): New pattern. + (*eor_one_cmpl_sidi3_alt_ze): Likewise. + * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle MVN-shift + appropriately. Handle alternative EON form. + 2015-04-30 Renlin Li * config/aarch64/aarch64-simd.md (vec_shr): Defined as an unspec. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 7d7f8908a05..7579f5b2519 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -6049,13 +6049,45 @@ cost_plus: return false; case NOT: + x = XEXP (x, 0); + op0 = aarch64_strip_shift (x); + + /* MVN-shifted-reg. */ + if (op0 != x) + { + *cost += rtx_cost (op0, (enum rtx_code) code, 0, speed); + + if (speed) + *cost += extra_cost->alu.log_shift; + + return true; + } + /* EON can have two forms: (xor (not a) b) but also (not (xor a b)). + Handle the second form here taking care that 'a' in the above can + be a shift. */ + else if (GET_CODE (op0) == XOR) + { + rtx newop0 = XEXP (op0, 0); + rtx newop1 = XEXP (op0, 1); + rtx op0_stripped = aarch64_strip_shift (newop0); + + *cost += rtx_cost (newop1, (enum rtx_code) code, 1, speed) + + rtx_cost (op0_stripped, XOR, 0, speed); + + if (speed) + { + if (op0_stripped != newop0) + *cost += extra_cost->alu.log_shift; + else + *cost += extra_cost->alu.logical; + } + + return true; + } /* MVN. */ if (speed) *cost += extra_cost->alu.logical; - /* The logical instruction could have the shifted register form, - but the cost is the same if the shift is processed as a separate - instruction, so we don't bother with it here. */ return false; case ZERO_EXTEND: diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 429c5bac000..194bfd3d2bd 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3151,6 +3151,32 @@ [(set_attr "type" "logics_shift_imm")] ) +(define_insn "*eor_one_cmpl_3_alt" + [(set (match_operand:GPI 0 "register_operand" "=r") + (not:GPI (xor:GPI + (SHIFT:GPI + (match_operand:GPI 1 "register_operand" "r") + (match_operand:QI 2 "aarch64_shift_imm_" "n")) + (match_operand:GPI 3 "register_operand" "r"))))] + "" + "eon\\t%0, %3, %1, %2" + [(set_attr "type" "logic_shift_imm")] +) + +;; Zero-extend version of the above. +(define_insn "*eor_one_cmpl_sidi3_alt_ze" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (not:SI (xor:SI + (SHIFT:SI + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "aarch64_shift_imm_si" "n")) + (match_operand:SI 3 "register_operand" "r")))))] + "" + "eon\\t%w0, %w3, %w1, %2" + [(set_attr "type" "logic_shift_imm")] +) + (define_insn "*and_one_cmpl_3_compare0" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ -- 2.11.4.GIT