commit 59598566ce06e11455a60b305245af839138fe37
Author: Christophe Lyon <christophe.lyon@st.com>
Date:   Wed Sep 5 10:22:20 2012 +0200

    2012-09-05  Christophe Lyon  <christophe.lyon@linaro.org>
    
    	gcc/
    	* config/arm/arm.md (arm_revsh): New pattern to support
    	builtin_bswap16.
    	(thumb1_revsh, arm_rev16, thumb1_rev16, bswaphi2): Likewise.
    
    	gcc/testuite/
    	* gcc.target/arm/builtin-bswap-1.c: New testcase.

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 6a642bf..32750c6 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11473,6 +11473,50 @@
   "
 )
 
+;; 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" "=r")
+	(sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "r"))))]
+  "TARGET_32BIT && arm_arch6"
+  "revsh%?\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "length" "4")]
+)
+
+(define_insn "*thumb1_revsh"
+  [(set (match_operand:SI 0 "s_register_operand" "=l")
+	(sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l"))))]
+  "TARGET_THUMB1 && arm_arch6"
+   "revsh\t%0, %1"
+  [(set_attr "length" "2")]
+)
+
+(define_insn "*arm_rev16"
+  [(set (match_operand:HI 0 "s_register_operand" "=r")
+	(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
+  "TARGET_32BIT && arm_arch6"
+  "rev16%?\t%0, %1"
+  [(set_attr "predicable" "yes")
+   (set_attr "length" "4")]
+)
+
+(define_insn "*thumb1_rev16"
+  [(set (match_operand:HI 0 "s_register_operand" "=l")
+	(bswap:HI (match_operand:HI 1 "s_register_operand" "l")))]
+  "TARGET_THUMB1 && arm_arch6"
+   "rev16\t%0, %1"
+  [(set_attr "length" "2")]
+)
+
+(define_expand "bswaphi2"
+  [(set (match_operand:HI 0 "s_register_operand" "=r")
+	(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
+"TARGET_EITHER && arm_arch6"
+""
+)
+
 ;; Load the load/store multiple patterns
 (include "ldmstm.md")
 
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..bebeef2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/builtin-bswap-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "orr\[ \t\]" } } */
+
+short foo1 (short x)
+{
+  return __builtin_bswap16 (x);
+}
+
+unsigned short foo2 (unsigned short x)
+{
+  return __builtin_bswap16 (x);
+}
