~ chicken-core (chicken-5) fdae1c59fe2cca92db621daaebe14f4b25dbf29e
commit fdae1c59fe2cca92db621daaebe14f4b25dbf29e Author: Peter Bex <peter@more-magic.net> AuthorDate: Thu Mar 12 22:27:48 2015 +0100 Commit: Peter Bex <peter@more-magic.net> CommitDate: Sun May 31 14:55:23 2015 +0200 Convert dyadic integer plus and integer minus to use scratch space. diff --git a/chicken.h b/chicken.h index 89a34e9a..f0387662 100644 --- a/chicken.h +++ b/chicken.h @@ -1965,11 +1965,9 @@ C_fctexport void C_ccall C_u_2_integer_times(C_word c, C_word self, C_word k, C_ /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */ C_fctexport void C_ccall C_plus(C_word c, C_word closure, C_word k, ...) C_noret; C_fctexport void C_ccall C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; -C_fctexport void C_ccall C_u_2_integer_plus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */ C_fctexport void C_ccall C_minus(C_word c, C_word closure, C_word k, C_word n1, ...) C_noret; C_fctexport void C_ccall C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; -C_fctexport void C_ccall C_u_2_integer_minus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */ C_fctexport void C_ccall C_divide(C_word c, C_word closure, C_word k, C_word n1, ...) C_noret; C_fctexport void C_ccall C_basic_quotient(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; @@ -2192,8 +2190,11 @@ C_fctexport C_word C_fcall C_i_file_exists_p(C_word name, C_word file, C_word di C_fctexport C_word C_fcall C_s_a_i_abs(C_word **ptr, C_word n, C_word x) C_regparm; C_fctexport C_word C_fcall C_s_a_i_negate(C_word **ptr, C_word n, C_word x) C_regparm; C_fctexport C_word C_fcall C_s_a_u_i_integer_negate(C_word **ptr, C_word n, C_word x) C_regparm; +C_fctexport C_word C_fcall C_s_a_u_i_integer_minus(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; +C_fctexport C_word C_fcall C_s_a_u_i_integer_plus(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; C_fctexport C_word C_fcall C_s_a_u_i_integer_gcd(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; + C_fctexport C_word C_fcall C_i_foreign_char_argumentp(C_word x) C_regparm; C_fctexport C_word C_fcall C_i_foreign_fixnum_argumentp(C_word x) C_regparm; C_fctexport C_word C_fcall C_i_foreign_flonum_argumentp(C_word x) C_regparm; diff --git a/library.scm b/library.scm index e7ef8bd6..3c6f756f 100644 --- a/library.scm +++ b/library.scm @@ -1208,7 +1208,9 @@ EOF (##sys#+-2 x (##sys#slot args 0))) ) ) ) ) ) ) (define ##sys#+-2 (##core#primitive "C_2_basic_plus")) -(define ##sys#integer-plus (##core#primitive "C_u_2_integer_plus")) +;; OBSOLETE: Remove this (or change to define-inline) +(define (##sys#integer-plus x y) + (##core#inline_allocate ("C_s_a_u_i_integer_plus" 6) x y)) (define (##sys#extended-plus x y) (cond ((or (cplxnum? x) (cplxnum? y)) @@ -1252,7 +1254,9 @@ EOF (##sys#--2 x (##sys#slot args 0))) ) ) ) ) (define ##sys#--2 (##core#primitive "C_2_basic_minus")) -(define ##sys#integer-minus (##core#primitive "C_u_2_integer_minus")) +;; OBSOLETE: Remove this (or change to define-inline) +(define (##sys#integer-minus x y) + (##core#inline_allocate ("C_s_a_u_i_integer_minus" 6) x y)) (define (##sys#extended-minus x y) (cond ((or (cplxnum? x) (cplxnum? y)) diff --git a/runtime.c b/runtime.c index 63d66f92..5de43743 100644 --- a/runtime.c +++ b/runtime.c @@ -518,10 +518,8 @@ static void bignum_actual_shift(C_word c, C_word self, C_word result) C_noret; static void bignum_times_bignum_unsigned(C_word k, C_word x, C_word y, C_word negp) C_noret; static void bignum_times_bignum_unsigned_2(C_word c, C_word self, C_word result) C_noret; static void integer_times_2(C_word c, C_word self, C_word new_big) C_noret; -static void bignum_plus_unsigned(C_word k, C_word x, C_word y, C_word negp) C_noret; -static void bignum_plus_unsigned_2(C_word c, C_word self, C_word result) C_noret; -static void bignum_minus_unsigned(C_word k, C_word x, C_word y) C_noret; -static void bignum_minus_unsigned_2(C_word c, C_word self, C_word result) C_noret; +static C_word bignum_plus_unsigned(C_word **ptr, C_word x, C_word y, C_word negp); +static C_word bignum_minus_unsigned(C_word **ptr, C_word x, C_word y); static C_regparm void basic_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_r, C_word return_q) C_noret; static C_regparm void integer_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_q, C_word return_r) C_noret; static C_word bignum_remainder_unsigned_halfdigit(C_word num, C_word den); @@ -846,7 +844,7 @@ static C_PTABLE_ENTRY *create_initial_ptable() { /* IMPORTANT: hardcoded table size - this must match the number of C_pte calls + 1 (NULL terminator)! */ - C_PTABLE_ENTRY *pt = (C_PTABLE_ENTRY *)C_malloc(sizeof(C_PTABLE_ENTRY) * 76); + C_PTABLE_ENTRY *pt = (C_PTABLE_ENTRY *)C_malloc(sizeof(C_PTABLE_ENTRY) * 74); int i = 0; if(pt == NULL) @@ -923,8 +921,6 @@ static C_PTABLE_ENTRY *create_initial_ptable() C_pte(C_basic_quotient); C_pte(C_basic_remainder); C_pte(C_basic_divrem); - C_pte(C_u_2_integer_plus); - C_pte(C_u_2_integer_minus); C_pte(C_u_2_integer_times); C_pte(C_u_integer_quotient); C_pte(C_u_integer_remainder); @@ -7549,9 +7545,11 @@ C_regparm C_word C_fcall C_2_times(C_word **ptr, C_word x, C_word y) return C_flonum(ptr, 0.0/0.0); } -static void bignum_plus_unsigned(C_word k, C_word x, C_word y, C_word negp) +static C_word bignum_plus_unsigned(C_word **ptr, C_word x, C_word y, C_word negp) { - C_word kab[C_SIZEOF_CLOSURE(4)], *ka = kab, k2, size; + C_word size, result; + C_uword sum, digit, *scan_y, *end_y, *scan_r, *end_r; + int carry = 0; if (C_bignum_size(y) > C_bignum_size(x)) { /* Ensure size(y) <= size(x) */ C_word z = x; @@ -7559,23 +7557,13 @@ static void bignum_plus_unsigned(C_word k, C_word x, C_word y, C_word negp) y = z; } - k2 = C_closure(&ka, 4, (C_word)bignum_plus_unsigned_2, k, x, y); - size = C_fix(C_bignum_size(x) + 1); /* One more digit, for possible carry. */ - C_allocate_bignum(5, (C_word)NULL, k2, size, negp, C_SCHEME_FALSE); -} + result = C_allocate_scratch_bignum(ptr, size, negp, C_SCHEME_FALSE); -static void bignum_plus_unsigned_2(C_word c, C_word self, C_word result) -{ - C_word k = C_block_item(self, 1), - x = C_block_item(self, 2), - y = C_block_item(self, 3); - C_uword *scan_y = C_bignum_digits(y), - *end_y = scan_y + C_bignum_size(y), - *scan_r = C_bignum_digits(result), - *end_r = scan_r + C_bignum_size(result), - sum, digit; - int carry = 0; + scan_y = C_bignum_digits(y); + end_y = scan_y + C_bignum_size(y); + scan_r = C_bignum_digits(result); + end_r = scan_r + C_bignum_size(result); /* Copy x into r so we can operate on two pointers, which is faster * than three, and we can stop earlier after adding y. It's slower @@ -7605,7 +7593,7 @@ static void bignum_plus_unsigned_2(C_word c, C_word self, C_word result) } assert(scan_r <= end_r); - C_kontinue(k, C_bignum_simplify(result)); + return C_bignum_simplify(result); } void C_ccall @@ -7621,7 +7609,8 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y) C_word *a = C_alloc(C_SIZEOF_FLONUM); C_kontinue(k, C_flonum(&a, (double)C_unfix(x) + C_flonum_magnitude(y))); } else if (C_truep(C_bignump(y))) { - C_u_2_integer_plus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_plus(&a, 2, x, y)); } else { try_extended_number("\003sysextended-plus", 3, k, x, y); } @@ -7642,14 +7631,16 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y) } } else if (C_truep(C_bignump(x))) { if (y & C_FIXNUM_BIT) { - C_u_2_integer_plus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_plus(&a, 2, x, y)); } else if (C_immediatep(y)) { barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y); } else if (C_block_header(y) == C_FLONUM_TAG) { C_word *a = C_alloc(C_SIZEOF_FLONUM); C_kontinue(k, C_flonum(&a, C_bignum_to_double(x)+C_flonum_magnitude(y))); } else if (C_truep(C_bignump(y))) { - C_u_2_integer_plus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_plus(&a, 2, x, y)); } else { try_extended_number("\003sysextended-plus", 3, k, x, y); } @@ -7658,23 +7649,28 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y) } } -void C_ccall -C_u_2_integer_plus(C_word c, C_word self, C_word k, C_word x, C_word y) +C_regparm C_word C_fcall +C_s_a_u_i_integer_plus(C_word **ptr, C_word n, C_word x, C_word y) { if ((x & y) & C_FIXNUM_BIT) { - C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab; - C_kontinue(k, C_a_i_fixnum_plus(&a, 2, x, y)); + return C_a_i_fixnum_plus(ptr, 2, x, y); } else { - C_word ab[C_SIZEOF_FIX_BIGNUM * 2], *a = ab; + C_word ab[C_SIZEOF_FIX_BIGNUM * 2 + C_SIZEOF_BIGNUM_WRAPPER], *a = ab; if (x & C_FIXNUM_BIT) x = C_a_u_i_fix_to_big(&a, x); if (y & C_FIXNUM_BIT) y = C_a_u_i_fix_to_big(&a, y); if (C_bignum_negativep(x)) { - if (C_bignum_negativep(y)) bignum_plus_unsigned(k, x, y, C_SCHEME_TRUE); - else bignum_minus_unsigned(k, y, x); + if (C_bignum_negativep(y)) { + return bignum_plus_unsigned(ptr, x, y, C_SCHEME_TRUE); + } else { + return bignum_minus_unsigned(ptr, y, x); + } } else { - if (C_bignum_negativep(y)) bignum_minus_unsigned(k, x, y); - else bignum_plus_unsigned(k, x, y, C_SCHEME_FALSE); + if (C_bignum_negativep(y)) { + return bignum_minus_unsigned(ptr, x, y); + } else { + return bignum_plus_unsigned(ptr, x, y, C_SCHEME_FALSE); + } } } } @@ -7758,41 +7754,35 @@ C_regparm C_word C_fcall C_2_plus(C_word **ptr, C_word x, C_word y) return C_flonum(ptr, 0.0/0.0); } -static void bignum_minus_unsigned(C_word k, C_word x, C_word y) +static C_word bignum_minus_unsigned(C_word **ptr, C_word x, C_word y) { - C_word kab[C_SIZEOF_CLOSURE(4)], *ka = kab, k2, size; + C_word res, size; + C_uword *scan_r, *end_r, *scan_y, *end_y, difference, digit; + int borrow = 0; switch(bignum_cmp_unsigned(x, y)) { case 0: /* x = y, return 0 */ - C_kontinue(k, C_fix(0)); + return C_fix(0); case -1: /* abs(x) < abs(y), return -(abs(y) - abs(x)) */ - k2 = C_closure(&ka, 4, (C_word)bignum_minus_unsigned_2, k, y, x); - size = C_fix(C_bignum_size(y)); /* Maximum size of result is length of y. */ - C_allocate_bignum(5, (C_word)NULL, k2, size, C_SCHEME_TRUE, C_SCHEME_FALSE); + res = C_allocate_scratch_bignum(ptr, size, C_SCHEME_TRUE, C_SCHEME_FALSE); + size = y; + y = x; + x = size; + break; case 1: /* abs(x) > abs(y), return abs(x) - abs(y) */ default: - k2 = C_closure(&ka, 4, (C_word)bignum_minus_unsigned_2, k, x, y); - size = C_fix(C_bignum_size(x)); /* Maximum size of result is length of x. */ - C_allocate_bignum(5, (C_word)NULL, k2, size, C_SCHEME_FALSE, C_SCHEME_FALSE); + res = C_allocate_scratch_bignum(ptr, size, C_SCHEME_FALSE, C_SCHEME_FALSE); break; } -} -static void bignum_minus_unsigned_2(C_word c, C_word self, C_word result) -{ - C_word k = C_block_item(self, 1), - x = C_block_item(self, 2), - y = C_block_item(self, 3); - C_uword *scan_r = C_bignum_digits(result), - *end_r = scan_r + C_bignum_size(result), - *scan_y = C_bignum_digits(y), - *end_y = scan_y + C_bignum_size(y), - difference, digit; - int borrow = 0; + scan_r = C_bignum_digits(res); + end_r = scan_r + C_bignum_size(res); + scan_y = C_bignum_digits(y); + end_y = scan_y + C_bignum_size(y); - bignum_digits_destructive_copy(result, x); /* See bignum_plus_unsigned_2 */ + bignum_digits_destructive_copy(res, x); /* See bignum_plus_unsigned */ /* Destructively subtract y's digits w/ borrow from and back into r. */ while (scan_y < end_y) { @@ -7817,7 +7807,7 @@ static void bignum_minus_unsigned_2(C_word c, C_word self, C_word result) assert(scan_r <= end_r); - C_kontinue(k, C_bignum_simplify(result)); + return C_bignum_simplify(res); } void C_ccall @@ -7833,7 +7823,8 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y) C_word *a = C_alloc(C_SIZEOF_FLONUM); C_kontinue(k, C_flonum(&a, (double)C_unfix(x) - C_flonum_magnitude(y))); } else if (C_truep(C_bignump(y))) { - C_u_2_integer_minus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_minus(&a, 2, x, y)); } else { try_extended_number("\003sysextended-minus", 3, k, x, y); } @@ -7854,14 +7845,16 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y) } } else if (C_truep(C_bignump(x))) { if (y & C_FIXNUM_BIT) { - C_u_2_integer_minus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_minus(&a, 2, x, y)); } else if (C_immediatep(y)) { barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y); } else if (C_block_header(y) == C_FLONUM_TAG) { C_word *a = C_alloc(C_SIZEOF_FLONUM); C_kontinue(k, C_flonum(&a, C_bignum_to_double(x)-C_flonum_magnitude(y))); } else if (C_truep(C_bignump(y))) { - C_u_2_integer_minus(4, (C_word)NULL, k, x, y); + C_word ab[C_SIZEOF_BIGNUM_WRAPPER], *a = ab; + C_kontinue(k, C_s_a_u_i_integer_minus(&a, 2, x, y)); } else { try_extended_number("\003sysextended-minus", 3, k, x, y); } @@ -7870,23 +7863,28 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y) } } -void C_ccall -C_u_2_integer_minus(C_word c, C_word self, C_word k, C_word x, C_word y) +C_regparm C_word C_fcall +C_s_a_u_i_integer_minus(C_word **ptr, C_word n, C_word x, C_word y) { if ((x & y) & C_FIXNUM_BIT) { - C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab; - C_kontinue(k, C_a_i_fixnum_difference(&a, 2, x, y)); + return C_a_i_fixnum_difference(ptr, 2, x, y); } else { - C_word ab[C_SIZEOF_FIX_BIGNUM * 2], *a = ab; + C_word ab[C_SIZEOF_FIX_BIGNUM * 2 + C_SIZEOF_BIGNUM_WRAPPER], *a = ab; if (x & C_FIXNUM_BIT) x = C_a_u_i_fix_to_big(&a, x); if (y & C_FIXNUM_BIT) y = C_a_u_i_fix_to_big(&a, y); if (C_bignum_negativep(x)) { - if (C_bignum_negativep(y)) bignum_minus_unsigned(k, y, x); - else bignum_plus_unsigned(k, x, y, C_SCHEME_TRUE); + if (C_bignum_negativep(y)) { + return bignum_minus_unsigned(ptr, y, x); + } else { + return bignum_plus_unsigned(ptr, x, y, C_SCHEME_TRUE); + } } else { - if (C_bignum_negativep(y)) bignum_plus_unsigned(k, x, y, C_SCHEME_FALSE); - else bignum_minus_unsigned(k, x, y); + if (C_bignum_negativep(y)) { + return bignum_plus_unsigned(ptr, x, y, C_SCHEME_FALSE); + } else { + return bignum_minus_unsigned(ptr, x, y); + } } } } diff --git a/types.db b/types.db index ca8ca2ca..dbe39e66 100644 --- a/types.db +++ b/types.db @@ -319,7 +319,7 @@ ((fixnum fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_plus" 6) #(1) #(2))) ((integer integer) (integer) - (##sys#integer-plus #(1) #(2))) + (##core#inline_allocate ("C_s_a_u_i_integer_plus" 6) #(1) #(2))) ((* *) (number) (##sys#+-2 #(1) #(2)))) @@ -344,7 +344,7 @@ ((fixnum fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_difference" 6) #(1) #(2))) ((integer integer) (integer) - (##sys#integer-minus #(1) #(2))) + (##core#inline_allocate ("C_s_a_u_i_integer_minus" 6) #(1) #(2))) ((* *) (number) (##sys#--2 #(1) #(2))))Trap