1 | /**
|
---|
2 | * @file bswap.h
|
---|
3 | * byte swap.
|
---|
4 | */
|
---|
5 |
|
---|
6 | #ifndef __BSWAP_H__
|
---|
7 | #define __BSWAP_H__
|
---|
8 |
|
---|
9 | #ifdef HAVE_BYTESWAP_H
|
---|
10 | #include <byteswap.h>
|
---|
11 | #else
|
---|
12 |
|
---|
13 | #ifdef ARCH_X86_64
|
---|
14 | # define LEGACY_REGS "=Q"
|
---|
15 | #else
|
---|
16 | # define LEGACY_REGS "=q"
|
---|
17 | #endif
|
---|
18 |
|
---|
19 | #if defined(ARCH_X86) || defined(ARCH_X86_64)
|
---|
20 | static always_inline uint16_t bswap_16(uint16_t x)
|
---|
21 | {
|
---|
22 | __asm("rorw $8, %0" :
|
---|
23 | LEGACY_REGS (x) :
|
---|
24 | "0" (x));
|
---|
25 | return x;
|
---|
26 | }
|
---|
27 |
|
---|
28 | static always_inline uint32_t bswap_32(uint32_t x)
|
---|
29 | {
|
---|
30 | #if __CPU__ != 386
|
---|
31 | __asm("bswap %0":
|
---|
32 | "=r" (x) :
|
---|
33 | #else
|
---|
34 | __asm("xchgb %b0,%h0\n"
|
---|
35 | " rorl $16,%0\n"
|
---|
36 | " xchgb %b0,%h0":
|
---|
37 | LEGACY_REGS (x) :
|
---|
38 | #endif
|
---|
39 | "0" (x));
|
---|
40 | return x;
|
---|
41 | }
|
---|
42 |
|
---|
43 | static inline uint64_t bswap_64(uint64_t x)
|
---|
44 | {
|
---|
45 | #ifdef ARCH_X86_64
|
---|
46 | __asm("bswap %0":
|
---|
47 | "=r" (x) :
|
---|
48 | "0" (x));
|
---|
49 | return x;
|
---|
50 | #else
|
---|
51 | union {
|
---|
52 | uint64_t ll;
|
---|
53 | struct {
|
---|
54 | uint32_t l,h;
|
---|
55 | } l;
|
---|
56 | } r;
|
---|
57 | r.l.l = bswap_32 (x);
|
---|
58 | r.l.h = bswap_32 (x>>32);
|
---|
59 | return r.ll;
|
---|
60 | #endif
|
---|
61 | }
|
---|
62 |
|
---|
63 | #elif defined(ARCH_SH4)
|
---|
64 |
|
---|
65 | static always_inline uint16_t bswap_16(uint16_t x) {
|
---|
66 | __asm__("swap.b %0,%0":"=r"(x):"0"(x));
|
---|
67 | return x;
|
---|
68 | }
|
---|
69 |
|
---|
70 | static always_inline uint32_t bswap_32(uint32_t x) {
|
---|
71 | __asm__(
|
---|
72 | "swap.b %0,%0\n"
|
---|
73 | "swap.w %0,%0\n"
|
---|
74 | "swap.b %0,%0\n"
|
---|
75 | :"=r"(x):"0"(x));
|
---|
76 | return x;
|
---|
77 | }
|
---|
78 |
|
---|
79 | static inline uint64_t bswap_64(uint64_t x)
|
---|
80 | {
|
---|
81 | union {
|
---|
82 | uint64_t ll;
|
---|
83 | struct {
|
---|
84 | uint32_t l,h;
|
---|
85 | } l;
|
---|
86 | } r;
|
---|
87 | r.l.l = bswap_32 (x);
|
---|
88 | r.l.h = bswap_32 (x>>32);
|
---|
89 | return r.ll;
|
---|
90 | }
|
---|
91 | #else
|
---|
92 |
|
---|
93 | static always_inline uint16_t bswap_16(uint16_t x){
|
---|
94 | return (x>>8) | (x<<8);
|
---|
95 | }
|
---|
96 |
|
---|
97 | #ifdef ARCH_ARM
|
---|
98 | static always_inline uint32_t bswap_32(uint32_t x){
|
---|
99 | uint32_t t;
|
---|
100 | __asm__ (
|
---|
101 | "eor %1, %0, %0, ror #16 \n\t"
|
---|
102 | "bic %1, %1, #0xFF0000 \n\t"
|
---|
103 | "mov %0, %0, ror #8 \n\t"
|
---|
104 | "eor %0, %0, %1, lsr #8 \n\t"
|
---|
105 | : "+r"(x), "+r"(t));
|
---|
106 | return x;
|
---|
107 | }
|
---|
108 | #else
|
---|
109 | static always_inline uint32_t bswap_32(uint32_t x){
|
---|
110 | x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
|
---|
111 | return (x>>16) | (x<<16);
|
---|
112 | }
|
---|
113 | #endif
|
---|
114 |
|
---|
115 | static inline uint64_t bswap_64(uint64_t x)
|
---|
116 | {
|
---|
117 | #if 0
|
---|
118 | x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
|
---|
119 | x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
|
---|
120 | return (x>>32) | (x<<32);
|
---|
121 | #else
|
---|
122 | union {
|
---|
123 | uint64_t ll;
|
---|
124 | uint32_t l[2];
|
---|
125 | } w, r;
|
---|
126 | w.ll = x;
|
---|
127 | r.l[0] = bswap_32 (w.l[1]);
|
---|
128 | r.l[1] = bswap_32 (w.l[0]);
|
---|
129 | return r.ll;
|
---|
130 | #endif
|
---|
131 | }
|
---|
132 | #endif /* !ARCH_X86 */
|
---|
133 |
|
---|
134 | #endif /* !HAVE_BYTESWAP_H */
|
---|
135 |
|
---|
136 | // be2me ... BigEndian to MachineEndian
|
---|
137 | // le2me ... LittleEndian to MachineEndian
|
---|
138 |
|
---|
139 | #ifdef WORDS_BIGENDIAN
|
---|
140 | #define be2me_16(x) (x)
|
---|
141 | #define be2me_32(x) (x)
|
---|
142 | #define be2me_64(x) (x)
|
---|
143 | #define le2me_16(x) bswap_16(x)
|
---|
144 | #define le2me_32(x) bswap_32(x)
|
---|
145 | #define le2me_64(x) bswap_64(x)
|
---|
146 | #else
|
---|
147 | #define be2me_16(x) bswap_16(x)
|
---|
148 | #define be2me_32(x) bswap_32(x)
|
---|
149 | #define be2me_64(x) bswap_64(x)
|
---|
150 | #define le2me_16(x) (x)
|
---|
151 | #define le2me_32(x) (x)
|
---|
152 | #define le2me_64(x) (x)
|
---|
153 | #endif
|
---|
154 |
|
---|
155 | #endif /* __BSWAP_H__ */
|
---|