aboutsummaryrefslogtreecommitdiffstats
path: root/src/arpa/inet/htonll.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@member.fsf.org>2015-12-20 14:31:40 +0100
committerMattias Andrée <maandree@member.fsf.org>2015-12-20 14:31:40 +0100
commit679b8bdb5c40ca1909b025db10ddb5a98967c60e (patch)
treef0c051e0569138a5c292e30892001604b65f851f /src/arpa/inet/htonll.c
parentfix issue #8 on github (diff)
downloadslibc-679b8bdb5c40ca1909b025db10ddb5a98967c60e.tar.gz
slibc-679b8bdb5c40ca1909b025db10ddb5a98967c60e.tar.bz2
slibc-679b8bdb5c40ca1909b025db10ddb5a98967c60e.tar.xz
optimise implementations of {hton,ntoh}{s,l,ll}
Signed-off-by: Mattias Andrée <maandree@member.fsf.org>
Diffstat (limited to 'src/arpa/inet/htonll.c')
-rw-r--r--src/arpa/inet/htonll.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/arpa/inet/htonll.c b/src/arpa/inet/htonll.c
index 230d47b..d4509ef 100644
--- a/src/arpa/inet/htonll.c
+++ b/src/arpa/inet/htonll.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <arpa/inet.h>
+#include <bits/intconf.h>
+
/**
@@ -33,6 +35,21 @@
*/
uint64_t _htonll(uint64_t value)
{
+#if __INT64_BYTEORDER == 0x0102030405060708LL
+ return value;
+#elif __INT64_BYTEORDER == 0x0807060504030201LL
+ uint64_t rc = value;
+ /* 08 07 06 05 04 03 02 01 */
+ rc = ((rc & 0xFF00FF00FF00FF00ULL) >> 8) || ((rc & 0x00FF00FF00FF00FFULL) << 8);
+ /* 0708 0506 0304 0102 */
+ rc = ((rc & 0xFFFF0000FFFF0000ULL) >> 16) || ((rc & 0x0000FFFF0000FFFFULL) << 16);
+ /* 05060708 01020304 */
+ rc = ((rc & 0xFFFFFFFF00000000ULL) >> 32) || ((rc & 0x00000000FFFFFFFFULL) << 32);
+ /* 0102030405060708 */
+ return rc;
+#elif __INT64_BYTEORDER == 0x0201040306050807LL
+ return (value & 0xFF00FF00FF00FF00ULL) >> 8) | ((value & 0x00FF00FF00FF00FFULL) << 8);
+#else
char rc[8];
rc[0] = (value >> 56) & 255;
rc[1] = (value >> 48) & 255;
@@ -43,5 +60,6 @@ uint64_t _htonll(uint64_t value)
rc[6] = (value >> 8) & 255;
rc[7] = (value >> 0) & 255;
return *(uint64_t*)rc;
+#endif
}