From: Rostislav Krasny <rostiprodev@gmail.com>
To: git@vger.kernel.org
Cc: Rostislav Krasny <rostiprodev@gmail.com>,
Junio C Hamano <gitster@pobox.com>,
Sebastian Andrzej Siewior <sebastian@breakpoint.cc>,
Jeff King <peff@peff.net>
Subject: [PATCH 1/1] compat: modernize and simplify byte swapping functions
Date: Fri, 2 Jan 2026 02:27:35 +0200 [thread overview]
Message-ID: <20260102002735.31390-2-rostiprodev@gmail.com> (raw)
In-Reply-To: <20260102002735.31390-1-rostiprodev@gmail.com>
Replace manual bit operations with memcpy + network functions for better
maintainability. Add missing 16-bit network byte order conversion.
Key improvements:
- Simplify the get_be*() and put_be*() functions
- Add bswap16() macro with automatic compiler optimization:
* GCC/Clang: __builtin_bswap16() intrinsic
* MSVC: _byteswap_ushort() intrinsic
- Add default_bswap16() static inline function with manual fallback implementation
- Rename default_swab32() to default_bswap32() for naming consistency
- Add ntohs() and htons() macros for complete 16/32/64-bit network conversion
- Add put_be16() function for API completeness alongside existing put_be*() and
get_be*() functions
- Performance improvements (GCC 15.2.1, Clang 21.1.7):
* on x86-64 with -O0 4.2x faster (GCC), 3.7x faster (Clang)
* on x86-64 with -O1 4x faster (GCC), identical (Clang)
* on x86-64 with -O2 identical (GCC), 1.8x faster (Clang)
Signed-off-by: Rostislav Krasny <rostiprodev@gmail.com>
---
compat/bswap.h | 74 ++++++++++++++++++++++++++++++--------------------
1 file changed, 44 insertions(+), 30 deletions(-)
diff --git a/compat/bswap.h b/compat/bswap.h
index 28635ebc69..f9954ef090 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -9,10 +9,15 @@
*/
/*
- * Default version that the compiler ought to optimize properly with
+ * Default versions that the compiler ought to optimize properly with
* constant values.
*/
-static inline uint32_t default_swab32(uint32_t val)
+static inline uint16_t default_bswap16(uint16_t val)
+{
+ return ((val & 0xff00) >> 8) | ((val & 0x00ff) << 8);
+}
+
+static inline uint32_t default_bswap32(uint32_t val)
{
return (((val & 0xff000000) >> 24) |
((val & 0x00ff0000) >> 8) |
@@ -40,6 +45,7 @@ static inline uint64_t default_bswap64(uint64_t val)
# define __has_builtin(x) 0
#endif
+#undef bswap16
#undef bswap32
#undef bswap64
@@ -47,6 +53,7 @@ static inline uint64_t default_bswap64(uint64_t val)
#include <stdlib.h>
+#define bswap16(x) _byteswap_ushort(x)
#define bswap32(x) _byteswap_ulong(x)
#define bswap64(x) _byteswap_uint64(x)
@@ -54,8 +61,9 @@ static inline uint64_t default_bswap64(uint64_t val)
#define GIT_BIG_ENDIAN 4321
#define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
-#elif __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
+#elif __has_builtin(__builtin_bswap16) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
+#define bswap16(x) __builtin_bswap16((x))
#define bswap32(x) __builtin_bswap32((x))
#define bswap64(x) __builtin_bswap64((x))
@@ -98,24 +106,36 @@ static inline uint64_t default_bswap64(uint64_t val)
#endif
+#undef ntohs
+#undef htons
#undef ntohl
#undef htonl
#undef ntohll
#undef htonll
#if GIT_BYTE_ORDER == GIT_BIG_ENDIAN
+# define ntohs(x) (x)
+# define htons(x) (x)
# define ntohl(x) (x)
# define htonl(x) (x)
# define ntohll(x) (x)
# define htonll(x) (x)
#else
+# if defined(bswap16)
+# define ntohs(x) bswap16(x)
+# define htons(x) bswap16(x)
+# else
+# define ntohs(x) default_bswap16(x)
+# define htons(x) default_bswap16(x)
+# endif
+
# if defined(bswap32)
# define ntohl(x) bswap32(x)
# define htonl(x) bswap32(x)
# else
-# define ntohl(x) default_swab32(x)
-# define htonl(x) default_swab32(x)
+# define ntohl(x) default_bswap32(x)
+# define htonl(x) default_bswap32(x)
# endif
# if defined(bswap64)
@@ -129,47 +149,41 @@ static inline uint64_t default_bswap64(uint64_t val)
static inline uint16_t get_be16(const void *ptr)
{
- const unsigned char *p = ptr;
- return (uint16_t)p[0] << 8 |
- (uint16_t)p[1] << 0;
+ uint16_t n;
+ memcpy(&n, ptr, sizeof n);
+ return ntohs(n);
}
static inline uint32_t get_be32(const void *ptr)
{
- const unsigned char *p = ptr;
- return (uint32_t)p[0] << 24 |
- (uint32_t)p[1] << 16 |
- (uint32_t)p[2] << 8 |
- (uint32_t)p[3] << 0;
+ uint32_t n;
+ memcpy(&n, ptr, sizeof n);
+ return ntohl(n);
}
static inline uint64_t get_be64(const void *ptr)
{
- const unsigned char *p = ptr;
- return (uint64_t)get_be32(&p[0]) << 32 |
- (uint64_t)get_be32(&p[4]) << 0;
+ uint64_t n;
+ memcpy(&n, ptr, sizeof n);
+ return ntohll(n);
+}
+
+static inline void put_be16(void *ptr, uint16_t value)
+{
+ uint16_t n = htons(value);
+ memcpy(ptr, &n, sizeof n);
}
static inline void put_be32(void *ptr, uint32_t value)
{
- unsigned char *p = ptr;
- p[0] = (value >> 24) & 0xff;
- p[1] = (value >> 16) & 0xff;
- p[2] = (value >> 8) & 0xff;
- p[3] = (value >> 0) & 0xff;
+ uint32_t n = htonl(value);
+ memcpy(ptr, &n, sizeof n);
}
static inline void put_be64(void *ptr, uint64_t value)
{
- unsigned char *p = ptr;
- p[0] = (value >> 56) & 0xff;
- p[1] = (value >> 48) & 0xff;
- p[2] = (value >> 40) & 0xff;
- p[3] = (value >> 32) & 0xff;
- p[4] = (value >> 24) & 0xff;
- p[5] = (value >> 16) & 0xff;
- p[6] = (value >> 8) & 0xff;
- p[7] = (value >> 0) & 0xff;
+ uint64_t n = htonll(value);
+ memcpy(ptr, &n, sizeof n);
}
#endif /* COMPAT_BSWAP_H */
--
2.52.0
next prev parent reply other threads:[~2026-01-02 0:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-02 0:27 [PATCH 0/1] compat: modernize and simplify byte swapping functions Rostislav Krasny
2026-01-02 0:27 ` Rostislav Krasny [this message]
2026-01-02 6:16 ` [PATCH 1/1] " Jeff King
2026-01-02 17:37 ` Rostislav Krasny
2026-01-11 22:05 ` Rostislav Krasny
2026-01-14 21:14 ` Jeff King
2026-01-02 7:29 ` [PATCH 0/1] " Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260102002735.31390-2-rostiprodev@gmail.com \
--to=rostiprodev@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
--cc=sebastian@breakpoint.cc \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.