Add alias-safe aligned AV_[RW]N macros
[libav.git] / libavutil / intreadwrite.h
CommitLineData
f5a90186
DB
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
98790382
SS
19#ifndef AVUTIL_INTREADWRITE_H
20#define AVUTIL_INTREADWRITE_H
cf1e119b 21
99545457 22#include <stdint.h>
a087028a 23#include "config.h"
c08be350 24#include "bswap.h"
d10458c9
MR
25#include "common.h"
26
27typedef union {
28 uint64_t u64;
29 uint32_t u32[2];
30 uint16_t u16[4];
31 uint8_t u8 [8];
32 double f64;
33 float f32[2];
34} av_alias av_alias64;
35
36typedef union {
37 uint32_t u32;
38 uint16_t u16[2];
39 uint8_t u8 [4];
40 float f32;
41} av_alias av_alias32;
42
43typedef union {
44 uint16_t u16;
45 uint8_t u8 [2];
46} av_alias av_alias16;
99545457 47
a6783b89
MR
48/*
49 * Arch-specific headers can provide any combination of
f6d03906
AS
50 * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
51 * Preprocessor symbols must be defined, even if these are implemented
52 * as inline functions.
a6783b89
MR
53 */
54
3c55ce03
MR
55#if ARCH_ARM
56# include "arm/intreadwrite.h"
d691da95
MR
57#elif ARCH_AVR32
58# include "avr32/intreadwrite.h"
530456bf
MR
59#elif ARCH_MIPS
60# include "mips/intreadwrite.h"
9f5ff83f
MR
61#elif ARCH_PPC
62# include "ppc/intreadwrite.h"
f6d03906
AS
63#elif ARCH_X86
64# include "x86/intreadwrite.h"
3c55ce03 65#endif
a6783b89
MR
66
67/*
63826ceb
MR
68 * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers.
69 */
70
71#if HAVE_BIGENDIAN
72
73# if defined(AV_RN16) && !defined(AV_RB16)
74# define AV_RB16(p) AV_RN16(p)
75# elif !defined(AV_RN16) && defined(AV_RB16)
76# define AV_RN16(p) AV_RB16(p)
77# endif
78
79# if defined(AV_WN16) && !defined(AV_WB16)
80# define AV_WB16(p, v) AV_WN16(p, v)
81# elif !defined(AV_WN16) && defined(AV_WB16)
82# define AV_WN16(p, v) AV_WB16(p, v)
83# endif
84
63826ceb
MR
85# if defined(AV_RN24) && !defined(AV_RB24)
86# define AV_RB24(p) AV_RN24(p)
87# elif !defined(AV_RN24) && defined(AV_RB24)
88# define AV_RN24(p) AV_RB24(p)
89# endif
90
91# if defined(AV_WN24) && !defined(AV_WB24)
92# define AV_WB24(p, v) AV_WN24(p, v)
93# elif !defined(AV_WN24) && defined(AV_WB24)
94# define AV_WN24(p, v) AV_WB24(p, v)
95# endif
96
4a051891
MR
97# if defined(AV_RN32) && !defined(AV_RB32)
98# define AV_RB32(p) AV_RN32(p)
99# elif !defined(AV_RN32) && defined(AV_RB32)
100# define AV_RN32(p) AV_RB32(p)
101# endif
102
63826ceb
MR
103# if defined(AV_WN32) && !defined(AV_WB32)
104# define AV_WB32(p, v) AV_WN32(p, v)
105# elif !defined(AV_WN32) && defined(AV_WB32)
106# define AV_WN32(p, v) AV_WB32(p, v)
107# endif
108
109# if defined(AV_RN64) && !defined(AV_RB64)
110# define AV_RB64(p) AV_RN64(p)
111# elif !defined(AV_RN64) && defined(AV_RB64)
112# define AV_RN64(p) AV_RB64(p)
113# endif
114
115# if defined(AV_WN64) && !defined(AV_WB64)
116# define AV_WB64(p, v) AV_WN64(p, v)
117# elif !defined(AV_WN64) && defined(AV_WB64)
118# define AV_WN64(p, v) AV_WB64(p, v)
119# endif
120
121#else /* HAVE_BIGENDIAN */
122
123# if defined(AV_RN16) && !defined(AV_RL16)
124# define AV_RL16(p) AV_RN16(p)
125# elif !defined(AV_RN16) && defined(AV_RL16)
126# define AV_RN16(p) AV_RL16(p)
127# endif
128
129# if defined(AV_WN16) && !defined(AV_WL16)
130# define AV_WL16(p, v) AV_WN16(p, v)
131# elif !defined(AV_WN16) && defined(AV_WL16)
132# define AV_WN16(p, v) AV_WL16(p, v)
133# endif
134
63826ceb
MR
135# if defined(AV_RN24) && !defined(AV_RL24)
136# define AV_RL24(p) AV_RN24(p)
137# elif !defined(AV_RN24) && defined(AV_RL24)
138# define AV_RN24(p) AV_RL24(p)
139# endif
140
141# if defined(AV_WN24) && !defined(AV_WL24)
142# define AV_WL24(p, v) AV_WN24(p, v)
143# elif !defined(AV_WN24) && defined(AV_WL24)
144# define AV_WN24(p, v) AV_WL24(p, v)
145# endif
146
4a051891
MR
147# if defined(AV_RN32) && !defined(AV_RL32)
148# define AV_RL32(p) AV_RN32(p)
149# elif !defined(AV_RN32) && defined(AV_RL32)
150# define AV_RN32(p) AV_RL32(p)
151# endif
152
63826ceb
MR
153# if defined(AV_WN32) && !defined(AV_WL32)
154# define AV_WL32(p, v) AV_WN32(p, v)
155# elif !defined(AV_WN32) && defined(AV_WL32)
156# define AV_WN32(p, v) AV_WL32(p, v)
157# endif
158
159# if defined(AV_RN64) && !defined(AV_RL64)
160# define AV_RL64(p) AV_RN64(p)
161# elif !defined(AV_RN64) && defined(AV_RL64)
162# define AV_RN64(p) AV_RL64(p)
163# endif
164
165# if defined(AV_WN64) && !defined(AV_WL64)
166# define AV_WL64(p, v) AV_WN64(p, v)
167# elif !defined(AV_WN64) && defined(AV_WL64)
168# define AV_WN64(p, v) AV_WL64(p, v)
169# endif
170
171#endif /* !HAVE_BIGENDIAN */
172
173/*
a6783b89
MR
174 * Define AV_[RW]N helper macros to simplify definitions not provided
175 * by per-arch headers.
176 */
177
e7ea5e3d 178#if HAVE_ATTRIBUTE_PACKED
cf1e119b 179
0c76e635
MR
180union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias;
181union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
182union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
cf1e119b 183
0c76e635
MR
184# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
185# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v))
cf1e119b 186
b7b38fb2
MR
187#elif defined(__DECC)
188
a6783b89 189# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
c2521027 190# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
fbbea48e 191
a6783b89 192#elif HAVE_FAST_UNALIGNED
fbbea48e 193
0c76e635
MR
194# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
195# define AV_WN(s, p, v) (((uint##s##_t*)(p))->u##s = (v))
fbbea48e 196
a6783b89 197#else
fbbea48e 198
a6783b89 199#ifndef AV_RB16
4a051891
MR
200# define AV_RB16(x) \
201 ((((const uint8_t*)(x))[0] << 8) | \
202 ((const uint8_t*)(x))[1])
a6783b89
MR
203#endif
204#ifndef AV_WB16
4a051891
MR
205# define AV_WB16(p, d) do { \
206 ((uint8_t*)(p))[1] = (d); \
207 ((uint8_t*)(p))[0] = (d)>>8; \
208 } while(0)
a6783b89 209#endif
a3550abd 210
a6783b89 211#ifndef AV_RL16
4a051891
MR
212# define AV_RL16(x) \
213 ((((const uint8_t*)(x))[1] << 8) | \
214 ((const uint8_t*)(x))[0])
a6783b89
MR
215#endif
216#ifndef AV_WL16
4a051891
MR
217# define AV_WL16(p, d) do { \
218 ((uint8_t*)(p))[0] = (d); \
219 ((uint8_t*)(p))[1] = (d)>>8; \
220 } while(0)
a6783b89 221#endif
7b829d2a 222
a6783b89 223#ifndef AV_RB32
4a051891
MR
224# define AV_RB32(x) \
225 ((((const uint8_t*)(x))[0] << 24) | \
226 (((const uint8_t*)(x))[1] << 16) | \
227 (((const uint8_t*)(x))[2] << 8) | \
228 ((const uint8_t*)(x))[3])
a6783b89
MR
229#endif
230#ifndef AV_WB32
4a051891
MR
231# define AV_WB32(p, d) do { \
232 ((uint8_t*)(p))[3] = (d); \
233 ((uint8_t*)(p))[2] = (d)>>8; \
234 ((uint8_t*)(p))[1] = (d)>>16; \
235 ((uint8_t*)(p))[0] = (d)>>24; \
236 } while(0)
a6783b89 237#endif
a3550abd 238
a6783b89 239#ifndef AV_RL32
4a051891
MR
240# define AV_RL32(x) \
241 ((((const uint8_t*)(x))[3] << 24) | \
242 (((const uint8_t*)(x))[2] << 16) | \
243 (((const uint8_t*)(x))[1] << 8) | \
244 ((const uint8_t*)(x))[0])
a6783b89
MR
245#endif
246#ifndef AV_WL32
4a051891
MR
247# define AV_WL32(p, d) do { \
248 ((uint8_t*)(p))[0] = (d); \
249 ((uint8_t*)(p))[1] = (d)>>8; \
250 ((uint8_t*)(p))[2] = (d)>>16; \
251 ((uint8_t*)(p))[3] = (d)>>24; \
252 } while(0)
a6783b89 253#endif
9e010b41 254
a6783b89 255#ifndef AV_RB64
4a051891
MR
256# define AV_RB64(x) \
257 (((uint64_t)((const uint8_t*)(x))[0] << 56) | \
258 ((uint64_t)((const uint8_t*)(x))[1] << 48) | \
259 ((uint64_t)((const uint8_t*)(x))[2] << 40) | \
260 ((uint64_t)((const uint8_t*)(x))[3] << 32) | \
261 ((uint64_t)((const uint8_t*)(x))[4] << 24) | \
262 ((uint64_t)((const uint8_t*)(x))[5] << 16) | \
263 ((uint64_t)((const uint8_t*)(x))[6] << 8) | \
264 (uint64_t)((const uint8_t*)(x))[7])
a6783b89
MR
265#endif
266#ifndef AV_WB64
4a051891
MR
267# define AV_WB64(p, d) do { \
268 ((uint8_t*)(p))[7] = (d); \
269 ((uint8_t*)(p))[6] = (d)>>8; \
270 ((uint8_t*)(p))[5] = (d)>>16; \
271 ((uint8_t*)(p))[4] = (d)>>24; \
272 ((uint8_t*)(p))[3] = (d)>>32; \
273 ((uint8_t*)(p))[2] = (d)>>40; \
274 ((uint8_t*)(p))[1] = (d)>>48; \
275 ((uint8_t*)(p))[0] = (d)>>56; \
276 } while(0)
a6783b89 277#endif
9e010b41 278
a6783b89 279#ifndef AV_RL64
4a051891
MR
280# define AV_RL64(x) \
281 (((uint64_t)((const uint8_t*)(x))[7] << 56) | \
282 ((uint64_t)((const uint8_t*)(x))[6] << 48) | \
283 ((uint64_t)((const uint8_t*)(x))[5] << 40) | \
284 ((uint64_t)((const uint8_t*)(x))[4] << 32) | \
285 ((uint64_t)((const uint8_t*)(x))[3] << 24) | \
286 ((uint64_t)((const uint8_t*)(x))[2] << 16) | \
287 ((uint64_t)((const uint8_t*)(x))[1] << 8) | \
288 (uint64_t)((const uint8_t*)(x))[0])
a6783b89
MR
289#endif
290#ifndef AV_WL64
4a051891
MR
291# define AV_WL64(p, d) do { \
292 ((uint8_t*)(p))[0] = (d); \
293 ((uint8_t*)(p))[1] = (d)>>8; \
294 ((uint8_t*)(p))[2] = (d)>>16; \
295 ((uint8_t*)(p))[3] = (d)>>24; \
296 ((uint8_t*)(p))[4] = (d)>>32; \
297 ((uint8_t*)(p))[5] = (d)>>40; \
298 ((uint8_t*)(p))[6] = (d)>>48; \
299 ((uint8_t*)(p))[7] = (d)>>56; \
300 } while(0)
a6783b89
MR
301#endif
302
63613fe6 303#if HAVE_BIGENDIAN
a6783b89
MR
304# define AV_RN(s, p) AV_RB##s(p)
305# define AV_WN(s, p, v) AV_WB##s(p, v)
306#else
307# define AV_RN(s, p) AV_RL##s(p)
308# define AV_WN(s, p, v) AV_WL##s(p, v)
309#endif
310
311#endif /* HAVE_FAST_UNALIGNED */
312
313#ifndef AV_RN16
314# define AV_RN16(p) AV_RN(16, p)
315#endif
316
317#ifndef AV_RN32
318# define AV_RN32(p) AV_RN(32, p)
319#endif
320
321#ifndef AV_RN64
322# define AV_RN64(p) AV_RN(64, p)
323#endif
324
325#ifndef AV_WN16
326# define AV_WN16(p, v) AV_WN(16, p, v)
327#endif
328
329#ifndef AV_WN32
330# define AV_WN32(p, v) AV_WN(32, p, v)
331#endif
332
333#ifndef AV_WN64
334# define AV_WN64(p, v) AV_WN(64, p, v)
335#endif
336
63613fe6 337#if HAVE_BIGENDIAN
63826ceb
MR
338# define AV_RB(s, p) AV_RN##s(p)
339# define AV_WB(s, p, v) AV_WN##s(p, v)
340# define AV_RL(s, p) bswap_##s(AV_RN##s(p))
341# define AV_WL(s, p, v) AV_WN##s(p, bswap_##s(v))
a6783b89 342#else
63826ceb
MR
343# define AV_RB(s, p) bswap_##s(AV_RN##s(p))
344# define AV_WB(s, p, v) AV_WN##s(p, bswap_##s(v))
345# define AV_RL(s, p) AV_RN##s(p)
346# define AV_WL(s, p, v) AV_WN##s(p, v)
a6783b89
MR
347#endif
348
349#define AV_RB8(x) (((const uint8_t*)(x))[0])
350#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0)
351
352#define AV_RL8(x) AV_RB8(x)
353#define AV_WL8(p, d) AV_WB8(p, d)
354
355#ifndef AV_RB16
356# define AV_RB16(p) AV_RB(16, p)
357#endif
358#ifndef AV_WB16
359# define AV_WB16(p, v) AV_WB(16, p, v)
360#endif
361
362#ifndef AV_RL16
363# define AV_RL16(p) AV_RL(16, p)
364#endif
365#ifndef AV_WL16
366# define AV_WL16(p, v) AV_WL(16, p, v)
367#endif
368
369#ifndef AV_RB32
370# define AV_RB32(p) AV_RB(32, p)
371#endif
372#ifndef AV_WB32
373# define AV_WB32(p, v) AV_WB(32, p, v)
374#endif
375
376#ifndef AV_RL32
377# define AV_RL32(p) AV_RL(32, p)
378#endif
379#ifndef AV_WL32
380# define AV_WL32(p, v) AV_WL(32, p, v)
381#endif
382
383#ifndef AV_RB64
384# define AV_RB64(p) AV_RB(64, p)
385#endif
386#ifndef AV_WB64
387# define AV_WB64(p, v) AV_WB(64, p, v)
388#endif
389
390#ifndef AV_RL64
391# define AV_RL64(p) AV_RL(64, p)
392#endif
393#ifndef AV_WL64
394# define AV_WL64(p, v) AV_WL(64, p, v)
395#endif
fbbea48e 396
57c36bdc 397#ifndef AV_RB24
4a051891
MR
398# define AV_RB24(x) \
399 ((((const uint8_t*)(x))[0] << 16) | \
400 (((const uint8_t*)(x))[1] << 8) | \
401 ((const uint8_t*)(x))[2])
57c36bdc
MR
402#endif
403#ifndef AV_WB24
4a051891
MR
404# define AV_WB24(p, d) do { \
405 ((uint8_t*)(p))[2] = (d); \
406 ((uint8_t*)(p))[1] = (d)>>8; \
407 ((uint8_t*)(p))[0] = (d)>>16; \
408 } while(0)
57c36bdc 409#endif
fbbea48e 410
57c36bdc 411#ifndef AV_RL24
4a051891
MR
412# define AV_RL24(x) \
413 ((((const uint8_t*)(x))[2] << 16) | \
414 (((const uint8_t*)(x))[1] << 8) | \
415 ((const uint8_t*)(x))[0])
57c36bdc
MR
416#endif
417#ifndef AV_WL24
4a051891
MR
418# define AV_WL24(p, d) do { \
419 ((uint8_t*)(p))[0] = (d); \
420 ((uint8_t*)(p))[1] = (d)>>8; \
421 ((uint8_t*)(p))[2] = (d)>>16; \
422 } while(0)
57c36bdc 423#endif
9e010b41 424
f4a7434f
MR
425/*
426 * The AV_[RW]NA macros access naturally aligned data
427 * in a type-safe way.
428 */
429
430#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s)
431#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v))
432
433#ifndef AV_RN16A
434# define AV_RN16A(p) AV_RNA(16, p)
435#endif
436
437#ifndef AV_RN32A
438# define AV_RN32A(p) AV_RNA(32, p)
439#endif
440
441#ifndef AV_RN64A
442# define AV_RN64A(p) AV_RNA(64, p)
443#endif
444
445#ifndef AV_WN16A
446# define AV_WN16A(p, v) AV_WNA(16, p, v)
447#endif
448
449#ifndef AV_WN32A
450# define AV_WN32A(p, v) AV_WNA(32, p, v)
451#endif
452
453#ifndef AV_WN64A
454# define AV_WN64A(p, v) AV_WNA(64, p, v)
455#endif
456
f6d03906
AS
457/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
458 * naturally aligned. They may be implemented using MMX,
459 * so emms_c() must be called before using any float code
460 * afterwards.
461 */
462
7a6053ef
MR
463#define AV_COPY(n, d, s) \
464 (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n)
f6d03906 465
6c88973a
MR
466#ifndef AV_COPY32
467# define AV_COPY32(d, s) AV_COPY(32, d, s)
468#endif
469
f6d03906
AS
470#ifndef AV_COPY64
471# define AV_COPY64(d, s) AV_COPY(64, d, s)
472#endif
473
474#ifndef AV_COPY128
475# define AV_COPY128(d, s) \
476 do { \
477 AV_COPY64(d, s); \
478 AV_COPY64((char*)(d)+8, (char*)(s)+8); \
479 } while(0)
480#endif
481
7a6053ef 482#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b))
f6d03906
AS
483
484#ifndef AV_SWAP64
485# define AV_SWAP64(a, b) AV_SWAP(64, a, b)
486#endif
487
7a6053ef
MR
488#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0)
489
490#ifndef AV_ZERO32
491# define AV_ZERO32(d) AV_ZERO(32, d)
492#endif
f6d03906
AS
493
494#ifndef AV_ZERO64
495# define AV_ZERO64(d) AV_ZERO(64, d)
496#endif
497
498#ifndef AV_ZERO128
499# define AV_ZERO128(d) \
500 do { \
501 AV_ZERO64(d); \
502 AV_ZERO64((char*)(d)+8); \
503 } while(0)
504#endif
505
98790382 506#endif /* AVUTIL_INTREADWRITE_H */