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