xref: /aosp_15_r20/external/deqp/framework/delibs/debase/deInt32.h (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DEINT32_H
2*35238bceSAndroid Build Coastguard Worker #define _DEINT32_H
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  * drawElements Base Portability Library
5*35238bceSAndroid Build Coastguard Worker  * -------------------------------------
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker  *
9*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker  *
15*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker  *
21*35238bceSAndroid Build Coastguard Worker  *//*!
22*35238bceSAndroid Build Coastguard Worker  * \file
23*35238bceSAndroid Build Coastguard Worker  * \brief 32-bit integer math.
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deDefs.h"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_MSC)
29*35238bceSAndroid Build Coastguard Worker #include <intrin.h>
30*35238bceSAndroid Build Coastguard Worker #endif
31*35238bceSAndroid Build Coastguard Worker 
32*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker enum
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker     DE_RCP_FRAC_BITS = 30 /*!< Number of fractional bits in deRcp32() result. */
37*35238bceSAndroid Build Coastguard Worker };
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker void deRcp32(uint32_t a, uint32_t *rcp, int *exp);
40*35238bceSAndroid Build Coastguard Worker void deInt32_computeLUTs(void);
41*35238bceSAndroid Build Coastguard Worker void deInt32_selfTest(void);
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
44*35238bceSAndroid Build Coastguard Worker  * \brief Compute the absolute of an int.
45*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
46*35238bceSAndroid Build Coastguard Worker  * \return Absolute of the input value.
47*35238bceSAndroid Build Coastguard Worker  *
48*35238bceSAndroid Build Coastguard Worker  * \note The input 0x80000000u (for which the abs value cannot be
49*35238bceSAndroid Build Coastguard Worker  * represented), is asserted and returns the value itself.
50*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deAbs32(int a)51*35238bceSAndroid Build Coastguard Worker DE_INLINE int deAbs32(int a)
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((unsigned int)a != 0x80000000u);
54*35238bceSAndroid Build Coastguard Worker     return (a < 0) ? -a : a;
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
58*35238bceSAndroid Build Coastguard Worker  * \brief Compute the signed minimum of two values.
59*35238bceSAndroid Build Coastguard Worker  * \param a    First input value.
60*35238bceSAndroid Build Coastguard Worker  * \param b Second input value.
61*35238bceSAndroid Build Coastguard Worker  * \return The smallest of the two input values.
62*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deMin32(int a,int b)63*35238bceSAndroid Build Coastguard Worker DE_INLINE int deMin32(int a, int b)
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker     return (a <= b) ? a : b;
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
69*35238bceSAndroid Build Coastguard Worker  * \brief Compute the signed maximum of two values.
70*35238bceSAndroid Build Coastguard Worker  * \param a    First input value.
71*35238bceSAndroid Build Coastguard Worker  * \param b Second input value.
72*35238bceSAndroid Build Coastguard Worker  * \return The largest of the two input values.
73*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deMax32(int a,int b)74*35238bceSAndroid Build Coastguard Worker DE_INLINE int deMax32(int a, int b)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker     return (a >= b) ? a : b;
77*35238bceSAndroid Build Coastguard Worker }
78*35238bceSAndroid Build Coastguard Worker 
79*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
80*35238bceSAndroid Build Coastguard Worker  * \brief Compute the unsigned minimum of two values.
81*35238bceSAndroid Build Coastguard Worker  * \param a    First input value.
82*35238bceSAndroid Build Coastguard Worker  * \param b Second input value.
83*35238bceSAndroid Build Coastguard Worker  * \return The smallest of the two input values.
84*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deMinu32(uint32_t a,uint32_t b)85*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deMinu32(uint32_t a, uint32_t b)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     return (a <= b) ? a : b;
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker 
90*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
91*35238bceSAndroid Build Coastguard Worker  * \brief Compute the unsigned minimum of two values.
92*35238bceSAndroid Build Coastguard Worker  * \param a    First input value.
93*35238bceSAndroid Build Coastguard Worker  * \param b Second input value.
94*35238bceSAndroid Build Coastguard Worker  * \return The smallest of the two input values.
95*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deMinu64(uint64_t a,uint64_t b)96*35238bceSAndroid Build Coastguard Worker DE_INLINE uint64_t deMinu64(uint64_t a, uint64_t b)
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker     return (a <= b) ? a : b;
99*35238bceSAndroid Build Coastguard Worker }
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
102*35238bceSAndroid Build Coastguard Worker  * \brief Compute the unsigned maximum of two values.
103*35238bceSAndroid Build Coastguard Worker  * \param a    First input value.
104*35238bceSAndroid Build Coastguard Worker  * \param b Second input value.
105*35238bceSAndroid Build Coastguard Worker  * \return The largest of the two input values.
106*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deMaxu32(uint32_t a,uint32_t b)107*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deMaxu32(uint32_t a, uint32_t b)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker     return (a >= b) ? a : b;
110*35238bceSAndroid Build Coastguard Worker }
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
113*35238bceSAndroid Build Coastguard Worker  * \brief Check if a value is in the <b>inclusive<b> range [mn, mx].
114*35238bceSAndroid Build Coastguard Worker  * \param a        Value to check for range.
115*35238bceSAndroid Build Coastguard Worker  * \param mn    Range minimum value.
116*35238bceSAndroid Build Coastguard Worker  * \param mx    Range maximum value.
117*35238bceSAndroid Build Coastguard Worker  * \return True if (a >= mn) and (a <= mx), false otherwise.
118*35238bceSAndroid Build Coastguard Worker  *
119*35238bceSAndroid Build Coastguard Worker  * \see deInBounds32()
120*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deInRange32(int a,int mn,int mx)121*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInRange32(int a, int mn, int mx)
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker     return (a >= mn) && (a <= mx);
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker 
126*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
127*35238bceSAndroid Build Coastguard Worker  * \brief Check if a value is in the half-inclusive bounds [mn, mx[.
128*35238bceSAndroid Build Coastguard Worker  * \param a        Value to check for range.
129*35238bceSAndroid Build Coastguard Worker  * \param mn    Range minimum value.
130*35238bceSAndroid Build Coastguard Worker  * \param mx    Range maximum value.
131*35238bceSAndroid Build Coastguard Worker  * \return True if (a >= mn) and (a < mx), false otherwise.
132*35238bceSAndroid Build Coastguard Worker  *
133*35238bceSAndroid Build Coastguard Worker  * \see deInRange32()
134*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deInBounds32(int a,int mn,int mx)135*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInBounds32(int a, int mn, int mx)
136*35238bceSAndroid Build Coastguard Worker {
137*35238bceSAndroid Build Coastguard Worker     return (a >= mn) && (a < mx);
138*35238bceSAndroid Build Coastguard Worker }
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
141*35238bceSAndroid Build Coastguard Worker  * \brief Clamp a value into the range [mn, mx].
142*35238bceSAndroid Build Coastguard Worker  * \param a        Value to clamp.
143*35238bceSAndroid Build Coastguard Worker  * \param mn    Minimum value.
144*35238bceSAndroid Build Coastguard Worker  * \param mx    Maximum value.
145*35238bceSAndroid Build Coastguard Worker  * \return The clamped value in [mn, mx] range.
146*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deClamp32(int a,int mn,int mx)147*35238bceSAndroid Build Coastguard Worker DE_INLINE int deClamp32(int a, int mn, int mx)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(mn <= mx);
150*35238bceSAndroid Build Coastguard Worker     if (a < mn)
151*35238bceSAndroid Build Coastguard Worker         return mn;
152*35238bceSAndroid Build Coastguard Worker     if (a > mx)
153*35238bceSAndroid Build Coastguard Worker         return mx;
154*35238bceSAndroid Build Coastguard Worker     return a;
155*35238bceSAndroid Build Coastguard Worker }
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
158*35238bceSAndroid Build Coastguard Worker  * \brief Get the sign of an integer.
159*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
160*35238bceSAndroid Build Coastguard Worker  * \return +1 if a>0, 0 if a==0, -1 if a<0.
161*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deSign32(int a)162*35238bceSAndroid Build Coastguard Worker DE_INLINE int deSign32(int a)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker     if (a > 0)
165*35238bceSAndroid Build Coastguard Worker         return +1;
166*35238bceSAndroid Build Coastguard Worker     if (a < 0)
167*35238bceSAndroid Build Coastguard Worker         return -1;
168*35238bceSAndroid Build Coastguard Worker     return 0;
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
172*35238bceSAndroid Build Coastguard Worker  * \brief Extract the sign bit of a.
173*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
174*35238bceSAndroid Build Coastguard Worker  * \return 0x80000000 if a<0, 0 otherwise.
175*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deSignBit32(int32_t a)176*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deSignBit32(int32_t a)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker     return (int32_t)((uint32_t)a & 0x80000000u);
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
182*35238bceSAndroid Build Coastguard Worker  * \brief Integer rotate right.
183*35238bceSAndroid Build Coastguard Worker  * \param val    Value to rotate.
184*35238bceSAndroid Build Coastguard Worker  * \param r        Number of bits to rotate (in range [0, 32]).
185*35238bceSAndroid Build Coastguard Worker  * \return The rotated value.
186*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deRor32(int val,int r)187*35238bceSAndroid Build Coastguard Worker DE_INLINE int deRor32(int val, int r)
188*35238bceSAndroid Build Coastguard Worker {
189*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(r >= 0 && r <= 32);
190*35238bceSAndroid Build Coastguard Worker     if (r == 0 || r == 32)
191*35238bceSAndroid Build Coastguard Worker         return val;
192*35238bceSAndroid Build Coastguard Worker     else
193*35238bceSAndroid Build Coastguard Worker         return (int)(((uint32_t)val >> r) | ((uint32_t)val << (32 - r)));
194*35238bceSAndroid Build Coastguard Worker }
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
197*35238bceSAndroid Build Coastguard Worker  * \brief Integer rotate left.
198*35238bceSAndroid Build Coastguard Worker  * \param val    Value to rotate.
199*35238bceSAndroid Build Coastguard Worker  * \param r        Number of bits to rotate (in range [0, 32]).
200*35238bceSAndroid Build Coastguard Worker  * \return The rotated value.
201*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deRol32(int val,int r)202*35238bceSAndroid Build Coastguard Worker DE_INLINE int deRol32(int val, int r)
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(r >= 0 && r <= 32);
205*35238bceSAndroid Build Coastguard Worker     if (r == 0 || r == 32)
206*35238bceSAndroid Build Coastguard Worker         return val;
207*35238bceSAndroid Build Coastguard Worker     else
208*35238bceSAndroid Build Coastguard Worker         return (int)(((uint32_t)val << r) | ((uint32_t)val >> (32 - r)));
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker 
211*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
212*35238bceSAndroid Build Coastguard Worker  * \brief Check if a value is a power-of-two.
213*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
214*35238bceSAndroid Build Coastguard Worker  * \return True if input is a power-of-two value, false otherwise.
215*35238bceSAndroid Build Coastguard Worker  *
216*35238bceSAndroid Build Coastguard Worker  * \note Also returns true for zero.
217*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo32(int a)218*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsPowerOfTwo32(int a)
219*35238bceSAndroid Build Coastguard Worker {
220*35238bceSAndroid Build Coastguard Worker     return ((a & (a - 1)) == 0);
221*35238bceSAndroid Build Coastguard Worker }
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
224*35238bceSAndroid Build Coastguard Worker  * \brief Check if a value is a power-of-two.
225*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
226*35238bceSAndroid Build Coastguard Worker  * \return True if input is a power-of-two value, false otherwise.
227*35238bceSAndroid Build Coastguard Worker  *
228*35238bceSAndroid Build Coastguard Worker  * \note Also returns true for zero.
229*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo64(uint64_t a)230*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsPowerOfTwo64(uint64_t a)
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker     return ((a & (a - 1ull)) == 0);
233*35238bceSAndroid Build Coastguard Worker }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
236*35238bceSAndroid Build Coastguard Worker  * \brief Check if a value is a power-of-two.
237*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
238*35238bceSAndroid Build Coastguard Worker  * \return True if input is a power-of-two value, false otherwise.
239*35238bceSAndroid Build Coastguard Worker  *
240*35238bceSAndroid Build Coastguard Worker  * \note Also returns true for zero.
241*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsPowerOfTwoSize(size_t a)242*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsPowerOfTwoSize(size_t a)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker #if (DE_PTR_SIZE == 4)
245*35238bceSAndroid Build Coastguard Worker     return deIsPowerOfTwo32(a);
246*35238bceSAndroid Build Coastguard Worker #elif (DE_PTR_SIZE == 8)
247*35238bceSAndroid Build Coastguard Worker     return deIsPowerOfTwo64(a);
248*35238bceSAndroid Build Coastguard Worker #else
249*35238bceSAndroid Build Coastguard Worker #error "Invalid DE_PTR_SIZE"
250*35238bceSAndroid Build Coastguard Worker #endif
251*35238bceSAndroid Build Coastguard Worker }
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
254*35238bceSAndroid Build Coastguard Worker  * \brief Roud a value up to a power-of-two.
255*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
256*35238bceSAndroid Build Coastguard Worker  * \return Smallest power-of-two value that is greater or equal to an input value.
257*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoU32(uint32_t a)258*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deSmallestGreaterOrEquallPowerOfTwoU32(uint32_t a)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker     --a;
261*35238bceSAndroid Build Coastguard Worker     a |= a >> 1u;
262*35238bceSAndroid Build Coastguard Worker     a |= a >> 2u;
263*35238bceSAndroid Build Coastguard Worker     a |= a >> 4u;
264*35238bceSAndroid Build Coastguard Worker     a |= a >> 8u;
265*35238bceSAndroid Build Coastguard Worker     a |= a >> 16u;
266*35238bceSAndroid Build Coastguard Worker     return ++a;
267*35238bceSAndroid Build Coastguard Worker }
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
270*35238bceSAndroid Build Coastguard Worker  * \brief Roud a value up to a power-of-two.
271*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
272*35238bceSAndroid Build Coastguard Worker  * \return Smallest power-of-two value that is greater or equal to an input value.
273*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoU64(uint64_t a)274*35238bceSAndroid Build Coastguard Worker DE_INLINE uint64_t deSmallestGreaterOrEquallPowerOfTwoU64(uint64_t a)
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker     --a;
277*35238bceSAndroid Build Coastguard Worker     a |= a >> 1u;
278*35238bceSAndroid Build Coastguard Worker     a |= a >> 2u;
279*35238bceSAndroid Build Coastguard Worker     a |= a >> 4u;
280*35238bceSAndroid Build Coastguard Worker     a |= a >> 8u;
281*35238bceSAndroid Build Coastguard Worker     a |= a >> 16u;
282*35238bceSAndroid Build Coastguard Worker     a |= a >> 32u;
283*35238bceSAndroid Build Coastguard Worker     return ++a;
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker 
286*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
287*35238bceSAndroid Build Coastguard Worker  * \brief Roud a value up to a power-of-two.
288*35238bceSAndroid Build Coastguard Worker  * \param a Input value.
289*35238bceSAndroid Build Coastguard Worker  * \return Smallest power-of-two value that is greater or equal to an input value.
290*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoSize(size_t a)291*35238bceSAndroid Build Coastguard Worker DE_INLINE size_t deSmallestGreaterOrEquallPowerOfTwoSize(size_t a)
292*35238bceSAndroid Build Coastguard Worker {
293*35238bceSAndroid Build Coastguard Worker #if (DE_PTR_SIZE == 4)
294*35238bceSAndroid Build Coastguard Worker     return deSmallestGreaterOrEquallPowerOfTwoU32(a);
295*35238bceSAndroid Build Coastguard Worker #elif (DE_PTR_SIZE == 8)
296*35238bceSAndroid Build Coastguard Worker     return deSmallestGreaterOrEquallPowerOfTwoU64(a);
297*35238bceSAndroid Build Coastguard Worker #else
298*35238bceSAndroid Build Coastguard Worker #error "Invalid DE_PTR_SIZE"
299*35238bceSAndroid Build Coastguard Worker #endif
300*35238bceSAndroid Build Coastguard Worker }
301*35238bceSAndroid Build Coastguard Worker 
302*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
303*35238bceSAndroid Build Coastguard Worker  * \brief Check if an integer is aligned to given power-of-two size.
304*35238bceSAndroid Build Coastguard Worker  * \param a        Input value.
305*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for.
306*35238bceSAndroid Build Coastguard Worker  * \return True if input is aligned, false otherwise.
307*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsAligned32(int a,int align)308*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsAligned32(int a, int align)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIsPowerOfTwo32(align));
311*35238bceSAndroid Build Coastguard Worker     return ((a & (align - 1)) == 0);
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
315*35238bceSAndroid Build Coastguard Worker  * \brief Check if an integer is aligned to given power-of-two size.
316*35238bceSAndroid Build Coastguard Worker  * \param a        Input value.
317*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for.
318*35238bceSAndroid Build Coastguard Worker  * \return True if input is aligned, false otherwise.
319*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsAligned64(int64_t a,int64_t align)320*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsAligned64(int64_t a, int64_t align)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIsPowerOfTwo64(align));
323*35238bceSAndroid Build Coastguard Worker     return ((a & (align - 1)) == 0);
324*35238bceSAndroid Build Coastguard Worker }
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
327*35238bceSAndroid Build Coastguard Worker  * \brief Check if a pointer is aligned to given power-of-two size.
328*35238bceSAndroid Build Coastguard Worker  * \param ptr    Input pointer.
329*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for (power-of-two).
330*35238bceSAndroid Build Coastguard Worker  * \return True if input is aligned, false otherwise.
331*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deIsAlignedPtr(const void * ptr,uintptr_t align)332*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deIsAlignedPtr(const void *ptr, uintptr_t align)
333*35238bceSAndroid Build Coastguard Worker {
334*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((align & (align - 1)) == 0); /* power of two */
335*35238bceSAndroid Build Coastguard Worker     return (((uintptr_t)ptr & (align - 1)) == 0);
336*35238bceSAndroid Build Coastguard Worker }
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
339*35238bceSAndroid Build Coastguard Worker  * \brief Align an integer to given power-of-two size.
340*35238bceSAndroid Build Coastguard Worker  * \param val    Input to align.
341*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for (power-of-two).
342*35238bceSAndroid Build Coastguard Worker  * \return The aligned value (larger or equal to input).
343*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deAlign32(int32_t val,int32_t align)344*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deAlign32(int32_t val, int32_t align)
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIsPowerOfTwo32(align));
347*35238bceSAndroid Build Coastguard Worker     return (val + align - 1) & ~(align - 1);
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
351*35238bceSAndroid Build Coastguard Worker  * \brief Align an integer to given power-of-two size.
352*35238bceSAndroid Build Coastguard Worker  * \param val    Input to align.
353*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for (power-of-two).
354*35238bceSAndroid Build Coastguard Worker  * \return The aligned value (larger or equal to input).
355*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deAlign64(int64_t val,int64_t align)356*35238bceSAndroid Build Coastguard Worker DE_INLINE int64_t deAlign64(int64_t val, int64_t align)
357*35238bceSAndroid Build Coastguard Worker {
358*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIsPowerOfTwo64(align));
359*35238bceSAndroid Build Coastguard Worker     return (val + align - 1) & ~(align - 1);
360*35238bceSAndroid Build Coastguard Worker }
361*35238bceSAndroid Build Coastguard Worker 
362*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
363*35238bceSAndroid Build Coastguard Worker  * \brief Align a pointer to given power-of-two size.
364*35238bceSAndroid Build Coastguard Worker  * \param ptr    Input pointer to align.
365*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for (power-of-two).
366*35238bceSAndroid Build Coastguard Worker  * \return The aligned pointer (larger or equal to input).
367*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deAlignPtr(void * ptr,uintptr_t align)368*35238bceSAndroid Build Coastguard Worker DE_INLINE void *deAlignPtr(void *ptr, uintptr_t align)
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker     uintptr_t val = (uintptr_t)ptr;
371*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((align & (align - 1)) == 0); /* power of two */
372*35238bceSAndroid Build Coastguard Worker     return (void *)((val + align - 1) & ~(align - 1));
373*35238bceSAndroid Build Coastguard Worker }
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
376*35238bceSAndroid Build Coastguard Worker  * \brief Align a size_t value to given power-of-two size.
377*35238bceSAndroid Build Coastguard Worker  * \param ptr    Input value to align.
378*35238bceSAndroid Build Coastguard Worker  * \param align    Alignment to check for (power-of-two).
379*35238bceSAndroid Build Coastguard Worker  * \return The aligned size (larger or equal to input).
380*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deAlignSize(size_t val,size_t align)381*35238bceSAndroid Build Coastguard Worker DE_INLINE size_t deAlignSize(size_t val, size_t align)
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIsPowerOfTwoSize(align));
384*35238bceSAndroid Build Coastguard Worker     return (val + align - 1) & ~(align - 1);
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker extern const int8_t g_clzLUT[256];
388*35238bceSAndroid Build Coastguard Worker 
389*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
390*35238bceSAndroid Build Coastguard Worker  * \brief Compute number of leading zeros in an integer.
391*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
392*35238bceSAndroid Build Coastguard Worker  * \return The number of leading zero bits in the input.
393*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deClz32(uint32_t a)394*35238bceSAndroid Build Coastguard Worker DE_INLINE int deClz32(uint32_t a)
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_MSC)
397*35238bceSAndroid Build Coastguard Worker     unsigned long i;
398*35238bceSAndroid Build Coastguard Worker     if (_BitScanReverse(&i, (unsigned long)a) == 0)
399*35238bceSAndroid Build Coastguard Worker         return 32;
400*35238bceSAndroid Build Coastguard Worker     else
401*35238bceSAndroid Build Coastguard Worker         return 31 - i;
402*35238bceSAndroid Build Coastguard Worker #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
403*35238bceSAndroid Build Coastguard Worker     if (a == 0)
404*35238bceSAndroid Build Coastguard Worker         return 32;
405*35238bceSAndroid Build Coastguard Worker     else
406*35238bceSAndroid Build Coastguard Worker         return __builtin_clz((unsigned int)a);
407*35238bceSAndroid Build Coastguard Worker #else
408*35238bceSAndroid Build Coastguard Worker     if ((a & 0xFF000000u) != 0)
409*35238bceSAndroid Build Coastguard Worker         return (int)g_clzLUT[a >> 24];
410*35238bceSAndroid Build Coastguard Worker     if ((a & 0x00FF0000u) != 0)
411*35238bceSAndroid Build Coastguard Worker         return 8 + (int)g_clzLUT[a >> 16];
412*35238bceSAndroid Build Coastguard Worker     if ((a & 0x0000FF00u) != 0)
413*35238bceSAndroid Build Coastguard Worker         return 16 + (int)g_clzLUT[a >> 8];
414*35238bceSAndroid Build Coastguard Worker     return 24 + (int)g_clzLUT[a];
415*35238bceSAndroid Build Coastguard Worker #endif
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker extern const int8_t g_ctzLUT[256];
419*35238bceSAndroid Build Coastguard Worker 
420*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
421*35238bceSAndroid Build Coastguard Worker  * \brief Compute number of trailing zeros in an integer.
422*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
423*35238bceSAndroid Build Coastguard Worker  * \return The number of trailing zero bits in the input.
424*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deCtz32(uint32_t a)425*35238bceSAndroid Build Coastguard Worker DE_INLINE int deCtz32(uint32_t a)
426*35238bceSAndroid Build Coastguard Worker {
427*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_MSC)
428*35238bceSAndroid Build Coastguard Worker     unsigned long i;
429*35238bceSAndroid Build Coastguard Worker     if (_BitScanForward(&i, (unsigned long)a) == 0)
430*35238bceSAndroid Build Coastguard Worker         return 32;
431*35238bceSAndroid Build Coastguard Worker     else
432*35238bceSAndroid Build Coastguard Worker         return i;
433*35238bceSAndroid Build Coastguard Worker #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
434*35238bceSAndroid Build Coastguard Worker     if (a == 0)
435*35238bceSAndroid Build Coastguard Worker         return 32;
436*35238bceSAndroid Build Coastguard Worker     else
437*35238bceSAndroid Build Coastguard Worker         return __builtin_ctz((unsigned int)a);
438*35238bceSAndroid Build Coastguard Worker #else
439*35238bceSAndroid Build Coastguard Worker     if ((a & 0x00FFFFFFu) == 0)
440*35238bceSAndroid Build Coastguard Worker         return (int)g_ctzLUT[a >> 24] + 24;
441*35238bceSAndroid Build Coastguard Worker     if ((a & 0x0000FFFFu) == 0)
442*35238bceSAndroid Build Coastguard Worker         return (int)g_ctzLUT[(a >> 16) & 0xffu] + 16;
443*35238bceSAndroid Build Coastguard Worker     if ((a & 0x000000FFu) == 0)
444*35238bceSAndroid Build Coastguard Worker         return (int)g_ctzLUT[(a >> 8) & 0xffu] + 8;
445*35238bceSAndroid Build Coastguard Worker     return (int)g_ctzLUT[a & 0xffu];
446*35238bceSAndroid Build Coastguard Worker #endif
447*35238bceSAndroid Build Coastguard Worker }
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
450*35238bceSAndroid Build Coastguard Worker  * \brief Compute integer 'floor' of 'log2' for a positive integer.
451*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
452*35238bceSAndroid Build Coastguard Worker  * \return floor(log2(a)).
453*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deLog2Floor32(int32_t a)454*35238bceSAndroid Build Coastguard Worker DE_INLINE int deLog2Floor32(int32_t a)
455*35238bceSAndroid Build Coastguard Worker {
456*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a > 0);
457*35238bceSAndroid Build Coastguard Worker     return 31 - deClz32((uint32_t)a);
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker 
460*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
461*35238bceSAndroid Build Coastguard Worker  * \brief Compute integer 'ceil' of 'log2' for a positive integer.
462*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
463*35238bceSAndroid Build Coastguard Worker  * \return ceil(log2(a)).
464*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deLog2Ceil32(int32_t a)465*35238bceSAndroid Build Coastguard Worker DE_INLINE int deLog2Ceil32(int32_t a)
466*35238bceSAndroid Build Coastguard Worker {
467*35238bceSAndroid Build Coastguard Worker     int log2floor = deLog2Floor32(a);
468*35238bceSAndroid Build Coastguard Worker     if (deIsPowerOfTwo32(a))
469*35238bceSAndroid Build Coastguard Worker         return log2floor;
470*35238bceSAndroid Build Coastguard Worker     else
471*35238bceSAndroid Build Coastguard Worker         return log2floor + 1;
472*35238bceSAndroid Build Coastguard Worker }
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
475*35238bceSAndroid Build Coastguard Worker  * \brief Compute the bit population count of an integer.
476*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
477*35238bceSAndroid Build Coastguard Worker  * \return The number of one bits in the input.
478*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
dePop32(uint32_t a)479*35238bceSAndroid Build Coastguard Worker DE_INLINE int dePop32(uint32_t a)
480*35238bceSAndroid Build Coastguard Worker {
481*35238bceSAndroid Build Coastguard Worker     uint32_t mask0 = 0x55555555; /* 1-bit values. */
482*35238bceSAndroid Build Coastguard Worker     uint32_t mask1 = 0x33333333; /* 2-bit values. */
483*35238bceSAndroid Build Coastguard Worker     uint32_t mask2 = 0x0f0f0f0f; /* 4-bit values. */
484*35238bceSAndroid Build Coastguard Worker     uint32_t mask3 = 0x00ff00ff; /* 8-bit values. */
485*35238bceSAndroid Build Coastguard Worker     uint32_t mask4 = 0x0000ffff; /* 16-bit values. */
486*35238bceSAndroid Build Coastguard Worker     uint32_t t     = (uint32_t)a;
487*35238bceSAndroid Build Coastguard Worker     t              = (t & mask0) + ((t >> 1) & mask0);
488*35238bceSAndroid Build Coastguard Worker     t              = (t & mask1) + ((t >> 2) & mask1);
489*35238bceSAndroid Build Coastguard Worker     t              = (t & mask2) + ((t >> 4) & mask2);
490*35238bceSAndroid Build Coastguard Worker     t              = (t & mask3) + ((t >> 8) & mask3);
491*35238bceSAndroid Build Coastguard Worker     t              = (t & mask4) + (t >> 16);
492*35238bceSAndroid Build Coastguard Worker     return (int)t;
493*35238bceSAndroid Build Coastguard Worker }
494*35238bceSAndroid Build Coastguard Worker 
dePop64(uint64_t a)495*35238bceSAndroid Build Coastguard Worker DE_INLINE int dePop64(uint64_t a)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker     return dePop32((uint32_t)(a & 0xffffffffull)) + dePop32((uint32_t)(a >> 32));
498*35238bceSAndroid Build Coastguard Worker }
499*35238bceSAndroid Build Coastguard Worker 
500*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
501*35238bceSAndroid Build Coastguard Worker  * \brief Reverse bytes in 32-bit integer (for example MSB -> LSB).
502*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
503*35238bceSAndroid Build Coastguard Worker  * \return The input with bytes reversed
504*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deReverseBytes32(uint32_t v)505*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deReverseBytes32(uint32_t v)
506*35238bceSAndroid Build Coastguard Worker {
507*35238bceSAndroid Build Coastguard Worker     uint32_t b0 = v << 24;
508*35238bceSAndroid Build Coastguard Worker     uint32_t b1 = (v & 0x0000ff00) << 8;
509*35238bceSAndroid Build Coastguard Worker     uint32_t b2 = (v & 0x00ff0000) >> 8;
510*35238bceSAndroid Build Coastguard Worker     uint32_t b3 = v >> 24;
511*35238bceSAndroid Build Coastguard Worker     return b0 | b1 | b2 | b3;
512*35238bceSAndroid Build Coastguard Worker }
513*35238bceSAndroid Build Coastguard Worker 
514*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
515*35238bceSAndroid Build Coastguard Worker  * \brief Reverse bytes in 16-bit integer (for example MSB -> LSB).
516*35238bceSAndroid Build Coastguard Worker  * \param a    Input value.
517*35238bceSAndroid Build Coastguard Worker  * \return The input with bytes reversed
518*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deReverseBytes16(uint16_t v)519*35238bceSAndroid Build Coastguard Worker DE_INLINE uint16_t deReverseBytes16(uint16_t v)
520*35238bceSAndroid Build Coastguard Worker {
521*35238bceSAndroid Build Coastguard Worker     return (uint16_t)((v << 8) | (v >> 8));
522*35238bceSAndroid Build Coastguard Worker }
523*35238bceSAndroid Build Coastguard Worker 
deSafeMul32(int32_t a,int32_t b)524*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deSafeMul32(int32_t a, int32_t b)
525*35238bceSAndroid Build Coastguard Worker {
526*35238bceSAndroid Build Coastguard Worker     int32_t res = a * b;
527*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int64_t)res == ((int64_t)a * (int64_t)b));
528*35238bceSAndroid Build Coastguard Worker     return res;
529*35238bceSAndroid Build Coastguard Worker }
530*35238bceSAndroid Build Coastguard Worker 
deSafeAdd32(int32_t a,int32_t b)531*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deSafeAdd32(int32_t a, int32_t b)
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int64_t)a + (int64_t)b == (int64_t)(a + b));
534*35238bceSAndroid Build Coastguard Worker     return (a + b);
535*35238bceSAndroid Build Coastguard Worker }
536*35238bceSAndroid Build Coastguard Worker 
deDivRoundUp32(int32_t a,int32_t b)537*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deDivRoundUp32(int32_t a, int32_t b)
538*35238bceSAndroid Build Coastguard Worker {
539*35238bceSAndroid Build Coastguard Worker     return a / b + ((a % b) ? 1 : 0);
540*35238bceSAndroid Build Coastguard Worker }
541*35238bceSAndroid Build Coastguard Worker 
542*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
543*35238bceSAndroid Build Coastguard Worker  * \brief Return value a rounded up to nearest multiple of b.
544*35238bceSAndroid Build Coastguard Worker  * \param a        Input value.
545*35238bceSAndroid Build Coastguard Worker  * \param b        Alignment to use.
546*35238bceSAndroid Build Coastguard Worker  * \return a if already aligned to b, otherwise next largest aligned value
547*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deRoundUp32(int32_t a,int32_t b)548*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deRoundUp32(int32_t a, int32_t b)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker     int32_t d = a / b;
551*35238bceSAndroid Build Coastguard Worker     return d * b == a ? a : (d + 1) * b;
552*35238bceSAndroid Build Coastguard Worker }
553*35238bceSAndroid Build Coastguard Worker 
554*35238bceSAndroid Build Coastguard Worker /* \todo [petri] Move to int64_t.h? */
555*35238bceSAndroid Build Coastguard Worker 
deMulAsr32(int32_t a,int32_t b,int shift)556*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deMulAsr32(int32_t a, int32_t b, int shift)
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker     return (int32_t)(((int64_t)a * (int64_t)b) >> shift);
559*35238bceSAndroid Build Coastguard Worker }
560*35238bceSAndroid Build Coastguard Worker 
deSafeMulAsr32(int32_t a,int32_t b,int shift)561*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deSafeMulAsr32(int32_t a, int32_t b, int shift)
562*35238bceSAndroid Build Coastguard Worker {
563*35238bceSAndroid Build Coastguard Worker     int64_t res = ((int64_t)a * (int64_t)b) >> shift;
564*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(res == (int64_t)(int32_t)res);
565*35238bceSAndroid Build Coastguard Worker     return (int32_t)res;
566*35238bceSAndroid Build Coastguard Worker }
567*35238bceSAndroid Build Coastguard Worker 
deSafeMuluAsr32(uint32_t a,uint32_t b,int shift)568*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deSafeMuluAsr32(uint32_t a, uint32_t b, int shift)
569*35238bceSAndroid Build Coastguard Worker {
570*35238bceSAndroid Build Coastguard Worker     uint64_t res = ((uint64_t)a * (uint64_t)b) >> shift;
571*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(res == (uint64_t)(uint32_t)res);
572*35238bceSAndroid Build Coastguard Worker     return (uint32_t)res;
573*35238bceSAndroid Build Coastguard Worker }
574*35238bceSAndroid Build Coastguard Worker 
deMul32_32_64(int32_t a,int32_t b)575*35238bceSAndroid Build Coastguard Worker DE_INLINE int64_t deMul32_32_64(int32_t a, int32_t b)
576*35238bceSAndroid Build Coastguard Worker {
577*35238bceSAndroid Build Coastguard Worker     return ((int64_t)a * (int64_t)b);
578*35238bceSAndroid Build Coastguard Worker }
579*35238bceSAndroid Build Coastguard Worker 
deAbs64(int64_t a)580*35238bceSAndroid Build Coastguard Worker DE_INLINE int64_t deAbs64(int64_t a)
581*35238bceSAndroid Build Coastguard Worker {
582*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((uint64_t)a != 0x8000000000000000LL);
583*35238bceSAndroid Build Coastguard Worker     return (a >= 0) ? a : -a;
584*35238bceSAndroid Build Coastguard Worker }
585*35238bceSAndroid Build Coastguard Worker 
deClz64(uint64_t a)586*35238bceSAndroid Build Coastguard Worker DE_INLINE int deClz64(uint64_t a)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker     if ((a >> 32) != 0)
589*35238bceSAndroid Build Coastguard Worker         return deClz32((uint32_t)(a >> 32));
590*35238bceSAndroid Build Coastguard Worker     return deClz32((uint32_t)a) + 32;
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker 
593*35238bceSAndroid Build Coastguard Worker /* Common hash & compare functions. */
594*35238bceSAndroid Build Coastguard Worker 
deInt32Hash(int32_t a)595*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deInt32Hash(int32_t a)
596*35238bceSAndroid Build Coastguard Worker {
597*35238bceSAndroid Build Coastguard Worker     /* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
598*35238bceSAndroid Build Coastguard Worker     uint32_t key = (uint32_t)a;
599*35238bceSAndroid Build Coastguard Worker     key          = (key ^ 61) ^ (key >> 16);
600*35238bceSAndroid Build Coastguard Worker     key          = key + (key << 3);
601*35238bceSAndroid Build Coastguard Worker     key          = key ^ (key >> 4);
602*35238bceSAndroid Build Coastguard Worker     key          = key * 0x27d4eb2d; /* prime/odd constant */
603*35238bceSAndroid Build Coastguard Worker     key          = key ^ (key >> 15);
604*35238bceSAndroid Build Coastguard Worker     return key;
605*35238bceSAndroid Build Coastguard Worker }
606*35238bceSAndroid Build Coastguard Worker 
deInt64Hash(int64_t a)607*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deInt64Hash(int64_t a)
608*35238bceSAndroid Build Coastguard Worker {
609*35238bceSAndroid Build Coastguard Worker     /* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
610*35238bceSAndroid Build Coastguard Worker     uint64_t key = (uint64_t)a;
611*35238bceSAndroid Build Coastguard Worker     key          = (~key) + (key << 21); /* key = (key << 21) - key - 1; */
612*35238bceSAndroid Build Coastguard Worker     key          = key ^ (key >> 24);
613*35238bceSAndroid Build Coastguard Worker     key          = (key + (key << 3)) + (key << 8); /* key * 265 */
614*35238bceSAndroid Build Coastguard Worker     key          = key ^ (key >> 14);
615*35238bceSAndroid Build Coastguard Worker     key          = (key + (key << 2)) + (key << 4); /* key * 21 */
616*35238bceSAndroid Build Coastguard Worker     key          = key ^ (key >> 28);
617*35238bceSAndroid Build Coastguard Worker     key          = key + (key << 31);
618*35238bceSAndroid Build Coastguard Worker     return (uint32_t)key;
619*35238bceSAndroid Build Coastguard Worker }
620*35238bceSAndroid Build Coastguard Worker 
deInt16Hash(int16_t v)621*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deInt16Hash(int16_t v)
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker     return deInt32Hash(v);
624*35238bceSAndroid Build Coastguard Worker }
deUint16Hash(uint16_t v)625*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deUint16Hash(uint16_t v)
626*35238bceSAndroid Build Coastguard Worker {
627*35238bceSAndroid Build Coastguard Worker     return deInt32Hash((int32_t)v);
628*35238bceSAndroid Build Coastguard Worker }
deUint32Hash(uint32_t v)629*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deUint32Hash(uint32_t v)
630*35238bceSAndroid Build Coastguard Worker {
631*35238bceSAndroid Build Coastguard Worker     return deInt32Hash((int32_t)v);
632*35238bceSAndroid Build Coastguard Worker }
deUint64Hash(uint64_t v)633*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deUint64Hash(uint64_t v)
634*35238bceSAndroid Build Coastguard Worker {
635*35238bceSAndroid Build Coastguard Worker     return deInt64Hash((int64_t)v);
636*35238bceSAndroid Build Coastguard Worker }
637*35238bceSAndroid Build Coastguard Worker 
deInt16Equal(int16_t a,int16_t b)638*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInt16Equal(int16_t a, int16_t b)
639*35238bceSAndroid Build Coastguard Worker {
640*35238bceSAndroid Build Coastguard Worker     return (a == b);
641*35238bceSAndroid Build Coastguard Worker }
deUint16Equal(uint16_t a,uint16_t b)642*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deUint16Equal(uint16_t a, uint16_t b)
643*35238bceSAndroid Build Coastguard Worker {
644*35238bceSAndroid Build Coastguard Worker     return (a == b);
645*35238bceSAndroid Build Coastguard Worker }
deInt32Equal(int32_t a,int32_t b)646*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInt32Equal(int32_t a, int32_t b)
647*35238bceSAndroid Build Coastguard Worker {
648*35238bceSAndroid Build Coastguard Worker     return (a == b);
649*35238bceSAndroid Build Coastguard Worker }
deUint32Equal(uint32_t a,uint32_t b)650*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deUint32Equal(uint32_t a, uint32_t b)
651*35238bceSAndroid Build Coastguard Worker {
652*35238bceSAndroid Build Coastguard Worker     return (a == b);
653*35238bceSAndroid Build Coastguard Worker }
deInt64Equal(int64_t a,int64_t b)654*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInt64Equal(int64_t a, int64_t b)
655*35238bceSAndroid Build Coastguard Worker {
656*35238bceSAndroid Build Coastguard Worker     return (a == b);
657*35238bceSAndroid Build Coastguard Worker }
deUint64Equal(uint64_t a,uint64_t b)658*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deUint64Equal(uint64_t a, uint64_t b)
659*35238bceSAndroid Build Coastguard Worker {
660*35238bceSAndroid Build Coastguard Worker     return (a == b);
661*35238bceSAndroid Build Coastguard Worker }
662*35238bceSAndroid Build Coastguard Worker 
dePointerHash(const void * ptr)663*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t dePointerHash(const void *ptr)
664*35238bceSAndroid Build Coastguard Worker {
665*35238bceSAndroid Build Coastguard Worker     uintptr_t val = (uintptr_t)ptr;
666*35238bceSAndroid Build Coastguard Worker #if (DE_PTR_SIZE == 4)
667*35238bceSAndroid Build Coastguard Worker     return deInt32Hash((int)val);
668*35238bceSAndroid Build Coastguard Worker #elif (DE_PTR_SIZE == 8)
669*35238bceSAndroid Build Coastguard Worker     return deInt64Hash((int64_t)val);
670*35238bceSAndroid Build Coastguard Worker #else
671*35238bceSAndroid Build Coastguard Worker #error Unsupported pointer size.
672*35238bceSAndroid Build Coastguard Worker #endif
673*35238bceSAndroid Build Coastguard Worker }
674*35238bceSAndroid Build Coastguard Worker 
dePointerEqual(const void * a,const void * b)675*35238bceSAndroid Build Coastguard Worker DE_INLINE bool dePointerEqual(const void *a, const void *b)
676*35238bceSAndroid Build Coastguard Worker {
677*35238bceSAndroid Build Coastguard Worker     return (a == b);
678*35238bceSAndroid Build Coastguard Worker }
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker /**
681*35238bceSAndroid Build Coastguard Worker  *    \brief    Modulo that generates the same sign as divisor and rounds toward
682*35238bceSAndroid Build Coastguard Worker  *            negative infinity -- assuming c99 %-operator.
683*35238bceSAndroid Build Coastguard Worker  */
deInt32ModF(int32_t n,int32_t d)684*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deInt32ModF(int32_t n, int32_t d)
685*35238bceSAndroid Build Coastguard Worker {
686*35238bceSAndroid Build Coastguard Worker     int32_t r = n % d;
687*35238bceSAndroid Build Coastguard Worker     if ((r > 0 && d < 0) || (r < 0 && d > 0))
688*35238bceSAndroid Build Coastguard Worker         r = r + d;
689*35238bceSAndroid Build Coastguard Worker     return r;
690*35238bceSAndroid Build Coastguard Worker }
691*35238bceSAndroid Build Coastguard Worker 
deInt64InInt32Range(int64_t x)692*35238bceSAndroid Build Coastguard Worker DE_INLINE bool deInt64InInt32Range(int64_t x)
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker     return ((x >= (((int64_t)((int32_t)(-0x7FFFFFFF - 1))))) && (x <= ((1ll << 31) - 1)));
695*35238bceSAndroid Build Coastguard Worker }
696*35238bceSAndroid Build Coastguard Worker 
deBitMask32(int leastSignificantBitNdx,int numBits)697*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deBitMask32(int leastSignificantBitNdx, int numBits)
698*35238bceSAndroid Build Coastguard Worker {
699*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(leastSignificantBitNdx, 0, 32));
700*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(numBits, 0, 32));
701*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(leastSignificantBitNdx + numBits, 0, 32));
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker     if (numBits < 32 && leastSignificantBitNdx < 32)
704*35238bceSAndroid Build Coastguard Worker         return ((1u << numBits) - 1u) << (uint32_t)leastSignificantBitNdx;
705*35238bceSAndroid Build Coastguard Worker     else if (numBits == 0 && leastSignificantBitNdx == 32)
706*35238bceSAndroid Build Coastguard Worker         return 0u;
707*35238bceSAndroid Build Coastguard Worker     else
708*35238bceSAndroid Build Coastguard Worker     {
709*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numBits == 32 && leastSignificantBitNdx == 0);
710*35238bceSAndroid Build Coastguard Worker         return 0xFFFFFFFFu;
711*35238bceSAndroid Build Coastguard Worker     }
712*35238bceSAndroid Build Coastguard Worker }
713*35238bceSAndroid Build Coastguard Worker 
deUintMaxValue32(int numBits)714*35238bceSAndroid Build Coastguard Worker DE_INLINE uint32_t deUintMaxValue32(int numBits)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(numBits, 1, 32));
717*35238bceSAndroid Build Coastguard Worker     if (numBits < 32)
718*35238bceSAndroid Build Coastguard Worker         return ((1u << numBits) - 1u);
719*35238bceSAndroid Build Coastguard Worker     else
720*35238bceSAndroid Build Coastguard Worker         return 0xFFFFFFFFu;
721*35238bceSAndroid Build Coastguard Worker }
722*35238bceSAndroid Build Coastguard Worker 
deIntMaxValue32(int numBits)723*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deIntMaxValue32(int numBits)
724*35238bceSAndroid Build Coastguard Worker {
725*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(numBits, 1, 32));
726*35238bceSAndroid Build Coastguard Worker     if (numBits < 32)
727*35238bceSAndroid Build Coastguard Worker         return ((int32_t)1 << (numBits - 1)) - 1;
728*35238bceSAndroid Build Coastguard Worker     else
729*35238bceSAndroid Build Coastguard Worker     {
730*35238bceSAndroid Build Coastguard Worker         /* avoid undefined behavior of int overflow when shifting */
731*35238bceSAndroid Build Coastguard Worker         return 0x7FFFFFFF;
732*35238bceSAndroid Build Coastguard Worker     }
733*35238bceSAndroid Build Coastguard Worker }
734*35238bceSAndroid Build Coastguard Worker 
deIntMinValue32(int numBits)735*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deIntMinValue32(int numBits)
736*35238bceSAndroid Build Coastguard Worker {
737*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(numBits, 1, 32));
738*35238bceSAndroid Build Coastguard Worker     if (numBits < 32)
739*35238bceSAndroid Build Coastguard Worker         return -((int32_t)1 << (numBits - 1));
740*35238bceSAndroid Build Coastguard Worker     else
741*35238bceSAndroid Build Coastguard Worker     {
742*35238bceSAndroid Build Coastguard Worker         /* avoid undefined behavior of int overflow when shifting */
743*35238bceSAndroid Build Coastguard Worker         return (int32_t)(-0x7FFFFFFF - 1);
744*35238bceSAndroid Build Coastguard Worker     }
745*35238bceSAndroid Build Coastguard Worker }
746*35238bceSAndroid Build Coastguard Worker 
deSignExtendTo32(int32_t value,int numBits)747*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deSignExtendTo32(int32_t value, int numBits)
748*35238bceSAndroid Build Coastguard Worker {
749*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deInRange32(numBits, 1, 32));
750*35238bceSAndroid Build Coastguard Worker 
751*35238bceSAndroid Build Coastguard Worker     if (numBits < 32)
752*35238bceSAndroid Build Coastguard Worker     {
753*35238bceSAndroid Build Coastguard Worker         bool signSet      = ((uint32_t)value & (1u << (numBits - 1))) != 0;
754*35238bceSAndroid Build Coastguard Worker         uint32_t signMask = deBitMask32(numBits, 32 - numBits);
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(((uint32_t)value & signMask) == 0u);
757*35238bceSAndroid Build Coastguard Worker 
758*35238bceSAndroid Build Coastguard Worker         return (int32_t)((uint32_t)value | (signSet ? signMask : 0u));
759*35238bceSAndroid Build Coastguard Worker     }
760*35238bceSAndroid Build Coastguard Worker     else
761*35238bceSAndroid Build Coastguard Worker         return value;
762*35238bceSAndroid Build Coastguard Worker }
763*35238bceSAndroid Build Coastguard Worker 
deIntIsPow2(int powerOf2)764*35238bceSAndroid Build Coastguard Worker DE_INLINE int deIntIsPow2(int powerOf2)
765*35238bceSAndroid Build Coastguard Worker {
766*35238bceSAndroid Build Coastguard Worker     if (powerOf2 <= 0)
767*35238bceSAndroid Build Coastguard Worker         return 0;
768*35238bceSAndroid Build Coastguard Worker     return (powerOf2 & (powerOf2 - (int)1)) == (int)0;
769*35238bceSAndroid Build Coastguard Worker }
770*35238bceSAndroid Build Coastguard Worker 
deIntRoundToPow2(int number,int powerOf2)771*35238bceSAndroid Build Coastguard Worker DE_INLINE int deIntRoundToPow2(int number, int powerOf2)
772*35238bceSAndroid Build Coastguard Worker {
773*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deIntIsPow2(powerOf2));
774*35238bceSAndroid Build Coastguard Worker     return (number + (int)powerOf2 - (int)1) & (int)(~(powerOf2 - 1));
775*35238bceSAndroid Build Coastguard Worker }
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
778*35238bceSAndroid Build Coastguard Worker  * \brief Destructively loop over all of the bits in a mask as in:
779*35238bceSAndroid Build Coastguard Worker  *
780*35238bceSAndroid Build Coastguard Worker  *   while (mymask) {
781*35238bceSAndroid Build Coastguard Worker  *     int i = bitScan(&mymask);
782*35238bceSAndroid Build Coastguard Worker  *     ... process element i
783*35238bceSAndroid Build Coastguard Worker  *   }
784*35238bceSAndroid Build Coastguard Worker  * \param mask        mask value, it will remove LSB that is enabled.
785*35238bceSAndroid Build Coastguard Worker  * \return LSB position that was enabled before overwriting the mask.
786*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deInt32BitScan(int32_t * mask)787*35238bceSAndroid Build Coastguard Worker DE_INLINE int32_t deInt32BitScan(int32_t *mask)
788*35238bceSAndroid Build Coastguard Worker {
789*35238bceSAndroid Build Coastguard Worker     const int32_t i = deCtz32(*mask);
790*35238bceSAndroid Build Coastguard Worker     if (i == 32)
791*35238bceSAndroid Build Coastguard Worker         return i;
792*35238bceSAndroid Build Coastguard Worker     *mask ^= (1u << i);
793*35238bceSAndroid Build Coastguard Worker     return i;
794*35238bceSAndroid Build Coastguard Worker }
795*35238bceSAndroid Build Coastguard Worker 
796*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
797*35238bceSAndroid Build Coastguard Worker 
798*35238bceSAndroid Build Coastguard Worker #endif /* _DEINT32_H */
799