fix AMD64 %fixnum* overflow
parent
4cbf30669d
commit
b0cfcca990
|
@ -5,6 +5,14 @@ USING: arrays hashtables kernel lists math namespaces sequences ;
|
||||||
|
|
||||||
! Optimizations performed here:
|
! Optimizations performed here:
|
||||||
! - combining %inc-d/%inc-r within a single basic block
|
! - 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 loads of stack locations into vregs
|
||||||
! - removing dead stores of vregs into stack locations
|
! - removing dead stores of vregs into stack locations
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ M: %fixnum* generate-node ( vop -- )
|
||||||
"end" get BNO
|
"end" get BNO
|
||||||
>3-vop< MULHW
|
>3-vop< MULHW
|
||||||
4 0 scratch MR
|
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
|
! now we have to shift it by three bits to remove the second
|
||||||
! tag
|
! tag
|
||||||
tag-bits neg 4 LI
|
tag-bits neg 4 LI
|
||||||
|
|
|
@ -44,7 +44,7 @@ M: %fixnum* generate-node ( vop -- )
|
||||||
0 input-operand IMUL
|
0 input-operand IMUL
|
||||||
<label> "end" set
|
<label> "end" set
|
||||||
"end" get JNO
|
"end" get JNO
|
||||||
"s48_long_long_to_bignum" f
|
"s48_long_pair_to_bignum" f
|
||||||
1 input-operand remainder-reg 2array compile-c-call*
|
1 input-operand remainder-reg 2array compile-c-call*
|
||||||
! now we have to shift it by three bits to remove the second
|
! now we have to shift it by three bits to remove the second
|
||||||
! tag
|
! tag
|
||||||
|
|
|
@ -194,6 +194,12 @@ cell 8 = [
|
||||||
[ t ] [ 1 59 fixnum-shift dup [ fixnum+ ] compile-1 1 60 fixnum-shift = ] unit-test
|
[ 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
|
[ -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 [ 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
|
[ 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 [ 64 fixnum-shift ] compile-1 ] unit-test
|
||||||
[ -18446744073709551616 ] [ -1 [ 32 fixnum-shift 32 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 ] [ -1152921504606846976 >fixnum -1 [ fixnum/i ] compile-1 ] unit-test
|
||||||
|
|
||||||
[ 1152921504606846976 0 ] [ -1152921504606846976 >fixnum -1 [ fixnum/mod ] compile-1 ] unit-test
|
[ 1152921504606846976 0 ] [ -1152921504606846976 >fixnum -1 [ fixnum/mod ] compile-1 ] unit-test
|
||||||
|
|
|
@ -381,6 +381,17 @@ FOO_TO_BIGNUM(ulong,unsigned long,unsigned long)
|
||||||
FOO_TO_BIGNUM(long_long,s64,u64)
|
FOO_TO_BIGNUM(long_long,s64,u64)
|
||||||
FOO_TO_BIGNUM(ulong_long,u64,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) \
|
#define BIGNUM_TO_FOO(name,type,utype) \
|
||||||
type s48_bignum_to_##name(bignum_type bignum) \
|
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 * u_scan_start = (u_scan - v_length);
|
||||||
bignum_digit_type * v_start = (BIGNUM_START_PTR (v));
|
bignum_digit_type * v_start = (BIGNUM_START_PTR (v));
|
||||||
bignum_digit_type * v_end = (v_start + v_length);
|
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 v1 = (v_end[-1]);
|
||||||
bignum_digit_type v2 = (v_end[-2]);
|
bignum_digit_type v2 = (v_end[-2]);
|
||||||
bignum_digit_type ph; /* high half of double-digit product */
|
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_type
|
||||||
bignum_magnitude_ash(bignum_type arg1, long n)
|
bignum_magnitude_ash(bignum_type arg1, long n)
|
||||||
{
|
{
|
||||||
bignum_type result;
|
bignum_type result = NULL;
|
||||||
bignum_digit_type *scan1;
|
bignum_digit_type *scan1;
|
||||||
bignum_digit_type *scanr;
|
bignum_digit_type *scanr;
|
||||||
bignum_digit_type *end;
|
bignum_digit_type *end;
|
||||||
|
|
|
@ -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_long_long_to_bignum(s64 n);
|
||||||
DLLEXPORT bignum_type s48_ulong_long_to_bignum(u64 n);
|
DLLEXPORT bignum_type s48_ulong_long_to_bignum(u64 n);
|
||||||
DLLEXPORT bignum_type s48_ulong_to_bignum(unsigned long);
|
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);
|
long s48_bignum_to_long(bignum_type);
|
||||||
unsigned long s48_bignum_to_ulong(bignum_type);
|
unsigned long s48_bignum_to_ulong(bignum_type);
|
||||||
s64 s48_bignum_to_long_long(bignum_type);
|
s64 s48_bignum_to_long_long(bignum_type);
|
||||||
|
|
Loading…
Reference in New Issue