From a486b4991f22f09de49935898a6e0c40f6baccf4 Mon Sep 17 00:00:00 2001 From: clyon Date: Thu, 13 Sep 2012 08:55:30 +0000 Subject: [PATCH] 2012-09-13 Christophe Lyon Richard Earnshaw gcc/ * config/arm/arm.md (arm_rev): Factorize thumb1, thumb2 and arm variants for rev instruction.. (thumb1_rev): Delete pattern. (arm_revsh): New pattern to support builtin_bswap16. (arm_rev16, bswaphi2): Likewise. gcc/testsuite/ * gcc.target/arm/builtin-bswap-1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191243 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++ gcc/config/arm/arm.md | 57 +++++++++++++----- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.target/arm/builtin-bswap-1.c | 81 ++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/builtin-bswap-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 860c81b..12f7930 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2012-09-13 Christophe Lyon + Richard Earnshaw + + * config/arm/arm.md (arm_rev): Factorize thumb1, thumb2 and arm + variants for rev instruction.. + (thumb1_rev): Delete pattern. + (arm_revsh): New pattern to support builtin_bswap16. + (arm_rev16, bswaphi2): Likewise. + 2012-09-12 Teresa Johnson PR gcov-profile/54487 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index a60e659..43a9f1f 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -11371,20 +11371,15 @@ ) (define_insn "*arm_rev" - [(set (match_operand:SI 0 "s_register_operand" "=r") - (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] - "TARGET_32BIT && arm_arch6" - "rev%?\t%0, %1" - [(set_attr "predicable" "yes") - (set_attr "length" "4")] -) - -(define_insn "*thumb1_rev" - [(set (match_operand:SI 0 "s_register_operand" "=l") - (bswap:SI (match_operand:SI 1 "s_register_operand" "l")))] - "TARGET_THUMB1 && arm_arch6" - "rev\t%0, %1" - [(set_attr "length" "2")] + [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") + (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))] + "arm_arch6" + "@ + rev\t%0, %1 + rev%?\t%0, %1 + rev%?\t%0, %1" + [(set_attr "arch" "t1,t2,32") + (set_attr "length" "2,2,4")] ) (define_expand "arm_legacy_rev" @@ -11472,6 +11467,40 @@ " ) +;; bswap16 patterns: use revsh and rev16 instructions for the signed +;; and unsigned variants, respectively. For rev16, expose +;; byte-swapping in the lower 16 bits only. +(define_insn "*arm_revsh" + [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") + (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))] + "arm_arch6" + "@ + revsh\t%0, %1 + revsh%?\t%0, %1 + revsh%?\t%0, %1" + [(set_attr "arch" "t1,t2,32") + (set_attr "length" "2,2,4")] +) + +(define_insn "*arm_rev16" + [(set (match_operand:HI 0 "s_register_operand" "=l,l,r") + (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))] + "arm_arch6" + "@ + rev16\t%0, %1 + rev16%?\t%0, %1 + rev16%?\t%0, %1" + [(set_attr "arch" "t1,t2,32") + (set_attr "length" "2,2,4")] +) + +(define_expand "bswaphi2" + [(set (match_operand:HI 0 "s_register_operand" "=r") + (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))] +"arm_arch6" +"" +) + ;; Load the load/store multiple patterns (include "ldmstm.md") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa1f3dd..8e5ac77 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-09-13 Christophe Lyon + + * gcc.target/arm/builtin-bswap-1.c: New testcase. + 2012-09-12 Kyrylo Tkachov * c-c++-common/pr51712.c: Handle for short-enum targets. diff --git a/gcc/testsuite/gcc.target/arm/builtin-bswap-1.c b/gcc/testsuite/gcc.target/arm/builtin-bswap-1.c new file mode 100644 index 0000000..43195bd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin-bswap-1.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm_arch_v6_ok } */ +/* { dg-add-options arm_arch_v6 } */ +/* { dg-final { scan-assembler-not "orr\[ \t\]" } } */ +/* { dg-final { scan-assembler-times "revsh\\t" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "revshne\\t" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "revsh\\t" 2 { target { ! arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "rev16\\t" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "rev16ne\\t" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "rev16\\t" 2 { target { ! arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "rev\\t" 2 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "revne\\t" 2 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "rev\\t" 4 { target { ! arm_nothumb } } } } */ + +/* revsh */ +short swaps16 (short x) +{ + return __builtin_bswap16 (x); +} + +extern short foos16 (short); + +/* revshne */ +short swaps16_cond (short x, int y) +{ + short z = x; + if (y) + z = __builtin_bswap16 (x); + return foos16 (z); +} + +/* rev16 */ +unsigned short swapu16 (unsigned short x) +{ + return __builtin_bswap16 (x); +} + +extern unsigned short foou16 (unsigned short); + +/* rev16ne */ +unsigned short swapu16_cond (unsigned short x, int y) +{ + unsigned short z = x; + if (y) + z = __builtin_bswap16 (x); + return foou16 (z); +} + +/* rev */ +int swaps32 (int x) { + return __builtin_bswap32 (x); +} + +extern int foos32 (int); + +/* revne */ +int swaps32_cond (int x, int y) +{ + int z = x; + if (y) + z = __builtin_bswap32 (x); + return foos32 (z); +} + +/* rev */ +unsigned int swapu32 (unsigned int x) +{ + return __builtin_bswap32 (x); +} + +extern unsigned int foou32 (unsigned int); + +/* revne */ +unsigned int swapsu2 (unsigned int x, int y) +{ + int z = x; + if (y) + z = __builtin_bswap32 (x); + return foou32 (z); +} -- 2.7.4