[PATCH] arm: use built-in byte swap function

From: Kim Phillips
Date: Mon Jan 28 2013 - 20:30:33 EST


Enable the compiler intrinsic for byte swapping on arch ARM. This
allows the compiler to detect and be able to optimize out byte
swappings.

__builtin_bswap{32,64} support was added in gcc 4.4, but until
gcc 4.5, it emitted calls to libgcc's __bswap[sd]i2 (even
with -O2).

All gcc versions tested (4.[4567]) emit calls to __bswap[sd]i2 when
optimizing for size, so we add the !CC_OPTIMIZE_FOR_SIZE check.

Support for 16-bit built-ins will be in gcc version 4.8.

This has a tiny benefit on vmlinux text size (gcc 4.6.4):

multi_v7_defconfig:
text data bss dec hex filename
3135208 188396 203344 3526948 35d124 vmlinux
multi_v7_defconfig with builtin_bswap:
text data bss dec hex filename
3135112 188396 203344 3526852 35d0c4 vmlinux

exynos_defconfig:
text data bss dec hex filename
4286605 360564 223172 4870341 4a50c5 vmlinux
exynos_defconfig with builtin_bswap:
text data bss dec hex filename
4286405 360564 223172 4870141 4a4ffd vmlinux

The savings come mostly from device-tree related code, and some
from drivers.

Signed-off-by: Kim Phillips <kim.phillips@xxxxxxxxxxxxx>
---
akin to: http://comments.gmane.org/gmane.linux.kernel.cross-arch/16016

based on linux-next-20130128. Depends on commit "compiler-gcc{3,4}.h:
Use GCC_VERSION macro" by Daniel Santos <daniel.santos@xxxxxxxxx>,
currently in the akpm branch.

v5: re-work based on new gcc version test data:
- moved outside armv6 protection
- check for gcc 4.6+ demoted to gcc 4.5+ with:
!defined(CONFIG_CC_OPTIMIZE_FOR_SIZE)

v4:
- undo v2-2's addition of ARCH_DEFINES_BUILTIN_BSWAP per Boris
and David - object is to find arches that define _HAVE_BSWAP
and clean it up in the future: patch is much less intrusive. :)

v3:
- moved out of uapi swab.h into arch/arm/include/asm/swab.h
- moved ARCH_DEFINES_BUILTIN_BSWAP help text into commit message
- moved GCC_VERSION >= 40800 ifdef into GCC_VERSION >= 40600 block

v2:
- at91 and lpd270 builds fixed by limiting to ARMv6 and above
(i.e., ARM cores that have support for the 'rev' instruction).
Otherwise, the compiler emits calls to libgcc's __bswapsi2 on
these ARMv4/v5 builds (and arch ARM doesn't link with libgcc).
All ARM defconfigs now have the same build status as they did
without this patch (some are broken on linux-next).

- move ARM check from generic compiler.h to arch ARM's swab.h.
- pretty sure it should be limited to __KERNEL__ builds

- add new ARCH_DEFINES_BUILTIN_BSWAP (see Kconfig help).
- if set, generic compiler header does not set HAVE_BUILTIN_BSWAPxx
- not too sure about this having to be a new CONFIG_, but it's hard
to find a place for it given linux/compiler.h doesn't include any
arch-specific files.

- move new selects to end of CONFIG_ARM's Kconfig select list,
as is done in David Woodhouse's original patchseries for ppc/x86.

arch/arm/include/asm/swab.h | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
index 537fc9b..159ab16 100644
--- a/arch/arm/include/asm/swab.h
+++ b/arch/arm/include/asm/swab.h
@@ -35,4 +35,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
#define __arch_swab32 __arch_swab32

#endif
+
+#if !defined(CONFIG_CC_OPTIMIZE_FOR_SIZE) && GCC_VERSION >= 40500
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#if GCC_VERSION >= 40800
+#define __HAVE_BUILTIN_BSWAP16__
+#endif
+#endif
+
#endif
--
1.7.9.7

Thanks,

Kim

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44392
[2] http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/