2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

Rewrite the bit rotate functions using __builtin or generic

In gcc 15, __builtin_stdc_rotate_{left,right} was added.  Use these
builtins when available otherwise rewrite the ISC_ROTATE_LEFT and
ISC_ROTATE_RIGHT using _Generic.
This commit is contained in:
Ondřej Surý 2025-08-26 07:31:07 +02:00
parent 7e12c7de0b
commit e01151f729
4 changed files with 92 additions and 89 deletions

View File

@ -62,92 +62,84 @@
#endif /* __has_header(<stdbit.h>) */
#define ISC_ROTATE_LEFT8(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 8, \
"rotation must be a constant between 0 and 8"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint8_t), \
"rotated value must be uint8_t"); \
((x) << (n) | (x) >> (8 - (n))); \
})
#if HAVE_BUILTIN_STD_ROTATE_LEFT && HAVE_BUILTIN_STD_ROTATE_RIGHT
#define ISC_ROTATE_LEFT(x, n) __builtin_stdc_rotate_left(x, n)
#define ISC_ROTATE_RIGHT(x, n) __builtin_stdc_rotate_right(x, n)
#else /* HAVE_BUILTIN_STD_ROTATE_LEFT && HAVE_BUILTIN_STD_ROTATE_RIGHT */
#define ISC_ROTATE_LEFT16(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 16, \
"rotation must be a constant between 0 and 16"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint16_t), \
"rotated value must be uint16_t"); \
((x) << (n) | (x) >> (16 - (n))); \
})
static inline uint8_t
isc_rotate_left8(const uint8_t x, uint32_t n) {
return (x << n) | (x >> (8 - n));
}
#define ISC_ROTATE_LEFT32(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 32, \
"rotation must be a constant between 0 and 32"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint32_t), \
"rotated value must be uint32_t"); \
((x) << (n) | (x) >> (32 - (n))); \
})
static inline uint16_t
isc_rotate_left16(const uint16_t x, uint32_t n) {
return (x << n) | (x >> (16 - n));
}
#define ISC_ROTATE_LEFT64(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 64, \
"rotation must be a constant between 0 and 64"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint64_t), \
"rotated value must be uint64_t"); \
((x) << (n) | (x) >> (64 - (n))); \
})
static inline uint32_t
isc_rotate_left32(const uint32_t x, uint32_t n) {
return (x << n) | (x >> (32 - n));
}
#define ISC_ROTATE_RIGHT8(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 8, \
"rotation must be a constant between 0 and 8"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint8_t), \
"rotated value must be uint8_t"); \
((x) >> (n) | (x) << (8 - (n))); \
})
static inline uint64_t
isc_rotate_left64(const uint64_t x, uint32_t n) {
return (x << n) | (x >> (64 - n));
}
#define ISC_ROTATE_RIGHT16(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 16, \
"rotation must be a constant between 0 and 16"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint16_t), \
"rotated value must be uint16_t"); \
((x) >> (n) | (x) << (16 - (n))); \
})
static inline uint8_t
isc_rotate_right8(const uint8_t x, uint32_t n) {
return (x >> n) | (x << (8 - n));
}
#define ISC_ROTATE_RIGHT32(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 32, \
"rotation must be a constant between 0 and 32"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint32_t), \
"rotated value must be uint32_t"); \
((x) >> (n) | (x) << (32 - (n))); \
})
static inline uint16_t
isc_rotate_right16(const uint16_t x, uint32_t n) {
return (x >> n) | (x << (16 - n));
}
#define ISC_ROTATE_RIGHT64(x, n) \
({ \
STATIC_ASSERT(n > 0 && n < 64, \
"rotation must be a constant between 0 and 64"); \
STATIC_ASSERT( \
__builtin_types_compatible_p(typeof(x), uint64_t), \
"rotated value must be uint64_t"); \
((x) >> (n) | (x) << (64 - (n))); \
})
static inline uint32_t
isc_rotate_right32(const uint32_t x, uint32_t n) {
return (x >> n) | (x << (32 - n));
}
static inline uint64_t
isc_rotate_right64(const uint64_t x, uint32_t n) {
return (x >> n) | (x << (64 - n));
}
#if __APPLE_CC__
/*
* Apple compiler doesn't recognize size_t and uintXX_t types as same,
* so we need to add kludges for size_t below.
*/
#if SIZE_MAX == UINT64_MAX
#define ISC_ROTATE_LEFTSIZE(x, n) ISC_ROTATE_LEFT64((uint64_t)x, n)
#define ISC_ROTATE_RIGHTSIZE(x, n) ISC_ROTATE_RIGHT64((uint64_t)x, n)
#define EXTRA_ROTATE_LEFT , size_t : isc_rotate_left64
#define EXTRA_ROTATE_RIGHT , size_t : isc_rotate_right64
#elif SIZE_MAX == UINT32_MAX
#define ISC_ROTATE_LEFTSIZE(x, n) ISC_ROTATE_LEFT32((uint32_t)x, n)
#define ISC_ROTATE_RIGHTSIZE(x, n) ISC_ROTATE_RIGHT32((uint32_t)x, n)
#define EXTRA_ROTATE_LEFT , size_t : isc_rotate_left32
#define EXTRA_ROTATE_RIGHT , size_t : isc_rotate_right32
#else
#error "size_t must be either 32 or 64-bits"
#endif
#else
#define EXTRA_ROTATE_LEFT
#define EXTRA_ROTATE_RIGHT
#endif
#define ISC_ROTATE_LEFT(x, n) \
_Generic((x), \
uint8_t: isc_rotate_left8, \
uint16_t: isc_rotate_left16, \
uint32_t: isc_rotate_left32, \
uint64_t: isc_rotate_left64 EXTRA_ROTATE_LEFT)(x, n)
#define ISC_ROTATE_RIGHT(x, n) \
_Generic((x), \
uint8_t: isc_rotate_right8, \
uint16_t: isc_rotate_right16, \
uint32_t: isc_rotate_right32, \
uint64_t: isc_rotate_right64 EXTRA_ROTATE_RIGHT)(x, n)
#endif /* HAVE_BUILTIN_STD_ROTATE_LEFT && HAVE_BUILTIN_STD_ROTATE_RIGHT */

