From a50b4d566f089ae46402a6f38096a0ff9c50eae2 Mon Sep 17 00:00:00 2001 From: "Evgeny Grin (Karlson2k)" Date: Fri, 19 Apr 2019 22:07:37 +0300 Subject: mhd_bithelpers.h: use bytes swap instead of individual bytes assignment when endianess is known to significantly speedup MD5 and SHA256 calculations. Use built-in bytes swap when available. --- src/microhttpd/mhd_bithelpers.h | 78 +++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 15 deletions(-) (limited to 'src/microhttpd/mhd_bithelpers.h') diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h index bf20293f..fa09f92a 100644 --- a/src/microhttpd/mhd_bithelpers.h +++ b/src/microhttpd/mhd_bithelpers.h @@ -29,6 +29,34 @@ #include "mhd_byteorder.h" #include + +#ifdef MHD_HAVE___BUILTIN_BSWAP32 +#define _MHD_BYTES_SWAP32(value32) \ + ((uint32_t)__builtin_bswap32((uint32_t)value32)) +#else /* ! MHD_HAVE___BUILTIN_BSWAP32 */ +#define _MHD_BYTES_SWAP32(value32) \ + ( (((uint32_t)(value32)) << 24) | \ + ((((uint32_t)(value32)) & ((uint32_t)0x0000FF00)) << 8) | \ + ((((uint32_t)(value32)) & ((uint32_t)0x00FF0000)) >> 8) | \ + (((uint32_t)(value32)) >> 24) ) +#endif /* ! MHD_HAVE___BUILTIN_BSWAP32 */ + + +#ifdef MHD_HAVE___BUILTIN_BSWAP64 +#define _MHD_BYTES_SWAP64(value64) \ + ((uint64_t)__builtin_bswap64((uint64_t)value64)) +#else /* ! MHD_HAVE___BUILTIN_BSWAP64 */ +#define _MHD_BYTES_SWAP64(value64) \ + ( (((uint64_t)(value64)) << 56) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x000000000000FF00)) << 40) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x0000000000FF0000)) << 24) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x00000000FF000000)) << 8) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x000000FF00000000)) >> 8) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x0000FF0000000000)) >> 24) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x00FF000000000000)) >> 40) | \ + (((uint64_t)(value64)) >> 56) ) +#endif /* ! MHD_HAVE___BUILTIN_BSWAP64 */ + /* _MHD_PUT_64BIT_LE (addr, value64) * put native-endian 64-bit value64 to addr * in little-endian mode. @@ -36,8 +64,12 @@ #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN #define _MHD_PUT_64BIT_LE(addr, value64) \ ((*(uint64_t*)(addr)) = (uint64_t)(value64)) -#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ -#define _MHD_PUT_64BIT_LE(addr, value64) do { \ +#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN +#define _MHD_PUT_64BIT_LE(addr, value64) \ + ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) +#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_64BIT_LE(addr, value64) do { \ ((uint8_t*)(addr))[0] = (uint8_t)((uint64_t)(value64)); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 8); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint64_t)(value64)) >> 16); \ @@ -47,23 +79,27 @@ ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 48); \ ((uint8_t*)(addr))[7] = (uint8_t)(((uint64_t)(value64)) >> 56); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ /* _MHD_PUT_32BIT_LE (addr, value32) * put native-endian 32-bit value32 to addr * in little-endian mode. */ #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN -#define _MHD_PUT_32BIT_LE(addr, value32) \ +#define _MHD_PUT_32BIT_LE(addr,value32) \ ((*(uint32_t*)(addr)) = (uint32_t)(value32)) -#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ -#define _MHD_PUT_32BIT_LE(addr, value32) do { \ +#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN +#define _MHD_PUT_32BIT_LE(addr, value32) \ + ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) +#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_32BIT_LE(addr, value32) do { \ ((uint8_t*)(addr))[0] = (uint8_t)((uint32_t)(value32)); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 8); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 16); \ ((uint8_t*)(addr))[3] = (uint8_t)(((uint32_t)(value32)) >> 24); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ /* _MHD_PUT_64BIT_BE (addr, value64) @@ -73,8 +109,12 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_PUT_64BIT_BE(addr, value64) \ ((*(uint64_t*)(addr)) = (uint64_t)(value64)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ -#define _MHD_PUT_64BIT_BE(addr, value64) do { \ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_PUT_64BIT_BE(addr, value64) \ + ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_64BIT_BE(addr, value64) do { \ ((uint8_t*)(addr))[7] = (uint8_t)((uint64_t)(value64)); \ ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 8); \ ((uint8_t*)(addr))[5] = (uint8_t)(((uint64_t)(value64)) >> 16); \ @@ -84,7 +124,7 @@ ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 48); \ ((uint8_t*)(addr))[0] = (uint8_t)(((uint64_t)(value64)) >> 56); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /* _MHD_PUT_32BIT_BE (addr, value32) * put native-endian 32-bit value32 to addr @@ -93,14 +133,18 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_PUT_32BIT_BE(addr, value32) \ ((*(uint32_t*)(addr)) = (uint32_t)(value32)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ -#define _MHD_PUT_32BIT_BE(addr, value32) do { \ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_PUT_32BIT_BE(addr, value32) \ + ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_32BIT_BE(addr, value32) do { \ ((uint8_t*)(addr))[3] = (uint8_t)((uint32_t)(value32)); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 8); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 16); \ ((uint8_t*)(addr))[0] = (uint8_t)(((uint32_t)(value32)) >> 24); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /* _MHD_GET_32BIT_BE (addr) * get big-endian 32-bit value storied at addr @@ -109,13 +153,17 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_GET_32BIT_BE(addr) \ (*(uint32_t*)(addr)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_GET_32BIT_BE(addr) \ + _MHD_BYTES_SWAP32(*(uint32_t*)(addr)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ #define _MHD_GET_32BIT_BE(addr) \ ( (((uint32_t)(((uint8_t*)addr)[0])) << 24) | \ (((uint32_t)(((uint8_t*)addr)[1])) << 16) | \ (((uint32_t)(((uint8_t*)addr)[2])) << 8) | \ ((uint32_t) (((uint8_t*)addr)[3])) ) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /** * Rotate right 32-bit value by number of bits. -- cgit v1.2.3