a73582fe588a6af9611be5ac8524332f0e0a356b
[oftp] / libs / watt32 / sys / swap.h
1 /*!\file sys/swap.h
2  * Swapping of short/long values.
3  */
4
5 #ifndef __SYS_SWAP_BYTES_H
6 #define __SYS_SWAP_BYTES_H
7
8 #ifndef __SYS_W32API_H
9 #include <sys/w32api.h>
10 #endif
11
12 #ifndef __SYS_CDEFS_H
13 #include <sys/cdefs.h>
14 #endif
15
16 #ifndef __NETINET_IN_H
17 #include <netinet/in.h>
18 #endif
19
20 #if defined(__dj_include_netinet_in_h_)
21 #error "You are using the wrong version of <netinet/in.h>. Ref. point 10 of the INSTALL file"
22 #endif
23
24
25 __BEGIN_DECLS
26
27 #if defined(WIN32) || defined(_WIN32) /* provide some real versions too */
28   W32_FUNC unsigned short W32_CALL ntohs (unsigned short);
29   W32_FUNC unsigned short W32_CALL htons (unsigned short);
30   W32_FUNC unsigned long  W32_CALL ntohl (unsigned long);
31   W32_FUNC unsigned long  W32_CALL htonl (unsigned long);
32   W32_FUNC unsigned long  cdecl   _w32_intel   (unsigned long x);
33   W32_FUNC unsigned short cdecl   _w32_intel16 (unsigned short x);
34 #endif
35
36 #undef  ntohs
37 #undef  htons
38 #undef  ntohl
39 #undef  htonl
40 #define ntohs(x)  intel16(x)
41 #define htons(x)  intel16(x)
42 #define ntohl(x)  intel(x)
43 #define htonl(x)  intel(x)
44
45
46 /*
47  * Hard to believe, but someone uses Watt-32 on a
48  * Motorola/PowerPC embedded target.
49  */
50 #if defined(BIG_ENDIAN_MACHINE) || defined(USE_BIGENDIAN)
51   #define intel(x)    x
52   #define intel16(x)  x
53
54 #elif defined(__GNUC__) && !defined(__NO_INLINE__)  /* -O0 */
55   #define intel(x)   __ntohl(x)
56   #define intel16(x) __ntohs(x)
57
58   /*
59    * Ripped (and adapted) from <linux/include/asm-386/byteorder.h>
60    */
61   /*@unused@*/ extern __inline__ unsigned long __ntohl (unsigned long x)
62   {
63     __asm__ __volatile (
64              "xchgb %b0, %h0\n\t"   /* swap lower bytes  */
65              "rorl  $16, %0\n\t"    /* swap words        */
66              "xchgb %b0, %h0"       /* swap higher bytes */
67             : "=q" (x) : "0" (x));
68     return (x);
69   }
70
71   /*@unused@*/ extern __inline__ unsigned short __ntohs (unsigned short x)
72   {
73     __asm__ __volatile__ (
74               "xchgb %b0, %h0"       /* swap bytes */
75             : "=q" (x) : "0" (x));
76     return (x);
77   }
78
79 #elif defined(__POCC__)             /* PellesC */
80   #define intel(x)   __ntohl(x)
81   #define intel16(x) __ntohs(x)
82
83   __declspec(naked) inline unsigned long __fastcall __ntohl (unsigned long x)
84   {
85     __asm xchg cl, ch    /* 'x' is in ecx */
86     __asm ror  ecx, 16
87     __asm xchg cl, ch
88     __asm mov  eax, ecx
89     __asm ret
90   }
91
92   __declspec(naked) inline unsigned short __fastcall __ntohs (unsigned short x)
93   {
94     __asm xchg  cl, ch    /* 'x' is in ecx */
95     __asm movzx eax, cx
96     __asm ret
97   }
98
99 #elif (defined(_MSC_VER) && (_MSC_VER >= 1200)) &&  /* MSVC 6+ */ \
100       !defined(__POCC__)           /* "pocc -Ze" sets _MSC_VER */
101   #define intel(x)   __ntohl(x)
102   #define intel16(x) __ntohs(x)
103
104   __declspec(naked) static unsigned long __ntohl (unsigned long x)
105   {
106     __asm mov  eax, [esp+4]
107     __asm xchg al, ah
108     __asm ror  eax, 16
109     __asm xchg al, ah
110     __asm ret
111   }
112
113   __declspec(naked) static unsigned short __ntohs (unsigned short x)
114   {
115     __asm mov  ax, [esp+4]
116     __asm xchg al, ah
117     __asm ret
118   }
119
120 #elif defined(__WATCOMC__) && defined(__FLAT__)  /* Watcom 32-bit */
121   #define intel(x)   __ntohl(x)
122   #define intel16(x) __ntohs(x)
123
124   extern unsigned long __ntohl (unsigned long x);
125   #pragma aux  __ntohl =     \
126               "xchg al, ah"  \
127               "ror  eax, 16" \
128               "xchg al, ah"  \
129               parm   [eax]   \
130               modify [eax];
131
132   extern unsigned short __ntohs (unsigned short x);
133   #pragma aux __ntohs =     \
134               "xchg al, ah" \
135               parm   [ax]   \
136               modify [ax];
137
138 #elif defined(__WATCOMC__) && !defined(__FLAT__)  /* Watcom 16-bit */
139   #define intel(x)   __ntohl(x)
140   #define intel16(x) __ntohs(x)
141
142   extern unsigned long __ntohl (unsigned long x);
143   #pragma aux  __ntohl =     \
144               "xchg al, dh"  \
145               "xchg ah, dl"  \
146               parm   [dx ax] \
147               modify [dx ax];
148
149   extern unsigned short __ntohs (unsigned short x);
150   #pragma aux __ntohs =     \
151               "xchg al, ah" \
152               parm   [ax]   \
153               modify [ax];
154
155 #elif (defined(__BORLANDC__) && defined(__FLAT__)) || /* bcc32 */ \
156       (defined(__DMC__) && (__INTSIZE==4))            /* dmc -mx */
157   #include <dos.h>
158
159   #define intel(x)    __ntohl(x)
160   #define intel16(x)  __ntohs(x)
161
162   #define __ntohs(x)  (_AX = x, \
163                        __emit__(0x86,0xC4),      /* xchg al, ah */ \
164                        _AX)
165
166   #define __ntohl(x)  (_EAX = x, \
167                        __emit__(0x86,0xC4),      /* xchg al, ah  */ \
168                        __emit__(0xC1,0xC8,0x10), /* ror  eax, 16 */ \
169                        __emit__(0x86,0xC4),      /* xchg al, ah  */ \
170                        _EAX)
171
172 #elif defined(__CCDL__) && defined(__386__)      /* LadSoft 386 */
173   #define intel(x)    __ntohl(x)
174   #define intel16(x)  __ntohs(x)
175
176   static unsigned long __ntohl (unsigned long x)
177   {
178     asm { mov  eax, [x]
179           xchg al, ah
180           ror  eax, 16
181           xchg al, ah
182         }
183     return (_EAX);
184   }
185   static unsigned short __ntohs (unsigned short x)
186   {
187     asm { mov  ax, [x]
188           xchg al, ah
189         }
190     return (unsigned short)_EAX;  /* doesn't have _AX */
191   }
192
193   /* This crashes mysteriously if we use _bswap()
194    */
195 #elif defined(__LCC__) && 0              /* LCC-Win32 */
196   #define intel(x)    __ntohl(x)
197   #define intel16(x)  __ntohs(x)
198   #if 0
199     #include <intrinsics.h>
200     #define W32_LCC_INTRINSICS_INCLUDED  /* header guard is missing */
201     #define __ntohl(x)   (unsigned long) _bswap(x)
202     #define __ntohs(x)  ((unsigned short) (_bswap(x) >> 16))
203   #else
204     unsigned long inline __declspec(naked) __ntohl (unsigned long x)
205     {
206       _asm ("movl (%esp), %eax");
207       _asm ("xchg %ah, %al");
208       _asm ("rorl $16, %eax");
209       _asm ("xchg %ah, %al");
210     }
211     unsigned short inline __declspec(naked) __ntohs (unsigned short x)
212     {
213       _asm ("movs (%esp), %ax");
214       _asm ("xchg %ah, %al");
215     }
216   #endif
217
218 #else  /* no inlining possible (or worth the effort) */
219   #define intel   W32_NAMESPACE (intel)
220   #define intel16 W32_NAMESPACE (intel16)
221   #define WATT_NO_INLINE_INTEL
222
223   W32_FUNC unsigned long  cdecl intel   (unsigned long x);
224   W32_FUNC unsigned short cdecl intel16 (unsigned short x);
225 #endif
226
227 __END_DECLS
228
229 #endif /* __SYS_SWAP_BYTES_H */