Back to index

glibc  2.9
byteswap.h
Go to the documentation of this file.
00001 /* Macros to swap the order of bytes in integer values.
00002    Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007, 2008
00003    Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
00022 # error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
00023 #endif
00024 
00025 #ifndef _BITS_BYTESWAP_H
00026 #define _BITS_BYTESWAP_H 1
00027 
00028 /* Swap bytes in 16 bit value.  */
00029 #define __bswap_constant_16(x) \
00030      ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
00031 
00032 #ifdef __GNUC__
00033 # if __GNUC__ >= 2
00034 #  define __bswap_16(x) \
00035      (__extension__                                                  \
00036       ({ register unsigned short int __v, __x = (x);                        \
00037         if (__builtin_constant_p (__x))                              \
00038           __v = __bswap_constant_16 (__x);                                  \
00039         else                                                         \
00040           __asm__ ("rorw $8, %w0"                                    \
00041                   : "=r" (__v)                                       \
00042                   : "0" (__x)                                               \
00043                   : "cc");                                           \
00044         __v; }))
00045 # else
00046 /* This is better than nothing.  */
00047 #  define __bswap_16(x) \
00048      (__extension__                                                  \
00049       ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
00050 # endif
00051 #else
00052 static __inline unsigned short int
00053 __bswap_16 (unsigned short int __bsx)
00054 {
00055   return __bswap_constant_16 (__bsx);
00056 }
00057 #endif
00058 
00059 /* Swap bytes in 32 bit value.  */
00060 #define __bswap_constant_32(x) \
00061      ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                    \
00062       (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
00063 
00064 #ifdef __GNUC__
00065 # if __GNUC__ >= 2
00066 /* To swap the bytes in a word the i486 processors and up provide the
00067    `bswap' opcode.  On i386 we have to use three instructions.  */
00068 #  if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
00069       && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \
00070       && !defined __k6__ && !defined __nocona__ && !defined __core2__ \
00071       && !defined __geode__ && !defined __amdfam10__
00072 #   define __bswap_32(x)                                             \
00073      (__extension__                                                  \
00074       ({ register unsigned int __v, __x = (x);                              \
00075         if (__builtin_constant_p (__x))                              \
00076           __v = __bswap_constant_32 (__x);                                  \
00077         else                                                         \
00078           __asm__ ("rorw $8, %w0;"                                   \
00079                   "rorl $16, %0;"                                    \
00080                   "rorw $8, %w0"                                     \
00081                   : "=r" (__v)                                       \
00082                   : "0" (__x)                                               \
00083                   : "cc");                                           \
00084         __v; }))
00085 #  else
00086 #   define __bswap_32(x) \
00087      (__extension__                                                  \
00088       ({ register unsigned int __v, __x = (x);                              \
00089         if (__builtin_constant_p (__x))                              \
00090           __v = __bswap_constant_32 (__x);                                  \
00091         else                                                         \
00092           __asm__ ("bswap %0" : "=r" (__v) : "0" (__x));                    \
00093         __v; }))
00094 #  endif
00095 # else
00096 #  define __bswap_32(x) \
00097      (__extension__                                                  \
00098       ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
00099 # endif
00100 #else
00101 static __inline unsigned int
00102 __bswap_32 (unsigned int __bsx)
00103 {
00104   return __bswap_constant_32 (__bsx);
00105 }
00106 #endif
00107 
00108 
00109 #if defined __GNUC__ && __GNUC__ >= 2
00110 /* Swap bytes in 64 bit value.  */
00111 #define __bswap_constant_64(x) \
00112      ((((x) & 0xff00000000000000ull) >> 56)                                 \
00113       | (((x) & 0x00ff000000000000ull) >> 40)                               \
00114       | (((x) & 0x0000ff0000000000ull) >> 24)                               \
00115       | (((x) & 0x000000ff00000000ull) >> 8)                                \
00116       | (((x) & 0x00000000ff000000ull) << 8)                                \
00117       | (((x) & 0x0000000000ff0000ull) << 24)                               \
00118       | (((x) & 0x000000000000ff00ull) << 40)                               \
00119       | (((x) & 0x00000000000000ffull) << 56))
00120 
00121 # define __bswap_64(x) \
00122      (__extension__                                                  \
00123       ({ union { __extension__ unsigned long long int __ll;                 \
00124                unsigned long int __l[2]; } __w, __r;                        \
00125          if (__builtin_constant_p (x))                                      \
00126           __r.__ll = __bswap_constant_64 (x);                               \
00127         else                                                         \
00128           {                                                          \
00129             __w.__ll = (x);                                          \
00130             __r.__l[0] = __bswap_32 (__w.__l[1]);                           \
00131             __r.__l[1] = __bswap_32 (__w.__l[0]);                           \
00132           }                                                          \
00133         __r.__ll; }))
00134 #endif
00135 
00136 #endif /* _BITS_BYTESWAP_H */