xref: /aosp_15_r20/external/webp/src/utils/endian_inl_utils.h (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
1*b2055c35SXin Li // Copyright 2014 Google Inc. All Rights Reserved.
2*b2055c35SXin Li //
3*b2055c35SXin Li // Use of this source code is governed by a BSD-style license
4*b2055c35SXin Li // that can be found in the COPYING file in the root of the source
5*b2055c35SXin Li // tree. An additional intellectual property rights grant can be found
6*b2055c35SXin Li // in the file PATENTS. All contributing project authors may
7*b2055c35SXin Li // be found in the AUTHORS file in the root of the source tree.
8*b2055c35SXin Li // -----------------------------------------------------------------------------
9*b2055c35SXin Li //
10*b2055c35SXin Li // Endian related functions.
11*b2055c35SXin Li 
12*b2055c35SXin Li #ifndef WEBP_UTILS_ENDIAN_INL_UTILS_H_
13*b2055c35SXin Li #define WEBP_UTILS_ENDIAN_INL_UTILS_H_
14*b2055c35SXin Li 
15*b2055c35SXin Li #ifdef HAVE_CONFIG_H
16*b2055c35SXin Li #include "src/webp/config.h"
17*b2055c35SXin Li #endif
18*b2055c35SXin Li 
19*b2055c35SXin Li #include "src/dsp/dsp.h"
20*b2055c35SXin Li #include "src/webp/types.h"
21*b2055c35SXin Li 
22*b2055c35SXin Li #if defined(WORDS_BIGENDIAN)
23*b2055c35SXin Li #define HToLE32 BSwap32
24*b2055c35SXin Li #define HToLE16 BSwap16
25*b2055c35SXin Li #else
26*b2055c35SXin Li #define HToLE32(x) (x)
27*b2055c35SXin Li #define HToLE16(x) (x)
28*b2055c35SXin Li #endif
29*b2055c35SXin Li 
30*b2055c35SXin Li #if !defined(HAVE_CONFIG_H)
31*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,8) || __has_builtin(__builtin_bswap16)
32*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP16
33*b2055c35SXin Li #endif
34*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap32)
35*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP32
36*b2055c35SXin Li #endif
37*b2055c35SXin Li #if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap64)
38*b2055c35SXin Li #define HAVE_BUILTIN_BSWAP64
39*b2055c35SXin Li #endif
40*b2055c35SXin Li #endif  // !HAVE_CONFIG_H
41*b2055c35SXin Li 
BSwap16(uint16_t x)42*b2055c35SXin Li static WEBP_INLINE uint16_t BSwap16(uint16_t x) {
43*b2055c35SXin Li #if defined(HAVE_BUILTIN_BSWAP16)
44*b2055c35SXin Li   return __builtin_bswap16(x);
45*b2055c35SXin Li #elif defined(_MSC_VER)
46*b2055c35SXin Li   return _byteswap_ushort(x);
47*b2055c35SXin Li #else
48*b2055c35SXin Li   // gcc will recognize a 'rorw $8, ...' here:
49*b2055c35SXin Li   return (x >> 8) | ((x & 0xff) << 8);
50*b2055c35SXin Li #endif  // HAVE_BUILTIN_BSWAP16
51*b2055c35SXin Li }
52*b2055c35SXin Li 
BSwap32(uint32_t x)53*b2055c35SXin Li static WEBP_INLINE uint32_t BSwap32(uint32_t x) {
54*b2055c35SXin Li #if defined(WEBP_USE_MIPS32_R2)
55*b2055c35SXin Li   uint32_t ret;
56*b2055c35SXin Li   __asm__ volatile (
57*b2055c35SXin Li     "wsbh   %[ret], %[x]          \n\t"
58*b2055c35SXin Li     "rotr   %[ret], %[ret],  16   \n\t"
59*b2055c35SXin Li     : [ret]"=r"(ret)
60*b2055c35SXin Li     : [x]"r"(x)
61*b2055c35SXin Li   );
62*b2055c35SXin Li   return ret;
63*b2055c35SXin Li #elif defined(HAVE_BUILTIN_BSWAP32)
64*b2055c35SXin Li   return __builtin_bswap32(x);
65*b2055c35SXin Li #elif defined(__i386__) || defined(__x86_64__)
66*b2055c35SXin Li   uint32_t swapped_bytes;
67*b2055c35SXin Li   __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
68*b2055c35SXin Li   return swapped_bytes;
69*b2055c35SXin Li #elif defined(_MSC_VER)
70*b2055c35SXin Li   return (uint32_t)_byteswap_ulong(x);
71*b2055c35SXin Li #else
72*b2055c35SXin Li   return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
73*b2055c35SXin Li #endif  // HAVE_BUILTIN_BSWAP32
74*b2055c35SXin Li }
75*b2055c35SXin Li 
BSwap64(uint64_t x)76*b2055c35SXin Li static WEBP_INLINE uint64_t BSwap64(uint64_t x) {
77*b2055c35SXin Li #if defined(HAVE_BUILTIN_BSWAP64)
78*b2055c35SXin Li   return __builtin_bswap64(x);
79*b2055c35SXin Li #elif defined(__x86_64__)
80*b2055c35SXin Li   uint64_t swapped_bytes;
81*b2055c35SXin Li   __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
82*b2055c35SXin Li   return swapped_bytes;
83*b2055c35SXin Li #elif defined(_MSC_VER)
84*b2055c35SXin Li   return (uint64_t)_byteswap_uint64(x);
85*b2055c35SXin Li #else  // generic code for swapping 64-bit values (suggested by bdb@)
86*b2055c35SXin Li   x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
87*b2055c35SXin Li   x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
88*b2055c35SXin Li   x = ((x & 0xff00ff00ff00ff00ull) >>  8) | ((x & 0x00ff00ff00ff00ffull) <<  8);
89*b2055c35SXin Li   return x;
90*b2055c35SXin Li #endif  // HAVE_BUILTIN_BSWAP64
91*b2055c35SXin Li }
92*b2055c35SXin Li 
93*b2055c35SXin Li #endif  // WEBP_UTILS_ENDIAN_INL_UTILS_H_
94