build: Drop support for legacy TI ARM compiler
[libav.git] / libavutil / intreadwrite.h
CommitLineData
f5a90186 1/*
2912e87a 2 * This file is part of Libav.
f5a90186 3 *
2912e87a 4 * Libav is free software; you can redistribute it and/or
f5a90186
DB
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 *
2912e87a 9 * Libav is distributed in the hope that it will be useful,
f5a90186
DB
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
2912e87a 15 * License along with Libav; if not, write to the Free Software
f5a90186
DB
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>
86816692 23#include "libavutil/avconfig.h"
7918375f 24#include "attributes.h"
c08be350 25#include "bswap.h"
d10458c9
MR
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
86816692
MR
55#ifdef HAVE_AV_CONFIG_H
56
57#include "config.h"
58
3c55ce03
MR
59#if ARCH_ARM
60# include "arm/intreadwrite.h"
d691da95
MR
61#elif ARCH_AVR32
62# include "avr32/intreadwrite.h"
530456bf
MR
63#elif ARCH_MIPS
64# include "mips/intreadwrite.h"
9f5ff83f
MR
65#elif ARCH_PPC
66# include "ppc/intreadwrite.h"
95c0d02d
MR
67#elif ARCH_TOMI
68# include "tomi/intreadwrite.h"
f6d03906
AS
69#elif ARCH_X86
70# include "x86/intreadwrite.h"
3c55ce03 71#endif
a6783b89 72
86816692
MR
73#endif /* HAVE_AV_CONFIG_H */
74
a6783b89 75/*
63826ceb
MR
76 * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers.
77 */
78
86816692 79#if AV_HAVE_BIGENDIAN
63826ceb
MR
80
81# if defined(AV_RN16) && !defined(AV_RB16)
82# define AV_RB16(p) AV_RN16(p)
83# elif !defined(AV_RN16) && defined(AV_RB16)
84# define AV_RN16(p) AV_RB16(p)
85# endif
86
87# if defined(AV_WN16) && !defined(AV_WB16)
88# define AV_WB16(p, v) AV_WN16(p, v)
89# elif !defined(AV_WN16) && defined(AV_WB16)
90# define AV_WN16(p, v) AV_WB16(p, v)
91# endif
92
63826ceb
MR
93# if defined(AV_RN24) && !defined(AV_RB24)
94# define AV_RB24(p) AV_RN24(p)
95# elif !defined(AV_RN24) && defined(AV_RB24)
96# define AV_RN24(p) AV_RB24(p)
97# endif
98
99# if defined(AV_WN24) && !defined(AV_WB24)
100# define AV_WB24(p, v) AV_WN24(p, v)
101# elif !defined(AV_WN24) && defined(AV_WB24)
102# define AV_WN24(p, v) AV_WB24(p, v)
103# endif
104
4a051891
MR
105# if defined(AV_RN32) && !defined(AV_RB32)
106# define AV_RB32(p) AV_RN32(p)
107# elif !defined(AV_RN32) && defined(AV_RB32)
108# define AV_RN32(p) AV_RB32(p)
109# endif
110
63826ceb
MR
111# if defined(AV_WN32) && !defined(AV_WB32)
112# define AV_WB32(p, v) AV_WN32(p, v)
113# elif !defined(AV_WN32) && defined(AV_WB32)
114# define AV_WN32(p, v) AV_WB32(p, v)
115# endif
116
117# if defined(AV_RN64) && !defined(AV_RB64)
118# define AV_RB64(p) AV_RN64(p)
119# elif !defined(AV_RN64) && defined(AV_RB64)
120# define AV_RN64(p) AV_RB64(p)
121# endif
122
123# if defined(AV_WN64) && !defined(AV_WB64)
124# define AV_WB64(p, v) AV_WN64(p, v)
125# elif !defined(AV_WN64) && defined(AV_WB64)
126# define AV_WN64(p, v) AV_WB64(p, v)
127# endif
128
86816692 129#else /* AV_HAVE_BIGENDIAN */
63826ceb
MR
130
131# if defined(AV_RN16) && !defined(AV_RL16)
132# define AV_RL16(p) AV_RN16(p)
133# elif !defined(AV_RN16) && defined(AV_RL16)
134# define AV_RN16(p) AV_RL16(p)
135# endif
136
137# if defined(AV_WN16) && !defined(AV_WL16)
138# define AV_WL16(p, v) AV_WN16(p, v)
139# elif !defined(AV_WN16) && defined(AV_WL16)
140# define AV_WN16(p, v) AV_WL16(p, v)
141# endif
142
63826ceb
MR
143# if defined(AV_RN24) && !defined(AV_RL24)
144# define AV_RL24(p) AV_RN24(p)
145# elif !defined(AV_RN24) && defined(AV_RL24)
146# define AV_RN24(p) AV_RL24(p)
147# endif
148
149# if defined(AV_WN24) && !defined(AV_WL24)
150# define AV_WL24(p, v) AV_WN24(p, v)
151# elif !defined(AV_WN24) && defined(AV_WL24)
152# define AV_WN24(p, v) AV_WL24(p, v)
153# endif
154
4a051891
MR
155# if defined(AV_RN32) && !defined(AV_RL32)
156# define AV_RL32(p) AV_RN32(p)
157# elif !defined(AV_RN32) && defined(AV_RL32)
158# define AV_RN32(p) AV_RL32(p)
159# endif
160
63826ceb
MR
161# if defined(AV_WN32) && !defined(AV_WL32)
162# define AV_WL32(p, v) AV_WN32(p, v)
163# elif !defined(AV_WN32) && defined(AV_WL32)
164# define AV_WN32(p, v) AV_WL32(p, v)
165# endif
166
167# if defined(AV_RN64) && !defined(AV_RL64)
168# define AV_RL64(p) AV_RN64(p)
169# elif !defined(AV_RN64) && defined(AV_RL64)
170# define AV_RN64(p) AV_RL64(p)
171# endif
172
173# if defined(AV_WN64) && !defined(AV_WL64)
174# define AV_WL64(p, v) AV_WN64(p, v)
175# elif !defined(AV_WN64) && defined(AV_WL64)
176# define AV_WN64(p, v) AV_WL64(p, v)
177# endif
178
86816692 179#endif /* !AV_HAVE_BIGENDIAN */
63826ceb
MR
180
181/*
a6783b89
MR
182 * Define AV_[RW]N helper macros to simplify definitions not provided
183 * by per-arch headers.
184 */
185
0af8a721 186#if defined(__GNUC__)
cf1e119b 187
0c76e635
MR
188union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias;
189union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
190union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
cf1e119b 191
0c76e635
MR
192# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
193# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v))
cf1e119b 194
f79d8474
MS
195#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64)) && AV_HAVE_FAST_UNALIGNED
196
197# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
198# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
199
86816692 200#elif AV_HAVE_FAST_UNALIGNED
fbbea48e 201
0c76e635 202# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
3d7b94ba 203# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v))
fbbea48e 204
a6783b89 205#else
fbbea48e 206
a6783b89 207#ifndef AV_RB16
4a051891
MR
208# define AV_RB16(x) \
209 ((((const uint8_t*)(x))[0] << 8) | \
210 ((const uint8_t*)(x))[1])
a6783b89
MR
211#endif
212#ifndef AV_WB16
230b1c07
MS
213# define AV_WB16(p, val) do { \
214 uint16_t d = val; \
4a051891
MR
215 ((uint8_t*)(p))[1] = (d); \
216 ((uint8_t*)(p))[0] = (d)>>8; \
217 } while(0)
a6783b89 218#endif
a3550abd 219
a6783b89 220#ifndef AV_RL16
4a051891
MR
221# define AV_RL16(x) \
222 ((((const uint8_t*)(x))[1] << 8) | \
223 ((const uint8_t*)(x))[0])
a6783b89
MR
224#endif
225#ifndef AV_WL16
230b1c07
MS
226# define AV_WL16(p, val) do { \
227 uint16_t d = val; \
4a051891
MR
228 ((uint8_t*)(p))[0] = (d); \
229 ((uint8_t*)(p))[1] = (d)>>8; \
230 } while(0)
a6783b89 231#endif
7b829d2a 232
a6783b89 233#ifndef AV_RB32
c98b928f
UU
234# define AV_RB32(x) \
235 (((uint32_t)((const uint8_t*)(x))[0] << 24) | \
236 (((const uint8_t*)(x))[1] << 16) | \
237 (((const uint8_t*)(x))[2] << 8) | \
238 ((const uint8_t*)(x))[3])
a6783b89
MR
239#endif
240#ifndef AV_WB32
230b1c07
MS
241# define AV_WB32(p, val) do { \
242 uint32_t d = val; \
4a051891
MR
243 ((uint8_t*)(p))[3] = (d); \
244 ((uint8_t*)(p))[2] = (d)>>8; \
245 ((uint8_t*)(p))[1] = (d)>>16; \
246 ((uint8_t*)(p))[0] = (d)>>24; \
247 } while(0)
a6783b89 248#endif
a3550abd 249
a6783b89 250#ifndef AV_RL32
c98b928f
UU
251# define AV_RL32(x) \
252 (((uint32_t)((const uint8_t*)(x))[3] << 24) | \
253 (((const uint8_t*)(x))[2] << 16) | \
254 (((const uint8_t*)(x))[1] << 8) | \
255 ((const uint8_t*)(x))[0])
a6783b89
MR
256#endif
257#ifndef AV_WL32
230b1c07
MS
258# define AV_WL32(p, val) do { \
259 uint32_t d = val; \
4a051891
MR
260 ((uint8_t*)(p))[0] = (d); \
261 ((uint8_t*)(p))[1] = (d)>>8; \
262 ((uint8_t*)(p))[2] = (d)>>16; \
263 ((uint8_t*)(p))[3] = (d)>>24; \
264 } while(0)
a6783b89 265#endif
9e010b41 266
a6783b89 267#ifndef AV_RB64
4a051891
MR
268# define AV_RB64(x) \
269 (((uint64_t)((const uint8_t*)(x))[0] << 56) | \
270 ((uint64_t)((const uint8_t*)(x))[1] << 48) | \
271 ((uint64_t)((const uint8_t*)(x))[2] << 40) | \
272 ((uint64_t)((const uint8_t*)(x))[3] << 32) | \
273 ((uint64_t)((const uint8_t*)(x))[4] << 24) | \
274 ((uint64_t)((const uint8_t*)(x))[5] << 16) | \
275 ((uint64_t)((const uint8_t*)(x))[6] << 8) | \
276 (uint64_t)((const uint8_t*)(x))[7])
a6783b89
MR
277#endif
278#ifndef AV_WB64
230b1c07
MS
279# define AV_WB64(p, val) do { \
280 uint64_t d = val; \
4a051891
MR
281 ((uint8_t*)(p))[7] = (d); \
282 ((uint8_t*)(p))[6] = (d)>>8; \
283 ((uint8_t*)(p))[5] = (d)>>16; \
284 ((uint8_t*)(p))[4] = (d)>>24; \
285 ((uint8_t*)(p))[3] = (d)>>32; \
286 ((uint8_t*)(p))[2] = (d)>>40; \
287 ((uint8_t*)(p))[1] = (d)>>48; \
288 ((uint8_t*)(p))[0] = (d)>>56; \
289 } while(0)
a6783b89 290#endif
9e010b41 291
a6783b89 292#ifndef AV_RL64
4a051891
MR
293# define AV_RL64(x) \
294 (((uint64_t)((const uint8_t*)(x))[7] << 56) | \
295 ((uint64_t)((const uint8_t*)(x))[6] << 48) | \
296 ((uint64_t)((const uint8_t*)(x))[5] << 40) | \
297 ((uint64_t)((const uint8_t*)(x))[4] << 32) | \
298 ((uint64_t)((const uint8_t*)(x))[3] << 24) | \
299 ((uint64_t)((const uint8_t*)(x))[2] << 16) | \
300 ((uint64_t)((const uint8_t*)(x))[1] << 8) | \
301 (uint64_t)((const uint8_t*)(x))[0])
a6783b89
MR
302#endif
303#ifndef AV_WL64
230b1c07
MS
304# define AV_WL64(p, val) do { \
305 uint64_t d = val; \
4a051891
MR
306 ((uint8_t*)(p))[0] = (d); \
307 ((uint8_t*)(p))[1] = (d)>>8; \
308 ((uint8_t*)(p))[2] = (d)>>16; \
309 ((uint8_t*)(p))[3] = (d)>>24; \
310 ((uint8_t*)(p))[4] = (d)>>32; \
311 ((uint8_t*)(p))[5] = (d)>>40; \
312 ((uint8_t*)(p))[6] = (d)>>48; \
313 ((uint8_t*)(p))[7] = (d)>>56; \
314 } while(0)
a6783b89
MR
315#endif
316
86816692 317#if AV_HAVE_BIGENDIAN
a6783b89
MR
318# define AV_RN(s, p) AV_RB##s(p)
319# define AV_WN(s, p, v) AV_WB##s(p, v)
320#else
321# define AV_RN(s, p) AV_RL##s(p)
322# define AV_WN(s, p, v) AV_WL##s(p, v)
323#endif
324
325#endif /* HAVE_FAST_UNALIGNED */
326
327#ifndef AV_RN16
328# define AV_RN16(p) AV_RN(16, p)
329#endif
330
331#ifndef AV_RN32
332# define AV_RN32(p) AV_RN(32, p)
333#endif
334
335#ifndef AV_RN64
336# define AV_RN64(p) AV_RN(64, p)
337#endif
338
339#ifndef AV_WN16
340# define AV_WN16(p, v) AV_WN(16, p, v)
341#endif
342
343#ifndef AV_WN32
344# define AV_WN32(p, v) AV_WN(32, p, v)
345#endif
346
347#ifndef AV_WN64
348# define AV_WN64(p, v) AV_WN(64, p, v)
349#endif
350
86816692 351#if AV_HAVE_BIGENDIAN
63826ceb
MR
352# define AV_RB(s, p) AV_RN##s(p)
353# define AV_WB(s, p, v) AV_WN##s(p, v)
8fc0162a
MR
354# define AV_RL(s, p) av_bswap##s(AV_RN##s(p))
355# define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v))
a6783b89 356#else
8fc0162a
MR
357# define AV_RB(s, p) av_bswap##s(AV_RN##s(p))
358# define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v))
63826ceb
MR
359# define AV_RL(s, p) AV_RN##s(p)
360# define AV_WL(s, p, v) AV_WN##s(p, v)
a6783b89
MR
361#endif
362
363#define AV_RB8(x) (((const uint8_t*)(x))[0])
364#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0)
365
366#define AV_RL8(x) AV_RB8(x)
367#define AV_WL8(p, d) AV_WB8(p, d)
368
369#ifndef AV_RB16
370# define AV_RB16(p) AV_RB(16, p)
371#endif
372#ifndef AV_WB16
373# define AV_WB16(p, v) AV_WB(16, p, v)
374#endif
375
376#ifndef AV_RL16
377# define AV_RL16(p) AV_RL(16, p)
378#endif
379#ifndef AV_WL16
380# define AV_WL16(p, v) AV_WL(16, p, v)
381#endif
382
383#ifndef AV_RB32
384# define AV_RB32(p) AV_RB(32, p)
385#endif
386#ifndef AV_WB32
387# define AV_WB32(p, v) AV_WB(32, p, v)
388#endif
389
390#ifndef AV_RL32
391# define AV_RL32(p) AV_RL(32, p)
392#endif
393#ifndef AV_WL32
394# define AV_WL32(p, v) AV_WL(32, p, v)
395#endif
396
397#ifndef AV_RB64
398# define AV_RB64(p) AV_RB(64, p)
399#endif
400#ifndef AV_WB64
401# define AV_WB64(p, v) AV_WB(64, p, v)
402#endif
403
404#ifndef AV_RL64
405# define AV_RL64(p) AV_RL(64, p)
406#endif
407#ifndef AV_WL64
408# define AV_WL64(p, v) AV_WL(64, p, v)
409#endif
fbbea48e 410
57c36bdc 411#ifndef AV_RB24
4a051891
MR
412# define AV_RB24(x) \
413 ((((const uint8_t*)(x))[0] << 16) | \
414 (((const uint8_t*)(x))[1] << 8) | \
415 ((const uint8_t*)(x))[2])
57c36bdc
MR
416#endif
417#ifndef AV_WB24
4a051891
MR
418# define AV_WB24(p, d) do { \
419 ((uint8_t*)(p))[2] = (d); \
420 ((uint8_t*)(p))[1] = (d)>>8; \
421 ((uint8_t*)(p))[0] = (d)>>16; \
422 } while(0)
57c36bdc 423#endif
fbbea48e 424
57c36bdc 425#ifndef AV_RL24
4a051891
MR
426# define AV_RL24(x) \
427 ((((const uint8_t*)(x))[2] << 16) | \
428 (((const uint8_t*)(x))[1] << 8) | \
429 ((const uint8_t*)(x))[0])
57c36bdc
MR
430#endif
431#ifndef AV_WL24
4a051891
MR
432# define AV_WL24(p, d) do { \
433 ((uint8_t*)(p))[0] = (d); \
434 ((uint8_t*)(p))[1] = (d)>>8; \
435 ((uint8_t*)(p))[2] = (d)>>16; \
436 } while(0)
57c36bdc 437#endif
9e010b41 438
f4a7434f
MR
439/*
440 * The AV_[RW]NA macros access naturally aligned data
441 * in a type-safe way.
442 */
443
444#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s)
445#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v))
446
447#ifndef AV_RN16A
448# define AV_RN16A(p) AV_RNA(16, p)
449#endif
450
451#ifndef AV_RN32A
452# define AV_RN32A(p) AV_RNA(32, p)
453#endif
454
455#ifndef AV_RN64A
456# define AV_RN64A(p) AV_RNA(64, p)
457#endif
458
459#ifndef AV_WN16A
460# define AV_WN16A(p, v) AV_WNA(16, p, v)
461#endif
462
463#ifndef AV_WN32A
464# define AV_WN32A(p, v) AV_WNA(32, p, v)
465#endif
466
467#ifndef AV_WN64A
468# define AV_WN64A(p, v) AV_WNA(64, p, v)
469#endif
470
af6dd6de
DB
471/*
472 * The AV_COPYxxU macros are suitable for copying data to/from unaligned
473 * memory locations.
474 */
475
fc94a1ac 476#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s));
af6dd6de
DB
477
478#ifndef AV_COPY16U
479# define AV_COPY16U(d, s) AV_COPYU(16, d, s)
480#endif
481
482#ifndef AV_COPY32U
483# define AV_COPY32U(d, s) AV_COPYU(32, d, s)
484#endif
485
486#ifndef AV_COPY64U
487# define AV_COPY64U(d, s) AV_COPYU(64, d, s)
488#endif
489
490#ifndef AV_COPY128U
491# define AV_COPY128U(d, s) \
492 do { \
493 AV_COPY64U(d, s); \
494 AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8); \
495 } while(0)
496#endif
497
f6d03906
AS
498/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
499 * naturally aligned. They may be implemented using MMX,
500 * so emms_c() must be called before using any float code
501 * afterwards.
502 */
503
7a6053ef
MR
504#define AV_COPY(n, d, s) \
505 (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n)
f6d03906 506
8ef4e65e
MN
507#ifndef AV_COPY16
508# define AV_COPY16(d, s) AV_COPY(16, d, s)
509#endif
510
6c88973a
MR
511#ifndef AV_COPY32
512# define AV_COPY32(d, s) AV_COPY(32, d, s)
513#endif
514
f6d03906
AS
515#ifndef AV_COPY64
516# define AV_COPY64(d, s) AV_COPY(64, d, s)
517#endif
518
519#ifndef AV_COPY128
520# define AV_COPY128(d, s) \
521 do { \
522 AV_COPY64(d, s); \
523 AV_COPY64((char*)(d)+8, (char*)(s)+8); \
524 } while(0)
525#endif
526
7a6053ef 527#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b))
f6d03906
AS
528
529#ifndef AV_SWAP64
530# define AV_SWAP64(a, b) AV_SWAP(64, a, b)
531#endif
532
7a6053ef
MR
533#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0)
534
8ef4e65e
MN
535#ifndef AV_ZERO16
536# define AV_ZERO16(d) AV_ZERO(16, d)
537#endif
538
7a6053ef
MR
539#ifndef AV_ZERO32
540# define AV_ZERO32(d) AV_ZERO(32, d)
541#endif
f6d03906
AS
542
543#ifndef AV_ZERO64
544# define AV_ZERO64(d) AV_ZERO(64, d)
545#endif
546
547#ifndef AV_ZERO128
548# define AV_ZERO128(d) \
549 do { \
550 AV_ZERO64(d); \
551 AV_ZERO64((char*)(d)+8); \
552 } while(0)
553#endif
554
98790382 555#endif /* AVUTIL_INTREADWRITE_H */