factor/native/arithmetic.c

220 lines
3.8 KiB
C
Raw Normal View History

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)