refined the msb positioning functions

migrated hcl_isint()/hcl_isbigint() to hcl-prv.h
This commit is contained in:
hyung-hwan 2019-05-04 17:56:45 +00:00
parent a58f9e47b0
commit 6e5a92a041
16 changed files with 282 additions and 263 deletions

View File

@ -84,95 +84,12 @@ static const hcl_uint8_t debruijn_64[64] =
# define LOG2_FOR_POW2_64(x) (debruijn_64[(hcl_uint64_t)((hcl_uint64_t)(x) * 0x022fdd63cc95386d) >> 58])
#endif
static HCL_INLINE int get_pos_of_msb_set_pow2 (hcl_oow_t x)
{
/* the caller must ensure that x is power of 2. if x happens to be zero,
* the return value is undefined as each method used may give different result. */
#if defined(HCL_HAVE_BUILTIN_CTZLL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG_LONG)
return __builtin_ctzll(x); /* count the number of trailing zeros */
#elif defined(HCL_HAVE_BUILTIN_CTZL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG)
return __builtin_ctzl(x); /* count the number of trailing zeros */
#elif defined(HCL_HAVE_BUILTIN_CTZ) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT)
return __builtin_ctz(x); /* count the number of trailing zeros */
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
hcl_oow_t pos;
/* use the Bit Scan Forward instruction */
#if 1
__asm__ volatile (
"bsf %1,%0\n\t"
: "=r"(pos) /* output */
: "r"(x) /* input */
);
#else
__asm__ volatile (
"bsf %[X],%[EXP]\n\t"
: [EXP]"=r"(pos) /* output */
: [X]"r"(x) /* input */
);
#endif
return (int)pos;
#elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__))
hcl_oow_t n;
/* CLZ is available in ARMv5T and above. there is no instruction to
* count trailing zeros or something similar. using RBIT with CLZ
* would be good in ARMv6T2 and above to avoid further calculation
* afte CLZ */
__asm__ volatile (
"clz %0,%1\n\t"
: "=r"(n) /* output */
: "r"(x) /* input */
);
return (int)(HCL_OOW_BITS - n - 1);
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
#else
int pos = 0;
while (x >>= 1) pos++;
return pos;
#endif
}
static HCL_INLINE int get_pos_of_msb_set (hcl_oow_t x)
{
/* x doesn't have to be power of 2. if x is zero, the result is undefined */
#if defined(HCL_HAVE_BUILTIN_CLZLL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG_LONG)
return HCL_OOW_BITS - __builtin_clzll(x) - 1; /* count the number of leading zeros */
#elif defined(HCL_HAVE_BUILTIN_CLZL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG)
return HCL_OOW_BITS - __builtin_clzl(x) - 1; /* count the number of leading zeros */
#elif defined(HCL_HAVE_BUILTIN_CLZ) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT)
return HCL_OOW_BITS - __builtin_clz(x) - 1; /* count the number of leading zeros */
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
/* bit scan reverse. not all x86 CPUs have LZCNT. */
hcl_oow_t pos;
__asm__ volatile (
"bsr %1,%0\n\t"
: "=r"(pos) /* output */
: "r"(x) /* input */
);
return (int)pos;
#elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__))
hcl_oow_t n;
__asm__ volatile (
"clz %0,%1\n\t"
: "=r"(n) /* output */
: "r"(x) /* input */
);
return (int)(HCL_OOW_BITS - n - 1);
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
#else
int pos = 0;
while (x >>= 1) pos++;
return pos;
#endif
}
#if defined(HCL_HAVE_UINT32_T) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_UINT32_T)
# define LOG2_FOR_POW2(x) LOG2_FOR_POW2_32(x)
#elif defined(HCL_HAVE_UINT64_T) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_UINT64_T)
# define LOG2_FOR_POW2(x) LOG2_FOR_POW2_64(x)
#else
# define LOG2_FOR_POW2(x) get_pos_of_msb_set_pow2(x)
# define LOG2_FOR_POW2(x) hcl_get_pos_of_msb_set_pow2(x)
#endif
@ -306,16 +223,6 @@ static int is_normalized_integer (hcl_t* hcl, hcl_oop_t oop)
return 0;
}
HCL_INLINE static int is_bigint (hcl_t* hcl, hcl_oop_t x)
{
return HCL_IS_BIGINT(hcl, x);
}
HCL_INLINE int hcl_isint (hcl_t* hcl, hcl_oop_t x)
{
return HCL_OOP_IS_SMOOI(x) || HCL_IS_BIGINT(hcl, x);
}
static HCL_INLINE int bigint_to_oow (hcl_t* hcl, hcl_oop_t num, hcl_oow_t* w)
{
HCL_ASSERT (hcl, HCL_IS_BIGINT(hcl,num));
@ -373,7 +280,7 @@ static HCL_INLINE int integer_to_oow (hcl_t* hcl, hcl_oop_t x, hcl_oow_t* w)
}
}
HCL_ASSERT (hcl, is_bigint(hcl, x));
HCL_ASSERT (hcl, hcl_isbigint(hcl, x));
return bigint_to_oow(hcl, x, w);
}
@ -396,7 +303,7 @@ int hcl_inttooow (hcl_t* hcl, hcl_oop_t x, hcl_oow_t* w)
}
}
if (is_bigint(hcl, x)) return bigint_to_oow(hcl, x, w);
if (hcl_isbigint(hcl, x)) return bigint_to_oow(hcl, x, w);
hcl_seterrbfmt (hcl, HCL_EINVAL, "parameter not integer - %O", x);
return 0; /* not convertable - too big, too small, or not integer */
@ -440,7 +347,7 @@ static HCL_INLINE hcl_oop_t make_bigint_with_oow (hcl_t* hcl, hcl_oow_t w)
hcl_liw_t hw[2];
hw[0] = w /*& HCL_LBMASK(hcl_oow_t,HCL_LIW_BITS)*/;
hw[1] = w >> HCL_LIW_BITS;
return hcl_makebigint(hcl, HCL_BRAND_PBIGINT, &hw, (hw[1] > 0? 2: 1));
return hcl_makebigint(hcl, HCL_BRAND_PBIGINT, hw, (hw[1] > 0? 2: 1));
#else
# error UNSUPPORTED LIW BIT SIZE
#endif
@ -475,7 +382,7 @@ static HCL_INLINE hcl_oop_t make_bigint_with_ooi (hcl_t* hcl, hcl_ooi_t i)
w = i;
hw[0] = w /*& HCL_LBMASK(hcl_oow_t,HCL_LIW_BITS)*/;
hw[1] = w >> HCL_LIW_BITS;
return hcl_makebigint(hcl, HCL_BRAND_PBIGINT, &hw, (hw[1] > 0? 2: 1));
return hcl_makebigint(hcl, HCL_BRAND_PBIGINT, hw, (hw[1] > 0? 2: 1));
}
else
{
@ -483,7 +390,7 @@ static HCL_INLINE hcl_oop_t make_bigint_with_ooi (hcl_t* hcl, hcl_ooi_t i)
w = -i;
hw[0] = w /*& HCL_LBMASK(hcl_oow_t,HCL_LIW_BITS)*/;
hw[1] = w >> HCL_LIW_BITS;
return hcl_makebigint(hcl, HCL_BRAND_NBIGINT, &hw, (hw[1] > 0? 2: 1));
return hcl_makebigint(hcl, HCL_BRAND_NBIGINT, hw, (hw[1] > 0? 2: 1));
}
#else
# error UNSUPPORTED LIW BIT SIZE
@ -1860,9 +1767,9 @@ static void divide_unsigned_array3 (hcl_t* hcl, const hcl_liw_t* x, hcl_oow_t xs
#endif
y1 = y[ys - 1];
/*s = HCL_LIW_BITS - ((y1 == 0)? -1: get_pos_of_msb_set(y1)) - 1;*/
/*s = HCL_LIW_BITS - ((y1 == 0)? -1: hcl_get_pos_of_msb_set(y1)) - 1;*/
HCL_ASSERT (hcl, y1 > 0); /* the highest word can't be non-zero in the context where this function is called */
s = HCL_LIW_BITS - get_pos_of_msb_set(y1) - 1;
s = HCL_LIW_BITS - hcl_get_pos_of_msb_set(y1) - 1;
for (i = ys; i > 1; )
{
--i;
@ -2152,7 +2059,7 @@ hcl_oop_t hcl_addints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint (hcl, y, HCL_OBJ_GET_SIZE(y));
@ -2164,7 +2071,7 @@ hcl_oop_t hcl_addints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (hcl, x, HCL_OBJ_GET_SIZE(x));
@ -2176,8 +2083,8 @@ hcl_oop_t hcl_addints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
}
if (HCL_OBJ_GET_FLAGS_BRAND(x) != HCL_OBJ_GET_FLAGS_BRAND(y))
@ -2256,7 +2163,7 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0)
@ -2272,7 +2179,7 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (hcl, x, HCL_OBJ_GET_SIZE(x));
@ -2284,8 +2191,8 @@ hcl_oop_t hcl_subints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
}
if (HCL_OBJ_GET_FLAGS_BRAND(x) != HCL_OBJ_GET_FLAGS_BRAND(y))
@ -2369,7 +2276,7 @@ hcl_oop_t hcl_mulints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
switch (v)
@ -2389,7 +2296,7 @@ hcl_oop_t hcl_mulints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
switch (v)
@ -2409,8 +2316,8 @@ hcl_oop_t hcl_mulints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
}
full_multiply:
@ -2538,7 +2445,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
{
hcl_ooi_t xv;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
/* divide a small integer by a big integer.
* the dividend is guaranteed to be greater than the divisor
@ -2565,7 +2472,7 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
{
hcl_ooi_t yv;
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
/* divide a big integer by a small integer. */
@ -2661,8 +2568,8 @@ hcl_oop_t hcl_divints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y, int modulo, hcl_oop
}
else
{
if (!is_bigint(hcl,x)) goto oops_einval;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
}
}
@ -2752,7 +2659,7 @@ hcl_oop_t hcl_negateint (hcl_t* hcl, hcl_oop_t x)
}
else
{
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
return clone_bigint_negated (hcl, x, HCL_OBJ_GET_SIZE(x));
}
@ -2789,7 +2696,7 @@ hcl_oop_t hcl_bitatint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
if (HCL_IS_NBIGINT(hcl, y)) return HCL_SMOOI_TO_OOP(0);
@ -2804,7 +2711,7 @@ hcl_oop_t hcl_bitatint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
hcl_ooi_t v;
hcl_oow_t wp, bp, xs;
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v < 0) return HCL_SMOOI_TO_OOP(0);
@ -2845,7 +2752,7 @@ hcl_oop_t hcl_bitatint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
int sign;
#endif
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
#if defined(HCL_LIMIT_OBJ_SIZE)
if (HCL_IS_NBIGINT(hcl, y)) return HCL_SMOOI_TO_OOP(0);
@ -2943,7 +2850,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0) return HCL_SMOOI_TO_OOP(0);
@ -2959,7 +2866,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return HCL_SMOOI_TO_OOP(0);
@ -2977,7 +2884,7 @@ hcl_oop_t hcl_bitandints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
hcl_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_bigint(hcl,x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl,x) || !hcl_isbigint(hcl, y)) goto oops_einval;
bigint_and_bigint:
xs = HCL_OBJ_GET_SIZE(x);
@ -3156,7 +3063,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint(hcl, y, HCL_OBJ_GET_SIZE(y));
@ -3172,7 +3079,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
@ -3190,7 +3097,7 @@ hcl_oop_t hcl_bitorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
hcl_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_bigint(hcl,x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl,x) || !hcl_isbigint(hcl, y)) goto oops_einval;
bigint_and_bigint:
xs = HCL_OBJ_GET_SIZE(x);
@ -3374,7 +3281,7 @@ hcl_oop_t hcl_bitxorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint(hcl, y, HCL_OBJ_GET_SIZE(y));
@ -3390,7 +3297,7 @@ hcl_oop_t hcl_bitxorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint(hcl, x, HCL_OBJ_GET_SIZE(x));
@ -3408,7 +3315,7 @@ hcl_oop_t hcl_bitxorints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
hcl_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_bigint(hcl,x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl,x) || !hcl_isbigint(hcl, y)) goto oops_einval;
bigint_and_bigint:
xs = HCL_OBJ_GET_SIZE(x);
@ -3592,7 +3499,7 @@ hcl_oop_t hcl_bitinvint (hcl_t* hcl, hcl_oop_t x)
hcl_oow_t i, xs, zs, zalloc;
int negx;
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
xs = HCL_OBJ_GET_SIZE(x);
negx = HCL_IS_NBIGINT(hcl, x);
@ -4013,7 +3920,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl,y)) goto oops_einval;
if (!hcl_isbigint(hcl,y)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(x);
if (v == 0) return HCL_SMOOI_TO_OOP(0);
@ -4038,7 +3945,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_ooi_t v;
if (!is_bigint(hcl,x)) goto oops_einval;
if (!hcl_isbigint(hcl,x)) goto oops_einval;
v = HCL_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (hcl, x, HCL_OBJ_GET_SIZE(x));
@ -4063,7 +3970,7 @@ hcl_oop_t hcl_bitshiftint (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
{
hcl_oop_t z;
if (!is_bigint(hcl,x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl,x) || !hcl_isbigint(hcl, y)) goto oops_einval;
bigint_and_bigint:
negx = HCL_IS_NBIGINT(hcl, x);
@ -4215,34 +4122,8 @@ hcl_oop_t hcl_strtoint (hcl_t* hcl, const hcl_ooch_t* str, hcl_oow_t len, int ra
/* get log2(radix) in a fast way under the fact that
* radix is a power of 2. the exponent acquired is
* the number of bits that a digit of the given radix takes up */
#if defined(HCL_HAVE_BUILTIN_CTZ)
exp = __builtin_ctz(radix);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
/* use the Bit Scan Forward instruction */
__asm__ volatile (
"bsf %1,%0\n\t"
: "=r"(exp) /* output */
: "r"(radix) /* input */
);
#elif defined(USE_UGLY_CODE) && defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__))
/* CLZ is available in ARMv5T and above. there is no instruction to
* count trailing zeros or something similar. using RBIT with CLZ
* would be good in ARMv6T2 and above to avoid further calculation
* afte CLZ */
__asm__ volatile (
"clz %0,%1\n\t"
: "=r"(exp) /* output */
: "r"(radix) /* input */
);
exp = (HCL_SIZEOF(exp) * 8) - exp - 1;
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
#else
/*exp = LOG2_FOR_POW2(radix);*/
exp = _exp_tab[radix - 1];
#endif
/* bytes */
outlen = ((hcl_oow_t)(end - str) * exp + 7) / 8;
@ -4437,7 +4318,7 @@ hcl_oop_t hcl_eqints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return is_equal(hcl, x, y)? hcl->_true: hcl->_false;
}
@ -4458,7 +4339,7 @@ hcl_oop_t hcl_neints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return !is_equal(hcl, x, y)? hcl->_true: hcl->_false;
}
@ -4475,17 +4356,17 @@ hcl_oop_t hcl_gtints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
return (HCL_IS_NBIGINT(hcl, y))? hcl->_true: hcl->_false;
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
return (HCL_IS_PBIGINT(hcl, x))? hcl->_true: hcl->_false;
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return is_greater(hcl, x, y)? hcl->_true: hcl->_false;
}
@ -4502,17 +4383,17 @@ hcl_oop_t hcl_geints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
return (HCL_IS_NBIGINT(hcl, y))? hcl->_true: hcl->_false;
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
return (HCL_IS_PBIGINT(hcl, x))? hcl->_true: hcl->_false;
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return (is_greater(hcl, x, y) || is_equal(hcl, x, y))? hcl->_true: hcl->_false;
}
@ -4529,17 +4410,17 @@ hcl_oop_t hcl_ltints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
return (HCL_IS_PBIGINT(hcl, y))? hcl->_true: hcl->_false;
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
return (HCL_IS_NBIGINT(hcl, x))? hcl->_true: hcl->_false;
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return is_less(hcl, x, y)? hcl->_true: hcl->_false;
}
@ -4556,17 +4437,17 @@ hcl_oop_t hcl_leints (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
}
else if (HCL_OOP_IS_SMOOI(x))
{
if (!is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, y)) goto oops_einval;
return (HCL_IS_PBIGINT(hcl, y))? hcl->_true: hcl->_false;
}
else if (HCL_OOP_IS_SMOOI(y))
{
if (!is_bigint(hcl, x)) goto oops_einval;
if (!hcl_isbigint(hcl, x)) goto oops_einval;
return (HCL_IS_NBIGINT(hcl, x))? hcl->_true: hcl->_false;
}
else
{
if (!is_bigint(hcl, x) || !is_bigint(hcl, y)) goto oops_einval;
if (!hcl_isbigint(hcl, x) || !hcl_isbigint(hcl, y)) goto oops_einval;
return (is_less(hcl, x, y) || is_equal(hcl, x, y))? hcl->_true: hcl->_false;
}

