1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2003-2008 Timothy B. Terriberry 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2008 Xiph.Org Foundation */ 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are met: 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions of source code must retain the above copyright 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer. 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions in binary form must reproduce the above copyright 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer in the 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Some common macros for potential platform-specific optimization.*/ 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "opus_types.h" 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h> 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <limits.h> 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h" 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if !defined(_ecintrin_H) 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define _ecintrin_H (1) 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org versions of these functions which can substantially improve performance. 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org We define macros for them to allow easy incorporation of these non-ANSI 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org features.*/ 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org given an appropriate architecture, but the branchless bit-twiddling versions 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are just as fast, and do not require any special target architecture. 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Earlier gcc versions (3.x) compiled both code to the same assembly 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org instructions, because of the way they represented ((_b)>(_a)) internally.*/ 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a)))) 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Count leading zeros. 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org This macro should only be used for implementing ec_ilog(), if it is defined. 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org All other code should use EC_ILOG() instead.*/ 516b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org#if defined(_MSC_VER) && (_MSC_VER >= 1400) 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# include <intrin.h> 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*In _DEBUG mode this is not an intrinsic by default.*/ 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# pragma intrinsic(_BitScanReverse) 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic __inline int ec_bsr(unsigned long _x){ 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned long ret; 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org _BitScanReverse(&ret,_x); 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return (int)ret; 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ0 (1) 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ(_x) (-ec_bsr(_x)) 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#elif defined(ENABLE_TI_DSPLIB) 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# include "dsplib.h" 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ0 (31) 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ(_x) (_lnorm(_x)) 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#elif __GNUC_PREREQ(3,4) 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# if INT_MAX>=2147483647 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT) 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ(_x) (__builtin_clz(_x)) 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# elif LONG_MAX>=2147483647L 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT) 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_CLZ(_x) (__builtin_clzl(_x)) 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# endif 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if defined(EC_CLZ) 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Note that __builtin_clz is not defined when _x==0, according to the gcc 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation (and that of the BSR instruction that implements it on x86). 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org The majority of the time we can never pass it zero. 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org When we need to, it can be special cased.*/ 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x)) 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint ec_ilog(opus_uint32 _v); 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define EC_ILOG(_x) (ec_ilog(_x)) 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 88