diff --git a/clients/simple-dmabuf-v4l.c b/clients/simple-dmabuf-v4l.c index b44221e2..8ed3a0b5 100644 --- a/clients/simple-dmabuf-v4l.c +++ b/clients/simple-dmabuf-v4l.c @@ -88,7 +88,7 @@ static inline const char * dump_format(uint32_t format, char out[4]) { #if BYTE_ORDER == BIG_ENDIAN - format = __builtin_bswap32(format); + format = bswap32(format); #endif memcpy(out, &format, 4); return out; diff --git a/libweston/data-device.c b/libweston/data-device.c index 45cafa3c..f259292c 100644 --- a/libweston/data-device.c +++ b/libweston/data-device.c @@ -201,7 +201,7 @@ data_offer_set_actions(struct wl_client *client, if (preferred_action && (!(preferred_action & dnd_actions) || - __builtin_popcount(preferred_action) > 1)) { + bitcount32(preferred_action) > 1)) { wl_resource_post_error(offer->resource, WL_DATA_OFFER_ERROR_INVALID_ACTION, "invalid action %x", preferred_action); diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 44e611c4..1f50333d 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -242,7 +242,7 @@ static inline const char * dump_format(uint32_t format, char out[4]) { #if BYTE_ORDER == BIG_ENDIAN - format = __builtin_bswap32(format); + format = bswap32(format); #endif memcpy(out, &format, 4); return out; diff --git a/libweston/screenshooter.c b/libweston/screenshooter.c index 9730baf1..4e0afc07 100644 --- a/libweston/screenshooter.c +++ b/libweston/screenshooter.c @@ -252,6 +252,9 @@ static uint32_t * output_run(uint32_t *p, uint32_t delta, int run) { int i; +#if !defined(HAVE_BUILTIN_CLZ) + int tmp; +#endif while (run > 0) { if (run <= 0xe0) { @@ -259,7 +262,11 @@ output_run(uint32_t *p, uint32_t delta, int run) break; } +#if defined(HAVE_BUILTIN_CLZ) i = 24 - __builtin_clz(run); +#else + for (i = 0, tmp = u >> 8; tmp; i++, tmp >>= 1); +#endif *p++ = delta | ((i + 0xe0) << 24); run -= 1 << (7 + i); } diff --git a/meson.build b/meson.build index e12356f2..3e43a01c 100644 --- a/meson.build +++ b/meson.build @@ -94,6 +94,17 @@ foreach hdr : optional_system_headers endif endforeach +optional_builtins = { + 'builtin_clz': 'return __builtin_clz(1);', + 'builtin_bswap32': 'return __builtin_bswap32(0);', + 'builtin_popcount': 'return __builtin_popcount(0);', +} +foreach name, check : optional_builtins + if cc.links('int main(void) { @0@ }'.format(check), name: name) + config_h.set('HAVE_' + name.to_upper(), 1) + endif +endforeach + env_modmap = '' config_h.set('_GNU_SOURCE', '1') diff --git a/shared/helpers.h b/shared/helpers.h index f31ca130..b5309ce4 100644 --- a/shared/helpers.h +++ b/shared/helpers.h @@ -22,6 +22,8 @@ #ifndef WESTON_HELPERS_H #define WESTON_HELPERS_H +#include "config.h" + #include #ifdef __cplusplus @@ -233,6 +235,46 @@ do { \ #define unreachable(str) assert(!str) #endif +/** + * Returns number of bits set in 32-bit value x. + * + * @param x a 32-bit value. + * @return the number of bits set. + */ +static inline int +bitcount32(uint32_t x) +{ +#if defined(HAVE_BUILTIN_POPCOUNT) + return __builtin_popcount(x); +#else + int n; + + for (n = 0; x; n++) + x &= x - 1; + + return n; +#endif +} + +/** + * Returns 32-bit value x in reversed byte order. + * + * @param x a 32-bit value. + * @return the reversed 32-bit value. + */ +static inline uint32_t +bswap32(uint32_t x) +{ +#if defined(HAVE_BUILTIN_BSWAP32) + return __builtin_bswap32(x); +#else + return (x >> 24) | + ((x >> 8) & 0x0000ff00) | + ((x << 8) & 0x00ff0000) | + (x << 24); +#endif +} + #ifdef __cplusplus } #endif