added more code for bigint multiplication

This commit is contained in:
hyunghwan.chung 2015-11-13 15:55:56 +00:00
parent b0f8561238
commit 346131b3e3
4 changed files with 97 additions and 13 deletions

View File

@ -264,7 +264,8 @@ PROCESS TESTING
##((-2305843009213693952 - 10) * (-2305843009213693952 - 10) *(-2305843009213693952 - 10) * (-2305843009213693952 - 10) * 255) dump.
##(-16rFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF * 1) dump.
((-2305843009213693952 * -1) - 1 + 2) dump.
##((-2305843009213693952 * -1) - 1 + 2) dump.
((-2305843009213693952 * -2305843009213693952 * 2305843009213693952 * 2305843009213693952 * 2305843009213693952) - 1 + 2) dump.
"
FFI isNil dump.
FFI notNil dump.

View File

@ -67,6 +67,29 @@ static STIX_INLINE int oow_mul_overflow (stix_oow_t a, stix_oow_t b, stix_oow_t*
}
#endif
#if (STIX_SIZEOF_OOI_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_SMUL_OVERFLOW)
# define ooi_mul_overflow(a,b,c) __builtin_smul_overflow(a,b,c)
#elif (STIX_SIZEOF_OOI_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_SMULL_OVERFLOW)
# define ooi_mul_overflow(a,b,c) __builtin_smull_overflow(a,b,c)
#elif (STIX_SIZEOF_OOI_T == STIX_SIZEOF_LONG_LONG) && defined(STIX_HAVE_BUILTIN_SMULLL_OVERFLOW)
# define ooi_mul_overflow(a,b,c) __builtin_smulll_overflow(a,b,c)
#else
static STIX_INLINE int ooi_mul_overflow (stix_ooi_t a, stix_ooi_t b, stix_ooi_t* c)
{
#if (STIX_SIZEOF_UINTMAX_T > STIX_SIZEOF_OOI_T)
stix_intmax_t k;
k = (stix_intmax_t)a * (stix_intmax_t)b;
*c = (stix_ooi_t)k;
return k > STIX_TYPE_MAX(stix_ooi_t) || k < STIX_TYPE_MIN(stix_ooi_t);
#else
/* TODO: fix this */
#error not implemented
*c = a * b;
return b > 0 && a > STIX_TYPE_MAX(stix_ooi_t) / b; /* works for unsigned types only */
#endif
}
#endif
#if (SIZEOF_ATOM_T == STIX_SIZEOF_INT) && defined(STIX_HAVE_BUILTIN_UADD_OVERFLOW)
# define atom_add_overflow(a,b,c) __builtin_uadd_overflow(a,b,c)
#elif (SIZEOF_ATOM_T == STIX_SIZEOF_LONG) && defined(STIX_HAVE_BUILTIN_UADDL_OVERFLOW)
@ -158,12 +181,12 @@ static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax_t v)
{
/* this is not a generic function. it can't handle v
* if it's STIX_TYPE_MIN(stix_intmax_t) */
stix_oow_t len;
atom_t buf[STIX_SIZEOF_INTMAX_T / SIZEOF_ATOM_T];
stix_uintmax_t ui;
/* this is not a generic function. it can't handle v
* if it's STIX_TYPE_MIN(stix_intmax_t) */
STIX_ASSERT (v > STIX_TYPE_MIN(stix_intmax_t));
ui = (v >= 0)? v: -v;
@ -175,6 +198,15 @@ static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax
}
while (ui > 0);
{ int i;
printf ("MKBI-INTMAX=>");
for (i = len; i > 0;)
{
printf ("%016lX ", (unsigned long)buf[--i]);
}
printf ("\n");
}
return stix_instantiate (stix, ((v >= 0)? stix->_large_positive_integer: stix->_large_negative_integer), buf, len);
}
@ -747,19 +779,42 @@ stix_oop_t stix_mulints (stix_t* stix, stix_oop_t x, stix_oop_t y)
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
#if STIX_SIZEOF_INTMAX_T > STIX_SIZEOF_OOI_T
/*#if STIX_SIZEOF_INTMAX_T > STIX_SIZEOF_OOI_T*/ /* TOOD: uncomment this line and remove the next line after #else block has been tested */
#if STIX_SIZEOF_INTMAX_T <= STIX_SIZEOF_OOI_T
stix_intmax_t i;
i = (stix_intmax_t)STIX_OOP_TO_SMOOI(x) * (stix_intmax_t)STIX_OOP_TO_SMOOI(y);
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP((stix_ooi_t)i);
return make_bigint_with_intmax (stix, i);
#else
stix_ooi_t i;
stix_ooi_t xv, yv;
xv = STIX_OOP_TO_SMOOI(x);
yv = STIX_OOP_TO_SMOOI(y);
if (ooi_mul_overflow (xv, yv, &i))
{
/* overflowed
* -----------------------------------------------------
* no need to call stix_pushtmp() on x and y as they are
* known to be small integers and we don't need them.
* actual values are all in xv and yv. */
if (!(x = make_bigint_with_ooi (stix, xv)) ||
!(y = make_bigint_with_ooi (stix, yv))) return STIX_NULL;
}
else
{
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP(i);
return make_bigint_with_ooi (stix, i);
}
/*
stix_ooi_t i;
i = STIX_OOP_TO_SMOOI(x) * STIX_OOP_TO_SMOOI(y);
if (STIX_IN_SMOOI_RANGE(i)) return STIX_SMOOI_TO_OOP(i);
return make_bigint_with_ooi (stix, i);
*/
#endif
}
else

