File: hbyteswp.h

package info (click to toggle)
hercules 3.13-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,392 kB
  • sloc: ansic: 175,124; sh: 8,792; makefile: 760; perl: 149
file content (126 lines) | stat: -rw-r--r-- 3,843 bytes parent folder | download | duplicates (5)
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
/* HBYTESWP.H   (c) Copyright Jan Jaeger, 2001-2009                  */
/*              Hercules Little <> Big Endian conversion             */

/* 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                 */

#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