Commit 51136f3e authored by japhie's avatar japhie

- Added possibility of configuring --without-gmp when cross-compiling

  to reduce memory usage when true bignums aren't needed (doesn't work
  for native compilation because compiler needs bignums).
parent 077a4913
......@@ -29,6 +29,10 @@ ECL 0.9h
- The code walker is no longer needed and has been removed from the core.
It will be available in the contributed packages.
- Possibility of configure --without-gmp when cross-compiling (there are no
true bignums then, just long long int if possible; doesn't work with native
compilation because compiler needs true bignums).
* Visible changes:
- The code for handling command line options has been redesigned. Now multiple
......
dnl -*- autoconf -*-
dnl --------------------------------------------------------------
dnl http://autoconf-archive.cryp.to/ac_c_long_long_.html
dnl Provides a test for the existance of the long long int type and defines HAVE_LONG_LONG if it is found.
AC_DEFUN([AC_C_LONG_LONG],
[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
[if test "$GCC" = yes; then
ac_cv_c_long_long=yes
else
AC_TRY_COMPILE(,[long long int i;],
ac_cv_c_long_long=yes,
ac_cv_c_long_long=no)
fi])
if test $ac_cv_c_long_long = yes; then
AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long])
fi
])
dnl --------------------------------------------------------------
dnl Add *feature* for conditional compilation.
AC_DEFUN([ECL_ADD_FEATURE], [
......
......@@ -41,7 +41,7 @@ OBJS = main.o symbol.o package.o list.o\
instance.o gfun.o reference.o character.o\
file.o read.o print.o error.o string.o cfun.o\
typespec.o assignment.o \
predicate.o big.o number.o\
predicate.o number.o\
num_pred.o num_comp.o num_arith.o num_sfun.o num_co.o\
num_log.o num_rand.o array.o sequence.o cmpaux.o\
macros.o backq.o stacks.o \
......
/*
big_ll.c -- Bignum emulation with long long.
*/
/*
Copyright (c) 2005, Maciek Pasternacki.
ECL is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
See file '../Copyright' for full details.
*/
#include "ecl.h"
#include "internal.h"
cl_object
big_register0_get(void)
{
cl_env.big_register[0]->big.big_num = 0ll;
return cl_env.big_register[0];
}
cl_object
big_register1_get(void)
{
cl_env.big_register[1]->big.big_num = 0ll;
return cl_env.big_register[1];
}
cl_object
big_register2_get(void)
{
cl_env.big_register[2]->big.big_num = 0ll;
return cl_env.big_register[2];
}
void
big_register_free(cl_object x) {}
cl_object
big_register_copy(cl_object old)
{
cl_object new_big = cl_alloc_object(t_bignum);
new_big->big.big_num = old->big.big_num;
return new_big;
}
cl_object
big_register_normalize(cl_object x)
{
if (x->big.big_num == 0ll)
return(MAKE_FIXNUM(0));
if (x->big.big_num <= MOST_POSITIVE_FIXNUM && x->big.big_num >= MOST_NEGATIVE_FIXNUM)
return(MAKE_FIXNUM(x->big.big_num));
return big_register_copy(x);
}
static cl_object
big_alloc(int size)
{
volatile cl_object x = cl_alloc_object(t_bignum);
if (size <= 0)
error("negative or zero size for bignum in big_alloc");
x->big.big_num = 0ll;
return x;
}
cl_object
bignum1(cl_fixnum val)
{
volatile cl_object z = cl_alloc_object(t_bignum);
z->big.big_num = val;
return(z);
}
cl_object
bignum2(cl_fixnum hi, cl_fixnum lo)
{
cl_object z;
z = big_alloc(2);
z->big.big_num = hi<<32 + lo;
return(z);
}
cl_object
big_copy(cl_object x)
{
volatile cl_object y = cl_alloc_object(t_bignum);
y->big.big_num = x->big.big_num;
return(y);
}
/*
big_minus(x) returns the complement of bignum x.
*/
cl_object
big_minus(cl_object x)
{
volatile cl_object y = big_copy(x);
y->big.big_num = -x->big.big_num;
return y;
}
cl_object
big_plus(cl_object x, cl_object y)
{
volatile cl_object z = big_register0_get();
z->big.big_num = x->big.big_num + y->big.big_num;
return(big_register_copy(z));
}
cl_object
big_normalize(cl_object x)
{
if (x->big.big_num == 0ll)
return(MAKE_FIXNUM(0));
if (x->big.big_num <= MOST_POSITIVE_FIXNUM && x->big.big_num >= MOST_NEGATIVE_FIXNUM)
return(MAKE_FIXNUM(x->big.big_num));
return(x);
}
int big_num_t_sgn(big_num_t x)
{
return ( x == (big_num_t)0 ) ? 0 : (x < (big_num_t)0) ? -1 : 1;
}
void init_big_registers(void)
{
int i;
for (i = 0; i < 3; i++) {
cl_env.big_register[i] = cl_alloc_object(t_bignum);
cl_env.big_register[i]->big.big_num = 0ll;
}
}
void
init_big(void)
{
init_big_registers();
}
......@@ -133,6 +133,7 @@ BEGIN:
switch (type_of(x)) {
case t_bignum:
#ifdef WITH_GMP
if (collect_blocks) {
/* GMP may set num.alloc before actually allocating anything.
With these checks we make sure we do not move anything
......@@ -143,6 +144,7 @@ BEGIN:
size_t size = x->big.big_dim * sizeof(mp_limb_t);
if (size) mark_contblock(limbs, size);
}
#endif /* WITH_GMP */
break;
case t_ratio:
......
......@@ -129,6 +129,7 @@ BEGIN:
switch (type_of(x)) {
case t_bignum: {
#ifdef WITH_GMP
/* GMP may set num.alloc before actually allocating anything.
With these checks we make sure we do not move anything
we don't have to. Besides, we use big_dim as the size
......@@ -137,6 +138,7 @@ BEGIN:
cl_ptr limbs = (cl_ptr)x->big.big_limbs;
cl_index size = x->big.big_dim * sizeof(mp_limb_t);
if (size) mark_contblock(limbs, size);
#endif /* WITH_GMP */
break;
}
case t_ratio:
......
......@@ -120,8 +120,12 @@ _hash_eql(cl_hashkey h, cl_object x)
BEGIN:
switch (type_of(x)) {
case t_bignum:
#ifdef WITH_GMP
return hash_string(h, (unsigned char*)x->big.big_limbs,
labs(x->big.big_size) * sizeof(mp_limb_t));
#else /* WITH_GMP */
return hash_word(h, (uint32_t)(x->big.big_num));
#endif /* WITH_GMP */
case t_ratio:
h = _hash_eql(h, x->ratio.num);
return _hash_eql(h, x->ratio.den);
......
......@@ -377,16 +377,19 @@ cl_boot(int argc, char **argv)
cl_list(8, @'&optional', @'&rest', @'&key', @'&allow-other-keys',
@'&aux', @'&whole', @'&environment', @'&body'));
features = cl_list(5,
features = cl_list(4,
make_keyword("ECL"),
make_keyword("COMMON"),
make_keyword("ANSI-CL"),
make_keyword("COMMON-LISP"),
make_keyword(ECL_ARCHITECTURE),
make_keyword("FFI"));
#define ADD_FEATURE(name) features = CONS(make_keyword(name),features)
#ifdef WITH_GMP
ADD_FEATURE("COMMON-LISP");
ADD_FEATURE("ANSI-CL");
#endif /* WITH_GMP */
#if defined(GBC_BOEHM)
ADD_FEATURE("BOEHM-GC");
#endif
......
......@@ -32,8 +32,12 @@ fixnum_times(cl_fixnum i, cl_fixnum j)
{
cl_object x = big_register0_get();
#ifdef WITH_GMP
mpz_set_si(x->big.big_num, i);
mpz_mul_si(x->big.big_num, x->big.big_num, (long int)j);
#else /* WITH_GMP */
x->big.big_num = (big_num_t)i * (big_num_t)j;
#endif /* WITH_GMP */
return big_register_normalize(x);
}
......@@ -47,7 +51,11 @@ big_times_fix(cl_object b, cl_fixnum i)
if (i == -1)
return(big_minus(b));
z = big_register0_get();
#ifdef WITH_GMP
mpz_mul_si(z->big.big_num, b->big.big_num, (long int)i);
#else /* WITH_GMP */
z->big.big_num = b->big.big_num * i;
#endif /* WITH_GMP */
z = big_register_normalize(z);
return(z);
}
......@@ -57,7 +65,11 @@ big_times_big(cl_object x, cl_object y)
{
cl_object z;
z = big_register0_get();
#ifdef WITH_GMP
mpz_mul(z->big.big_num, x->big.big_num, y->big.big_num);
#else /* WITH_GMP */
z->big.big_num = x->big.big_num * y->big.big_num;
#endif /* WITH_GMP */
z = big_register_normalize(z);
return(z);
}
......@@ -212,10 +224,14 @@ number_plus(cl_object x, cl_object y)
if ((i = fix(x)) == 0)
return(y);
z = big_register0_get();
#ifdef WITH_GMP
if (i > 0)
mpz_add_ui(z->big.big_num, y->big.big_num, (unsigned long)i);
else
mpz_sub_ui(z->big.big_num, y->big.big_num, (unsigned long)(-i));
#else /* WITH_GMP */
z->big.big_num = y->big.big_num + i;
#endif /* WITH_GMP */
z = big_register_normalize(z);
return(z);
case t_ratio:
......@@ -240,10 +256,14 @@ number_plus(cl_object x, cl_object y)
if ((j = fix(y)) == 0)
return(x);
z = big_register0_get();
#ifdef WITH_GMP
if (j > 0)
mpz_add_ui(z->big.big_num, x->big.big_num, (unsigned long)j);
else
mpz_sub_ui(z->big.big_num, x->big.big_num, (unsigned long)(-j));
#else /* WITH_GMP */
z->big.big_num = x->big.big_num + j;
#endif /* WITH_GMP */
z = big_register_normalize(z);
return(z);
case t_bignum:
......@@ -365,10 +385,14 @@ number_minus(cl_object x, cl_object y)
case t_bignum:
z = big_register0_get();
i = fix(x);
#ifdef WITH_GMP
if (i > 0)
mpz_sub_ui(z->big.big_num, y->big.big_num, (unsigned long)i);
else
mpz_add_ui(z->big.big_num, y->big.big_num, (unsigned long)(-i));
#else /* WITH_GMP */
z->big.big_num = (big_num_t)i - y->big.big_num;
#endif /* WITH_GMP */
big_complement(z);
z = big_register_normalize(z);
return(z);
......@@ -392,10 +416,14 @@ number_minus(cl_object x, cl_object y)
if ((j = fix(y)) == 0)
return(x);
z = big_register0_get();
#ifdef WITH_GMP
if (j > 0)
mpz_sub_ui(z->big.big_num, x->big.big_num, (unsigned long)j);
else
mpz_add_ui(z->big.big_num, x->big.big_num, (unsigned long)(-j));
#else /* WITH_GMP */
z->big.big_num = x->big.big_num - j;
#endif /* WITH_GMP */
z = big_register_normalize(z);
return(z);
case t_bignum:
......@@ -528,7 +556,11 @@ number_negate(cl_object x)
}
case t_bignum:
z = big_register0_get();
#ifdef WITH_GMP
mpz_neg(z->big.big_num, x->big.big_num);
#else /* WITH_GMP */
z->big.big_num = -(x->big.big_num);
#endif /* WITH_GMP */
return big_register_normalize(z);
case t_ratio:
......@@ -703,10 +735,14 @@ integer_divide(cl_object x, cl_object y)
* MOST_NEGATIVE_FIXNUM = - MOST_POSITIVE_FIXNUM.
*/
if (-MOST_NEGATIVE_FIXNUM > MOST_POSITIVE_FIXNUM) {
#ifdef WITH_GMP
if (mpz_cmp_si(y->big.big_num, -fix(x)))
return MAKE_FIXNUM(0);
else
return MAKE_FIXNUM(-1);
#else /* WITH_GMP */
return y->big.big_num != -fix(x) ? MAKE_FIXNUM(0) : MAKE_FIXNUM(-1);
#endif /* WITH_GMP */
} else {
return MAKE_FIXNUM(0);
}
......@@ -716,12 +752,20 @@ integer_divide(cl_object x, cl_object y)
if (tx == t_bignum) {
cl_object q = big_register0_get();
if (ty == t_bignum) {
#ifdef WITH_GMP
mpz_tdiv_q(q->big.big_num, x->big.big_num, y->big.big_num);
#else /* WITH_GMP */
q->big.big_num = x->big.big_num / y->big.big_num;
#endif /* WITH_GMP */
} else if (ty == t_fixnum) {
long j = fix(y);
#ifdef WITH_GMP
mpz_tdiv_q_ui(q->big.big_num, x->big.big_num, (unsigned long)labs(j));
if (j < 0)
mpz_neg(q->big.big_num, q->big.big_num);
#else /* WITH_GMP */
q->big.big_num = x->big.big_num / j;
#endif /* WITH_GMP */
} else {
FEtype_error_integer(y);
}
......@@ -785,7 +829,28 @@ get_gcd(cl_object x, cl_object y)
y = bignum1(fix(y));
case t_bignum:
gcd = big_register0_get();
mpz_gcd(gcd->big.big_num, x->big.big_num, y->big.big_num);
#ifdef WITH_GMP
mpz_gcd(gcd->big.big_num, x->big.big_num, y->big.big_num); /* FIXME!!! */
#else /* WITH_GMP */
{
big_num_t i = x->big.big_num, j = y->big.big_num;
while ( 1 ) {
big_num_t k;
if ( i<j ) {
k = i;
i = j;
j = k;
}
if ( j == 0 ) {
gcd->big.big_num = k;
break;
}
k = i % j;
i = j;
j = k;
}
}
#endif /* WITH_GMP */
gcd = big_register_normalize(gcd);
return(gcd);
default:
......
......@@ -47,7 +47,11 @@ double_to_integer(double d)
return MAKE_FIXNUM((cl_fixnum)d);
else {
cl_object x = big_register0_get();
#ifdef WITH_GMP
mpz_set_d(x->big.big_num, d);
#else /* WITH_GMP */
x->big.big_num = (big_num_t)d;
#endif /* WITH_GMP */
return big_register_copy(x);
}
}
......@@ -59,7 +63,11 @@ float_to_integer(float d)
return MAKE_FIXNUM((cl_fixnum)d);
else {
cl_object x = big_register0_get();
#ifdef WITH_GMP
mpz_set_d(x->big.big_num, d);
#else /* WITH_GMP */
x->big.big_num = (big_num_t)d;
#endif /* WITH_GMP */
return big_register_copy(x);
}
}
......@@ -213,9 +221,14 @@ floor2(cl_object x, cl_object y)
*/
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
cl_object j = big_register2_get();
mpz_set_si(j->big.big_num, fix(x));
mpz_fdiv_qr(q->big.big_num, r->big.big_num, j->big.big_num, y->big.big_num);
#else /* WITH_GMP */
q->big.big_num = (big_num_t)fix(x) / y->big.big_num;
r->big.big_num = (big_num_t)fix(x) % y->big.big_num;
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......@@ -249,9 +262,14 @@ floor2(cl_object x, cl_object y)
case t_fixnum: { /* BIG / FIX */
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
cl_object j = big_register2_get();
mpz_set_si(j->big.big_num, fix(y));
mpz_fdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, j->big.big_num);
#else /* WITH_GMP */
q->big.big_num = x->big.big_num / fix(y);
r->big.big_num = x->big.big_num % fix(y);
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......@@ -259,7 +277,12 @@ floor2(cl_object x, cl_object y)
case t_bignum: { /* BIG / BIG */
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
mpz_fdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, y->big.big_num);
#else /* WITH_GMP */
q = x->big.big_num / y->big.big_num;
r = x->big.big_num % y->big.big_num;
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......@@ -392,9 +415,14 @@ ceiling2(cl_object x, cl_object y)
*/
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
cl_object j = big_register2_get();
mpz_set_si(j->big.big_num, fix(x));
mpz_cdiv_qr(q->big.big_num, r->big.big_num, j->big.big_num, y->big.big_num);
#else /* WITH_GMP */
q = (big_num_t)fix(x) / y->big.big_num;
r = (big_num_t)fix(x) % y->big.big_num;
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......@@ -428,9 +456,14 @@ ceiling2(cl_object x, cl_object y)
case t_fixnum: { /* BIG / FIX */
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
cl_object j = big_register2_get();
mpz_set_si(j->big.big_num, fix(y));
mpz_cdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, j->big.big_num);
#else /* WITH_GMP */
q = x->big.big_num / fix(y);
r = x->big.big_num % fix(y);
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......@@ -438,7 +471,12 @@ ceiling2(cl_object x, cl_object y)
case t_bignum: { /* BIG / BIG */
cl_object q = big_register0_get();
cl_object r = big_register1_get();
#ifdef WITH_GMP
mpz_cdiv_qr(q->big.big_num, r->big.big_num, x->big.big_num, y->big.big_num);
#else /* WITH_GMP */
q->big.big_num = x->big.big_num / y->big.big_num;
r->big.big_num = x->big.big_num % y->big.big_num;
#endif /* WITH_GMP */
VALUES(0) = big_register_normalize(q);
VALUES(1) = big_register_normalize(r);
break;
......
......@@ -31,7 +31,11 @@ ior_op(cl_fixnum i, cl_fixnum j)
static void
mpz_ior_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_ior(i->big.big_num, i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num |= j->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -43,7 +47,11 @@ xor_op(cl_fixnum i, cl_fixnum j)
static void
mpz_xor_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_xor(i->big.big_num, i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num ^= j->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -55,7 +63,11 @@ and_op(cl_fixnum i, cl_fixnum j)
static void
mpz_and_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_and(i->big.big_num, i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num &= j->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -67,8 +79,12 @@ eqv_op(cl_fixnum i, cl_fixnum j)
static void
mpz_eqv_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_xor(i->big.big_num, i->big.big_num, j->big.big_num);
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = ~(i->big.big_num ^ j->big.big_num);
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -80,8 +96,12 @@ nand_op(cl_fixnum i, cl_fixnum j)
static void
mpz_nand_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_and(i->big.big_num, i->big.big_num, j->big.big_num);
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = ~(i->big.big_num & j->big.big_num);
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -93,8 +113,12 @@ nor_op(cl_fixnum i, cl_fixnum j)
static void
mpz_nor_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_ior(i->big.big_num, i->big.big_num, j->big.big_num);
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = ~(i->big.big_num | j->big.big_num);
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -106,8 +130,12 @@ andc1_op(cl_fixnum i, cl_fixnum j)
static void
mpz_andc1_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_com(i->big.big_num, i->big.big_num);
mpz_and(i->big.big_num, i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num = (~i->big.big_num) & (big_num_t)j;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -121,9 +149,13 @@ static void mpz_orc1_op(cl_object, cl_object);
static void
mpz_andc2_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
/* (i & ~j) = ~((~i) | j) */
mpz_orc1_op(i, j);
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = i->big.big_num & (~j->big.big_num);
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -135,8 +167,12 @@ orc1_op(cl_fixnum i, cl_fixnum j)
static void
mpz_orc1_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_com(i->big.big_num, i->big.big_num);
mpz_ior(i->big.big_num, i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num = (~i->big.big_num) | j->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -148,9 +184,13 @@ orc2_op(cl_fixnum i, cl_fixnum j)
static void
mpz_orc2_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
/* (i | ~j) = ~((~i) & j) */
mpz_andc1_op(i, j);
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = i->big.big_num | (~j->big.big_num);
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -162,7 +202,11 @@ b_clr_op(cl_fixnum i, cl_fixnum j)
static void
mpz_b_clr_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_set_si(i->big.big_num, 0);
#else /* WITH_GMP */
i->big.big_num = 0ll;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -174,7 +218,11 @@ b_set_op(cl_fixnum i, cl_fixnum j)
static void
mpz_b_set_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_set_si(i->big.big_num, -1);
#else /* WITH_GMP */
i->big.big_num = -1ll;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -197,7 +245,11 @@ b_2_op(cl_fixnum i, cl_fixnum j)
static void
mpz_b_2_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_set(i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num = j->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -209,7 +261,11 @@ b_c1_op(cl_fixnum i, cl_fixnum j)
static void
mpz_b_c1_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_com(i->big.big_num, i->big.big_num);
#else /* WITH_GMP */
i->big.big_num = ~i->big.big_num;
#endif /* WITH_GMP */
}
static cl_fixnum
......@@ -221,7 +277,11 @@ b_c2_op(cl_fixnum i, cl_fixnum j)
static void
mpz_b_c2_op(cl_object i, cl_object j)
{
#ifdef WITH_GMP
mpz_com(i->big.big_num, j->big.big_num);
#else /* WITH_GMP */
i->big.big_num = ~j->big.big_num;
#endif /* WITH_GMP */
}
typedef cl_fixnum (*bit_operator)(cl_fixnum, cl_fixnum);
......@@ -371,7 +431,11 @@ ecl_boole(int op, cl_object x, cl_object y)
switch (type_of(y)) {
case t_fixnum: {
cl_object z = big_register1_get();
#ifdef WITH_GMP
mpz_set_si(z->big.big_num, fix(y));
#else /* WITH_GMP */
z->big.big_num = fix(y);
#endif /* WITH_GMP */
(*big_log_op)(x, z);
big_register_free(z);
break;
......@@ -410,6 +474,7 @@ count_bits(cl_object x)
break;
}
case t_bignum:
#ifdef WITH_GMP
if (big_sign(x) >= 0)
count = mpz_popcount(x->big.big_num);
else {
......@@ -418,6 +483,15 @@ count_bits(cl_object x)