[libdvdnav-devel] [Git][videolan/libdvdread][master] 4 commits: bswap: prefer compiler builtins for byte swapping
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri Jul 31 07:44:12 UTC 2026
Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread
Commits:
15544323 by Kacper Michajłow at 2026-07-31T09:43:01+02:00
bswap: prefer compiler builtins for byte swapping
Every GCC and Clang able to build this project provides the
__builtin_bswap* family (GCC >= 4.8, Clang >= 3.2), so use it
unconditionally instead of the version checks, and use the _byteswap_*
intrinsics on MSVC.
- - - - -
b5d511a9 by Kacper Michajłow at 2026-07-31T09:43:01+02:00
bswap: rewrite portable version
Use inline funciton to avoid muliple evaluation issue that previous
macros had. Use macros to expand the swapping, instead of hand rolling
byte masks.
Note the BSWAP* macros are for readability, to avoid repeaning
masks/cast in each inline function. Otherwise compiler would warn about
implicit conversions, but since it sees full chain, it is happy.
Also note, contrary to the old comment, this version is not slow. Any
competent optimizing compiler will recognize the byte swapping pattern,
and use dedicated instruction if available.
- - - - -
15238fc3 by Kacper Michajłow at 2026-07-31T09:43:01+02:00
bswap: remove system specific byte swap functions
These branches predate compiler byteswap builtins and by now are
redundant. Most if not all of those platform specific functions, are
expand to the same builtins on any current system, so they added mostly
noise. For majority of deployments GCC/Clang/MSVC(-like) compilers the
builtin is used, for the rest portable C version, which modern
optimizers lower to a single bswap instruction anyway.
Exotic compilers that fail to recognize the byteswap idiom will emit a
few extra ALU ops, which is an acceptable trade-off for the
simplification. They probably wouldn't compile with meson anyway...
- - - - -
337c1519 by Kacper Michajłow at 2026-07-31T09:43:01+02:00
meson: remove sys/param.h check
Not needed anymore.
- - - - -
2 changed files:
- meson.build
- src/bswap.h
Changes:
=====================================
meson.build
=====================================
@@ -47,18 +47,6 @@ if host_machine.system() == 'windows'
'-D_CRT_SECURE_NO_WARNINGS']
endif
-# Header checks
-
-check_headers = [
- 'sys/param.h',
-]
-
-foreach h : check_headers
- if cc.has_header(h, args: test_args)
- cdata.set('HAVE_' + h.underscorify().to_upper(), 1)
- endif
-endforeach
-
cdata.set('UNUSED', cc.has_function_attribute('unused') ? '__attribute__((unused))' : '')
if host_machine.endian() == 'big'
=====================================
src/bswap.h
=====================================
@@ -22,116 +22,46 @@
#ifndef LIBDVDREAD_BSWAP_H
#define LIBDVDREAD_BSWAP_H
-#include <config.h>
-
#if defined(WORDS_BIGENDIAN)
/* All bigendian systems are fine, just ignore the swaps. */
#define B2N_16(x) (void)(x)
#define B2N_32(x) (void)(x)
#define B2N_64(x) (void)(x)
-#else /* WORDS_BIGENDIAN */
-
-#if defined(__clang__)
-# if __has_builtin (__builtin_bswap16)
-# define BSWAP_BUILTIN 1
-# endif
-
-#elif defined (__GNUC__) && ((__GNUC__ > (4)) || (__GNUC__ == (4) && __GNUC_MINOR__ >= (8)))
-# define BSWAP_BUILTIN 1
-#endif
-
-#if defined(BSWAP_BUILTIN)
-
-#define B2N_16(x) x = __builtin_bswap16(x)
-#define B2N_32(x) x = __builtin_bswap32(x)
-#define B2N_64(x) x = __builtin_bswap64(x)
-
-#else /* BSWAP_BUILTIN */
-
-/* For __FreeBSD_version */
-#if defined(HAVE_SYS_PARAM_H)
-#include <sys/param.h>
-#endif
-
-#if defined(__linux__) || defined(__GLIBC__)
-#include <byteswap.h>
-#define B2N_16(x) x = bswap_16(x)
-#define B2N_32(x) x = bswap_32(x)
-#define B2N_64(x) x = bswap_64(x)
+#elif defined(__GNUC__) || defined(__clang__)
-#elif defined(__APPLE__)
-#include <libkern/OSByteOrder.h>
-#define B2N_16(x) x = OSSwapBigToHostInt16(x)
-#define B2N_32(x) x = OSSwapBigToHostInt32(x)
-#define B2N_64(x) x = OSSwapBigToHostInt64(x)
+#define B2N_16(x) ((x) = __builtin_bswap16(x))
+#define B2N_32(x) ((x) = __builtin_bswap32(x))
+#define B2N_64(x) ((x) = __builtin_bswap64(x))
-#elif defined(__NetBSD__)
-#include <sys/endian.h>
-#define B2N_16(x) BE16TOH(x)
-#define B2N_32(x) BE32TOH(x)
-#define B2N_64(x) BE64TOH(x)
+#elif defined(_MSC_VER)
-#elif defined(__OpenBSD__)
-#include <sys/endian.h>
-#define B2N_16(x) x = swap16(x)
-#define B2N_32(x) x = swap32(x)
-#define B2N_64(x) x = swap64(x)
+#include <stdlib.h>
-#elif defined(__FreeBSD__) && __FreeBSD_version >= 470000
-#include <sys/endian.h>
-#define B2N_16(x) x = be16toh(x)
-#define B2N_32(x) x = be32toh(x)
-#define B2N_64(x) x = be64toh(x)
+#define B2N_16(x) ((x) = _byteswap_ushort(x))
+#define B2N_32(x) ((x) = _byteswap_ulong(x))
+#define B2N_64(x) ((x) = _byteswap_uint64(x))
-#elif defined(__QNXNTO__)
-#include <gulliver.h>
-#define B2N_16(x) x = ENDIAN_RET16(x)
-#define B2N_32(x) x = ENDIAN_RET32(x)
-#define B2N_64(x) x = ENDIAN_RET64(x)
+#else
-#elif defined(__DragonFly__)
-#include <sys/endian.h>
-#define B2N_16(x) x = bswap16(x)
-#define B2N_32(x) x = bswap32(x)
-#define B2N_64(x) x = bswap64(x)
+#include <stdint.h>
-/* This is a slow but portable implementation, it has multiple evaluation
- * problems so beware.
- * Old FreeBSD's and Solaris don't have <byteswap.h> or any other such
- * functionality!
- */
+#define BSWAP16(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff))
+#define BSWAP32(x) (BSWAP16(x) << 16 | BSWAP16((x) >> 16))
+#define BSWAP64(x) (BSWAP32(x) << 32 | BSWAP32((x) >> 32))
-#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(_WIN32) || defined(__CYGWIN__) || defined(__BEOS__) || defined(__OS2__)
-#define B2N_16(x) \
- x = ((((x) & 0xff00) >> 8) | \
- (((x) & 0x00ff) << 8))
-#define B2N_32(x) \
- x = ((((x) & 0xff000000) >> 24) | \
- (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | \
- (((x) & 0x000000ff) << 24))
-#define B2N_64(x) \
- x = ((((x) & 0xff00000000000000ULL) >> 56) | \
- (((x) & 0x00ff000000000000ULL) >> 40) | \
- (((x) & 0x0000ff0000000000ULL) >> 24) | \
- (((x) & 0x000000ff00000000ULL) >> 8) | \
- (((x) & 0x00000000ff000000ULL) << 8) | \
- (((x) & 0x0000000000ff0000ULL) << 24) | \
- (((x) & 0x000000000000ff00ULL) << 40) | \
- (((x) & 0x00000000000000ffULL) << 56))
+static inline uint16_t dvdread_bswap16(uint16_t x) { return BSWAP16(x); }
+static inline uint32_t dvdread_bswap32(uint32_t x) { return BSWAP32(x); }
+static inline uint64_t dvdread_bswap64(uint64_t x) { return BSWAP64(x); }
-#else
+#define B2N_16(x) ((x) = dvdread_bswap16(x))
+#define B2N_32(x) ((x) = dvdread_bswap32(x))
+#define B2N_64(x) ((x) = dvdread_bswap64(x))
-/* If there isn't a header provided with your system with this functionality
- * add the relevant || define( ) to the portable implementation above.
- */
-#error "You need to add endian swap macros for your system"
+#undef BSWAP16
+#undef BSWAP32
+#undef BSWAP64
#endif
-#endif /* BSWAP_BUILTIN */
-
-#endif /* WORDS_BIGENDIAN */
-
#endif /* LIBDVDREAD_BSWAP_H */
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/e149111f8f69ef291e4d8c166527257c3c86cea4...337c1519ed6ecdd123b07c56d0aceda169b6ae61
--
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/e149111f8f69ef291e4d8c166527257c3c86cea4...337c1519ed6ecdd123b07c56d0aceda169b6ae61
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the libdvdnav-devel
mailing list