View File

@ -544,6 +544,7 @@ typedef stix_ucs_t stix_oocs_t;
#if __has_builtin(__builtin_ctz)
#define STIX_HAVE_BUILTIN_CTZ
#endif
#if __has_builtin(__builtin_uadd_overflow)
#define STIX_HAVE_BUILTIN_UADD_OVERFLOW
#endif
@ -563,8 +564,30 @@ typedef stix_ucs_t stix_oocs_t;
#define STIX_HAVE_BUILTIN_UMULLL_OVERFLOW
#endif
#if __has_builtin(__builtin_sadd_overflow)
#define STIX_HAVE_BUILTIN_SADD_OVERFLOW
#endif
#if __has_builtin(__builtin_saddl_overflow)
#define STIX_HAVE_BUILTIN_SADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_saddll_overflow)
#define STIX_HAVE_BUILTIN_SADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_smul_overflow)
#define STIX_HAVE_BUILTIN_SMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_smull_overflow)
#define STIX_HAVE_BUILTIN_SMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_smulll_overflow)
#define STIX_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define STIX_HAVE_BUILTIN_CTZ
#endif
#if (__GNUC__ >= 5)
#define STIX_HAVE_BUILTIN_UADD_OVERFLOW
#define STIX_HAVE_BUILTIN_UADDL_OVERFLOW
@ -572,11 +595,15 @@ typedef stix_ucs_t stix_oocs_t;
#define STIX_HAVE_BUILTIN_UMUL_OVERFLOW
#define STIX_HAVE_BUILTIN_UMULL_OVERFLOW
#define STIX_HAVE_BUILTIN_UMULLL_OVERFLOW
#define STIX_HAVE_BUILTIN_SADD_OVERFLOW
#define STIX_HAVE_BUILTIN_SADDL_OVERFLOW
#define STIX_HAVE_BUILTIN_SADDLL_OVERFLOW
#define STIX_HAVE_BUILTIN_SMUL_OVERFLOW
#define STIX_HAVE_BUILTIN_SMULL_OVERFLOW
#define STIX_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define STIX_HAVE_BUILTIN_CTZ
#endif
#endif
/*

View File

@ -92,9 +92,10 @@ typedef struct stix_obj_byte_t* stix_oop_byte_t;
typedef struct stix_obj_halfword_t* stix_oop_halfword_t;
typedef struct stix_obj_word_t* stix_oop_word_t;
#define STIX_OOW_BITS (STIX_SIZEOF(stix_oow_t) * 8)
#define STIX_OOP_BITS (STIX_SIZEOF(stix_oop_t) * 8)
#define STIX_OOHW_BITS (STIX_SIZEOF(stix_oohw_t) * 8)
#define STIX_OOW_BITS (STIX_SIZEOF_OOW_T * 8)
#define STIX_OOI_BITS (STIX_SIZEOF_OOI_T * 8)
#define STIX_OOP_BITS (STIX_SIZEOF_OOP_T * 8)
#define STIX_OOHW_BITS (STIX_SIZEOF_OOHW_T * 8)
/*
* OOP encoding