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