first public release
[dpdk.git] / lib / librte_eal / common / include / rte_byteorder.h
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  *  version: DPDK.L.1.2.3-3
34  */
35
36 #ifndef _RTE_BYTEORDER_H_
37 #define _RTE_BYTEORDER_H_
38
39 /**
40  * @file
41  *
42  * Byte Swap Operations
43  *
44  * This file defines a generic API for byte swap operations. Part of
45  * the implementation is architecture-specific.
46  */
47
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51
52 #include <stdint.h>
53
54 /*
55  * An internal function to swap bytes in a 16-bit value.
56  *
57  * It is used by rte_bswap16() when the value is constant. Do not use
58  * this function directly; rte_bswap16() is preferred.
59  */
60 static inline uint16_t
61 rte_constant_bswap16(uint16_t x)
62 {
63         return (uint16_t)(((x & 0x00ffU) << 8) |
64                 ((x & 0xff00U) >> 8));
65 }
66
67 /*
68  * An internal function to swap bytes in a 32-bit value.
69  *
70  * It is used by rte_bswap32() when the value is constant. Do not use
71  * this function directly; rte_bswap32() is preferred.
72  */
73 static inline uint32_t
74 rte_constant_bswap32(uint32_t x)
75 {
76         return  ((x & 0x000000ffUL) << 24) |
77                 ((x & 0x0000ff00UL) << 8) |
78                 ((x & 0x00ff0000UL) >> 8) |
79                 ((x & 0xff000000UL) >> 24);
80 }
81
82 /*
83  * An internal function to swap bytes of a 64-bit value.
84  *
85  * It is used by rte_bswap64() when the value is constant. Do not use
86  * this function directly; rte_bswap64() is preferred.
87  */
88 static inline uint64_t
89 rte_constant_bswap64(uint64_t x)
90 {
91         return  ((x & 0x00000000000000ffULL) << 56) |
92                 ((x & 0x000000000000ff00ULL) << 40) |
93                 ((x & 0x0000000000ff0000ULL) << 24) |
94                 ((x & 0x00000000ff000000ULL) <<  8) |
95                 ((x & 0x000000ff00000000ULL) >>  8) |
96                 ((x & 0x0000ff0000000000ULL) >> 24) |
97                 ((x & 0x00ff000000000000ULL) >> 40) |
98                 ((x & 0xff00000000000000ULL) >> 56);
99 }
100
101 /*
102  * An architecture-optimized byte swap for a 16-bit value.
103  *
104  * Do not use this function directly. The preferred function is rte_bswap16().
105  */
106 static inline uint16_t rte_arch_bswap16(uint16_t _x)
107 {
108         register uint16_t x = _x;
109         asm volatile ("xchgb %b[x1],%h[x2]"
110                       : [x1] "=Q" (x)
111                       : [x2] "0" (x)
112                       );
113         return x;
114 }
115
116 /*
117  * An architecture-optimized byte swap for a 32-bit value.
118  *
119  * Do not use this function directly. The preferred function is rte_bswap32().
120  */
121 static inline uint32_t rte_arch_bswap32(uint32_t _x)
122 {
123         register uint32_t x = _x;
124         asm volatile ("bswap %[x]"
125                       : [x] "+r" (x)
126                       );
127         return x;
128 }
129
130 /*
131  * An architecture-optimized byte swap for a 64-bit value.
132  *
133   * Do not use this function directly. The preferred function is rte_bswap64().
134  */
135 #ifdef RTE_ARCH_X86_64
136 /* 64-bit mode */
137 static inline uint64_t rte_arch_bswap64(uint64_t _x)
138 {
139         register uint64_t x = _x;
140         asm volatile ("bswap %[x]"
141                       : [x] "+r" (x)
142                       );
143         return x;
144 }
145 #else /* ! RTE_ARCH_X86_64 */
146 /* Compat./Leg. mode */
147 static inline uint64_t rte_arch_bswap64(uint64_t x)
148 {
149         uint64_t ret = 0;
150         ret |= ((uint64_t)rte_arch_bswap32(x & 0xffffffffUL) << 32);
151         ret |= ((uint64_t)rte_arch_bswap32((x >> 32) & 0xffffffffUL));
152         return ret;
153 }
154 #endif /* RTE_ARCH_X86_64 */
155
156 /**
157  * Swap bytes in a 16-bit value.
158  */
159 #define rte_bswap16(x) ((uint16_t)(__builtin_constant_p(x) ?            \
160                                    rte_constant_bswap16(x) :            \
161                                    rte_arch_bswap16(x)))                \
162
163 /**
164  * Swap bytes in a 32-bit value.
165  */
166 #define rte_bswap32(x) ((uint32_t)(__builtin_constant_p(x) ?            \
167                                    rte_constant_bswap32(x) :            \
168                                    rte_arch_bswap32(x)))                \
169
170 /**
171  * Swap bytes in a 64-bit value.
172  */
173 #define rte_bswap64(x) ((uint64_t)(__builtin_constant_p(x) ?            \
174                                    rte_constant_bswap64(x) :            \
175                                    rte_arch_bswap64(x)))                \
176
177 /**
178  * Convert a 16-bit value from CPU order to little endian.
179  */
180 #define rte_cpu_to_le_16(x) (x)
181
182 /**
183  * Convert a 32-bit value from CPU order to little endian.
184  */
185 #define rte_cpu_to_le_32(x) (x)
186
187 /**
188  * Convert a 64-bit value from CPU order to little endian.
189  */
190 #define rte_cpu_to_le_64(x) (x)
191
192
193 /**
194  * Convert a 16-bit value from CPU order to big endian.
195  */
196 #define rte_cpu_to_be_16(x) rte_bswap16(x)
197
198 /**
199  * Convert a 32-bit value from CPU order to big endian.
200  */
201 #define rte_cpu_to_be_32(x) rte_bswap32(x)
202
203 /**
204  * Convert a 64-bit value from CPU order to big endian.
205  */
206 #define rte_cpu_to_be_64(x) rte_bswap64(x)
207
208
209 /**
210  * Convert a 16-bit value from little endian to CPU order.
211  */
212 #define rte_le_to_cpu_16(x) (x)
213
214 /**
215  * Convert a 32-bit value from little endian to CPU order.
216  */
217 #define rte_le_to_cpu_32(x) (x)
218
219 /**
220  * Convert a 64-bit value from little endian to CPU order.
221  */
222 #define rte_le_to_cpu_64(x) (x)
223
224
225 /**
226  * Convert a 16-bit value from big endian to CPU order.
227  */
228 #define rte_be_to_cpu_16(x) rte_bswap16(x)
229
230 /**
231  * Convert a 32-bit value from big endian to CPU order.
232  */
233 #define rte_be_to_cpu_32(x) rte_bswap32(x)
234
235 /**
236  * Convert a 64-bit value from big endian to CPU order.
237  */
238 #define rte_be_to_cpu_64(x) rte_bswap64(x)
239
240 #ifdef __cplusplus
241 }
242 #endif
243
244 #endif /* _RTE_BYTEORDER_H_ */