xref: /aosp_15_r20/external/libvpx/vpx_util/endian_inl.h (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker // Copyright 2014 Google Inc. All Rights Reserved.
2*fb1b10abSAndroid Build Coastguard Worker //
3*fb1b10abSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license
4*fb1b10abSAndroid Build Coastguard Worker // that can be found in the COPYING file in the root of the source
5*fb1b10abSAndroid Build Coastguard Worker // tree. An additional intellectual property rights grant can be found
6*fb1b10abSAndroid Build Coastguard Worker // in the file PATENTS. All contributing project authors may
7*fb1b10abSAndroid Build Coastguard Worker // be found in the AUTHORS file in the root of the source tree.
8*fb1b10abSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
9*fb1b10abSAndroid Build Coastguard Worker //
10*fb1b10abSAndroid Build Coastguard Worker // Endian related functions.
11*fb1b10abSAndroid Build Coastguard Worker 
12*fb1b10abSAndroid Build Coastguard Worker #ifndef VPX_VPX_UTIL_ENDIAN_INL_H_
13*fb1b10abSAndroid Build Coastguard Worker #define VPX_VPX_UTIL_ENDIAN_INL_H_
14*fb1b10abSAndroid Build Coastguard Worker 
15*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
16*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
17*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_integer.h"
18*fb1b10abSAndroid Build Coastguard Worker 
19*fb1b10abSAndroid Build Coastguard Worker #if defined(__GNUC__)
20*fb1b10abSAndroid Build Coastguard Worker #define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
21*fb1b10abSAndroid Build Coastguard Worker #define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
22*fb1b10abSAndroid Build Coastguard Worker #else
23*fb1b10abSAndroid Build Coastguard Worker #define LOCAL_GCC_VERSION 0
24*fb1b10abSAndroid Build Coastguard Worker #define LOCAL_GCC_PREREQ(maj, min) 0
25*fb1b10abSAndroid Build Coastguard Worker #endif
26*fb1b10abSAndroid Build Coastguard Worker 
27*fb1b10abSAndroid Build Coastguard Worker // handle clang compatibility
28*fb1b10abSAndroid Build Coastguard Worker #ifndef __has_builtin
29*fb1b10abSAndroid Build Coastguard Worker #define __has_builtin(x) 0
30*fb1b10abSAndroid Build Coastguard Worker #endif
31*fb1b10abSAndroid Build Coastguard Worker 
32*fb1b10abSAndroid Build Coastguard Worker // some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
33*fb1b10abSAndroid Build Coastguard Worker #if !defined(WORDS_BIGENDIAN) &&                   \
34*fb1b10abSAndroid Build Coastguard Worker     (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
35*fb1b10abSAndroid Build Coastguard Worker      (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
36*fb1b10abSAndroid Build Coastguard Worker #define WORDS_BIGENDIAN
37*fb1b10abSAndroid Build Coastguard Worker #endif
38*fb1b10abSAndroid Build Coastguard Worker 
39*fb1b10abSAndroid Build Coastguard Worker #if defined(WORDS_BIGENDIAN)
40*fb1b10abSAndroid Build Coastguard Worker #define HToLE32 BSwap32
41*fb1b10abSAndroid Build Coastguard Worker #define HToLE16 BSwap16
42*fb1b10abSAndroid Build Coastguard Worker #define HToBE64(x) (x)
43*fb1b10abSAndroid Build Coastguard Worker #define HToBE32(x) (x)
44*fb1b10abSAndroid Build Coastguard Worker #else
45*fb1b10abSAndroid Build Coastguard Worker #define HToLE32(x) (x)
46*fb1b10abSAndroid Build Coastguard Worker #define HToLE16(x) (x)
47*fb1b10abSAndroid Build Coastguard Worker #define HToBE64(X) BSwap64(X)
48*fb1b10abSAndroid Build Coastguard Worker #define HToBE32(X) BSwap32(X)
49*fb1b10abSAndroid Build Coastguard Worker #endif
50*fb1b10abSAndroid Build Coastguard Worker 
51*fb1b10abSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16)
52*fb1b10abSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP16
53*fb1b10abSAndroid Build Coastguard Worker #endif
54*fb1b10abSAndroid Build Coastguard Worker 
55*fb1b10abSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32)
56*fb1b10abSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP32
57*fb1b10abSAndroid Build Coastguard Worker #endif
58*fb1b10abSAndroid Build Coastguard Worker 
59*fb1b10abSAndroid Build Coastguard Worker #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64)
60*fb1b10abSAndroid Build Coastguard Worker #define HAVE_BUILTIN_BSWAP64
61*fb1b10abSAndroid Build Coastguard Worker #endif
62*fb1b10abSAndroid Build Coastguard Worker 
63*fb1b10abSAndroid Build Coastguard Worker #if HAVE_MIPS32 && defined(__mips__) && !defined(__mips64) && \
64*fb1b10abSAndroid Build Coastguard Worker     defined(__mips_isa_rev) && (__mips_isa_rev >= 2) && (__mips_isa_rev < 6)
65*fb1b10abSAndroid Build Coastguard Worker #define VPX_USE_MIPS32_R2
66*fb1b10abSAndroid Build Coastguard Worker #endif
67*fb1b10abSAndroid Build Coastguard Worker 
BSwap16(uint16_t x)68*fb1b10abSAndroid Build Coastguard Worker static INLINE uint16_t BSwap16(uint16_t x) {
69*fb1b10abSAndroid Build Coastguard Worker #if defined(HAVE_BUILTIN_BSWAP16)
70*fb1b10abSAndroid Build Coastguard Worker   return __builtin_bswap16(x);
71*fb1b10abSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
72*fb1b10abSAndroid Build Coastguard Worker   return _byteswap_ushort(x);
73*fb1b10abSAndroid Build Coastguard Worker #else
74*fb1b10abSAndroid Build Coastguard Worker   // gcc will recognize a 'rorw $8, ...' here:
75*fb1b10abSAndroid Build Coastguard Worker   return (x >> 8) | ((x & 0xff) << 8);
76*fb1b10abSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP16
77*fb1b10abSAndroid Build Coastguard Worker }
78*fb1b10abSAndroid Build Coastguard Worker 
BSwap32(uint32_t x)79*fb1b10abSAndroid Build Coastguard Worker static INLINE uint32_t BSwap32(uint32_t x) {
80*fb1b10abSAndroid Build Coastguard Worker #if defined(VPX_USE_MIPS32_R2)
81*fb1b10abSAndroid Build Coastguard Worker   uint32_t ret;
82*fb1b10abSAndroid Build Coastguard Worker   __asm__ volatile(
83*fb1b10abSAndroid Build Coastguard Worker       "wsbh   %[ret], %[x]          \n\t"
84*fb1b10abSAndroid Build Coastguard Worker       "rotr   %[ret], %[ret],  16   \n\t"
85*fb1b10abSAndroid Build Coastguard Worker       : [ret] "=r"(ret)
86*fb1b10abSAndroid Build Coastguard Worker       : [x] "r"(x));
87*fb1b10abSAndroid Build Coastguard Worker   return ret;
88*fb1b10abSAndroid Build Coastguard Worker #elif defined(HAVE_BUILTIN_BSWAP32)
89*fb1b10abSAndroid Build Coastguard Worker   return __builtin_bswap32(x);
90*fb1b10abSAndroid Build Coastguard Worker #elif defined(__i386__) || defined(__x86_64__)
91*fb1b10abSAndroid Build Coastguard Worker   uint32_t swapped_bytes;
92*fb1b10abSAndroid Build Coastguard Worker   __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
93*fb1b10abSAndroid Build Coastguard Worker   return swapped_bytes;
94*fb1b10abSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
95*fb1b10abSAndroid Build Coastguard Worker   return (uint32_t)_byteswap_ulong(x);
96*fb1b10abSAndroid Build Coastguard Worker #else
97*fb1b10abSAndroid Build Coastguard Worker   return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
98*fb1b10abSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP32
99*fb1b10abSAndroid Build Coastguard Worker }
100*fb1b10abSAndroid Build Coastguard Worker 
BSwap64(uint64_t x)101*fb1b10abSAndroid Build Coastguard Worker static INLINE uint64_t BSwap64(uint64_t x) {
102*fb1b10abSAndroid Build Coastguard Worker #if defined(HAVE_BUILTIN_BSWAP64)
103*fb1b10abSAndroid Build Coastguard Worker   return __builtin_bswap64(x);
104*fb1b10abSAndroid Build Coastguard Worker #elif defined(__x86_64__)
105*fb1b10abSAndroid Build Coastguard Worker   uint64_t swapped_bytes;
106*fb1b10abSAndroid Build Coastguard Worker   __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
107*fb1b10abSAndroid Build Coastguard Worker   return swapped_bytes;
108*fb1b10abSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
109*fb1b10abSAndroid Build Coastguard Worker   return (uint64_t)_byteswap_uint64(x);
110*fb1b10abSAndroid Build Coastguard Worker #else   // generic code for swapping 64-bit values (suggested by bdb@)
111*fb1b10abSAndroid Build Coastguard Worker   x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
112*fb1b10abSAndroid Build Coastguard Worker   x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
113*fb1b10abSAndroid Build Coastguard Worker   x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8);
114*fb1b10abSAndroid Build Coastguard Worker   return x;
115*fb1b10abSAndroid Build Coastguard Worker #endif  // HAVE_BUILTIN_BSWAP64
116*fb1b10abSAndroid Build Coastguard Worker }
117*fb1b10abSAndroid Build Coastguard Worker 
118*fb1b10abSAndroid Build Coastguard Worker #endif  // VPX_VPX_UTIL_ENDIAN_INL_H_
119