1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
266c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
566c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
1366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
1766c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2566c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Math utilities and approximations for common math functions.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reduced precision is usually acceptable in shaders...
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "fast" is used in the names of functions which are low-precision,
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or at least lower-precision than the normal C lib functions.
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef U_MATH_H
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define U_MATH_H
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <math.h>
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdarg.h>
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_OS_UNIX
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <strings.h> /* for ffs */
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef M_SQRT2
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define M_SQRT2 1.41421356237309504880
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6466c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org#if defined(_MSC_VER)
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if _MSC_VER < 1400 && !defined(__cplusplus)
6766c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org
6866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float cosf( float f )
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) cos( (double) f );
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
7366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float sinf( float f )
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) sin( (double) f );
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
7866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float ceilf( float f )
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) ceil( (double) f );
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
8366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float floorf( float f )
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) floor( (double) f );
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
8866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float powf( float f, float g )
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) pow( (double) f, (double) g );
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
9366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float sqrtf( float f )
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) sqrt( (double) f );
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
9866c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float fabsf( float f )
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) fabs( (double) f );
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
10366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.orgstatic INLINE float logf( float f )
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) log( (double) f );
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Work-around an extra semi-colon in VS 2005 logf definition */
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef logf
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef logf
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define logf(x) ((float)log((double)(x)))
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* logf */
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#if _MSC_VER < 1800
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define isfinite(x) _finite((double)(x))
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define isnan(x) _isnan((double)(x))
118e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#endif /* _MSC_VER < 1800 */
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#if _MSC_VER < 1800
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE double log2( double x )
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const double invln2 = 1.442695041;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return log( x ) * invln2;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE double
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orground(double x)
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5);
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroundf(float x)
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
139e510ef026f853574a76ff832d27b8292c03c707bhans@chromium.org#endif
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* _MSC_VER */
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SIZE_LOG2 9
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2)
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_OFFSET (POW2_TABLE_SIZE/2)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POW2_TABLE_SCALE ((float)(POW2_TABLE_SIZE/2))
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern float pow2_table[POW2_TABLE_SIZE];
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize math module.  This should be called before using any
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other functions in this module.
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern void
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_init_math(void);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion fi {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float f;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int32_t i;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t ui;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion di {
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double d;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int64_t i;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint64_t ui;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast version of 2^x
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Identity: exp2(a + b) = exp2(a) * exp2(b)
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Let ipart = int(x)
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Let fpart = x - ipart;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * So, exp2(x) = exp2(ipart) * exp2(fpart)
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute exp2(ipart) with i << ipart
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute exp2(fpart) with lookup table.
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_exp2(float x)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int32_t ipart;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float fpart, mpart;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi epart;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(x > 129.00000f)
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 3.402823466e+38f;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (x < -126.99999f)
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0f;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ipart = (int32_t) x;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fpart = x - (float) ipart;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* same as
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   epart.f = (float) (1 << ipart)
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * but faster and without integer overflow for ipart > 31
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   epart.i = (ipart + 127 ) << 23;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)];
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return epart.f * mpart;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to exp(x).
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_exp(float x)
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const float k = 1.44269f; /* = log2(e) */
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return util_fast_exp2(k * x);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SIZE_LOG2 16
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2)
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1)
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern float log2_table[LOG2_TABLE_SIZE];
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to log2(x).
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_log2(float x)
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi num;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float epart, mpart;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num.f = x;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   epart = (float)(((num.i & 0x7f800000) >> 23) - 127);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* mpart = log2_table[mantissa*LOG2_TABLE_SCALE + 0.5] */
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)];
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return epart + mpart;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fast approximation to x^y.
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_fast_pow(float x, float y)
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return util_fast_exp2(util_fast_log2(x) * y);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Note that this counts zero as a power of two.
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_power_of_two( unsigned v )
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (v & (v-1)) == 0;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Floor(x), returned as int.
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_ifloor(float f)
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ai, bi;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double af, bf;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi u;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   af = (3 << 22) + 0.5 + (double) f;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bf = (3 << 22) + 0.5 - (double) f;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u.f = (float) af;  ai = u.i;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u.f = (float) bf;  bi = u.i;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (ai - bi) >> 1;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Round float to nearest int.
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_iround(float f)
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
28366c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int r;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return r;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int r;
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _asm {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fld f
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fistp r
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return r;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (f >= 0.0f)
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int) (f + 0.5f);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int) (f - 0.5f);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Approximate floating point comparison
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_approx(float a, float b, float tol)
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fabs(b - a) <= tol;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_is_X_inf_or_nan = test if x is NaN or +/- Inf
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_is_X_nan        = test if x is NaN
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * util_X_inf_sign      = return +1 for +Inf, -1 for -Inf, or 0 for not Inf
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NaN can be checked with x != x, however this fails with the fast math flag
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **/
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Single-float
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_inf_or_nan(float x)
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi tmp;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.f = x;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (tmp.ui & 0x7f800000) == 0x7f800000;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_nan(float x)
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi tmp;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.f = x;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (tmp.ui & 0x7fffffff) > 0x7f800000;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_inf_sign(float x)
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi tmp;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.f = x;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((tmp.ui & 0x7fffffff) != 0x7f800000) {
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x < 0) ? -1 : 1;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Double-float
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_double_inf_or_nan(double x)
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union di tmp;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.d = x;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (tmp.ui & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_double_nan(double x)
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union di tmp;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.d = x;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (tmp.ui & 0x7fffffffffffffffULL) > 0x7ff0000000000000ULL;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_double_inf_sign(double x)
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union di tmp;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.d = x;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((tmp.ui & 0x7fffffffffffffffULL) != 0x7ff0000000000000ULL) {
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x < 0) ? -1 : 1;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Half-float
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_half_inf_or_nan(int16_t x)
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x & 0x7c00) == 0x7c00;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_is_half_nan(int16_t x)
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x & 0x7fff) > 0x7c00;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_half_inf_sign(int16_t x)
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((x & 0x7fff) != 0x7c00) {
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (x < 0) ? -1 : 1;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find first bit set in word.  Least significant bit is 1.
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return 0 if no bits set.
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef FFS_DEFINED
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FFS_DEFINED 1
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64)
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned char _BitScanForward(unsigned long* Index, unsigned long Mask);
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#pragma intrinsic(_BitScanForward)
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned long ffs( unsigned long u )
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned long i;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_BitScanForward(&i, u))
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i + 1;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned ffs( unsigned u )
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (u == 0) {
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __asm bsf eax, [u]
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __asm inc eax
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __asm mov [i], eax
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return i;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(__MINGW32__) || defined(PIPE_OS_ANDROID)
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ffs __builtin_ffs
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* FFS_DEFINED */
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find last bit set in a word.  The least significant bit is 1.
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return 0 if no bits are set.
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned util_last_bit(unsigned u)
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned r = 0;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (u) {
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       r++;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       u >>= 1;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return r;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Destructively loop over all of the bits in a mask as in:
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * while (mymask) {
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   int i = u_bit_scan(&mymask);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   ... process element i
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * }
48066c1c789ce3407472de9ed620c9f815639058835rmcilroy@chromium.org *
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int u_bit_scan(unsigned *mask)
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i = ffs(*mask) - 1;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *mask &= ~(1 << i);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return i;
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return float bits.
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfui( float f )
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi fi;
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi.f = f;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fi.ui;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert ubyte to float in [0, 1].
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX a 256-entry lookup table would be slightly faster.
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgubyte_to_float(ubyte ub)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float) ub * (1.0f / 255.0f);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert float in [0,1] to ubyte in [0,255] with clamping.
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE ubyte
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat_to_ubyte(float f)
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int ieee_0996 = 0x3f7f0000;   /* 0.996 or so */
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union fi tmp;
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp.f = f;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (tmp.i < 0) {
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (ubyte) 0;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (tmp.i >= ieee_0996) {
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (ubyte) 255;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f;
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (ubyte) tmp.i;
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbyte_to_float_tex(int8_t b)
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (b == -128) ? -1.0F : b * 1.0F / 127.0F;
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int8_t
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat_to_byte_tex(float f)
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (int8_t) (127.0F * f);
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calc log base 2
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_logbase2(unsigned n)
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304)
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1));
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned pos = 0;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n >= 1<<16) { n >>= 16; pos += 16; }
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n >= 1<< 8) { n >>=  8; pos +=  8; }
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n >= 1<< 4) { n >>=  4; pos +=  4; }
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n >= 1<< 2) { n >>=  2; pos +=  2; }
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n >= 1<< 1) {           pos +=  1; }
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pos;
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the smallest power of two >= x
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_next_power_of_two(unsigned x)
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304)
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (x <= 1)
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return 1;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned val = x;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (x <= 1)
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1;
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_is_power_of_two(x))
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return x;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val--;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = (val >> 1) | val;
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = (val >> 2) | val;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = (val >> 4) | val;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = (val >> 8) | val;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val = (val >> 16) | val;
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   val++;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return val;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in n.
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bitcount(unsigned n)
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304)
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return __builtin_popcount(n);
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* K&R classic bitcount.
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * For each iteration, clear the LSB from the bitfield.
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Requires only one iteration per set bit, instead of
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * one iteration per bit less than highest set bit.
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned bits = 0;
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (bits; n; bits++) {
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      n &= n - 1;
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return bits;
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert from little endian to CPU byte order.
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_ARCH_BIG_ENDIAN
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le32_to_cpu(x) util_bswap32(x)
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le16_to_cpu(x) util_bswap16(x)
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le32_to_cpu(x) (x)
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define util_le16_to_cpu(x) (x)
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reverse byte order of a 32 bit word.
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bswap32(uint32_t n)
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 403)
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return __builtin_bswap32(n);
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (n >> 24) |
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ((n >> 8) & 0x0000ff00) |
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ((n << 8) & 0x00ff0000) |
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          (n << 24);
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reverse byte order of a 16 bit word.
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint16_t
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_bswap16(uint16_t n)
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (n >> 8) |
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          (n << 8);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Clamp X to [MIN, MAX].
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is a macro to allow float, int, uint, etc. types.
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D))
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D))
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Align a value, only works pot alignemnts.
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgalign(int value, int alignment)
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (value + alignment - 1) & ~(alignment - 1);
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Works like align but on npot alignments.
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE size_t
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgutil_align_npot(size_t value, size_t alignment)
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value % alignment)
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return value + (alignment - (value % alignment));
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return value;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgu_minify(unsigned value, unsigned levels)
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return MAX2(1, value >> levels);
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef COPY_4V
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define COPY_4V( DST, SRC )         \
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo {                                \
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[0] = (SRC)[0];             \
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[1] = (SRC)[1];             \
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[2] = (SRC)[2];             \
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[3] = (SRC)[3];             \
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef COPY_4FV
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define COPY_4FV( DST, SRC )  COPY_4V(DST, SRC)
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef ASSIGN_4V
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo {                                     \
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[0] = (V0);                      \
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[1] = (V1);                      \
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[2] = (V2);                      \
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (DST)[3] = (V3);                      \
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits)
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits));
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int32_t util_signed_fixed(float value, unsigned frac_bits)
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (int32_t)(value * (1<<frac_bits));
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* U_MATH_H */
750