mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
The RISC-V Bit-manipulation Extension for Cryptography (Zbkb) provides the 'brev8' instruction, which reverses the bits within each byte. Combined with the 'rev8' instruction (from Zbb or Zbkb), which reverses the byte order of a register, we can efficiently implement 16-bit, 32-bit, and (on RV64) 64-bit bit reversal. This is significantly faster than the default software table-lookup implementation in lib/bitrev.c, as it replaces memory accesses and multiple arithmetic operations with just two or three hardware instructions. Select HAVE_ARCH_BITREVERSE as well as GENERIC_BITREVERSE, and provide <asm/bitrev.h> to utilize these instructions when the Zbkb extension is available at runtime via the alternatives mechanism. [Yury: select the options conditionally on BITREVERSE] Link: https://docs.riscv.org/reference/isa/unpriv/b-st-ext.html Suggested-by: David Laight <david.laight.linux@gmail.com> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Signed-off-by: Yury Norov <ynorov@nvidia.com>
52 lines
1.0 KiB
C
52 lines
1.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __ASM_BITREV_H
|
|
#define __ASM_BITREV_H
|
|
|
|
#include <linux/types.h>
|
|
#include <asm/cpufeature-macros.h>
|
|
#include <asm/hwcap.h>
|
|
#include <asm-generic/bitops/__bitrev.h>
|
|
|
|
static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
|
|
{
|
|
unsigned long result;
|
|
|
|
if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
|
|
return generic___bitrev32(x);
|
|
|
|
asm volatile(
|
|
".option push\n"
|
|
".option arch,+zbkb\n"
|
|
"rev8 %0, %1\n"
|
|
"brev8 %0, %0\n"
|
|
".option pop"
|
|
: "=r" (result) : "r" ((long)x)
|
|
);
|
|
|
|
return result >> (__riscv_xlen - 32);
|
|
}
|
|
|
|
static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
|
|
{
|
|
return __arch_bitrev32(x) >> 16;
|
|
}
|
|
|
|
static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
|
|
{
|
|
unsigned long result;
|
|
|
|
if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
|
|
return generic___bitrev8(x);
|
|
|
|
asm volatile(
|
|
".option push\n"
|
|
".option arch,+zbkb\n"
|
|
"brev8 %0, %1\n"
|
|
".option pop"
|
|
: "=r" (result) : "r" ((long)x)
|
|
);
|
|
|
|
return result;
|
|
}
|
|
#endif
|