https://gcc.gnu.org/g:1495df4fba8235a59e88d63fce50fe772df06dbf
commit r17-592-g1495df4fba8235a59e88d63fce50fe772df06dbf Author: Georg-Johann Lay <[email protected]> Date: Tue May 19 09:43:11 2026 +0200 AVR: Add insns and libgcc functions for __builtin_bitreverse16/32. gcc/ * config/avr/avr.md (bitreversehi2, bitreversesi2): New insn_and_split. (*bitreversehi2.libgcc, *bitreversesi2.libgcc): New insns. libgcc/ * config/avr/t-avr (LIB1ASMFUNCS): Add _bitreverse8, _bitreverse16, _bitreverse24, _bitreverse32. * config/avr/lib1funcs.S (__bitreverse8, __bitreverse16) (__bitreverse24, __bitreverse32): New functions. Diff: --- gcc/config/avr/avr.md | 38 +++++++++++++++++++++++++ libgcc/config/avr/lib1funcs.S | 65 +++++++++++++++++++++++++++++++++++++++++++ libgcc/config/avr/t-avr | 1 + 3 files changed, 104 insertions(+) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 17b614a6d706..7d5c70b961d7 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -9036,6 +9036,44 @@ (set (reg:QI 25) (const_int 0))]) + +;; Bit Reverse + +(define_insn_and_split "bitreversehi2" + [(set (match_operand:HI 0 "register_operand" "={r24}") + (bitreverse:HI (match_operand:HI 1 "register_operand" "{r24}")))] + "" + "#" + "&& reload_completed" + [(scratch)] + { DONE_ADD_CCC }) + +(define_insn "*bitreversehi2.libgcc" + [(set (reg:HI 24) + (bitreverse:HI (reg:HI 24))) + (clobber (reg:CC REG_CC))] + "reload_completed" + "%~call __bitreverse16" + [(set_attr "type" "xcall")]) + +(define_insn_and_split "bitreversesi2" + [(set (match_operand:SI 0 "register_operand" "={r22}") + (bitreverse:SI (match_operand:SI 1 "register_operand" "{r22}")))] + "" + "#" + "&& reload_completed" + [(scratch)] + { DONE_ADD_CCC }) + +(define_insn "*bitreversesi2.libgcc" + [(set (reg:SI 22) + (bitreverse:SI (reg:SI 22))) + (clobber (reg:CC REG_CC))] + "reload_completed" + "%~call __bitreverse32" + [(set_attr "type" "xcall")]) + + ;; Count Leading Zeros (define_expand "clzhi2" diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index 1cb2decbb51d..f0f06e478e16 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -3205,6 +3205,71 @@ DEFUN __bswapdi2 ENDF __bswapdi2 #endif /* defined (L_bswapdi2) */ + +/***************************************** + * Reverse bitorder (__builtin_bitreverse) + ****************************************/ + +#if defined (L_bitreverse8) +DEFUN __bitreverse8 + ;; 76543210 + lsl r24 + adc r24, __zero_reg__ + ;; ...3...7 + mov __tmp_reg__, r24 ; 65432107 + bst __tmp_reg__, 1 $ bld r24, 7 + ;; 0..3...7 + bst __tmp_reg__, 2 $ bld r24, 6 + ;; 01.3...7 + bst __tmp_reg__, 3 $ bld r24, 5 + ;; 0123...7 + bst __tmp_reg__, 5 $ bld r24, 3 + ;; 01234..7 + bst __tmp_reg__, 6 $ bld r24, 2 + ;; 012345.7 + bst __tmp_reg__, 7 $ bld r24, 1 + ;; 01234567 + ret +ENDF __bitreverse8 +#endif /* L_bitreverse8 */ + +#if defined (L_bitreverse16) +DEFUN __bitreverse16 + XCALL __bitreverse8 + bswap r24, r25 + XJMP __bitreverse8 +ENDF __bitreverse16 +#endif /* L_bitreverse16 */ + +#if defined (L_bitreverse24) +DEFUN __bitreverse24 + XCALL __bitreverse8 + push r24 + mov r24, r23 + XCALL __bitreverse8 + mov r23, r24 + mov r24, r22 + pop r22 + XJMP __bitreverse8 +ENDF __bitreverse24 +#endif /* L_bitreverse24 */ + +#if defined (L_bitreverse32) +DEFUN __bitreverse32 + XCALL __bitreverse16 +#if defined (__AVR_HAVE_MOVW__) + movw __tmp_reg__, r22 + movw r22, r24 + movw r24, __tmp_reg__ + clr __zero_reg__ +#else + bswap r22, r24 + bswap r23, r25 +#endif + XJMP __bitreverse16 +ENDF __bitreverse32 +#endif /* L_bitreverse32 */ + /********************************** * 64-bit shifts diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index d181784e0e72..9b05c8575b6a 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -34,6 +34,7 @@ LIB1ASMFUNCS = \ _popcountsi2 \ _popcountqi2 \ _bswapsi2 \ + _bitreverse8 _bitreverse16 _bitreverse24 _bitreverse32 \ _fmul _fmuls _fmulsu \ _mulqq3 \ _mulhq3 _muluhq3 \
