Richard Earnshaw <rearnsha@arm.com>
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
+2012-09-13 Christophe Lyon <christophe.lyon@linaro.org>
+ Richard Earnshaw <rearnsha@arm.com>
+
+ * 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 <tejohnson@google.com>
PR gcov-profile/54487
)
(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"
"
)
+;; 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")
+2012-09-13 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/builtin-bswap-1.c: New testcase.
+
2012-09-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* c-c++-common/pr51712.c: Handle for short-enum targets.
--- /dev/null
+/* { 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);
+}