1 #ifndef BSWAP_H
2 #define BSWAP_H
3 
4 //#include "config-host.h"
5 
6 #include <inttypes.h>
7 
8 #if defined(__NetBSD__)
9 #include <sys/endian.h>
10 #include <sys/types.h>
11 #elif defined(__OpenBSD__)
12 #include <machine/endian.h>
13 #define bswap_16(x) swap16(x)
14 #define bswap_32(x) swap32(x)
15 #define bswap_64(x) swap64(x)
16 #elif defined(__linux__)
17 
18 #include <endian.h>
19 #include <byteswap.h>
20 
bswap16(uint16_t x)21 static inline uint16_t bswap16(uint16_t x)
22 {
23     return bswap_16(x);
24 }
25 
bswap32(uint32_t x)26 static inline uint32_t bswap32(uint32_t x)
27 {
28     return bswap_32(x);
29 }
30 
bswap64(uint64_t x)31 static inline uint64_t bswap64(uint64_t x)
32 {
33     return bswap_64(x);
34 }
35 
bswap16s(uint16_t * s)36 static inline void bswap16s(uint16_t *s)
37 {
38     *s = bswap16(*s);
39 }
40 
bswap32s(uint32_t * s)41 static inline void bswap32s(uint32_t *s)
42 {
43     *s = bswap32(*s);
44 }
45 
bswap64s(uint64_t * s)46 static inline void bswap64s(uint64_t *s)
47 {
48     *s = bswap64(*s);
49 }
50 
51 #endif
52 
53 #if defined(WORDS_BIGENDIAN)
54 #define be_bswap(v, size) (v)
55 #define le_bswap(v, size) bswap ## size(v)
56 #define be_bswaps(v, size)
57 #define le_bswaps(p, size) *p = bswap ## size(*p);
58 #else
59 #define le_bswap(v, size) (v)
60 #define be_bswap(v, size) bswap ## size(v)
61 #define le_bswaps(v, size)
62 #define be_bswaps(p, size) *p = bswap ## size(*p);
63 #endif
64 
65 #define CPU_CONVERT(endian, size, type)\
66 static inline type endian ## size ## _to_cpu(type v)\
67 {\
68     return endian ## _bswap(v, size);\
69 }\
70 \
71 static inline type cpu_to_ ## endian ## size(type v)\
72 {\
73     return endian ## _bswap(v, size);\
74 }\
75 \
76 static inline void endian ## size ## _to_cpus(type *p)\
77 {\
78     endian ## _bswaps(p, size)\
79 }\
80 \
81 static inline void cpu_to_ ## endian ## size ## s(type *p)\
82 {\
83     endian ## _bswaps(p, size)\
84 }\
85 \
86 static inline type endian ## size ## _to_cpup(const type *p)\
87 {\
88     return endian ## size ## _to_cpu(*p);\
89 }\
90 \
91 static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
92 {\
93      *p = cpu_to_ ## endian ## size(v);\
94 }
95 
96 CPU_CONVERT(be, 16, uint16_t)
97 CPU_CONVERT(be, 32, uint32_t)
98 CPU_CONVERT(be, 64, uint64_t)
99 
100 CPU_CONVERT(le, 16, uint16_t)
101 CPU_CONVERT(le, 32, uint32_t)
102 CPU_CONVERT(le, 64, uint64_t)
103 
104 /* unaligned versions (optimized for frequent unaligned accesses)*/
105 
106 #if defined(__i386__) || defined(__powerpc__)
107 
108 #define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
109 #define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
110 #define le16_to_cpupu(p) le16_to_cpup(p)
111 #define le32_to_cpupu(p) le32_to_cpup(p)
112 
113 #define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
114 #define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
115 
116 #else
117 
118 static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
119 {
120     uint8_t *p1 = (uint8_t *)p;
121 
122     p1[0] = v;
123     p1[1] = v >> 8;
124 }
125 
126 static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
127 {
128     uint8_t *p1 = (uint8_t *)p;
129 
130     p1[0] = v;
131     p1[1] = v >> 8;
132     p1[2] = v >> 16;
133     p1[3] = v >> 24;
134 }
135 
136 static inline uint16_t le16_to_cpupu(const uint16_t *p)
137 {
138     const uint8_t *p1 = (const uint8_t *)p;
139     return p1[0] | (p1[1] << 8);
140 }
141 
142 static inline uint32_t le32_to_cpupu(const uint32_t *p)
143 {
144     const uint8_t *p1 = (const uint8_t *)p;
145     return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
146 }
147 
148 static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
149 {
150     uint8_t *p1 = (uint8_t *)p;
151 
152     p1[0] = v >> 8;
153     p1[1] = v;
154 }
155 
156 static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
157 {
158     uint8_t *p1 = (uint8_t *)p;
159 
160     p1[0] = v >> 24;
161     p1[1] = v >> 16;
162     p1[2] = v >> 8;
163     p1[3] = v;
164 }
165 
166 #endif
167 
168 #ifdef WORDS_BIGENDIAN
169 #define cpu_to_32wu cpu_to_be32wu
170 #else
171 #define cpu_to_32wu cpu_to_le32wu
172 #endif
173 
174 #undef le_bswap
175 #undef be_bswap
176 #undef le_bswaps
177 #undef be_bswaps
178 
179 #endif /* BSWAP_H */
180