View File

@ -33,11 +33,11 @@
#define HCL_CLIENT_TOKEN_NAME_ALIGN 64
struct dummy_hcl_xtn_t
struct client_hcl_xtn_t
{
hcl_client_t* client;
};
typedef struct dummy_hcl_xtn_t dummy_hcl_xtn_t;
typedef struct client_hcl_xtn_t client_hcl_xtn_t;
enum hcl_client_reply_attr_type_t
{
@ -131,7 +131,7 @@ struct hcl_client_t
static void log_write_for_dummy (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
dummy_hcl_xtn_t* xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
client_hcl_xtn_t* xtn = (client_hcl_xtn_t*)hcl_getxtn(hcl);
hcl_client_t* client;
client = xtn->client;
@ -184,7 +184,7 @@ static int add_to_reply_token (hcl_client_t* client, hcl_ooch_t ch)
hcl_oow_t newcapa;
newcapa = HCL_ALIGN_POW2(client->rep.tok.len + 1, HCL_CLIENT_TOKEN_NAME_ALIGN);
tmp = hcl_client_reallocmem(client, client->rep.tok.ptr, newcapa * HCL_SIZEOF(*tmp));
tmp = (hcl_ooch_t*)hcl_client_reallocmem(client, client->rep.tok.ptr, newcapa * HCL_SIZEOF(*tmp));
if (!tmp) return -1;
client->rep.tok.capa = newcapa;
@ -458,7 +458,7 @@ static int handle_char (hcl_client_t* client, hcl_ooci_t c, hcl_oow_t nbytes)
{
hcl_ooch_t* tmp;
tmp = hcl_client_reallocmem(client, client->rep.last_attr_key.ptr, client->rep.tok.capa * HCL_SIZEOF(*tmp));
tmp = (hcl_ooch_t*)hcl_client_reallocmem(client, client->rep.last_attr_key.ptr, client->rep.tok.capa * HCL_SIZEOF(*tmp));
if (!tmp) goto oops;
client->rep.last_attr_key.ptr = tmp;
@ -800,7 +800,7 @@ hcl_client_t* hcl_client_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_client_p
hcl_client_t* client;
hcl_t* hcl;
hcl_vmprim_t vmprim;
dummy_hcl_xtn_t* xtn;
client_hcl_xtn_t* xtn;
client = (hcl_client_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*client) + xtnsize);
if (!client)
@ -821,7 +821,7 @@ hcl_client_t* hcl_client_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_client_p
return HCL_NULL;
}
xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
xtn = (client_hcl_xtn_t*)hcl_getxtn(hcl);
xtn->client = client;
HCL_MEMSET (client, 0, HCL_SIZEOF(*client) + xtnsize);

View File

@ -45,6 +45,10 @@
# error UNSUPPORTED SYSTEM
#endif
/* =========================================================================
* ARCHITECTURE/COMPILER TWEAKS
* ========================================================================= */
#if defined(EMSCRIPTEN)
# if defined(HCL_SIZEOF___INT128)
# undef HCL_SIZEOF___INT128
@ -57,6 +61,20 @@
# endif
#endif
#if defined(__GNUC__) && defined(__arm__) && !defined(__ARM_ARCH)
# if defined(__ARM_ARCH_8__)
# define __ARM_ARCH 8
# elif defined(__ARM_ARCH_7__)
# define __ARM_ARCH 7
# elif defined(__ARM_ARCH_6__)
# define __ARM_ARCH 6
# elif defined(__ARM_ARCH_5__)
# define __ARM_ARCH 5
# elif defined(__ARM_ARCH_4__)
# define __ARM_ARCH 4
# endif
#endif
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* ========================================================================= */
@ -317,6 +335,13 @@
# error UNKNOWN INTMAX SIZE
#endif
/* =========================================================================
* BASIC HARD-CODED DEFINES
* ========================================================================= */
#define HCL_BITS_PER_BYTE (8)
/* the maximum number of bch charaters to represent a single uch character */
#define HCL_BCSIZE_MAX 6
/* =========================================================================
* BASIC HCL TYPES
* ========================================================================= */
@ -356,11 +381,15 @@ typedef hcl_uintptr_t hcl_oow_t;
typedef hcl_intptr_t hcl_ooi_t;
#define HCL_SIZEOF_OOW_T HCL_SIZEOF_UINTPTR_T
#define HCL_SIZEOF_OOI_T HCL_SIZEOF_INTPTR_T
#define HCL_OOW_BITS (HCL_SIZEOF_OOW_T * HCL_BITS_PER_BYTE)
#define HCL_OOI_BITS (HCL_SIZEOF_OOI_T * HCL_BITS_PER_BYTE)
typedef hcl_ushortptr_t hcl_oohw_t; /* half word - half word */
typedef hcl_shortptr_t hcl_oohi_t; /* signed half word */
#define HCL_SIZEOF_OOHW_T HCL_SIZEOF_USHORTPTR_T
#define HCL_SIZEOF_OOHI_T HCL_SIZEOF_SHORTPTR_T
#define HCL_OOHW_BITS (HCL_SIZEOF_OOHW_T * HCL_BITS_PER_BYTE)
#define HCL_OOHI_BITS (HCL_SIZEOF_OOHI_T * HCL_BITS_PER_BYTE)
struct hcl_ucs_t
{
@ -392,9 +421,6 @@ typedef struct hcl_bcs_t hcl_bcs_t;
# define HCL_SIZEOF_OOCH_T HCL_SIZEOF_BCH_T
#endif
/* the maximum number of bch charaters to represent a single uch character */
#define HCL_BCSIZE_MAX 6
/* =========================================================================
* BASIC OOP ENCODING
* ========================================================================= */
@ -608,11 +634,11 @@ struct hcl_ntime_t
/* make a bit mask that can mask off low n bits */
#define HCL_LBMASK(type,n) (~(~((type)0) << (n)))
#define HCL_LBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * 8)? HCL_LBMASK(type,n): ~(type)0)
#define HCL_LBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * HCL_BITS_PER_BYTE)? HCL_LBMASK(type,n): ~(type)0)
/* make a bit mask that can mask off hig n bits */
#define HCL_HBMASK(type,n) (~(~((type)0) >> (n)))
#define HCL_HBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * 8)? HCL_HBMASK(type,n): ~(type)0)
#define HCL_HBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * HCL_BITS_PER_BYTE)? HCL_HBMASK(type,n): ~(type)0)
/* get 'length' bits starting from the bit at the 'offset' */
#define HCL_GETBITS(type,value,offset,length) \
@ -639,7 +665,7 @@ struct hcl_ntime_t
* \endcode
*/
/*#define HCL_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
#define HCL_BITS_MAX(type,nbits) ((~(type)0) >> (HCL_SIZEOF(type) * 8 - (nbits)))
#define HCL_BITS_MAX(type,nbits) ((~(type)0) >> (HCL_SIZEOF(type) * HCL_BITS_PER_BYTE - (nbits)))
/* =========================================================================
* MMGR
@ -790,11 +816,11 @@ typedef struct hcl_t hcl_t;
#define HCL_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
#define HCL_TYPE_SIGNED_MAX(type) \
((type)~((type)1 << ((type)HCL_SIZEOF(type) * 8 - 1)))
((type)~((type)1 << ((type)HCL_SIZEOF(type) * HCL_BITS_PER_BYTE - 1)))
#define HCL_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
#define HCL_TYPE_SIGNED_MIN(type) \
((type)((type)1 << ((type)HCL_SIZEOF(type) * 8 - 1)))
((type)((type)1 << ((type)HCL_SIZEOF(type) * HCL_BITS_PER_BYTE - 1)))
#define HCL_TYPE_UNSIGNED_MIN(type) ((type)0)
#define HCL_TYPE_MAX(type) \

View File

@ -129,10 +129,10 @@
* 2. the maximum number of bit shifts can be represented in the hcl_oow_t type.
*/
# define HCL_OBJ_SIZE_MAX ((hcl_oow_t)HCL_SMOOI_MAX)
# define HCL_OBJ_SIZE_BITS_MAX (HCL_OBJ_SIZE_MAX * 8)
# define HCL_OBJ_SIZE_BITS_MAX (HCL_OBJ_SIZE_MAX * HCL_BITS_PER_BYTE)
#else
# define HCL_OBJ_SIZE_MAX ((hcl_oow_t)HCL_TYPE_MAX(hcl_oow_t))
# define HCL_OBJ_SIZE_BITS_MAX (HCL_OBJ_SIZE_MAX * 8)
# define HCL_OBJ_SIZE_BITS_MAX (HCL_OBJ_SIZE_MAX * HCL_BITS_PER_BYTE)
#endif
@ -835,10 +835,15 @@ int hcl_utf8_to_ucs (
/* ========================================================================= */
/* bigint.c */
/* ========================================================================= */
int hcl_isint (
hcl_t* hcl,
hcl_oop_t x
);
static HCL_INLINE int hcl_isbigint (hcl_t* hcl, hcl_oop_t x)
{
return HCL_IS_BIGINT(hcl, x);
}
static HCL_INLINE int hcl_isint (hcl_t* hcl, hcl_oop_t x)
{
return HCL_OOP_IS_SMOOI(x) || HCL_IS_BIGINT(hcl, x);
}
hcl_oop_t hcl_addints (
hcl_t* hcl,

View File

@ -151,11 +151,11 @@ struct worker_hcl_xtn_t
};
typedef struct worker_hcl_xtn_t worker_hcl_xtn_t;
struct dummy_hcl_xtn_t
struct server_hcl_xtn_t
{
hcl_server_t* server;
};
typedef struct dummy_hcl_xtn_t dummy_hcl_xtn_t;
typedef struct server_hcl_xtn_t server_hcl_xtn_t;
enum hcl_server_proto_token_type_t
{
@ -657,7 +657,7 @@ static void log_write (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hc
static void log_write_for_dummy (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
dummy_hcl_xtn_t* xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
server_hcl_xtn_t* xtn = (server_hcl_xtn_t*)hcl_getxtn(hcl);
hcl_server_t* server;
server = xtn->server;
@ -794,7 +794,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
if (proto->reply.nchunks <= 0)
{
/* this is the first chunk */
iov[count].iov_base = ".OK\n.DATA chunked\n";
iov[count].iov_base = (void*)".OK\n.DATA chunked\n";
iov[count++].iov_len = 18;
}
@ -1570,7 +1570,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
hcl_t* hcl = HCL_NULL;
hcl_vmprim_t vmprim;
hcl_tmr_t* tmr = HCL_NULL;
dummy_hcl_xtn_t* xtn;
server_hcl_xtn_t* xtn;
int pfd[2], fcv;
hcl_bitmask_t trait;
@ -1639,7 +1639,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
}
#endif
xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
xtn = (server_hcl_xtn_t*)hcl_getxtn(hcl);
xtn->server = server;
HCL_MEMSET (server, 0, HCL_SIZEOF(*server) + xtnsize);

View File

@ -685,8 +685,9 @@ HCL_EXPORT int hcl_ucwidth (
);
/* ------------------------------------------------------------------------- */
/* =========================================================================
* BIT SWAP
* ========================================================================= */
#if defined(HCL_HAVE_INLINE)
#if defined(HCL_HAVE_UINT16_T)
@ -695,7 +696,10 @@ static HCL_INLINE hcl_uint16_t hcl_bswap16 (hcl_uint16_t x)
#if defined(HCL_HAVE_BUILTIN_BSWAP16)
return __builtin_bswap16(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
__asm__ volatile ("xchgb %b0, %h0" : "=Q"(x): "0"(x));
__asm__ /*volatile*/ ("xchgb %b0, %h0" : "=Q"(x): "0"(x));
return x;
#elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 6))
__asm__ /*volatile*/ ("rev16 %0, %0" : "+r"(x));
return x;
#else
return (x << 8) | (x >> 8);
@ -709,7 +713,23 @@ static HCL_INLINE hcl_uint32_t hcl_bswap32 (hcl_uint32_t x)
#if defined(HCL_HAVE_BUILTIN_BSWAP32)
return __builtin_bswap32(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
__asm__ volatile ("bswapl %0" : "=r"(x) : "0"(x));
__asm__ /*volatile*/ ("bswapl %0" : "=r"(x) : "0"(x));
return x;
#elif defined(__GNUC__) && defined(__aarch64__)
__asm__ /*volatile*/ ("rev32 %0, %0" : "+r"(x));
return x;
#elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 6))
__asm__ /*volatile*/ ("rev %0, %0" : "+r"(x));
return x;
#elif defined(__GNUC__) && defined(__ARM_ARCH)
hcl_uint32_t tmp;
__asm__ /*volatile*/ (
"eor %1, %0, %0, ror #16\n\t"
"bic %1, %1, #0x00ff0000\n\t"
"mov %0, %0, ror #8\n\t"
"eor %0, %0, %1, lsr #8\n\t"
:"+r"(x), "=&r"(tmp)
);
return x;
#else
return ((x >> 24)) |
@ -726,7 +746,10 @@ static HCL_INLINE hcl_uint64_t hcl_bswap64 (hcl_uint64_t x)
#if defined(HCL_HAVE_BUILTIN_BSWAP64)
return __builtin_bswap64(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64))
__asm__ volatile ("bswapq %0" : "=r"(x) : "0"(x));
__asm__ /*volatile*/ ("bswapq %0" : "=r"(x) : "0"(x));
return x;
#elif defined(__GNUC__) && defined(__aarch64__)
__asm__ /*volatile*/ ("rev %0, %0" : "+r"(x));
return x;
#else
return ((x >> 56)) |
@ -741,10 +764,12 @@ static HCL_INLINE hcl_uint64_t hcl_bswap64 (hcl_uint64_t x)
}
#endif
#if defined(HCL_HAVE_UINT128_T)
static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x)
{
#if defined(HCL_HAVE_BUILTIN_BSWAP128)
return __builtin_bswap128(x);
#else
return ((x >> 120)) |
((x >> 104) & ((hcl_uint128_t)0xff << 8)) |
((x >> 88) & ((hcl_uint128_t)0xff << 16)) |
@ -761,23 +786,35 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x)
((x << 88) & ((hcl_uint128_t)0xff << 104)) |
((x << 104) & ((hcl_uint128_t)0xff << 112)) |
((x << 120));
#endif
}
#endif
#else
#if defined(HCL_HAVE_UINT16_T)
# if defined(HCL_HAVE_BUILTIN_BSWAP16)
# define hcl_bswap16(x) ((hcl_uint16_t)__builtin_bswap16((hcl_uint16_t)(x)))
# else
# define hcl_bswap16(x) ((hcl_uint16_t)(((hcl_uint16_t)(x)) << 8) | (((hcl_uint16_t)(x)) >> 8))
# endif
#endif
#if defined(HCL_HAVE_UINT32_T)
# if defined(HCL_HAVE_BUILTIN_BSWAP32)
# define hcl_bswap32(x) ((hcl_uint32_t)__builtin_bswap32((hcl_uint32_t)(x)))
# else
# define hcl_bswap32(x) ((hcl_uint32_t)(((((hcl_uint32_t)(x)) >> 24)) | \
((((hcl_uint32_t)(x)) >> 8) & ((hcl_uint32_t)0xff << 8)) | \
((((hcl_uint32_t)(x)) << 8) & ((hcl_uint32_t)0xff << 16)) | \
((((hcl_uint32_t)(x)) << 24))))
# endif
#endif
#if defined(HCL_HAVE_UINT64_T)
# if defined(HCL_HAVE_BUILTIN_BSWAP64)
# define hcl_bswap64(x) ((hcl_uint64_t)__builtin_bswap64((hcl_uint64_t)(x)))
# else
# define hcl_bswap64(x) ((hcl_uint64_t)(((((hcl_uint64_t)(x)) >> 56)) | \
((((hcl_uint64_t)(x)) >> 40) & ((hcl_uint64_t)0xff << 8)) | \
((((hcl_uint64_t)(x)) >> 24) & ((hcl_uint64_t)0xff << 16)) | \
@ -787,8 +824,12 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x)
((((hcl_uint64_t)(x)) << 40) & ((hcl_uint64_t)0xff << 48)) | \
((((hcl_uint64_t)(x)) << 56))))
# endif
#endif
#if defined(HCL_HAVE_UINT128_T)
# if defined(HCL_HAVE_BUILTIN_BSWAP128)
# define hcl_bswap128(x) ((hcl_uint128_t)__builtin_bswap128((hcl_uint128_t)(x)))
# else
# define hcl_bswap128(x) ((hcl_uint128_t)(((((hcl_uint128_t)(x)) >> 120)) | \
((((hcl_uint128_t)(x)) >> 104) & ((hcl_uint128_t)0xff << 8)) | \
((((hcl_uint128_t)(x)) >> 88) & ((hcl_uint128_t)0xff << 16)) | \
@ -806,6 +847,7 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x)
((((hcl_uint128_t)(x)) << 104) & ((hcl_uint128_t)0xff << 112)) | \
((((hcl_uint128_t)(x)) << 120))))
# endif
#endif
#endif /* HCL_HAVE_INLINE */
@ -891,7 +933,89 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x)
# error UNKNOWN ENDIAN
#endif
/* =========================================================================
* BIT POSITION
* ========================================================================= */
static HCL_INLINE int hcl_get_pos_of_msb_set_pow2 (hcl_oow_t x)
{
/* the caller must ensure that x is power of 2. if x happens to be zero,
* the return value is undefined as each method used may give different result. */
#if defined(HCL_HAVE_BUILTIN_CTZLL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG_LONG)
return __builtin_ctzll(x); /* count the number of trailing zeros */
#elif defined(HCL_HAVE_BUILTIN_CTZL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG)
return __builtin_ctzl(x); /* count the number of trailing zeros */
#elif defined(HCL_HAVE_BUILTIN_CTZ) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT)
return __builtin_ctz(x); /* count the number of trailing zeros */
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
hcl_oow_t pos;
/* use the Bit Scan Forward instruction */
#if 1
__asm__ volatile (
"bsf %1,%0\n\t"
: "=r"(pos) /* output */
: "r"(x) /* input */
);
#else
__asm__ volatile (
"bsf %[X],%[EXP]\n\t"
: [EXP]"=r"(pos) /* output */
: [X]"r"(x) /* input */
);
#endif
return (int)pos;
#elif defined(__GNUC__) && defined(__aarch64__) || (defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 5)))
hcl_oow_t n;
/* CLZ is available in ARMv5T and above. there is no instruction to
* count trailing zeros or something similar. using RBIT with CLZ
* would be good in ARMv6T2 and above to avoid further calculation
* afte CLZ */
__asm__ volatile (
"clz %0,%1\n\t"
: "=r"(n) /* output */
: "r"(x) /* input */
);
return (int)(HCL_OOW_BITS - n - 1);
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
#else
int pos = 0;
while (x >>= 1) pos++;
return pos;
#endif
}
static HCL_INLINE int hcl_get_pos_of_msb_set (hcl_oow_t x)
{
/* x doesn't have to be power of 2. if x is zero, the result is undefined */
#if defined(HCL_HAVE_BUILTIN_CLZLL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG_LONG)
return HCL_OOW_BITS - __builtin_clzll(x) - 1; /* count the number of leading zeros */
#elif defined(HCL_HAVE_BUILTIN_CLZL) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_LONG)
return HCL_OOW_BITS - __builtin_clzl(x) - 1; /* count the number of leading zeros */
#elif defined(HCL_HAVE_BUILTIN_CLZ) && (HCL_SIZEOF_OOW_T == HCL_SIZEOF_INT)
return HCL_OOW_BITS - __builtin_clz(x) - 1; /* count the number of leading zeros */
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
/* bit scan reverse. not all x86 CPUs have LZCNT. */
hcl_oow_t pos;
__asm__ volatile (
"bsr %1,%0\n\t"
: "=r"(pos) /* output */
: "r"(x) /* input */
);
return (int)pos;
#elif defined(__GNUC__) && defined(__aarch64__) || (defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 5)))
hcl_oow_t n;
__asm__ volatile (
"clz %0,%1\n\t"
: "=r"(n) /* output */
: "r"(x) /* input */
);
return (int)(HCL_OOW_BITS - n - 1);
/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
#else
int pos = 0;
while (x >>= 1) pos++;
return pos;
#endif
}
#if defined(__cplusplus)
}
#endif

