Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / libc / include / endian.h
1 /*
2  * <endian.h>
3  *
4  * Open Hack'Ware BIOS: provides all common endianness conversions functions
5  * 
6  * Copyright (c) 2004-2005 Jocelyn Mayer
7  * 
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License V2
10  *   as published by the Free Software Foundation
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 /*
22  * This file provides:
23  *  void cpu_to_be16p (uint16_t *outp, uint16_t in);
24  *  void cpu_to_be32p (uint32_t *outp, uint32_t in);
25  *  void cpu_to_be64p (uint64_t *outp, uint64_t in);
26  *  void cpu_to_le16p (uint16_t *outp, uint16_t in);
27  *  void cpu_to_le32p (uint32_t *outp, uint32_t in);
28  *  void cpu_to_le64p (uint64_t *outp, uint64_t in);
29  *  void endian_to_cpu16p (uint16_t *outp, uint16_t in, endian_t endian);
30  *  void endian_to_cpu32p (uint32_t *outp, uint32_t in, endian_t endian);
31  *  void endian_to_cpu64p (uint64_t *outp, uint64_t in, endian_t endian);
32  *  void cpu16_to_endianp (uint16_t *outp, uint16_t in, endian_t endian);
33  *  void cpu32_to_endianp (uint32_t *outp, uint32_t in, endian_t endian);
34  *  void cpu64_to_endianp (uint64_t *outp, uint64_t in, endian_t endian);
35  *
36  */
37
38 #if !defined (__OHW_ENDIAN_H__)
39 #define __OHW_ENDIAN_H__
40
41 #include <stdint.h>
42
43 typedef enum endian_t endian_t;
44 enum endian_t {
45     ENDIAN_1234 = 0,
46     ENDIAN_4321,
47     ENDIAN_3412,
48     ENDIAN_2143,
49 };
50
51 /* Generic endian conversion functions */
52 static inline void generic_cpu_swap16p (uint16_t *outp, uint16_t in)
53 {
54     *outp = ((in & 0xFF00) >> 8) | ((in & 0x00FF) << 8);
55 }
56
57 static inline void generic_cpu_swap32p (uint32_t *outp, uint32_t in)
58 {
59     *outp = ((in & 0xFF000000) >> 24) | ((in & 0x00FF0000) >> 8) |
60         ((in & 0x0000FF00) << 8) | ((in & 0x000000FF) << 24);
61 }
62
63 static inline void generic_cpu_swap64p (uint64_t *outp, uint64_t in)
64 {
65     *outp = ((in & 0xFF00000000000000ULL) >> 56) |
66         ((in & 0x00FF000000000000ULL) >> 40) |
67         ((in & 0x0000FF0000000000ULL) >> 24) |
68         ((in & 0x000000FF00000000ULL) >> 8) |
69         ((in & 0x00000000FF000000ULL) << 8) |
70         ((in & 0x0000000000FF0000ULL) << 24) |
71         ((in & 0x000000000000FF00ULL) << 40) |
72         ((in & 0x00000000000000FFULL) << 56);
73 }
74
75 static inline void generic_cpu_swap64p_32 (uint64_t *outp, uint64_t in)
76 {
77     uint32_t *_outp = (uint32_t *)outp;
78
79     generic_cpu_swap32p(_outp, in);
80     generic_cpu_swap32p(_outp + 1, in >> 32);
81 }
82
83 #if defined (__i386__)
84
85 #define __CPU_ENDIAN_4321__
86 #define __CPU_LENGTH_32__
87
88 #elif defined (__x86_64__)
89
90 #define __CPU_ENDIAN_4321__
91 #define __CPU_LENGTH_64__
92
93 #elif defined (__powerpc__) || defined (_ARCH_PPC)
94
95 #define __CPU_ENDIAN_1234__
96 #define __CPU_LENGTH_32__
97
98 #define __HAVE_CPU_SWAP16P__
99 static inline void cpu_swap16p (uint16_t *outp, uint16_t in)
100 {
101     __asm__ __volatile__ ("sthbrx %4, 0(%3)");
102 }
103
104 #define __HAVE_CPU_SWAP32P__
105 static inline void cpu_swap32p (uint32_t *outp, uint32_t in)
106 {
107     __asm__ __volatile__ ("stwbrx %4, 0(%3)");
108 }
109
110 #define __HAVE_CPU_SWAP64P__
111 static inline void cpu_swap64p (uint64_t *outp, uint64_t in)
112 {
113     return generic_cpu_swap64p_32(outp, in);
114 }
115
116 #else
117
118 #error "unsupported CPU architecture"
119
120 #endif
121
122 /* Use generic swap function if no cpu specific were provided */
123 #if !defined (__HAVE_CPU_SWAP16P__)
124 static inline void cpu_swap16p (uint16_t *outp, uint16_t in)
125 {
126     generic_cpu_swap16p(outp, in);
127 }
128 #endif
129
130 #if !defined (__HAVE_CPU_SWAP32P__)
131 static inline void cpu_swap32p (uint32_t *outp, uint32_t in)
132 {
133     generic_cpu_swap32p(outp, in);
134 }
135 #endif
136
137 #if !defined (__HAVE_CPU_SWAP64P__)
138 static inline void cpu_swap64p (uint64_t *outp, uint64_t in)
139 {
140 #if defined (__CPU_LENGTH_64__)
141     generic_cpu_swap64p(outp, in);
142 #elif defined (__CPU_LENGTH_32__)
143     generic_cpu_swap64p_32(outp, in);
144 #else
145 #error "Don't know how to make 64 bits swapping on this arch"
146 #endif
147 }
148 #endif
149
150 static inline void cpu_nswap16p (uint16_t *outp, uint16_t in)
151 {
152     *outp = in;
153 }
154
155 static inline void cpu_nswap32p (uint32_t *outp, uint32_t in)
156 {
157     *outp = in;
158 }
159
160 static inline void cpu_nswap64p (uint64_t *outp, uint64_t in)
161 {
162     *outp = in;
163 }
164
165 static inline void _endian_be16_p (uint16_t *outp, uint16_t in,
166                                    endian_t endian)
167 {
168     switch (endian) {
169     case ENDIAN_4321:
170     case ENDIAN_2143:
171         cpu_swap16p(outp, in);
172         break;
173     case ENDIAN_1234:
174     case ENDIAN_3412:
175         cpu_nswap16p(outp, in);
176         break;
177     }
178 }        
179
180 static inline void _endian_be32_p (uint32_t *outp, uint32_t in,
181                                    endian_t endian)
182 {
183     switch (endian) {
184     case ENDIAN_4321:
185         cpu_swap32p(outp, in);
186         break;
187     case ENDIAN_1234:
188         cpu_nswap32p(outp, in);
189         break;
190     case ENDIAN_2143:
191         /* TODO */
192         break;
193     case ENDIAN_3412:
194         /* TODO */
195         break;
196     }
197 }        
198
199 static inline void _endian_be64_p (uint64_t *outp, uint64_t in,
200                                    endian_t endian)
201 {
202     switch (endian) {
203     case ENDIAN_4321:
204         cpu_swap64p(outp, in);
205         break;
206     case ENDIAN_1234:
207         cpu_nswap64p(outp, in);
208         break;
209     case ENDIAN_2143:
210         /* TODO */
211         break;
212     case ENDIAN_3412:
213         /* TODO */
214         break;
215     }
216 }        
217
218 static inline void _endian_le16_p (uint16_t *outp, uint16_t in,
219                                    endian_t endian)
220 {
221     switch (endian) {
222     case ENDIAN_4321:
223     case ENDIAN_2143:
224         cpu_nswap16p(outp, in);
225         break;
226     case ENDIAN_1234:
227     case ENDIAN_3412:
228         cpu_swap16p(outp, in);
229         break;
230     }
231 }        
232
233 static inline void _endian_le32_p (uint32_t *outp, uint32_t in,
234                                    endian_t endian)
235 {
236     switch (endian) {
237     case ENDIAN_4321:
238         cpu_nswap32p(outp, in);
239         break;
240     case ENDIAN_1234:
241         cpu_swap32p(outp, in);
242         break;
243     case ENDIAN_2143:
244         /* TODO */
245         break;
246     case ENDIAN_3412:
247         /* TODO */
248         break;
249     }
250 }        
251
252 static inline void _endian_le64_p (uint64_t *outp, uint64_t in,
253                                    endian_t endian)
254 {
255     switch (endian) {
256     case ENDIAN_4321:
257         cpu_nswap64p(outp, in);
258         break;
259     case ENDIAN_1234:
260         cpu_swap64p(outp, in);
261         break;
262     case ENDIAN_2143:
263         /* TODO */
264         break;
265     case ENDIAN_3412:
266         /* TODO */
267         break;
268     }
269 }        
270
271 static inline void endian_to_be16p (uint16_t *outp, uint16_t in,
272                                     endian_t endian)
273 {
274     _endian_be16_p(outp, in, endian);
275 }
276
277 static inline void endian_to_be32p (uint32_t *outp, uint32_t in,
278                                     endian_t endian)
279 {
280     _endian_be32_p(outp, in, endian);
281 }
282
283 static inline void endian_to_be64p (uint64_t *outp, uint64_t in,
284                                     endian_t endian)
285 {
286     _endian_be64_p(outp, in, endian);
287 }
288
289 static inline void endian_to_le16p (uint16_t *outp, uint16_t in,
290                                     endian_t endian)
291 {
292     _endian_le16_p(outp, in, endian);
293 }
294
295 static inline void endian_to_le32p (uint32_t *outp, uint32_t in,
296                                     endian_t endian)
297 {
298     _endian_le32_p(outp, in, endian);
299 }
300
301 static inline void endian_to_le64p (uint64_t *outp, uint64_t in,
302                                     endian_t endian)
303 {
304     _endian_le64_p(outp, in, endian);
305 }
306
307 static inline void be16_to_endianp (uint16_t *outp, uint16_t in,
308                                     endian_t endian)
309 {
310     _endian_be16_p(outp, in, endian);
311 }
312
313 static inline void be32_to_endianp (uint32_t *outp, uint32_t in,
314                                     endian_t endian)
315 {
316     _endian_be32_p(outp, in, endian);
317 }
318
319 static inline void be64_to_endianp (uint64_t *outp, uint64_t in,
320                                     endian_t endian)
321 {
322     _endian_be64_p(outp, in, endian);
323 }
324
325 static inline void le16_to_endianp (uint16_t *outp, uint16_t in,
326                                     endian_t endian)
327 {
328     _endian_le16_p(outp, in, endian);
329 }
330
331 static inline void le32_to_endianp (uint32_t *outp, uint32_t in,
332                                     endian_t endian)
333 {
334     _endian_le32_p(outp, in, endian);
335 }
336
337 static inline void le64_to_endianp (uint64_t *outp, uint64_t in,
338                                     endian_t endian)
339 {
340     _endian_le64_p(outp, in, endian);
341 }
342
343 #if defined (__CPU_ENDIAN_4321__)
344
345 static inline void cpu_to_be16p (uint16_t *outp, uint16_t in)
346 {
347     cpu_swap16p(outp, in);
348 }
349
350 static inline void cpu_to_be32p (uint32_t *outp, uint32_t in)
351 {
352     cpu_swap32p(outp, in);
353 }
354
355 static inline void cpu_to_be64p (uint64_t *outp, uint64_t in)
356 {
357     cpu_swap64p(outp, in);
358 }
359
360 static inline void cpu_to_le16p (uint16_t *outp, uint16_t in)
361 {
362     cpu_nswap16p(outp, in);
363 }
364
365 static inline void cpu_to_le32p (uint32_t *outp, uint32_t in)
366 {
367     cpu_nswap32p(outp, in);
368 }
369
370 static inline void cpu_to_le64p (uint64_t *outp, uint64_t in)
371 {
372     cpu_nswap64p(outp, in);
373 }
374
375 static inline void be16_to_cpup (uint16_t *outp, uint16_t in)
376 {
377     cpu_swap16p(outp, in);
378 }
379
380 static inline void be32_to_cpup (uint32_t *outp, uint32_t in)
381 {
382     cpu_swap32p(outp, in);
383 }
384
385 static inline void be64_to_cpup (uint64_t *outp, uint64_t in)
386 {
387     cpu_swap64p(outp, in);
388 }
389
390 static inline void le16_to_cpup (uint16_t *outp, uint16_t in)
391 {
392     cpu_nswap16p(outp, in);
393 }
394
395 static inline void le32_to_cpup (uint32_t *outp, uint32_t in)
396 {
397     cpu_nswap32p(outp, in);
398 }
399
400 static inline void le64_to_cpup (uint64_t *outp, uint64_t in)
401 {
402     cpu_nswap64p(outp, in);
403 }
404
405 static inline void endian_to_cpu16p (uint16_t *outp, uint16_t in,
406                                      endian_t endian)
407 {
408     endian_to_le16p(outp, in, endian);
409 }
410
411 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
412                                      endian_t endian)
413 {
414     endian_to_le32p(outp, in, endian);
415 }
416
417 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
418                                      endian_t endian)
419 {
420     endian_to_le64p(outp, in, endian);
421 }
422
423 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
424                                      endian_t endian)
425 {
426     le16_to_endianp(outp, in, endian);
427 }
428
429 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
430                                      endian_t endian)
431 {
432     le32_to_endianp(outp, in, endian);
433 }
434
435 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
436                                      endian_t endian)
437 {
438     le64_to_endianp(outp, in, endian);
439 }
440
441 #elif defined (__CPU_ENDIAN_1234__)
442
443 static inline void cpu_to_be16p (uint16_t *outp, uint16_t in)
444 {
445     cpu_nswap16p(outp, in);
446 }
447
448 static inline void cpu_to_be32p (uint32_t *outp, uint32_t in)
449 {
450     cpu_nswap32p(outp, in);
451 }
452
453 static inline void cpu_to_be64p (uint64_t *outp, uint64_t in)
454 {
455     cpu_nswap64p(outp, in);
456 }
457
458 static inline void cpu_to_le16p (uint16_t *outp, uint16_t in)
459 {
460     cpu_swap16p(outp, in);
461 }
462
463 static inline void cpu_to_le32p (uint32_t *outp, uint32_t in)
464 {
465     cpu_swap32p(outp, in);
466 }
467
468 static inline void cpu_to_le64p (uint64_t *outp, uint64_t in)
469 {
470     cpu_swap64p(outp, in);
471 }
472
473 static inline void endian_to_cpu16p (uint16_t *outp, uint16_t in,
474                                      endian_t endian)
475 {
476     endian_to_be16p(outp, in, endian);
477 }
478
479 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
480                                      endian_t endian)
481 {
482     endian_to_be32p(outp, in, endian);
483 }
484
485 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
486                                      endian_t endian)
487 {
488     endian_to_be64p(outp, in, endian);
489 }
490
491 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
492                                      endian_t endian)
493 {
494     be16_to_endianp(outp, in, endian);
495 }
496
497 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
498                                      endian_t endian)
499 {
500     be32_to_endianp(outp, in, endian);
501 }
502
503 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
504                                      endian_t endian)
505 {
506     be64_to_endianp(outp, in, endian);
507 }
508
509 #else /* 2143 / 3412 */
510 /* TODO */
511 #error "TODO"
512 #endif
513
514 #endif /* !defined (__OHW_ENDIAN_H__) */