diff options
author | Sean Anderson <sean.anderson@seco.com> | 2023-07-31 17:27:33 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-08-17 16:39:20 -0400 |
commit | 726a802fdaf1ffb4ca95ebf6910a738781137ef5 (patch) | |
tree | 7d2df62ee83092d7b8b6032f48a980b2a212df8c /arch/arm/lib | |
parent | 14ba0a8bbc342a677982acc787ae542b84ed7993 (diff) |
arm: Use builtins for ffs/fls
Since ARMv5, the clz instruction allows for efficient implementation of
ffs/fls with builtins. Until ARMv7 (with Thumb-2), this instruction is
only available in ARM mode. LTO makes it difficult to force specific
functions to be in ARM mode, as it is effectively a form of very
aggressive inlining. To work around this, fls/ffs are implemented in
assembly for ARMv5 and ARMv6 when compiling U-Boot in Thumb mode.
Overall, this saves around 75 bytes per call.
This code is synced with v5.15 of the Linux kernel.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/lib/bitops.S | 45 |
2 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 62cf80f373..b1bcd37466 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -113,6 +113,11 @@ AFLAGS_REMOVE_memset.o := -mthumb -mthumb-interwork AFLAGS_REMOVE_memcpy.o := -mthumb -mthumb-interwork AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD + +# This is only necessary to force ARM mode on THUMB1 targets. +ifneq ($(CONFIG_SYS_ARM_ARCH),4) +obj-y += bitops.o +endif endif endif diff --git a/arch/arm/lib/bitops.S b/arch/arm/lib/bitops.S new file mode 100644 index 0000000000..29d1524634 --- /dev/null +++ b/arch/arm/lib/bitops.S @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Sean Anderson <sean.anderson@seco.com> + * + * ARM bitops to call when using THUMB1, which doesn't have these instructions. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + +.pushsection .text.__fls +ENTRY(__fls) + clz r0, r0 + rsb r0, r0, #31 + ret lr +ENDPROC(__fls) +.popsection + +.pushsection .text.__ffs +ENTRY(__ffs) + rsb r3, r0, #0 + and r0, r0, r3 + clz r0, r0 + rsb r0, r0, #31 + ret lr +ENDPROC(__ffs) +.popsection + +.pushsection .text.fls +ENTRY(fls) + cmp r0, #0 + clzne r0, r0 + rsbne r0, r0, #32 + ret lr +ENDPROC(fls) +.popsection + +.pushsection .text.ffs +ENTRY(ffs) + rsb r3, r0, #0 + and r0, r0, r3 + clz r0, r0 + rsb r0, r0, #32 + ret lr +ENDPROC(ffs) +.popsection |