This peephole pattern combines the following instructions: bswap8: rev8 a5,a0 -> li a4,-65536 -> srai a5,a5,32 -> and a5,a5,a4 -> roriw a5,a5,16 and a0,a0,a4 or a0,a0,a5 sext.w a0,a0 ret
And emits this assembly: bswap8: rev8 a5,a0 -> li a4,-65536 -> srai a5,a5,48 and a0,a0,a4 or a0,a0,a5 sext.w a0,a0 ret Since the load instruction is required for the rest of the test function in the PR, the pattern conserves the load. 2025-07-10 Dusan Stojkovic <dusan.stojko...@rt-rk.com> PR target/120920 gcc/ChangeLog: * config/riscv/peephole.md: New pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/zbb_bswap8.c: New test. CONFIDENTIALITY: The contents of this e-mail are confidential and intended only for the above addressee(s). If you are not the intended recipient, or the person responsible for delivering it to the intended recipient, copying or delivering it to anyone else or using it in any unauthorized manner is prohibited and may be unlawful. If you receive this e-mail by mistake, please notify the sender and the systems administrator at straym...@rt-rk.com immediately.
--- gcc/config/riscv/peephole.md | 28 +++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/zbb_bswap8.c | 10 ++++++++ 2 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/zbb_bswap8.c diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md index b5cc1924c76..b07de8bf83e 100644 --- a/gcc/config/riscv/peephole.md +++ b/gcc/config/riscv/peephole.md @@ -66,3 +66,31 @@ (set (match_dup 2) (match_dup 3))])] ) + +;; ZBB + +(define_peephole2 + [(set (match_operand:DI 0 "register_operand") + (ashiftrt:DI (match_operand:DI 1 "register_operand") + (match_operand 2 "const_int_operand"))) + (set (match_operand:DI 3 "register_operand") + (match_operand 4 "const_int_operand")) + (set (match_dup 1) + (and:DI (match_dup 1) (match_dup 3))) + (set (match_operand:SI 5 "register_operand") + (rotatert:SI (match_operand:SI 6 "register_operand") + (match_operand 7 "const_int_operand")))] + "TARGET_ZBB && TARGET_64BIT + && (REGNO (operands[0]) == REGNO (operands[5])) + && (REGNO (operands[1]) == REGNO (operands[6])) + && (ctz_hwi (INTVAL (operands[4])) == INTVAL (operands[7]))" + [(set (match_dup 3) + (match_operand 4)) + (set (match_dup 0) + (ashiftrt:DI (match_dup 1) + (match_operand 7 "const_int_operand")))] +{ + unsigned HOST_WIDE_INT mask = INTVAL (operands[4]); + int trailing = ctz_hwi (mask); + operands[7] = GEN_INT (trailing + INTVAL (operands[2])); +}) diff --git a/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c b/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c new file mode 100644 index 00000000000..77441b720b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64d -O2" { target { rv64 } } } */ + +unsigned int bswap8(unsigned int n) +{ + return (n & 0xffff0000) | ((n & 0xff00) >> 8) | ((n & 0xff) << 8); +} + +/* { dg-final { scan-assembler {\mrev8} } } */ +/* { dg-final { scan-assembler {\msrai\s+[ax][0-9]+,\s*[ax][0-9]+,\s*48} } } */ -- 2.43.0