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