1/* $NetBSD: bswap64.c,v 1.2 2008/02/16 17:37:13 apb Exp $ */ 2 3/* 4 * Written by Manuel Bouyer <bouyer@NetBSD.org>. 5 * Public domain. 6 */ 7 8#include <sys/cdefs.h> 9#if defined(LIBC_SCCS) && !defined(lint) 10__RCSID("$NetBSD: bswap64.c,v 1.2 2008/02/16 17:37:13 apb Exp $"); 11#endif /* LIBC_SCCS and not lint */ 12 13#include <sys/types.h> 14#include <machine/bswap.h> 15 16#undef bswap64 17 18uint64_t 19bswap64(uint64_t x) 20{ 21#ifdef _LP64 22 /* 23 * Assume we have wide enough registers to do it without touching 24 * memory. 25 */ 26 return ( (x << 56) & 0xff00000000000000UL ) | 27 ( (x << 40) & 0x00ff000000000000UL ) | 28 ( (x << 24) & 0x0000ff0000000000UL ) | 29 ( (x << 8) & 0x000000ff00000000UL ) | 30 ( (x >> 8) & 0x00000000ff000000UL ) | 31 ( (x >> 24) & 0x0000000000ff0000UL ) | 32 ( (x >> 40) & 0x000000000000ff00UL ) | 33 ( (x >> 56) & 0x00000000000000ffUL ); 34#else 35 /* 36 * Split the operation in two 32bit steps. 37 */ 38 uint32_t tl, th; 39 40 th = bswap32((uint32_t)(x & 0x00000000ffffffffULL)); 41 tl = bswap32((uint32_t)((x >> 32) & 0x00000000ffffffffULL)); 42 return ((uint64_t)th << 32) | tl; 43#endif 44} 45