File: hbyteswp.h

package info (click to toggle)
hercules 3.07-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 14,572 kB
  • ctags: 18,225
  • sloc: ansic: 162,921; sh: 8,522; makefile: 781; perl: 202; sed: 16
file content (136 lines) | stat: -rw-r--r-- 4,062 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* BYTESWAP.H  Little <> Big Endian conversion - Jan Jaeger          */

/* These definitions are only nessesary when running on older        */
/* versions of linux that do not have /usr/include/byteswap.h        */
/* compile option -DNO_ASM_BYTESWAP will expand 'C' code             */
/* otherwise Intel (486+) assember will be generated                 */

// $Id: hbyteswp.h 5039 2009-01-08 01:59:20Z jmaynard $
//
// $Log$
// Revision 1.11  2009/01/07 18:00:13  jmaynard
// Added x86_64 assembler swap assists for those systems that don't have
// byteswap.h in the library.
//
// Revision 1.10  2006/12/08 09:43:21  jj
// Add CVS message log
//

#ifndef _BYTESWAP_H
#define _BYTESWAP_H

#if !defined(NO_ASM_BYTESWAP)

  #include "htypes.h"       // (need Hercules fixed-size data types)

  #if defined( _MSVC_ )

    static __inline  uint16_t  __fastcall  bswap_16 ( uint16_t  x )
    {
      return _byteswap_ushort((x));
    }

    static __inline  uint32_t  __fastcall  bswap_32 ( uint32_t  x )
    {
      return _byteswap_ulong((x));
    }

  #else // !defined( _MSVC_ )

    static __inline__ uint16_t (ATTR_REGPARM(1) bswap_16)(uint16_t x)
    {
#if defined(__x86_64__)
      __asm__("xchgb %b0,%h0" : "=Q" (x) :  "0" (x));
#else
      __asm__("xchgb %b0,%h0" : "=q" (x) :  "0" (x));
#endif
      return x;
    }

    static __inline__ uint32_t (ATTR_REGPARM(1) bswap_32)(uint32_t x)
    {
#if defined(__x86_64__)
      __asm__("bswapl %0" : "=r" (x) : "0" (x));
#else
      __asm__("bswap %0" : "=r" (x) : "0" (x));
#endif
      return x;
    }

  #endif // defined( _MSVC_ )

#else // defined(NO_ASM_BYTESWAP)

  #define bswap_16(_x) \
          ( (((_x) & 0xFF00) >> 8) \
          | (((_x) & 0x00FF) << 8) )

  #define bswap_32(_x) \
          ( (((_x) & 0xFF000000) >> 24) \
          | (((_x) & 0x00FF0000) >> 8)  \
          | (((_x) & 0x0000FF00) << 8)  \
          | (((_x) & 0x000000FF) << 24) )

#endif // !defined(NO_ASM_BYTESWAP)

#if defined( _MSVC_ )

  // Microsoft's Toolkit 2003 compiler (version 1300) has a known bug
  // that causes the _byteswap_uint64 intrinsic to screw up if global
  // otimizations are enabled. The new VStudio 8.0 compiler (version
  // 14.00) doesn't have this problem that I am aware of. NOTE that
  // the #pragma must be outside the function (at global scope) to
  // prevent compiler error C2156 "pragma must be outside function".

  #if ( _MSC_VER < 1400 )
    #pragma optimize("g",off)     // (disable global optimizations)
  #endif
  static __inline  uint64_t  __fastcall  bswap_64(uint64_t x)
  {
      return _byteswap_uint64((x));
  }
  #if ( _MSC_VER < 1400 )
    #pragma optimize ( "", on )
  #endif

#else // !defined( _MSVC_ )

  #if defined(NO_ASM_BYTESWAP)
    #define bswap_64(_x) \
          ( ((U64)((_x) & 0xFF00000000000000ULL) >> 56) \
          | ((U64)((_x) & 0x00FF000000000000ULL) >> 40) \
          | ((U64)((_x) & 0x0000FF0000000000ULL) >> 24) \
          | ((U64)((_x) & 0x000000FF00000000ULL) >> 8)  \
          | ((U64)((_x) & 0x00000000FF000000ULL) << 8)  \
          | ((U64)((_x) & 0x0000000000FF0000ULL) << 24) \
          | ((U64)((_x) & 0x000000000000FF00ULL) << 40) \
          | ((U64)((_x) & 0x00000000000000FFULL) << 56) )
  #else
    static __inline__ uint64_t (ATTR_REGPARM(1) bswap_64)(uint64_t x)
    {
    #if defined(__x86_64__)
      __asm__("bswapq %0" : "=r" (x) : "0" (x));
      return x;
    #else // swap the two words after byteswapping them
      union
      {
        struct
        {
          uint32_t high,low;
        } words;
        uint64_t quad;
      } value;
      
      value.quad=x;
      __asm__("bswap %0" : "=r" (value.words.high) : "0" (value.words.high));
      __asm__("bswap %0" : "=r" (value.words.low) : "0" (value.words.low));
      __asm__("xchgl %0,%1" : "=r" (value.words.high), "=r" (value.words.low) :
              "0" (value.words.high), "1" (value.words.low));
      return value.quad;
    #endif // defined(__x86_64__)
    }
  #endif // defined(NO_ASM_BYTESWAP)

#endif // defined( _MSVC_ )

#endif // _BYTESWAP_H