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, 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 #include <bits/wordsize.h>
00029 
00030 /* Swap bytes in 16 bit value.  */
00031 #define __bswap_constant_16(x) \
00032      ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
00033 
00034 #if defined __GNUC__ && __GNUC__ >= 2
00035 # define __bswap_16(x) \
00036      (__extension__                                                  \
00037       ({ register unsigned short int __v, __x = (x);                        \
00038         if (__builtin_constant_p (__x))                              \
00039           __v = __bswap_constant_16 (__x);                                  \
00040         else                                                         \
00041           __asm__ ("rorw $8, %w0"                                    \
00042                   : "=r" (__v)                                       \
00043                   : "0" (__x)                                               \
00044                   : "cc");                                           \
00045         __v; }))
00046 #else
00047 /* This is better than nothing.  */
00048 # define __bswap_16(x) \
00049      (__extension__                                                  \
00050       ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
00051 #endif
00052 
00053 
00054 /* Swap bytes in 32 bit value.  */
00055 #define __bswap_constant_32(x) \
00056      ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                    \
00057       (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
00058 
00059 #if defined __GNUC__ && __GNUC__ >= 2
00060 # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__           \
00061                        || defined __pentiumpro__ || defined __pentium4__   \
00062                        || defined __k8__ || defined __athlon__       \
00063                        || defined __k6__ || defined __nocona__       \
00064                        || defined __core2__ || defined __geode__            \
00065                        || defined __amdfam10__)
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 #  define __bswap_32(x) \
00069      (__extension__                                                  \
00070       ({ register unsigned int __v, __x = (x);                              \
00071         if (__builtin_constant_p (__x))                              \
00072           __v = __bswap_constant_32 (__x);                                  \
00073         else                                                         \
00074           __asm__ ("bswap %0" : "=r" (__v) : "0" (__x));                    \
00075         __v; }))
00076 # else
00077 #  define __bswap_32(x)                                                     \
00078      (__extension__                                                  \
00079       ({ register unsigned int __v, __x = (x);                              \
00080         if (__builtin_constant_p (__x))                              \
00081           __v = __bswap_constant_32 (__x);                                  \
00082         else                                                         \
00083           __asm__ ("rorw $8, %w0;"                                   \
00084                   "rorl $16, %0;"                                    \
00085                   "rorw $8, %w0"                                     \
00086                   : "=r" (__v)                                       \
00087                   : "0" (__x)                                               \
00088                   : "cc");                                           \
00089         __v; }))
00090 # endif
00091 #else
00092 # define __bswap_32(x) \
00093      (__extension__                                                  \
00094       ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
00095 #endif
00096 
00097 
00098 #if defined __GNUC__ && __GNUC__ >= 2
00099 /* Swap bytes in 64 bit value.  */
00100 # define __bswap_constant_64(x) \
00101      ((((x) & 0xff00000000000000ull) >> 56)                                 \
00102       | (((x) & 0x00ff000000000000ull) >> 40)                               \
00103       | (((x) & 0x0000ff0000000000ull) >> 24)                               \
00104       | (((x) & 0x000000ff00000000ull) >> 8)                                \
00105       | (((x) & 0x00000000ff000000ull) << 8)                                \
00106       | (((x) & 0x0000000000ff0000ull) << 24)                               \
00107       | (((x) & 0x000000000000ff00ull) << 40)                               \
00108       | (((x) & 0x00000000000000ffull) << 56))
00109 
00110 # if __WORDSIZE == 64
00111 #  define __bswap_64(x) \
00112      (__extension__                                                  \
00113       ({ register unsigned long __v, __x = (x);                             \
00114         if (__builtin_constant_p (__x))                              \
00115           __v = __bswap_constant_64 (__x);                                  \
00116         else                                                         \
00117           __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x));                   \
00118         __v; }))
00119 # else
00120 #  define __bswap_64(x) \
00121      (__extension__                                                           \
00122       ({ union { __extension__ unsigned long long int __ll;                   \
00123                  unsigned int __l[2]; } __w, __r;                             \
00124          if (__builtin_constant_p (x))                                        \
00125            __r.__ll = __bswap_constant_64 (x);                                \
00126          else                                                                 \
00127            {                                                                  \
00128              __w.__ll = (x);                                                  \
00129              __r.__l[0] = __bswap_32 (__w.__l[1]);                            \
00130              __r.__l[1] = __bswap_32 (__w.__l[0]);                            \
00131            }                                                                  \
00132          __r.__ll; }))
00133 # endif
00134 #endif
00135 
00136 #endif /* _BITS_BYTESWAP_H */