aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2015-08-23 22:04:41 +0200
committerLinaro Code Review <review@review.linaro.org>2015-08-27 17:24:38 +0000
commitdf20b8380b98041d8caca188ba775d66e15349a6 (patch)
treecdd506e1027cec7cc29cfa90d4c998cec7fb1cf6
parentbaae47ab892450bae13199b3fbf17b3cf518facf (diff)
gcc/
Backport from trunk r222637. 2015-04-30 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * config/aarch64/aarch64.md (*eor_one_cmpl_<SHIFT:optab><mode>3_alt): New pattern. (*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze): Likewise. * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle MVN-shift appropriately. Handle alternative EON form. Change-Id: Ib6c2b6fa14ed06dad7b23d899cb2465a7685dd5f
-rw-r--r--gcc/config/aarch64/aarch64.c38
-rw-r--r--gcc/config/aarch64/aarch64.md26
2 files changed, 61 insertions, 3 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index af5b4c23975..15fe7554532 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -6108,13 +6108,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 f51f8d8fade..c2efcd2f2eb 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3293,6 +3293,32 @@
[(set_attr "type" "logics_shift_imm")]
)
+(define_insn "*eor_one_cmpl_<SHIFT:optab><mode>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_<mode>" "n"))
+ (match_operand:GPI 3 "register_operand" "r"))))]
+ ""
+ "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
+ [(set_attr "type" "logic_shift_imm")]
+)
+
+;; Zero-extend version of the above.
+(define_insn "*eor_one_cmpl_<SHIFT:optab>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, <SHIFT:shift> %2"
+ [(set_attr "type" "logic_shift_imm")]
+)
+
(define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