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 Workerstatic 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 Workerstatic 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 Workerstatic 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