From a956c6fd410c8e3be1bbe18365928311896f25df Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Thu, 9 Jun 2022 19:14:06 -0700 Subject: [PATCH] WIP - bignum2 simplify --- include/cyclone/types.h | 1 + runtime.c | 62 ++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 7fcc6084..ab621028 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -854,6 +854,7 @@ typedef struct { #define C_bignum_digits(n) (&(((bignum2_type *)n)->sign) + 1) #define C_bignum_size(n) (((bignum2_type *)n)->num_digits) #define C_bignum_sign(n) (((bignum2_type *)n)->sign) +#define C_bignum_negativep(n) (((bignum2_type *)n)->sign == 1) // TODO: covert applicable definitions below - // #ifdef C_SIXTY_FOUR diff --git a/runtime.c b/runtime.c index 858d6793..1e752d48 100644 --- a/runtime.c +++ b/runtime.c @@ -2451,37 +2451,37 @@ int bignum2_num_digits(bignum2_type *bn, int radix) * in scratch space, we mark it as reclaimable. This means any * references to the original bignum are invalid after simplification! */ -//C_regparm C_word C_fcall C_bignum_simplify(C_word big) -//{ -// C_uword *start = C_bignum_digits(big), -// *last_digit = start + C_bignum_size(big) - 1, -// *scan = last_digit, tmp; -// int length; -// -// while (scan >= start && *scan == 0) -// scan--; -// length = scan - start + 1; -// -// switch(length) { -// case 0: -// if (C_in_scratchspacep(C_internal_bignum_vector(big))) -// C_mutate_scratch_slot(NULL, C_internal_bignum_vector(big)); -// return C_fix(0); -// case 1: -// tmp = *start; -// if (C_bignum_negativep(big) ? -// !(tmp & C_INT_SIGN_BIT) && C_fitsinfixnump(-(C_word)tmp) : -// C_ufitsinfixnump(tmp)) { -// if (C_in_scratchspacep(C_internal_bignum_vector(big))) -// C_mutate_scratch_slot(NULL, C_internal_bignum_vector(big)); -// return C_bignum_negativep(big) ? C_fix(-(C_word)tmp) : C_fix(tmp); -// } -// /* FALLTHROUGH */ -// default: -// if (scan < last_digit) C_bignum_mutate_size(big, length); -// return big; -// } -//} +object C_bignum_simplify(object big) +{ + uint32_t *start = C_bignum_digits(big), + *last_digit = start + C_bignum_size(big) - 1, + *scan = last_digit, tmp; + int length; + + while (scan >= start && *scan == 0) + scan--; + length = scan - start + 1; + + switch(length) { + case 0: + //if (C_in_scratchspacep(C_internal_bignum_vector(big))) + // C_mutate_scratch_slot(NULL, C_internal_bignum_vector(big)); + return obj_int2obj(0); + case 1: + tmp = *start; + if (C_bignum_negativep(big) ? + !(tmp & C_INT_SIGN_BIT) && C_fitsinfixnump(-(C_word)tmp) : + C_ufitsinfixnump(tmp)) { + if (C_in_scratchspacep(C_internal_bignum_vector(big))) + C_mutate_scratch_slot(NULL, C_internal_bignum_vector(big)); + return C_bignum_negativep(big) ? C_fix(-(C_word)tmp) : C_fix(tmp); + } + /* FALLTHROUGH */ + default: + if (scan < last_digit) C_bignum_mutate_size(big, length); + return big; + } +} static uint32_t bignum_digits_destructive_scale_down(uint32_t *start, uint32_t *end, uint32_t denominator) {