View File

@ -517,7 +517,7 @@ void hcl_freemem (hcl_t* hcl, void* ptr)
static struct
{
hcl_bch_t* modname;
const hcl_bch_t* modname;
int (*modload) (hcl_t* hcl, hcl_mod_t* mod);
}
static_modtab[] =

View File

@ -217,20 +217,16 @@ typedef struct hcl_obj_byte_t* hcl_oop_byte_t;
typedef struct hcl_obj_halfword_t* hcl_oop_halfword_t;
typedef struct hcl_obj_word_t* hcl_oop_word_t;
#define HCL_OOW_BITS (HCL_SIZEOF_OOW_T * 8)
#define HCL_OOI_BITS (HCL_SIZEOF_OOI_T * 8)
#define HCL_OOP_BITS (HCL_SIZEOF_OOP_T * 8)
#define HCL_OOHW_BITS (HCL_SIZEOF_OOHW_T * 8)
#define HCL_OOP_BITS (HCL_SIZEOF_OOP_T * HCL_BITS_PER_BYTE)
/* =========================================================================
* BIGINT TYPES AND MACROS
* ========================================================================= */
#if defined(HCL_ENABLE_FULL_LIW) && (HCL_SIZEOF_UINTMAX_T > HCL_SIZEOF_OOW_T)
# define HCL_USE_FULL_WORD
# define HCL_USE_OOW_FOR_LIW
#endif
#if defined(HCL_USE_FULL_WORD)
#if defined(HCL_USE_OOW_FOR_LIW)
typedef hcl_oow_t hcl_liw_t; /* large integer word */
typedef hcl_ooi_t hcl_lii_t;
typedef hcl_uintmax_t hcl_lidw_t; /* large integer double word */
@ -238,7 +234,7 @@ typedef struct hcl_obj_word_t* hcl_oop_word_t;
# define HCL_SIZEOF_LIW_T HCL_SIZEOF_OOW_T
# define HCL_SIZEOF_LIDW_T HCL_SIZEOF_UINTMAX_T
# define HCL_LIW_BITS HCL_OOW_BITS
# define HCL_LIDW_BITS (HCL_SIZEOF_UINTMAX_T * 8)
# define HCL_LIDW_BITS (HCL_SIZEOF_UINTMAX_T * HCL_BITS_PER_BYTE)
typedef hcl_oop_word_t hcl_oop_liword_t;
# define HCL_OBJ_TYPE_LIWORD HCL_OBJ_TYPE_WORD

