xref: /aosp_15_r20/external/libaom/aom_util/endian_inl.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker //
12*77c1e3ccSAndroid Build Coastguard Worker // Endian related functions.
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AOM_UTIL_ENDIAN_INL_H_
15*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AOM_UTIL_ENDIAN_INL_H_
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include <stdlib.h>
18*77c1e3ccSAndroid Build Coastguard Worker 
19*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
22*77c1e3ccSAndroid Build Coastguard Worker 
23*77c1e3ccSAndroid Build Coastguard Worker #if defined(__GNUC__)
24*77c1e3ccSAndroid Build Coastguard Worker #define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
25*77c1e3ccSAndroid Build Coastguard Worker #define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
26*77c1e3ccSAndroid Build Coastguard Worker #else
27*77c1e3ccSAndroid Build Coastguard Worker #define LOCAL_GCC_VERSION 0
28*77c1e3ccSAndroid Build Coastguard Worker #define LOCAL_GCC_PREREQ(maj, min) 0
29*77c1e3ccSAndroid Build Coastguard Worker #endif
30*77c1e3ccSAndroid Build Coastguard Worker 
31*77c1e3ccSAndroid Build Coastguard Worker // handle clang compatibility
32*77c1e3ccSAndroid Build Coastguard Worker #ifndef __has_builtin
33*77c1e3ccSAndroid Build Coastguard Worker #define __has_builtin(x) 0
34*77c1e3ccSAndroid Build Coastguard Worker #endif
35*77c1e3ccSAndroid Build Coastguard Worker 
36*77c1e3ccSAndroid Build Coastguard Worker // some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
37*77c1e3ccSAndroid Build Coastguard Worker #if !defined(WORDS_BIGENDIAN) &&                   \
38*77c1e3ccSAndroid Build Coastguard Worker     (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
39*77c1e3ccSAndroid Build Coastguard Worker      (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
40*77c1e3ccSAndroid Build Coastguard Worker #define WORDS_BIGENDIAN
41*77c1e3ccSAndroid Build Coastguard Worker #endif
42*77c1e3ccSAndroid Build Coastguard Worker 
43*77c1e3ccSAndroid Build Coastguard Worker #if defined(WORDS_BIGENDIAN)
44*77c1e3ccSAndroid Build Coastguard Worker #define HToLE32 BSwap32
45*77c1e3ccSAndroid Build Coastguard Worker #define HToLE16 BSwap16
46*77c1e3ccSAndroid Build Coastguard Worker #define HToBE64(x) (x)
47*77c1e3ccSAndroid Build Coastguard Worker #define HToBE32(x) (x)
48*77c1e3ccSAndroid Build Coastguard Worker #else
49*77c1e3ccSAndroid Build Coastguard Worker #define HToLE32(x) (x)
50*77c1e3ccSAndroid Build Coastguard Worker #define HToLE16(x) (x)
51*77c1e3ccSAndroid Build Coastguard Worker #define HToBE64(X) BSwap64(X)
52*77c1e3ccSAndroid Build Coastguard Worker #define HToBE32(X) BSwap32(X)
53*77c1e3ccSAndroid Build Coastguard Worker #endif
54*77c1e3ccSAndroid Build Coastguard Worker 
55*77c1e3ccSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16)
56*77c1e3ccSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP16
57*77c1e3ccSAndroid Build Coastguard Worker #endif
58*77c1e3ccSAndroid Build Coastguard Worker 
59*77c1e3ccSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32)
60*77c1e3ccSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP32
61*77c1e3ccSAndroid Build Coastguard Worker #endif
62*77c1e3ccSAndroid Build Coastguard Worker 
63*77c1e3ccSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64)
64*77c1e3ccSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP64
65*77c1e3ccSAndroid Build Coastguard Worker #endif
66*77c1e3ccSAndroid Build Coastguard Worker 
BSwap16(uint16_t x)67*77c1e3ccSAndroid Build Coastguard Worker static inline uint16_t BSwap16(uint16_t x) {
68*77c1e3ccSAndroid Build Coastguard Worker #if defined(HAVE_BUILTIN_BSWAP16)
69*77c1e3ccSAndroid Build Coastguard Worker   return __builtin_bswap16(x);
70*77c1e3ccSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
71*77c1e3ccSAndroid Build Coastguard Worker   return _byteswap_ushort(x);
72*77c1e3ccSAndroid Build Coastguard Worker #else
73*77c1e3ccSAndroid Build Coastguard Worker   // gcc will recognize a 'rorw $8, ...' here:
74*77c1e3ccSAndroid Build Coastguard Worker   return (x >> 8) | ((x & 0xff) << 8);
75*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP16
76*77c1e3ccSAndroid Build Coastguard Worker }
77*77c1e3ccSAndroid Build Coastguard Worker 
BSwap32(uint32_t x)78*77c1e3ccSAndroid Build Coastguard Worker static inline uint32_t BSwap32(uint32_t x) {
79*77c1e3ccSAndroid Build Coastguard Worker #if defined(HAVE_BUILTIN_BSWAP32)
80*77c1e3ccSAndroid Build Coastguard Worker   return __builtin_bswap32(x);
81*77c1e3ccSAndroid Build Coastguard Worker #elif defined(__i386__) || defined(__x86_64__)
82*77c1e3ccSAndroid Build Coastguard Worker   uint32_t swapped_bytes;
83*77c1e3ccSAndroid Build Coastguard Worker   __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
84*77c1e3ccSAndroid Build Coastguard Worker   return swapped_bytes;
85*77c1e3ccSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
86*77c1e3ccSAndroid Build Coastguard Worker   return (uint32_t)_byteswap_ulong(x);
87*77c1e3ccSAndroid Build Coastguard Worker #else
88*77c1e3ccSAndroid Build Coastguard Worker   return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
89*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP32
90*77c1e3ccSAndroid Build Coastguard Worker }
91*77c1e3ccSAndroid Build Coastguard Worker 
BSwap64(uint64_t x)92*77c1e3ccSAndroid Build Coastguard Worker static inline uint64_t BSwap64(uint64_t x) {
93*77c1e3ccSAndroid Build Coastguard Worker #if defined(HAVE_BUILTIN_BSWAP64)
94*77c1e3ccSAndroid Build Coastguard Worker   return __builtin_bswap64(x);
95*77c1e3ccSAndroid Build Coastguard Worker #elif defined(__x86_64__)
96*77c1e3ccSAndroid Build Coastguard Worker   uint64_t swapped_bytes;
97*77c1e3ccSAndroid Build Coastguard Worker   __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
98*77c1e3ccSAndroid Build Coastguard Worker   return swapped_bytes;
99*77c1e3ccSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
100*77c1e3ccSAndroid Build Coastguard Worker   return (uint64_t)_byteswap_uint64(x);
101*77c1e3ccSAndroid Build Coastguard Worker #else   // generic code for swapping 64-bit values (suggested by bdb@)
102*77c1e3ccSAndroid Build Coastguard Worker   x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
103*77c1e3ccSAndroid Build Coastguard Worker   x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
104*77c1e3ccSAndroid Build Coastguard Worker   x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8);
105*77c1e3ccSAndroid Build Coastguard Worker   return x;
106*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP64
107*77c1e3ccSAndroid Build Coastguard Worker }
108*77c1e3ccSAndroid Build Coastguard Worker 
109*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AOM_UTIL_ENDIAN_INL_H_
110