11cb0ef41Sopenharmony_ci/* MIT License
21cb0ef41Sopenharmony_ci *
31cb0ef41Sopenharmony_ci * Copyright (c) 2023 Brad House
41cb0ef41Sopenharmony_ci *
51cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
61cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
71cb0ef41Sopenharmony_ci * in the Software without restriction, including without limitation the rights
81cb0ef41Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
91cb0ef41Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
101cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions:
111cb0ef41Sopenharmony_ci *
121cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice (including the next
131cb0ef41Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
141cb0ef41Sopenharmony_ci * Software.
151cb0ef41Sopenharmony_ci *
161cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
191cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
201cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
211cb0ef41Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
221cb0ef41Sopenharmony_ci * SOFTWARE.
231cb0ef41Sopenharmony_ci *
241cb0ef41Sopenharmony_ci * SPDX-License-Identifier: MIT
251cb0ef41Sopenharmony_ci */
261cb0ef41Sopenharmony_ci#include "ares_setup.h"
271cb0ef41Sopenharmony_ci#include "ares.h"
281cb0ef41Sopenharmony_ci#include "ares_private.h"
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci/* Uses public domain code snippets from
311cb0ef41Sopenharmony_ci * http://graphics.stanford.edu/~seander/bithacks.html */
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cistatic unsigned int ares__round_up_pow2_u32(unsigned int n)
341cb0ef41Sopenharmony_ci{
351cb0ef41Sopenharmony_ci  /* NOTE: if already a power of 2, will return itself, not the next */
361cb0ef41Sopenharmony_ci  n--;
371cb0ef41Sopenharmony_ci  n |= n >> 1;
381cb0ef41Sopenharmony_ci  n |= n >> 2;
391cb0ef41Sopenharmony_ci  n |= n >> 4;
401cb0ef41Sopenharmony_ci  n |= n >> 8;
411cb0ef41Sopenharmony_ci  n |= n >> 16;
421cb0ef41Sopenharmony_ci  n++;
431cb0ef41Sopenharmony_ci  return n;
441cb0ef41Sopenharmony_ci}
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cistatic ares_int64_t ares__round_up_pow2_u64(ares_int64_t n)
471cb0ef41Sopenharmony_ci{
481cb0ef41Sopenharmony_ci  /* NOTE: if already a power of 2, will return itself, not the next */
491cb0ef41Sopenharmony_ci  n--;
501cb0ef41Sopenharmony_ci  n |= n >> 1;
511cb0ef41Sopenharmony_ci  n |= n >> 2;
521cb0ef41Sopenharmony_ci  n |= n >> 4;
531cb0ef41Sopenharmony_ci  n |= n >> 8;
541cb0ef41Sopenharmony_ci  n |= n >> 16;
551cb0ef41Sopenharmony_ci  n |= n >> 32;
561cb0ef41Sopenharmony_ci  n++;
571cb0ef41Sopenharmony_ci  return n;
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_cisize_t ares__round_up_pow2(size_t n)
611cb0ef41Sopenharmony_ci{
621cb0ef41Sopenharmony_ci  if (sizeof(size_t) > 4) {
631cb0ef41Sopenharmony_ci    return (size_t)ares__round_up_pow2_u64((ares_int64_t)n);
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  return (size_t)ares__round_up_pow2_u32((unsigned int)n);
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_cisize_t ares__log2(size_t n)
701cb0ef41Sopenharmony_ci{
711cb0ef41Sopenharmony_ci  static const unsigned char tab32[32] = { 0,  1,  28, 2,  29, 14, 24, 3,
721cb0ef41Sopenharmony_ci                                           30, 22, 20, 15, 25, 17, 4,  8,
731cb0ef41Sopenharmony_ci                                           31, 27, 13, 23, 21, 19, 16, 7,
741cb0ef41Sopenharmony_ci                                           26, 12, 18, 6,  11, 5,  10, 9 };
751cb0ef41Sopenharmony_ci  static const unsigned char tab64[64] = {
761cb0ef41Sopenharmony_ci    63, 0,  58, 1,  59, 47, 53, 2,  60, 39, 48, 27, 54, 33, 42, 3,
771cb0ef41Sopenharmony_ci    61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4,
781cb0ef41Sopenharmony_ci    62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
791cb0ef41Sopenharmony_ci    56, 45, 25, 31, 35, 16, 9,  12, 44, 24, 15, 8,  23, 7,  6,  5
801cb0ef41Sopenharmony_ci  };
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  if (sizeof(size_t) == 4) {
831cb0ef41Sopenharmony_ci    return tab32[(n * 0x077CB531) >> 27];
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  return tab64[(n * 0x07EDD5E59A4E28C2) >> 58];
871cb0ef41Sopenharmony_ci}
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci/* x^y */
901cb0ef41Sopenharmony_cisize_t ares__pow(size_t x, size_t y)
911cb0ef41Sopenharmony_ci{
921cb0ef41Sopenharmony_ci  size_t res = 1;
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  while (y > 0) {
951cb0ef41Sopenharmony_ci    /* If y is odd, multiply x with result */
961cb0ef41Sopenharmony_ci    if (y & 1) {
971cb0ef41Sopenharmony_ci      res = res * x;
981cb0ef41Sopenharmony_ci    }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci    /* y must be even now */
1011cb0ef41Sopenharmony_ci    y = y >> 1; /* y /= 2; */
1021cb0ef41Sopenharmony_ci    x = x * x;  /* x^2 */
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  return res;
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_cisize_t ares__count_digits(size_t n)
1091cb0ef41Sopenharmony_ci{
1101cb0ef41Sopenharmony_ci  size_t digits;
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  for (digits = 0; n > 0; digits++) {
1131cb0ef41Sopenharmony_ci    n /= 10;
1141cb0ef41Sopenharmony_ci  }
1151cb0ef41Sopenharmony_ci  if (digits == 0) {
1161cb0ef41Sopenharmony_ci    digits = 1;
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  return digits;
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_cisize_t ares__count_hexdigits(size_t n)
1231cb0ef41Sopenharmony_ci{
1241cb0ef41Sopenharmony_ci  size_t digits;
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  for (digits = 0; n > 0; digits++) {
1271cb0ef41Sopenharmony_ci    n /= 16;
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci  if (digits == 0) {
1301cb0ef41Sopenharmony_ci    digits = 1;
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  return digits;
1341cb0ef41Sopenharmony_ci}
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ciunsigned char ares__count_bits_u8(unsigned char x)
1371cb0ef41Sopenharmony_ci{
1381cb0ef41Sopenharmony_ci  /* Implementation obtained from:
1391cb0ef41Sopenharmony_ci   * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable */
1401cb0ef41Sopenharmony_ci#define B2(n) n, n + 1, n + 1, n + 2
1411cb0ef41Sopenharmony_ci#define B4(n) B2(n), B2(n + 1), B2(n + 1), B2(n + 2)
1421cb0ef41Sopenharmony_ci#define B6(n) B4(n), B4(n + 1), B4(n + 1), B4(n + 2)
1431cb0ef41Sopenharmony_ci  static const unsigned char lookup[256] = { B6(0), B6(1), B6(1), B6(2) };
1441cb0ef41Sopenharmony_ci  return lookup[x];
1451cb0ef41Sopenharmony_ci}
146