211a15c0abff965f23b07d7a7f4aab999b652d73
[libav.git] / libavutil / bswap.h
1 /*
2 * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file bswap.h
23 * byte swap.
24 */
25
26 #ifndef BSWAP_H
27 #define BSWAP_H
28
29 #include <stdint.h>
30 #include "common.h"
31
32 #ifdef HAVE_BYTESWAP_H
33 #include <byteswap.h>
34 #else
35
36 #ifdef ARCH_X86_64
37 # define LEGACY_REGS "=Q"
38 #else
39 # define LEGACY_REGS "=q"
40 #endif
41
42 static av_always_inline uint16_t bswap_16(uint16_t x)
43 {
44 #if defined(ARCH_X86)
45 __asm("rorw $8, %0" :
46 LEGACY_REGS (x) :
47 "0" (x));
48 #elif defined(ARCH_SH4)
49 __asm__("swap.b %0,%0":"=r"(x):"0"(x));
50 #else
51 x= (x>>8) | (x<<8);
52 #endif
53 return x;
54 }
55
56 static av_always_inline uint32_t bswap_32(uint32_t x)
57 {
58 #if defined(ARCH_X86)
59 #if __CPU__ != 386
60 __asm("bswap %0":
61 "=r" (x) :
62 #else
63 __asm("xchgb %b0,%h0\n"
64 " rorl $16,%0\n"
65 " xchgb %b0,%h0":
66 LEGACY_REGS (x) :
67 #endif
68 "0" (x));
69 #elif defined(ARCH_SH4)
70 __asm__(
71 "swap.b %0,%0\n"
72 "swap.w %0,%0\n"
73 "swap.b %0,%0\n"
74 :"=r"(x):"0"(x));
75 #elif defined(ARCH_ARM)
76 uint32_t t;
77 __asm__ (
78 "eor %1, %0, %0, ror #16 \n\t"
79 "bic %1, %1, #0xFF0000 \n\t"
80 "mov %0, %0, ror #8 \n\t"
81 "eor %0, %0, %1, lsr #8 \n\t"
82 : "+r"(x), "+r"(t));
83 #elif defined(ARCH_BFIN)
84 unsigned tmp;
85 asm("%1 = %0 >> 8 (V);\n\t"
86 "%0 = %0 << 8 (V);\n\t"
87 "%0 = %0 | %1;\n\t"
88 "%0 = PACK(%0.L, %0.H);\n\t"
89 : "+d"(x), "=&d"(tmp));
90 #else
91 x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
92 x= (x>>16) | (x<<16);
93 #endif
94 return x;
95 }
96
97 static inline uint64_t bswap_64(uint64_t x)
98 {
99 #if 0
100 x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
101 x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
102 return (x>>32) | (x<<32);
103 #elif defined(ARCH_X86_64)
104 __asm("bswap %0":
105 "=r" (x) :
106 "0" (x));
107 return x;
108 #else
109 union {
110 uint64_t ll;
111 uint32_t l[2];
112 } w, r;
113 w.ll = x;
114 r.l[0] = bswap_32 (w.l[1]);
115 r.l[1] = bswap_32 (w.l[0]);
116 return r.ll;
117 #endif
118 }
119
120 #endif /* !HAVE_BYTESWAP_H */
121
122 // be2me ... BigEndian to MachineEndian
123 // le2me ... LittleEndian to MachineEndian
124
125 #ifdef WORDS_BIGENDIAN
126 #define be2me_16(x) (x)
127 #define be2me_32(x) (x)
128 #define be2me_64(x) (x)
129 #define le2me_16(x) bswap_16(x)
130 #define le2me_32(x) bswap_32(x)
131 #define le2me_64(x) bswap_64(x)
132 #else
133 #define be2me_16(x) bswap_16(x)
134 #define be2me_32(x) bswap_32(x)
135 #define be2me_64(x) bswap_64(x)
136 #define le2me_16(x) (x)
137 #define le2me_32(x) (x)
138 #define le2me_64(x) (x)
139 #endif
140
141 #endif /* BSWAP_H */