aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2014-04-23 15:26:28 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2014-04-23 15:26:28 +0000
commitf7d5cf8df3193f8f6e62501def08e4b0b1baadbc (patch)
tree2510b3a45cf0d83f6649c31498711958ba864a74 /gcc/config/aarch64
parent9ac05ae59008ccdd479eca70e6c0c6742fad5b0e (diff)
downloadgcc-f7d5cf8df3193f8f6e62501def08e4b0b1baadbc.zip
gcc-f7d5cf8df3193f8f6e62501def08e4b0b1baadbc.tar.gz
gcc-f7d5cf8df3193f8f6e62501def08e4b0b1baadbc.tar.bz2
[AArch64][2/3] Recognise rev16 operations on SImode and DImode data
* config/aarch64/aarch64.md (rev16<mode>2): New pattern. (rev16<mode>2_alt): Likewise. * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle rev16 case. * config/arm/aarch-common.c (aarch_rev16_shright_mask_imm_p): New. (aarch_rev16_shleft_mask_imm_p): Likewise. (aarch_rev16_p_1): Likewise. (aarch_rev16_p): Likewise. * config/arm/aarch-common-protos.h (aarch_rev16_p): Declare extern. (aarch_rev16_shright_mask_imm_p): Likewise. (aarch_rev16_shleft_mask_imm_p): Likewise. * gcc.target/aarch64/rev16_1.c: New test. From-SVN: r209704
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r--gcc/config/aarch64/aarch64.c10
-rw-r--r--gcc/config/aarch64/aarch64.md32
2 files changed, 42 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index dacd7ee..68c29aa 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4695,6 +4695,16 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
return false;
case IOR:
+ if (aarch_rev16_p (x))
+ {
+ *cost = COSTS_N_INSNS (1);
+
+ if (speed)
+ *cost += extra_cost->alu.rev;
+
+ return true;
+ }
+ /* Fall through. */
case XOR:
case AND:
cost_logic:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index ee32b6c..98c46d1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3253,6 +3253,38 @@
[(set_attr "type" "rev")]
)
+;; There are no canonicalisation rules for the position of the lshiftrt, ashift
+;; operations within an IOR/AND RTX, therefore we have two patterns matching
+;; each valid permutation.
+
+(define_insn "rev16<mode>2"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:GPI 3 "const_int_operand" "n"))
+ (and:GPI (lshiftrt:GPI (match_dup 1)
+ (const_int 8))
+ (match_operand:GPI 2 "const_int_operand" "n"))))]
+ "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
+ "rev16\\t%<w>0, %<w>1"
+ [(set_attr "type" "rev")]
+)
+
+(define_insn "rev16<mode>2_alt"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:GPI 2 "const_int_operand" "n"))
+ (and:GPI (ashift:GPI (match_dup 1)
+ (const_int 8))
+ (match_operand:GPI 3 "const_int_operand" "n"))))]
+ "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
+ && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
+ "rev16\\t%<w>0, %<w>1"
+ [(set_attr "type" "rev")]
+)
+
;; zero_extend version of above
(define_insn "*bswapsi2_uxtw"
[(set (match_operand:DI 0 "register_operand" "=r")