diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-04-19 22:07:37 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-04-19 22:07:37 +0300 |
commit | a50b4d566f089ae46402a6f38096a0ff9c50eae2 (patch) | |
tree | f2db23e5e9ea8a3e5d6c324fe77e6738c9fc0843 | |
parent | 9998ca76905bb3b922c147281e13f4718bf72fe3 (diff) | |
download | libmicrohttpd-a50b4d566f089ae46402a6f38096a0ff9c50eae2.tar.gz libmicrohttpd-a50b4d566f089ae46402a6f38096a0ff9c50eae2.zip |
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.
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/microhttpd/mhd_bithelpers.h | 78 |
2 files changed, 77 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac index 62f5ed5e..c977f746 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -662,6 +662,20 @@ AX_CHECK_LINK_FLAG([-fno-strict-aliasing], | |||
662 | 662 | ||
663 | AC_C_BIGENDIAN | 663 | AC_C_BIGENDIAN |
664 | AC_C_VARARRAYS | 664 | AC_C_VARARRAYS |
665 | AC_CACHE_CHECK([[whether __builtin_bswap32() is available]], | ||
666 | [[mhd_cv_func___builtin_bswap32_avail]], [dnl | ||
667 | AC_TRY_LINK([#include<stdint.h>],[uint32_t a = 1; uint32_t b = __builtin_bswap32(a); a = b;], | ||
668 | [[mhd_cv_func___builtin_bswap32_avail="yes"]], [[mhd_cv_func___builtin_bswap32_avail="no"]]) | ||
669 | ]) | ||
670 | AS_IF([[test "x$mhd_cv_func___builtin_bswap32_avail" = "xyes"]], | ||
671 | [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP32]], [[1]], [Define to 1 if you have __builtin_bswap32() builtin function])]) | ||
672 | AC_CACHE_CHECK([[whether __builtin_bswap64() is available]], | ||
673 | [[mhd_cv_func___builtin_bswap64_avail]], [dnl | ||
674 | AC_TRY_LINK([#include<stdint.h>],[uint64_t a = 1; uint32_t b = __builtin_bswap64(a); a = b;], | ||
675 | [[mhd_cv_func___builtin_bswap64_avail="yes"]], [[mhd_cv_func___builtin_bswap64_avail="no"]]) | ||
676 | ]) | ||
677 | AS_IF([[test "x$mhd_cv_func___builtin_bswap64_avail" = "xyes"]], | ||
678 | [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP64]], [[1]], [Define to 1 if you have __builtin_bswap64() builtin function])]) | ||
665 | 679 | ||
666 | AC_CHECK_PROG([HAVE_CURL_BINARY],[curl],[yes],[no]) | 680 | AC_CHECK_PROG([HAVE_CURL_BINARY],[curl],[yes],[no]) |
667 | AM_CONDITIONAL([HAVE_CURL_BINARY],[test "x$HAVE_CURL_BINARY" = "xyes"]) | 681 | AM_CONDITIONAL([HAVE_CURL_BINARY],[test "x$HAVE_CURL_BINARY" = "xyes"]) |
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 @@ | |||
29 | #include "mhd_byteorder.h" | 29 | #include "mhd_byteorder.h" |
30 | #include <stdint.h> | 30 | #include <stdint.h> |
31 | 31 | ||
32 | |||
33 | #ifdef MHD_HAVE___BUILTIN_BSWAP32 | ||
34 | #define _MHD_BYTES_SWAP32(value32) \ | ||
35 | ((uint32_t)__builtin_bswap32((uint32_t)value32)) | ||
36 | #else /* ! MHD_HAVE___BUILTIN_BSWAP32 */ | ||
37 | #define _MHD_BYTES_SWAP32(value32) \ | ||
38 | ( (((uint32_t)(value32)) << 24) | \ | ||
39 | ((((uint32_t)(value32)) & ((uint32_t)0x0000FF00)) << 8) | \ | ||
40 | ((((uint32_t)(value32)) & ((uint32_t)0x00FF0000)) >> 8) | \ | ||
41 | (((uint32_t)(value32)) >> 24) ) | ||
42 | #endif /* ! MHD_HAVE___BUILTIN_BSWAP32 */ | ||
43 | |||
44 | |||
45 | #ifdef MHD_HAVE___BUILTIN_BSWAP64 | ||
46 | #define _MHD_BYTES_SWAP64(value64) \ | ||
47 | ((uint64_t)__builtin_bswap64((uint64_t)value64)) | ||
48 | #else /* ! MHD_HAVE___BUILTIN_BSWAP64 */ | ||
49 | #define _MHD_BYTES_SWAP64(value64) \ | ||
50 | ( (((uint64_t)(value64)) << 56) | \ | ||
51 | ((((uint64_t)(value64)) & ((uint64_t)0x000000000000FF00)) << 40) | \ | ||
52 | ((((uint64_t)(value64)) & ((uint64_t)0x0000000000FF0000)) << 24) | \ | ||
53 | ((((uint64_t)(value64)) & ((uint64_t)0x00000000FF000000)) << 8) | \ | ||
54 | ((((uint64_t)(value64)) & ((uint64_t)0x000000FF00000000)) >> 8) | \ | ||
55 | ((((uint64_t)(value64)) & ((uint64_t)0x0000FF0000000000)) >> 24) | \ | ||
56 | ((((uint64_t)(value64)) & ((uint64_t)0x00FF000000000000)) >> 40) | \ | ||
57 | (((uint64_t)(value64)) >> 56) ) | ||
58 | #endif /* ! MHD_HAVE___BUILTIN_BSWAP64 */ | ||
59 | |||
32 | /* _MHD_PUT_64BIT_LE (addr, value64) | 60 | /* _MHD_PUT_64BIT_LE (addr, value64) |
33 | * put native-endian 64-bit value64 to addr | 61 | * put native-endian 64-bit value64 to addr |
34 | * in little-endian mode. | 62 | * in little-endian mode. |
@@ -36,8 +64,12 @@ | |||
36 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN | 64 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
37 | #define _MHD_PUT_64BIT_LE(addr, value64) \ | 65 | #define _MHD_PUT_64BIT_LE(addr, value64) \ |
38 | ((*(uint64_t*)(addr)) = (uint64_t)(value64)) | 66 | ((*(uint64_t*)(addr)) = (uint64_t)(value64)) |
39 | #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | 67 | #elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
40 | #define _MHD_PUT_64BIT_LE(addr, value64) do { \ | 68 | #define _MHD_PUT_64BIT_LE(addr, value64) \ |
69 | ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) | ||
70 | #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | ||
71 | /* Endianess was not detected or non-standard like PDP-endian */ | ||
72 | #define _MHD_PUT_64BIT_LE(addr, value64) do { \ | ||
41 | ((uint8_t*)(addr))[0] = (uint8_t)((uint64_t)(value64)); \ | 73 | ((uint8_t*)(addr))[0] = (uint8_t)((uint64_t)(value64)); \ |
42 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 8); \ | 74 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 8); \ |
43 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint64_t)(value64)) >> 16); \ | 75 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint64_t)(value64)) >> 16); \ |
@@ -47,23 +79,27 @@ | |||
47 | ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 48); \ | 79 | ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 48); \ |
48 | ((uint8_t*)(addr))[7] = (uint8_t)(((uint64_t)(value64)) >> 56); \ | 80 | ((uint8_t*)(addr))[7] = (uint8_t)(((uint64_t)(value64)) >> 56); \ |
49 | } while (0) | 81 | } while (0) |
50 | #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | 82 | #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ |
51 | 83 | ||
52 | /* _MHD_PUT_32BIT_LE (addr, value32) | 84 | /* _MHD_PUT_32BIT_LE (addr, value32) |
53 | * put native-endian 32-bit value32 to addr | 85 | * put native-endian 32-bit value32 to addr |
54 | * in little-endian mode. | 86 | * in little-endian mode. |
55 | */ | 87 | */ |
56 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN | 88 | #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
57 | #define _MHD_PUT_32BIT_LE(addr, value32) \ | 89 | #define _MHD_PUT_32BIT_LE(addr,value32) \ |
58 | ((*(uint32_t*)(addr)) = (uint32_t)(value32)) | 90 | ((*(uint32_t*)(addr)) = (uint32_t)(value32)) |
59 | #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | 91 | #elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
60 | #define _MHD_PUT_32BIT_LE(addr, value32) do { \ | 92 | #define _MHD_PUT_32BIT_LE(addr, value32) \ |
93 | ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) | ||
94 | #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | ||
95 | /* Endianess was not detected or non-standard like PDP-endian */ | ||
96 | #define _MHD_PUT_32BIT_LE(addr, value32) do { \ | ||
61 | ((uint8_t*)(addr))[0] = (uint8_t)((uint32_t)(value32)); \ | 97 | ((uint8_t*)(addr))[0] = (uint8_t)((uint32_t)(value32)); \ |
62 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 8); \ | 98 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 8); \ |
63 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 16); \ | 99 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 16); \ |
64 | ((uint8_t*)(addr))[3] = (uint8_t)(((uint32_t)(value32)) >> 24); \ | 100 | ((uint8_t*)(addr))[3] = (uint8_t)(((uint32_t)(value32)) >> 24); \ |
65 | } while (0) | 101 | } while (0) |
66 | #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | 102 | #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ |
67 | 103 | ||
68 | 104 | ||
69 | /* _MHD_PUT_64BIT_BE (addr, value64) | 105 | /* _MHD_PUT_64BIT_BE (addr, value64) |
@@ -73,8 +109,12 @@ | |||
73 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN | 109 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
74 | #define _MHD_PUT_64BIT_BE(addr, value64) \ | 110 | #define _MHD_PUT_64BIT_BE(addr, value64) \ |
75 | ((*(uint64_t*)(addr)) = (uint64_t)(value64)) | 111 | ((*(uint64_t*)(addr)) = (uint64_t)(value64)) |
76 | #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 112 | #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
77 | #define _MHD_PUT_64BIT_BE(addr, value64) do { \ | 113 | #define _MHD_PUT_64BIT_BE(addr, value64) \ |
114 | ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) | ||
115 | #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | ||
116 | /* Endianess was not detected or non-standard like PDP-endian */ | ||
117 | #define _MHD_PUT_64BIT_BE(addr, value64) do { \ | ||
78 | ((uint8_t*)(addr))[7] = (uint8_t)((uint64_t)(value64)); \ | 118 | ((uint8_t*)(addr))[7] = (uint8_t)((uint64_t)(value64)); \ |
79 | ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 8); \ | 119 | ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 8); \ |
80 | ((uint8_t*)(addr))[5] = (uint8_t)(((uint64_t)(value64)) >> 16); \ | 120 | ((uint8_t*)(addr))[5] = (uint8_t)(((uint64_t)(value64)) >> 16); \ |
@@ -84,7 +124,7 @@ | |||
84 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 48); \ | 124 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 48); \ |
85 | ((uint8_t*)(addr))[0] = (uint8_t)(((uint64_t)(value64)) >> 56); \ | 125 | ((uint8_t*)(addr))[0] = (uint8_t)(((uint64_t)(value64)) >> 56); \ |
86 | } while (0) | 126 | } while (0) |
87 | #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 127 | #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ |
88 | 128 | ||
89 | /* _MHD_PUT_32BIT_BE (addr, value32) | 129 | /* _MHD_PUT_32BIT_BE (addr, value32) |
90 | * put native-endian 32-bit value32 to addr | 130 | * put native-endian 32-bit value32 to addr |
@@ -93,14 +133,18 @@ | |||
93 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN | 133 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
94 | #define _MHD_PUT_32BIT_BE(addr, value32) \ | 134 | #define _MHD_PUT_32BIT_BE(addr, value32) \ |
95 | ((*(uint32_t*)(addr)) = (uint32_t)(value32)) | 135 | ((*(uint32_t*)(addr)) = (uint32_t)(value32)) |
96 | #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 136 | #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
97 | #define _MHD_PUT_32BIT_BE(addr, value32) do { \ | 137 | #define _MHD_PUT_32BIT_BE(addr, value32) \ |
138 | ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) | ||
139 | #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | ||
140 | /* Endianess was not detected or non-standard like PDP-endian */ | ||
141 | #define _MHD_PUT_32BIT_BE(addr, value32) do { \ | ||
98 | ((uint8_t*)(addr))[3] = (uint8_t)((uint32_t)(value32)); \ | 142 | ((uint8_t*)(addr))[3] = (uint8_t)((uint32_t)(value32)); \ |
99 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 8); \ | 143 | ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 8); \ |
100 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 16); \ | 144 | ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 16); \ |
101 | ((uint8_t*)(addr))[0] = (uint8_t)(((uint32_t)(value32)) >> 24); \ | 145 | ((uint8_t*)(addr))[0] = (uint8_t)(((uint32_t)(value32)) >> 24); \ |
102 | } while (0) | 146 | } while (0) |
103 | #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 147 | #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ |
104 | 148 | ||
105 | /* _MHD_GET_32BIT_BE (addr) | 149 | /* _MHD_GET_32BIT_BE (addr) |
106 | * get big-endian 32-bit value storied at addr | 150 | * get big-endian 32-bit value storied at addr |
@@ -109,13 +153,17 @@ | |||
109 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN | 153 | #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN |
110 | #define _MHD_GET_32BIT_BE(addr) \ | 154 | #define _MHD_GET_32BIT_BE(addr) \ |
111 | (*(uint32_t*)(addr)) | 155 | (*(uint32_t*)(addr)) |
112 | #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 156 | #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN |
157 | #define _MHD_GET_32BIT_BE(addr) \ | ||
158 | _MHD_BYTES_SWAP32(*(uint32_t*)(addr)) | ||
159 | #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ | ||
160 | /* Endianess was not detected or non-standard like PDP-endian */ | ||
113 | #define _MHD_GET_32BIT_BE(addr) \ | 161 | #define _MHD_GET_32BIT_BE(addr) \ |
114 | ( (((uint32_t)(((uint8_t*)addr)[0])) << 24) | \ | 162 | ( (((uint32_t)(((uint8_t*)addr)[0])) << 24) | \ |
115 | (((uint32_t)(((uint8_t*)addr)[1])) << 16) | \ | 163 | (((uint32_t)(((uint8_t*)addr)[1])) << 16) | \ |
116 | (((uint32_t)(((uint8_t*)addr)[2])) << 8) | \ | 164 | (((uint32_t)(((uint8_t*)addr)[2])) << 8) | \ |
117 | ((uint32_t) (((uint8_t*)addr)[3])) ) | 165 | ((uint32_t) (((uint8_t*)addr)[3])) ) |
118 | #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ | 166 | #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ |
119 | 167 | ||
120 | /** | 168 | /** |
121 | * Rotate right 32-bit value by number of bits. | 169 | * Rotate right 32-bit value by number of bits. |