This patch teaches the arm target about the rev16 and revsh
instructions which can
efficiently execute the recently added __builtin_bswap16() function
(BSWAP:HI in RTL)
These instructions are available in thumb and arm modes on armv6
architecture and up.

Before this patch,

short swaps16(short x) {
  return __builtin_bswap16(x);
}

unsigned short swapu16(unsigned short x) {
  return __builtin_bswap16(x);
}

$ gcc -S -dp -O2 -marm -march=armv6 test_bswap16.c
outputs:

swaps16:
        uxth    r3, r0  @ 8     *arm_zero_extendhisi2_v6/1      [length = 4]
        mov     r3, r3, lsr #8  @ 9     *arm_shiftsi3   [length = 4]
        orr     r0, r3, r0, asl #8      @ 12    *arith_shiftsi/1
 [length = 4]
        sxth    r0, r0  @ 19    *arm_extendhisi2_v6/1   [length = 4]
        bx      lr      @ 29    *arm_return     [length = 12]
swapu16:
        mov     r3, r0, lsr #8  @ 7     *arm_shiftsi3   [length = 4]
        orr     r0, r3, r0, asl #8      @ 10    *arith_shiftsi/1
 [length = 4]
        uxth    r0, r0  @ 16    *arm_zero_extendhisi2_v6/1      [length = 4]
        bx      lr      @ 26    *arm_return     [length = 12]


After this patch it produces:

swaps16:
        revsh   r0, r0  @ 13    *arm_revsh      [length = 4]
        bx      lr      @ 23    *arm_return     [length = 12]
swapu16:
        rev16   r0, r0  @ 6     *arm_rev16      [length = 4]
        uxth    r0, r0  @ 12    *arm_zero_extendhisi2_v6/1      [length = 4]
        bx      lr      @ 22    *arm_return     [length = 12]

Similar improvements are seen for -mthumb -march=armv6 and -mthumb
-march=armv6t2

--- ChangeLog ---
2012-04-16  Louis Kruger  <lou...@gmail.com>

        * arm.md: Use the revsh and rev16 instructions for BSWAP:HI
RTL in armv6 and up

---
 gcc/config/arm/arm.md |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 79eff0e..317e295 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11327,6 +11327,24 @@
    (set_attr "length" "4")]
 )

+(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 "*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_rev"
   [(set (match_operand:SI 0 "s_register_operand" "=l")
        (bswap:SI (match_operand:SI 1 "s_register_operand" "l")))]
@@ -11335,6 +11353,22 @@
   [(set_attr "length" "2")]
 )

+(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 "*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 "arm_legacy_rev"
   [(set (match_operand:SI 2 "s_register_operand" "")
        (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
@@ -11420,6 +11454,13 @@
   "
 )

+(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")
 ;; Load the FPA co-processor patterns
-- 
1.7.7.3

Reply via email to