1 /* Macros to swap the order of bytes in integer values. 2 Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007, 2008, 2010, 2011 3 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, write to the Free 18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. */ 20 21 #if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H 22 # error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." 23 #endif 24 25 #ifndef _BITS_BYTESWAP_H 26 #define _BITS_BYTESWAP_H 1 27 28 /* Swap bytes in 16 bit value. */ 29 #define __bswap_constant_16(x) \ 30 ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) 31 32 #ifdef __GNUC__ 33 # if __GNUC__ >= 2 34 # define __bswap_16(x) \ 35 (__extension__ \ 36 ({ register unsigned short int __v, __x = (unsigned short int) (x); \ 37 if (__builtin_constant_p (__x)) \ 38 __v = __bswap_constant_16 (__x); \ 39 else \ 40 __asm__ ("rorw $8, %w0" \ 41 : "=r" (__v) \ 42 : "0" (__x) \ 43 : "cc"); \ 44 __v; })) 45 # else 46 /* This is better than nothing. */ 47 # define __bswap_16(x) \ 48 (__extension__ \ 49 ({ register unsigned short int __x = (unsigned short int) (x); \ 50 __bswap_constant_16 (__x); })) 51 # endif 52 #else 53 static __inline unsigned short int 54 __bswap_16 (unsigned short int __bsx) 55 { 56 return __bswap_constant_16 (__bsx); 57 } 58 #endif 59 60 /* Swap bytes in 32 bit value. */ 61 #define __bswap_constant_32(x) \ 62 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ 63 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 64 65 #ifdef __GNUC__ 66 # if __GNUC__ >= 2 67 /* To swap the bytes in a word the i486 processors and up provide the 68 `bswap' opcode. On i386 we have to use three instructions. */ 69 # if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \ 70 && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \ 71 && !defined __k6__ && !defined __nocona__ && !defined __core2__ \ 72 && !defined __geode__ && !defined __amdfam10__ 73 # define __bswap_32(x) \ 74 (__extension__ \ 75 ({ register unsigned int __v, __x = (x); \ 76 if (__builtin_constant_p (__x)) \ 77 __v = __bswap_constant_32 (__x); \ 78 else \ 79 __asm__ ("rorw $8, %w0;" \ 80 "rorl $16, %0;" \ 81 "rorw $8, %w0" \ 82 : "=r" (__v) \ 83 : "0" (__x) \ 84 : "cc"); \ 85 __v; })) 86 # else 87 # define __bswap_32(x) \ 88 (__extension__ \ 89 ({ register unsigned int __v, __x = (x); \ 90 if (__builtin_constant_p (__x)) \ 91 __v = __bswap_constant_32 (__x); \ 92 else \ 93 __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \ 94 __v; })) 95 # endif 96 # else 97 # define __bswap_32(x) \ 98 (__extension__ \ 99 ({ register unsigned int __x = (x); __bswap_constant_32 (__x); })) 100 # endif 101 #else 102 static __inline unsigned int 103 __bswap_32 (unsigned int __bsx) 104 { 105 return __bswap_constant_32 (__bsx); 106 } 107 #endif 108 109 110 #if defined __GNUC__ && __GNUC__ >= 2 111 /* Swap bytes in 64 bit value. */ 112 # define __bswap_constant_64(x) \ 113 (__extension__ ((((x) & 0xff00000000000000ull) >> 56) \ 114 | (((x) & 0x00ff000000000000ull) >> 40) \ 115 | (((x) & 0x0000ff0000000000ull) >> 24) \ 116 | (((x) & 0x000000ff00000000ull) >> 8) \ 117 | (((x) & 0x00000000ff000000ull) << 8) \ 118 | (((x) & 0x0000000000ff0000ull) << 24) \ 119 | (((x) & 0x000000000000ff00ull) << 40) \ 120 | (((x) & 0x00000000000000ffull) << 56))) 121 122 # define __bswap_64(x) \ 123 (__extension__ \ 124 ({ union { __extension__ unsigned long long int __ll; \ 125 unsigned long int __l[2]; } __w, __r; \ 126 if (__builtin_constant_p (x)) \ 127 __r.__ll = __bswap_constant_64 (x); \ 128 else \ 129 { \ 130 __w.__ll = (x); \ 131 __r.__l[0] = __bswap_32 (__w.__l[1]); \ 132 __r.__l[1] = __bswap_32 (__w.__l[0]); \ 133 } \ 134 __r.__ll; })) 135 #endif 136 137 #endif /* _BITS_BYTESWAP_H */ 138