View File

@ -40,7 +40,7 @@
static inline size_t
fx_add_to_hash(size_t hash, size_t i) {
return ISC_ROTATE_LEFTSIZE(hash, 5) ^ i * K;
return ISC_ROTATE_LEFT(hash, 5) ^ i * K;
}
/*

View File

@ -44,12 +44,12 @@
#define cROUNDS 2
#define dROUNDS 4
#define HALF_ROUND64(a, b, c, d, s, t) \
a += b; \
c += d; \
b = ISC_ROTATE_LEFT64(b, s) ^ a; \
d = ISC_ROTATE_LEFT64(d, t) ^ c; \
a = ISC_ROTATE_LEFT64(a, 32);
#define HALF_ROUND64(a, b, c, d, s, t) \
a += b; \
c += d; \
b = ISC_ROTATE_LEFT(b, s) ^ a; \
d = ISC_ROTATE_LEFT(d, t) ^ c; \
a = ISC_ROTATE_LEFT(a, 32);
#define FULL_ROUND64(v0, v1, v2, v3) \
HALF_ROUND64(v0, v1, v2, v3, 13, 16); \
@ -57,12 +57,12 @@
#define SIPROUND FULL_ROUND64
#define HALF_ROUND32(a, b, c, d, s, t) \
a += b; \
c += d; \
b = ISC_ROTATE_LEFT32(b, s) ^ a; \
d = ISC_ROTATE_LEFT32(d, t) ^ c; \
a = ISC_ROTATE_LEFT32(a, 16);
#define HALF_ROUND32(a, b, c, d, s, t) \
a += b; \
c += d; \
b = ISC_ROTATE_LEFT(b, s) ^ a; \
d = ISC_ROTATE_LEFT(d, t) ^ c; \
a = ISC_ROTATE_LEFT(a, 16);
#define FULL_ROUND32(v0, v1, v2, v3) \
HALF_ROUND32(v0, v1, v2, v3, 5, 8); \

View File

@ -314,6 +314,7 @@ if developer_mode
config.set('DNS_TYPEPAIR_CHECK', 1)
endif
# mandatory builtins
foreach fn : [
'__builtin_add_overflow',
'__builtin_expect',
@ -327,6 +328,16 @@ foreach fn : [
endif
endforeach
# optional builtins
foreach fn : [
'__builtin_stdc_rotate_left',
'__builtin_stdc_rotate_right',
]
if cc.has_function(fn)
config.set('HAVE_@0@'.format(fn.substring(2).to_upper()), 1)
endif
endforeach
# meson_version (>=1.3.0) : required in cc.has_function
if cc.has_function('__builtin_clzg')
config.set('HAVE_BUILTIN_CLZG', true)