View File

@ -33,11 +33,11 @@
#define HCL_JSON_TOKEN_NAME_ALIGN 64
struct dummy_hcl_xtn_t
struct json_hcl_xtn_t
{
hcl_json_t* json;
};
typedef struct dummy_hcl_xtn_t dummy_hcl_xtn_t;
typedef struct json_hcl_xtn_t json_hcl_xtn_t;
typedef struct hcl_json_state_node_t hcl_json_state_node_t;
@ -113,7 +113,7 @@ struct hcl_json_t
static void log_write_for_dummy (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
dummy_hcl_xtn_t* xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
json_hcl_xtn_t* xtn = (json_hcl_xtn_t*)hcl_getxtn(hcl);
hcl_json_t* json;
json = xtn->json;
@ -166,7 +166,7 @@ static int add_char_to_token (hcl_json_t* json, hcl_ooch_t ch)
hcl_oow_t newcapa;
newcapa = HCL_ALIGN_POW2(json->tok.len + 1, HCL_JSON_TOKEN_NAME_ALIGN);
tmp = hcl_json_reallocmem(json, json->tok.ptr, newcapa * HCL_SIZEOF(*tmp));
tmp = (hcl_ooch_t*)hcl_json_reallocmem(json, json->tok.ptr, newcapa * HCL_SIZEOF(*tmp));
if (!tmp) return -1;
json->tok_capa = newcapa;
@ -221,7 +221,7 @@ static int push_state (hcl_json_t* json, hcl_json_state_t state)
{
hcl_json_state_node_t* ss;
ss = hcl_json_callocmem(json, HCL_SIZEOF(*ss));
ss = (hcl_json_state_node_t*)hcl_json_callocmem(json, HCL_SIZEOF(*ss));
if (!ss) return -1;
ss->state = state;
@ -889,7 +889,7 @@ hcl_json_t* hcl_json_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_json_prim_t*
hcl_json_t* json;
hcl_t* hcl;
hcl_vmprim_t vmprim;
dummy_hcl_xtn_t* xtn;
json_hcl_xtn_t* xtn;
json = (hcl_json_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*json) + xtnsize);
if (!json)
@ -910,7 +910,7 @@ hcl_json_t* hcl_json_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_json_prim_t*
return HCL_NULL;
}
xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
xtn = (json_hcl_xtn_t*)hcl_getxtn(hcl);
xtn->json = json;
HCL_MEMSET (json, 0, HCL_SIZEOF(*json) + xtnsize);

