2004-07-28 19:02:24 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
FIXNUM to_fixnum(CELL tagged)
|
|
|
|
{
|
|
|
|
switch(type_of(tagged))
|
|
|
|
{
|
|
|
|
case FIXNUM_TYPE:
|
|
|
|
return untag_fixnum_fast(tagged);
|
|
|
|
case BIGNUM_TYPE:
|
|
|
|
return bignum_to_fixnum(tagged);
|
|
|
|
default:
|
|
|
|
type_error(FIXNUM_TYPE,tagged);
|
|
|
|
return -1; /* can't happen */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-28 19:02:24 -04:00
|
|
|
/* ADDITION */
|
|
|
|
INLINE void add_fixnum(CELL x, CELL y)
|
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
CELL_TO_INTEGER(untag_fixnum_fast(x) + untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void add_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
+ ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(add)
|
|
|
|
|
|
|
|
/* SUBTRACTION */
|
|
|
|
INLINE void subtract_fixnum(CELL x, CELL y)
|
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
CELL_TO_INTEGER(untag_fixnum_fast(x) - untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void subtract_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
- ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(subtract)
|
|
|
|
|
|
|
|
/* MULTIPLICATION */
|
|
|
|
INLINE void multiply_fixnum(CELL x, CELL y)
|
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
* (BIGNUM_2)untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void multiply_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
* ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(multiply)
|
|
|
|
|
|
|
|
/* DIVMOD */
|
|
|
|
INLINE void divmod_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
ldiv_t q = ldiv(x,y);
|
|
|
|
/* division takes common factor of 8 out. */
|
|
|
|
dpush(tag_fixnum(q.quot));
|
|
|
|
env.dt = q.rem;
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void divmod_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
dpush(tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
/ ((BIGNUM*)UNTAG(y))->n)));
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
% ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(divmod)
|
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
/* MOD */
|
|
|
|
INLINE void mod_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = x % y;
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void mod_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
% ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(mod)
|
|
|
|
|
|
|
|
/* AND */
|
|
|
|
INLINE void and_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = x & y;
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void and_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
& ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(and)
|
|
|
|
|
|
|
|
/* OR */
|
|
|
|
INLINE void or_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = x | y;
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void or_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
| ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(or)
|
|
|
|
|
|
|
|
/* XOR */
|
|
|
|
INLINE void xor_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = x ^ y;
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void xor_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
^ ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(xor)
|
|
|
|
|
|
|
|
/* SHIFTLEFT */
|
|
|
|
INLINE void shiftleft_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
<< (BIGNUM_2)untag_fixnum_fast(y));
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void shiftleft_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
<< ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(shiftleft)
|
|
|
|
|
|
|
|
/* SHIFTRIGHT */
|
|
|
|
INLINE void shiftright_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
>> (BIGNUM_2)untag_fixnum_fast(y));
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void shiftright_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
>> ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(shiftright)
|
|
|
|
|
2004-07-28 19:02:24 -04:00
|
|
|
/* LESS */
|
|
|
|
INLINE void less_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = tag_boolean((FIXNUM)x < (FIXNUM)y);
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void less_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_boolean(((BIGNUM*)UNTAG(x))->n
|
|
|
|
< ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(less)
|
|
|
|
|
|
|
|
/* LESSEQ */
|
|
|
|
INLINE void lesseq_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = tag_boolean((FIXNUM)x <= (FIXNUM)y);
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void lesseq_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_boolean(((BIGNUM*)UNTAG(x))->n
|
|
|
|
<= ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(lesseq)
|
|
|
|
|
|
|
|
/* GREATER */
|
|
|
|
INLINE void greater_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = tag_boolean((FIXNUM)x > (FIXNUM)y);
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void greater_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_boolean(((BIGNUM*)UNTAG(x))->n
|
|
|
|
> ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(greater)
|
|
|
|
|
|
|
|
/* GREATEREQ */
|
|
|
|
INLINE void greatereq_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
env.dt = tag_boolean((FIXNUM)x >= (FIXNUM)y);
|
|
|
|
}
|
|
|
|
|
2004-08-01 19:26:43 -04:00
|
|
|
void greatereq_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
env.dt = tag_boolean(((BIGNUM*)UNTAG(x))->n
|
|
|
|
>= ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(greatereq)
|