fix AMD64 %fixnum* overflow

cvs
Slava Pestov 2005-12-11 03:48:09 +00:00
parent 4cbf30669d
commit b0cfcca990
6 changed files with 30 additions and 8 deletions

View File

@ -5,6 +5,14 @@ USING: arrays hashtables kernel lists math namespaces sequences ;
! Optimizations performed here:
! - combining %inc-d/%inc-r within a single basic block
! - if a literal is loaded into a vreg but the vreg is
! overwritten before being read, the literal load is deleted
! - if a %replace is writing a vreg to a stack location already
! holding that vreg, or a stack location that is not read
! before being popped, the %replace is deleted
! - if a %peek is reading a stack location into a vreg that
! already holds that vreg, or if the vreg is overwritten
! before being read, the %peek is deleted
! - removing dead loads of stack locations into vregs
! - removing dead stores of vregs into stack locations

View File

@ -36,7 +36,7 @@ M: %fixnum* generate-node ( vop -- )
"end" get BNO
>3-vop< MULHW
4 0 scratch MR
"s48_long_long_to_bignum" f compile-c-call
"s48_long_pair_to_bignum" f compile-c-call
! now we have to shift it by three bits to remove the second
! tag
tag-bits neg 4 LI

View File

@ -44,7 +44,7 @@ M: %fixnum* generate-node ( vop -- )
0 input-operand IMUL
<label> "end" set
"end" get JNO
"s48_long_long_to_bignum" f
"s48_long_pair_to_bignum" f
1 input-operand remainder-reg 2array compile-c-call*
! now we have to shift it by three bits to remove the second
! tag

View File

@ -194,6 +194,12 @@ cell 8 = [
[ t ] [ 1 59 fixnum-shift dup [ fixnum+ ] compile-1 1 60 fixnum-shift = ] unit-test
[ -1152921504606846977 ] [ 1 60 shift neg >fixnum [ -1 fixnum+ ] compile-1 ] unit-test
[ t ] [ 1 40 shift 1 40 shift [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ t ] [ 1 40 shift neg 1 40 shift [ fixnum* ] compile-1 1 80 shift neg = ] unit-test
[ t ] [ 1 40 shift neg 1 40 shift neg [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ t ] [ 1 30 shift neg 1 50 shift neg [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ t ] [ 1 50 shift neg 1 30 shift neg [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ 18446744073709551616 ] [ 1 64 [ fixnum-shift ] compile-1 ] unit-test
[ 18446744073709551616 ] [ 1 [ 64 fixnum-shift ] compile-1 ] unit-test
[ 18446744073709551616 ] [ 1 [ 32 fixnum-shift 32 fixnum-shift ] compile-1 ] unit-test
@ -201,10 +207,6 @@ cell 8 = [
[ -18446744073709551616 ] [ -1 [ 64 fixnum-shift ] compile-1 ] unit-test
[ -18446744073709551616 ] [ -1 [ 32 fixnum-shift 32 fixnum-shift ] compile-1 ] unit-test
[ t ] [ 1 40 shift 1 40 shift [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ t ] [ 1 40 shift neg 1 40 shift [ fixnum* ] compile-1 1 80 shift neg = ] unit-test
[ t ] [ 1 40 shift neg 1 40 shift neg [ fixnum* ] compile-1 1 80 shift = ] unit-test
[ 1152921504606846976 ] [ -1152921504606846976 >fixnum -1 [ fixnum/i ] compile-1 ] unit-test
[ 1152921504606846976 0 ] [ -1152921504606846976 >fixnum -1 [ fixnum/mod ] compile-1 ] unit-test

View File

@ -381,6 +381,17 @@ FOO_TO_BIGNUM(ulong,unsigned long,unsigned long)
FOO_TO_BIGNUM(long_long,s64,u64)
FOO_TO_BIGNUM(ulong_long,u64,u64)
/* this is inefficient; its only used for fixnum multiplication overflow so
it probaly does not matter */
bignum_type s48_long_pair_to_bignum(unsigned long x, long y)
{
return s48_bignum_add(
s48_bignum_arithmetic_shift(
s48_long_to_bignum(y),
sizeof(unsigned long) * 8),
s48_ulong_to_bignum(x));
}
#define BIGNUM_TO_FOO(name,type,utype) \
type s48_bignum_to_##name(bignum_type bignum) \
{ \
@ -941,7 +952,7 @@ bignum_divide_unsigned_normalized(bignum_type u, bignum_type v, bignum_type q)
bignum_digit_type * u_scan_start = (u_scan - v_length);
bignum_digit_type * v_start = (BIGNUM_START_PTR (v));
bignum_digit_type * v_end = (v_start + v_length);
bignum_digit_type * q_scan;
bignum_digit_type * q_scan = NULL;
bignum_digit_type v1 = (v_end[-1]);
bignum_digit_type v2 = (v_end[-2]);
bignum_digit_type ph; /* high half of double-digit product */
@ -1615,7 +1626,7 @@ s48_bignum_bitwise_xor(bignum_type arg1, bignum_type arg2)
bignum_type
bignum_magnitude_ash(bignum_type arg1, long n)
{
bignum_type result;
bignum_type result = NULL;
bignum_digit_type *scan1;
bignum_digit_type *scanr;
bignum_digit_type *end;

View File

@ -69,6 +69,7 @@ DLLEXPORT bignum_type s48_long_to_bignum(long);
DLLEXPORT bignum_type s48_long_long_to_bignum(s64 n);
DLLEXPORT bignum_type s48_ulong_long_to_bignum(u64 n);
DLLEXPORT bignum_type s48_ulong_to_bignum(unsigned long);
DLLEXPORT bignum_type s48_long_pair_to_bignum(unsigned long x, long y);
long s48_bignum_to_long(bignum_type);
unsigned long s48_bignum_to_ulong(bignum_type);
s64 s48_bignum_to_long_long(bignum_type);