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 18 uint64_t 19 bswap64(x) 20 uint64_t x; 21 { 22 #ifdef _LP64 23 /* 24 * Assume we have wide enough registers to do it without touching 25 * memory. 26 */ 27 return ( (x << 56) & 0xff00000000000000UL ) | 28 ( (x << 40) & 0x00ff000000000000UL ) | 29 ( (x << 24) & 0x0000ff0000000000UL ) | 30 ( (x << 8) & 0x000000ff00000000UL ) | 31 ( (x >> 8) & 0x00000000ff000000UL ) | 32 ( (x >> 24) & 0x0000000000ff0000UL ) | 33 ( (x >> 40) & 0x000000000000ff00UL ) | 34 ( (x >> 56) & 0x00000000000000ffUL ); 35 #else 36 /* 37 * Split the operation in two 32bit steps. 38 */ 39 uint32_t tl, th; 40 41 th = bswap32((uint32_t)(x & 0x00000000ffffffffULL)); 42 tl = bswap32((uint32_t)((x >> 32) & 0x00000000ffffffffULL)); 43 return ((uint64_t)th << 32) | tl; 44 #endif 45 } 46