View File

@ -41,7 +41,7 @@
/* Max number conversion buffer length:
* hcl_intmax_t in base 2, plus NUL byte. */
#define MAXNBUF (HCL_SIZEOF(hcl_intmax_t) * 8 + 1)
#define MAXNBUF (HCL_SIZEOF(hcl_intmax_t) * HCL_BITS_PER_BYTE + 1)
enum
{

View File

@ -1009,7 +1009,7 @@ static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_lis
#else
register int shift = i * HCL_SIZEOF(hcl_oow_t);
hcl_oow_t x = va_arg (ap, hcl_oow_t);
num |= (hcl_uintmax_t)x << (shift * 8);
num |= (hcl_uintmax_t)x << (shift * HCL_BITS_PER_BYTE);
#endif
}
#else
@ -1053,7 +1053,7 @@ static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_lis
#else
register int shift = i * HCL_SIZEOF(hcl_oow_t);
hcl_oow_t x = va_arg (ap, hcl_oow_t);
num |= (hcl_uintmax_t)x << (shift * 8);
num |= (hcl_uintmax_t)x << (shift * HCL_BITS_PER_BYTE);
#endif
}
#else

View File

@ -88,9 +88,7 @@ static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len)
static int write_log (hcl_json_t* json, int fd, const hcl_bch_t* ptr, hcl_oow_t len)
{
json_xtn_t* xtn;
xtn = hcl_json_getxtn(json);
json_xtn_t* xtn = (json_xtn_t*)hcl_json_getxtn(json);
while (len > 0)
{
@ -139,8 +137,7 @@ static int write_log (hcl_json_t* json, int fd, const hcl_bch_t* ptr, hcl_oow_t
static void flush_log (hcl_json_t* json, int fd)
{
json_xtn_t* xtn;
xtn = hcl_json_getxtn(json);
json_xtn_t* xtn = (json_xtn_t*)hcl_json_getxtn(json);
if (xtn->logbuf.len > 0)
{
write_all (fd, xtn->logbuf.buf, xtn->logbuf.len);
@ -150,14 +147,13 @@ static void flush_log (hcl_json_t* json, int fd)
static void log_write (hcl_json_t* json, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
json_xtn_t* xtn = (json_xtn_t*)hcl_json_getxtn(json);
hcl_bch_t buf[256];
hcl_oow_t ucslen, bcslen;
json_xtn_t* xtn;
hcl_oow_t msgidx;
int n, logfd;
xtn = hcl_json_getxtn(json);
if (mask & HCL_LOG_STDERR)
{
/* the messages that go to STDERR don't get masked out */
@ -267,9 +263,7 @@ static void log_write (hcl_json_t* json, hcl_bitmask_t mask, const hcl_ooch_t* m
static int instcb (hcl_json_t* json, hcl_json_inst_t it, const hcl_oocs_t* str)
{
json_xtn_t* json_xtn;
json_xtn = hcl_json_getxtn(json);
json_xtn_t* json_xtn = (json_xtn_t*)hcl_json_getxtn(json);
switch (it)
{
@ -323,7 +317,7 @@ int main (int argc, char* argv[])
json = hcl_json_open (&sys_mmgr, HCL_SIZEOF(json_xtn_t), &json_prim, NULL);
json_xtn = hcl_json_getxtn(json);
json_xtn = (json_xtn_t*)hcl_json_getxtn(json);
json_xtn->logmask = HCL_LOG_ALL_LEVELS | HCL_LOG_ALL_TYPES;
p = "[ \"ab\\xab\\uC88B\\uC544\\uC6A9c\", \"kaden\", \"iron\", true, { \"null\": \"a\\1bc\", \"123\": \"AA20AA\", \"10\": -0.123, \"way\": '\\uC88A' } ]";

View File

@ -26,7 +26,6 @@
#include "hcl-prv.h"
static hcl_ooi_t equalize_scale (hcl_t* hcl, hcl_oop_t* x, hcl_oop_t* y)
{
hcl_ooi_t xs, ys;

View File

@ -26,7 +26,6 @@
#include "hcl-prv.h"
void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size)
{
hcl_uint8_t* ptr;

View File

@ -37,15 +37,14 @@ hcl_tmr_t* hcl_tmr_open (hcl_t* hcl, hcl_oow_t xtnsize, hcl_oow_t capa)
{
hcl_tmr_t* tmr;
tmr = HCL_MMGR_ALLOC(hcl->mmgr, HCL_SIZEOF(hcl_tmr_t) + xtnsize);
tmr = (hcl_tmr_t*)hcl_allocmem(hcl, HCL_SIZEOF(*tmr) + xtnsize);
if (tmr)
{
if (hcl_tmr_init(tmr, hcl, capa) <= -1)
{
HCL_MMGR_FREE (hcl->mmgr, tmr);
hcl_freemem (tmr->hcl, tmr);
return HCL_NULL;
}
else HCL_MEMSET (tmr + 1, 0, xtnsize);
}
@ -55,7 +54,7 @@ hcl_tmr_t* hcl_tmr_open (hcl_t* hcl, hcl_oow_t xtnsize, hcl_oow_t capa)
void hcl_tmr_close (hcl_tmr_t* tmr)
{
hcl_tmr_fini (tmr);
HCL_MMGR_FREE (tmr->hcl->mmgr, tmr);
hcl_freemem (tmr->hcl, tmr);
}
int hcl_tmr_init (hcl_tmr_t* tmr, hcl_t* hcl, hcl_oow_t capa)
@ -66,8 +65,8 @@ int hcl_tmr_init (hcl_tmr_t* tmr, hcl_t* hcl, hcl_oow_t capa)
if (capa <= 0) capa = 1;
tmp = HCL_MMGR_ALLOC(hcl->mmgr, capa * HCL_SIZEOF(*tmp));
if (tmp == HCL_NULL) return -1;
tmp = (hcl_tmr_event_t*)hcl_allocmem(hcl, capa * HCL_SIZEOF(*tmp));
if (!tmp) return -1;
tmr->hcl = hcl;
tmr->capa = capa;
@ -79,7 +78,11 @@ int hcl_tmr_init (hcl_tmr_t* tmr, hcl_t* hcl, hcl_oow_t capa)
void hcl_tmr_fini (hcl_tmr_t* tmr)
{
hcl_tmr_clear (tmr);
if (tmr->event) HCL_MMGR_FREE (tmr->hcl->mmgr, tmr->event);
if (tmr->event)
{
hcl_freemem (tmr->hcl, tmr->event);
tmr->event = HCL_NULL;
}
}
/*
@ -208,8 +211,8 @@ hcl_tmr_index_t hcl_tmr_insert (hcl_tmr_t* tmr, const hcl_tmr_event_t* event)
HCL_ASSERT (tmr->hcl, tmr->capa >= 1);
new_capa = tmr->capa * 2;
tmp = HCL_MMGR_REALLOC(tmr->hcl->mmgr, tmr->event, new_capa * HCL_SIZEOF(*tmp));
if (tmp == HCL_NULL) return HCL_TMR_INVALID_INDEX;
tmp = (hcl_tmr_event_t*)hcl_reallocmem(tmr->hcl, tmr->event, new_capa * HCL_SIZEOF(*tmp));
if (!tmp) return HCL_TMR_INVALID_INDEX;
tmr->event = tmp;
tmr->capa = new_capa;

View File

@ -361,7 +361,7 @@ hcl_bch_t* hcl_find_bchar_in_bcstr (const hcl_bch_t* ptr, hcl_bch_t c)
hcl_oow_t hcl_byte_to_bcstr (hcl_uint8_t byte, hcl_bch_t* buf, hcl_oow_t size, int flagged_radix, hcl_bch_t fill)
{
hcl_bch_t tmp[(HCL_SIZEOF(hcl_uint8_t) * 8)];
hcl_bch_t tmp[(HCL_SIZEOF(hcl_uint8_t) * HCL_BITS_PER_BYTE)];
hcl_bch_t* p = tmp, * bp = buf, * be = buf + size - 1;
int radix;
hcl_bch_t radix_char;
@ -395,9 +395,7 @@ hcl_oow_t hcl_byte_to_bcstr (hcl_uint8_t byte, hcl_bch_t* buf, hcl_oow_t size, i
/* ----------------------------------------------------------------------- */
HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (
const hcl_bch_t* bcs, hcl_oow_t* bcslen,
hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (const hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
{
const hcl_bch_t* p;
int ret = 0;
@ -516,9 +514,7 @@ HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (
return ret;
}
HCL_INLINE int hcl_conv_bcstr_to_ucstr_with_cmgr (
const hcl_bch_t* bcs, hcl_oow_t* bcslen,
hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
HCL_INLINE int hcl_conv_bcstr_to_ucstr_with_cmgr (const hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
{
const hcl_bch_t* bp;
hcl_oow_t mlen, wlen;
@ -539,9 +535,7 @@ HCL_INLINE int hcl_conv_bcstr_to_ucstr_with_cmgr (
return n;
}
HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (
const hcl_uch_t* ucs, hcl_oow_t* ucslen,
hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
{
const hcl_uch_t* p = ucs;
const hcl_uch_t* end = ucs + *ucslen;
@ -608,9 +602,7 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (
return ret;
}
HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (
const hcl_uch_t* ucs, hcl_oow_t* ucslen,
hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (const hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
{
const hcl_uch_t* p = ucs;
int ret = 0;