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