Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/Byteswap.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* @(#)root/base:$Id$ */
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT_Byteswap
0012 #define ROOT_Byteswap
0013 
0014 /* Originally (mid-1990s), this file contained copy/pasted assembler from RH6.0's
0015  * version of <bits/byteswap.h>.  Hence, we keep a copy of the FSF copyright below.
0016  * I believe all the original code has been excised, perhaps with exception of the
0017  * R__bswap_constant_* functions.  To be on the safe side, we are keeping the
0018  * copyright below.
0019  *   -- Brian Bockelman, August 2018
0020  */
0021 
0022 /* Copyright (C) 1997 Free Software Foundation, Inc.
0023    This file is part of the GNU C Library.
0024 
0025    The GNU C Library is free software; you can redistribute it and/or
0026    modify it under the terms of the GNU Library General Public License as
0027    published by the Free Software Foundation; either version 2 of the
0028    License, or (at your option) any later version.
0029 
0030    The GNU C Library is distributed in the hope that it will be useful,
0031    but WITHOUT ANY WARRANTY; without even the implied warranty of
0032    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0033    Library General Public License for more details.
0034 
0035    You should have received a copy of the GNU Library General Public
0036    License along with the GNU C Library; see the file COPYING.LIB.  If not,
0037    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0038    Boston, MA 02111-1307, USA.  */
0039 
0040 #include <cstdint>
0041 
0042 #ifndef R__USEASMSWAP
0043 #if (defined(__linux) || defined(__APPLE__)) &&   \
0044     (defined(__i386__) || defined(__x86_64__)) && \
0045     (defined(__GNUC__))
0046 # define R__USEASMSWAP
0047 #endif
0048 
0049 #if defined(_WIN32) && (_MSC_VER >= 1300)
0050 # include <stdlib.h>
0051 # pragma intrinsic(_byteswap_ushort,_byteswap_ulong,_byteswap_uint64)
0052 # define R__USEASMSWAP
0053 #endif
0054 #endif /* R__USEASMSWAP */
0055 
0056 /* Swap bytes in 16 bit value.  */
0057 #define R__bswap_constant_16(x) \
0058      ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
0059 
0060 #if defined(R__USEASMSWAP)
0061 # if defined(__GNUC__)
0062 #  define R__bswap_16(x) __builtin_bswap16(x)
0063 # elif defined(_MSC_VER)
0064 #  define R__bswap_16(x) _byteswap_ushort(x)
0065 # endif
0066 #else
0067 # define R__bswap_16(x) R__bswap_constant_16(x)
0068 #endif
0069 
0070 /* Swap bytes in 32 bit value.  */
0071 #define R__bswap_constant_32(x) \
0072      ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |               \
0073       (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
0074 
0075 #if defined(R__USEASMSWAP)
0076 # if defined(__GNUC__)
0077 #  define R__bswap_32(x) __builtin_bswap32(x)
0078 # elif defined(_MSC_VER)
0079 #  define R__bswap_32(x) _byteswap_ulong(x)
0080 # endif
0081 #else
0082 # define R__bswap_32(x) R__bswap_constant_32(x)
0083 #endif
0084 
0085 /* Swap bytes in 64 bit value.  */
0086 static inline uint64_t R__bswap_constant_64(uint64_t x) {
0087    x = ((x & 0x00000000ffffffff) << 32) | ((x & 0xffffffff00000000) >> 32);
0088    x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
0089    x = ((x & 0x00ff00ff00ff00ff) <<  8) | ((x & 0xff00ff00ff00ff00) >>  8);
0090    return x;
0091 }
0092 
0093 #if defined(R__USEASMSWAP)
0094 # if defined(__GNUC__)
0095 #  define R__bswap_64(x) __builtin_bswap64(x)
0096 # elif defined(_MSC_VER)
0097 #  define R__bswap_64(x) _byteswap_uint64(x)
0098 # endif
0099 #else
0100 # define R__bswap_64(x) R__bswap_constant_64(x)
0101 #endif
0102 
0103 
0104 /* Return a value with all bytes in the 16 bit argument swapped.  */
0105 #define Rbswap_16(x) R__bswap_16(x)
0106 
0107 /* Return a value with all bytes in the 32 bit argument swapped.  */
0108 #define Rbswap_32(x) R__bswap_32(x)
0109 
0110 /* Return a value with all bytes in the 64 bit argument swapped.  */
0111 #define Rbswap_64(x) R__bswap_64(x)
0112 
0113 /// \brief Helper templated class for swapping bytes; specializations for `N={2,4,8}`
0114 /// are provided below.  This class can be used to byteswap any other type, e.g. in a
0115 /// templated function (see example below).
0116 /// ```
0117 /// template <typename T>
0118 /// void byteswap_arg(T &x) {
0119 ///    using value_type = typename RByteSwap<sizeof(T)>::value_type;
0120 ///    x = RByteSwap<sizeof(T)>::bswap(reinterpret_cast<value_type>(x));
0121 /// }
0122 /// ```
0123 template <unsigned N>
0124 struct RByteSwap {
0125 };
0126 
0127 template <>
0128 struct RByteSwap<2> {
0129    // Signed integers can be safely byteswapped if they are reinterpret_cast'ed to unsigned
0130    using value_type = std::uint16_t;
0131    static value_type bswap(value_type x) { return Rbswap_16(x); }
0132 };
0133 
0134 template <>
0135 struct RByteSwap<4> {
0136    using value_type = std::uint32_t;
0137    static value_type bswap(value_type x) { return Rbswap_32(x); }
0138 };
0139 
0140 template <>
0141 struct RByteSwap<8> {
0142    using value_type = std::uint64_t;
0143    static value_type bswap(value_type x) { return Rbswap_64(x); }
0144 };
0145 
0146 #endif /* Byteswap.h */