diff --git a/lib/bigint.c b/lib/bigint.c index c676c65..f7c3bb6 100644 --- a/lib/bigint.c +++ b/lib/bigint.c @@ -83,96 +83,13 @@ static const hcl_uint8_t debruijn_64[64] = #if defined(HCL_HAVE_UINT64_T) # 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; } diff --git a/lib/hcl-c.c b/lib/hcl-c.c index af81592..2d97336 100644 --- a/lib/hcl-c.c +++ b/lib/hcl-c.c @@ -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); diff --git a/lib/hcl-cmn.h b/lib/hcl-cmn.h index 9544364..31c7fc2 100644 --- a/lib/hcl-cmn.h +++ b/lib/hcl-cmn.h @@ -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) \ diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 42458e7..96a056e 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -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, diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 784b18b..0e887b5 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -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); diff --git a/lib/hcl-utl.h b/lib/hcl-utl.h index 8fd60f9..bf27f36 100644 --- a/lib/hcl-utl.h +++ b/lib/hcl-utl.h @@ -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)) | \ @@ -786,9 +823,13 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x) ((((hcl_uint64_t)(x)) << 24) & ((hcl_uint64_t)0xff << 40)) | \ ((((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)) | \ @@ -805,6 +846,7 @@ static HCL_INLINE hcl_uint128_t hcl_bswap128 (hcl_uint128_t x) ((((hcl_uint128_t)(x)) << 88) & ((hcl_uint128_t)0xff << 104)) | \ ((((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 diff --git a/lib/hcl.c b/lib/hcl.c index b8def0d..bbf799b 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -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[] = diff --git a/lib/hcl.h b/lib/hcl.h index 1412798..b875058 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -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 diff --git a/lib/json.c b/lib/json.c index 00cabe2..a7ff6d7 100644 --- a/lib/json.c +++ b/lib/json.c @@ -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); diff --git a/lib/logfmt.c b/lib/logfmt.c index f484574..bd2e8ee 100644 --- a/lib/logfmt.c +++ b/lib/logfmt.c @@ -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 { diff --git a/lib/logfmtv.h b/lib/logfmtv.h index 4be05de..1acbff8 100644 --- a/lib/logfmtv.h +++ b/lib/logfmtv.h @@ -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 diff --git a/lib/main-j.c b/lib/main-j.c index 2969639..7f3d181 100644 --- a/lib/main-j.c +++ b/lib/main-j.c @@ -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' } ]"; diff --git a/lib/number.c b/lib/number.c index 14ce5c9..9c17b36 100644 --- a/lib/number.c +++ b/lib/number.c @@ -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; diff --git a/lib/obj.c b/lib/obj.c index f69abc6..e83a5b9 100644 --- a/lib/obj.c +++ b/lib/obj.c @@ -26,7 +26,6 @@ #include "hcl-prv.h" - void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size) { hcl_uint8_t* ptr; diff --git a/lib/tmr.c b/lib/tmr.c index 8e04aa6..ab8de08 100644 --- a/lib/tmr.c +++ b/lib/tmr.c @@ -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; diff --git a/lib/utl.c b/lib/utl.c index 6ab56d1..bbe88bc 100644 --- a/lib/utl.c +++ b/lib/utl.c @@ -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;