Dev checkpoint
parent
4f4c53c822
commit
552b9ecd81
|
@ -7,19 +7,29 @@ cell bignum_zero;
|
|||
cell bignum_pos_one;
|
||||
cell bignum_neg_one;
|
||||
|
||||
PRIMITIVE(bignum_to_fixnum)
|
||||
inline void factorvm::vmprim_bignum_to_fixnum()
|
||||
{
|
||||
drepl(tag_fixnum(bignum_to_fixnum(untag<bignum>(dpeek()))));
|
||||
}
|
||||
|
||||
PRIMITIVE(float_to_fixnum)
|
||||
PRIMITIVE(bignum_to_fixnum)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_to_fixnum();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_float_to_fixnum()
|
||||
{
|
||||
drepl(tag_fixnum(float_to_fixnum(dpeek())));
|
||||
}
|
||||
|
||||
PRIMITIVE(float_to_fixnum)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_float_to_fixnum();
|
||||
}
|
||||
|
||||
/* Division can only overflow when we are dividing the most negative fixnum
|
||||
by -1. */
|
||||
PRIMITIVE(fixnum_divint)
|
||||
inline void factorvm::vmprim_fixnum_divint()
|
||||
{
|
||||
fixnum y = untag_fixnum(dpop()); \
|
||||
fixnum x = untag_fixnum(dpeek());
|
||||
|
@ -30,7 +40,12 @@ PRIMITIVE(fixnum_divint)
|
|||
drepl(tag_fixnum(result));
|
||||
}
|
||||
|
||||
PRIMITIVE(fixnum_divmod)
|
||||
PRIMITIVE(fixnum_divint)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_fixnum_divint();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_fixnum_divmod()
|
||||
{
|
||||
cell y = ((cell *)ds)[0];
|
||||
cell x = ((cell *)ds)[-1];
|
||||
|
@ -46,26 +61,46 @@ PRIMITIVE(fixnum_divmod)
|
|||
}
|
||||
}
|
||||
|
||||
PRIMITIVE(fixnum_divmod)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_fixnum_divmod();
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're shifting right by n bits, we won't overflow as long as none of the
|
||||
* high WORD_SIZE-TAG_BITS-n bits are set.
|
||||
*/
|
||||
static inline fixnum sign_mask(fixnum x)
|
||||
inline fixnum factorvm::sign_mask(fixnum x)
|
||||
{
|
||||
return x >> (WORD_SIZE - 1);
|
||||
}
|
||||
|
||||
static inline fixnum branchless_max(fixnum x, fixnum y)
|
||||
inline fixnum sign_mask(fixnum x)
|
||||
{
|
||||
return vm->sign_mask(x);
|
||||
}
|
||||
|
||||
inline fixnum factorvm::branchless_max(fixnum x, fixnum y)
|
||||
{
|
||||
return (x - ((x - y) & sign_mask(x - y)));
|
||||
}
|
||||
|
||||
static inline fixnum branchless_abs(fixnum x)
|
||||
inline fixnum branchless_max(fixnum x, fixnum y)
|
||||
{
|
||||
return vm->branchless_max(x,y);
|
||||
}
|
||||
|
||||
inline fixnum factorvm::branchless_abs(fixnum x)
|
||||
{
|
||||
return (x ^ sign_mask(x)) - sign_mask(x);
|
||||
}
|
||||
|
||||
PRIMITIVE(fixnum_shift)
|
||||
inline fixnum branchless_abs(fixnum x)
|
||||
{
|
||||
return vm->branchless_abs(x);
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_fixnum_shift()
|
||||
{
|
||||
fixnum y = untag_fixnum(dpop());
|
||||
fixnum x = untag_fixnum(dpeek());
|
||||
|
@ -92,51 +127,91 @@ PRIMITIVE(fixnum_shift)
|
|||
fixnum_to_bignum(x),y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(fixnum_to_bignum)
|
||||
PRIMITIVE(fixnum_shift)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_fixnum_shift();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_fixnum_to_bignum()
|
||||
{
|
||||
drepl(tag<bignum>(fixnum_to_bignum(untag_fixnum(dpeek()))));
|
||||
}
|
||||
|
||||
PRIMITIVE(float_to_bignum)
|
||||
PRIMITIVE(fixnum_to_bignum)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_fixnum_to_bignum();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_float_to_bignum()
|
||||
{
|
||||
drepl(tag<bignum>(float_to_bignum(dpeek())));
|
||||
}
|
||||
|
||||
PRIMITIVE(float_to_bignum)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_float_to_bignum();
|
||||
}
|
||||
|
||||
#define POP_BIGNUMS(x,y) \
|
||||
bignum * y = untag<bignum>(dpop()); \
|
||||
bignum * x = untag<bignum>(dpop());
|
||||
|
||||
PRIMITIVE(bignum_eq)
|
||||
inline void factorvm::vmprim_bignum_eq()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
box_boolean(bignum_equal_p(x,y));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_add)
|
||||
PRIMITIVE(bignum_eq)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_eq();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_add()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_add(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_subtract)
|
||||
PRIMITIVE(bignum_add)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_add();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_subtract()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_subtract(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_multiply)
|
||||
PRIMITIVE(bignum_subtract)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_subtract();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_multiply()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_multiply(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_divint)
|
||||
PRIMITIVE(bignum_multiply)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_multiply();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_divint()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_quotient(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_divmod)
|
||||
PRIMITIVE(bignum_divint)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_divint();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_divmod()
|
||||
{
|
||||
bignum *q, *r;
|
||||
POP_BIGNUMS(x,y);
|
||||
|
@ -145,91 +220,166 @@ PRIMITIVE(bignum_divmod)
|
|||
dpush(tag<bignum>(r));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_mod)
|
||||
PRIMITIVE(bignum_divmod)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_divmod();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_mod()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_remainder(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_and)
|
||||
PRIMITIVE(bignum_mod)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_mod();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_and()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_bitwise_and(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_or)
|
||||
PRIMITIVE(bignum_and)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_and();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_or()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_bitwise_ior(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_xor)
|
||||
PRIMITIVE(bignum_or)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_or();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_xor()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
dpush(tag<bignum>(bignum_bitwise_xor(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_shift)
|
||||
PRIMITIVE(bignum_xor)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_xor();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_shift()
|
||||
{
|
||||
fixnum y = untag_fixnum(dpop());
|
||||
bignum* x = untag<bignum>(dpop());
|
||||
dpush(tag<bignum>(bignum_arithmetic_shift(x,y)));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_less)
|
||||
PRIMITIVE(bignum_shift)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_shift();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_less()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
box_boolean(bignum_compare(x,y) == bignum_comparison_less);
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_lesseq)
|
||||
PRIMITIVE(bignum_less)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_less();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_lesseq()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
box_boolean(bignum_compare(x,y) != bignum_comparison_greater);
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_greater)
|
||||
PRIMITIVE(bignum_lesseq)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_lesseq();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_greater()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
box_boolean(bignum_compare(x,y) == bignum_comparison_greater);
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_greatereq)
|
||||
PRIMITIVE(bignum_greater)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_greater();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_greatereq()
|
||||
{
|
||||
POP_BIGNUMS(x,y);
|
||||
box_boolean(bignum_compare(x,y) != bignum_comparison_less);
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_not)
|
||||
PRIMITIVE(bignum_greatereq)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_greatereq();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_not()
|
||||
{
|
||||
drepl(tag<bignum>(bignum_bitwise_not(untag<bignum>(dpeek()))));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_bitp)
|
||||
PRIMITIVE(bignum_not)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_not();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_bitp()
|
||||
{
|
||||
fixnum bit = to_fixnum(dpop());
|
||||
bignum *x = untag<bignum>(dpop());
|
||||
box_boolean(bignum_logbitp(bit,x));
|
||||
}
|
||||
|
||||
PRIMITIVE(bignum_log2)
|
||||
PRIMITIVE(bignum_bitp)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_bitp();
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_bignum_log2()
|
||||
{
|
||||
drepl(tag<bignum>(bignum_integer_length(untag<bignum>(dpeek()))));
|
||||
}
|
||||
|
||||
unsigned int bignum_producer(unsigned int digit)
|
||||
PRIMITIVE(bignum_log2)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_bignum_log2();
|
||||
}
|
||||
|
||||
unsigned int factorvm::bignum_producer(unsigned int digit)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char *)alien_offset(dpeek());
|
||||
return *(ptr + digit);
|
||||
}
|
||||
|
||||
PRIMITIVE(byte_array_to_bignum)
|
||||
unsigned int bignum_producer(unsigned int digit)
|
||||
{
|
||||
return vm->bignum_producer(digit);
|
||||
}
|
||||
|
||||
inline void factorvm::vmprim_byte_array_to_bignum()
|
||||
{
|
||||
cell n_digits = array_capacity(untag_check<byte_array>(dpeek()));
|
||||
bignum * result = digit_stream_to_bignum(n_digits,bignum_producer,0x100,0);
|
||||
bignum * result = factor::digit_stream_to_bignum(n_digits,factor::bignum_producer,0x100,0);
|
||||
drepl(tag<bignum>(result));
|
||||
}
|
||||
|
||||
PRIMITIVE(byte_array_to_bignum)
|
||||
{
|
||||
PRIMITIVE_GETVM()->vmprim_byte_array_to_bignum();
|
||||
}
|
||||
|
||||
cell unbox_array_size()
|
||||
{
|
||||
switch(tagged<object>(dpeek()).type())
|
||||
|
|
32
vm/vm.hpp
32
vm/vm.hpp
|
@ -244,6 +244,38 @@ struct factorvm {
|
|||
void update_word_xt(cell w_);
|
||||
inline void vmprim_optimized_p();
|
||||
inline void vmprim_wrapper();
|
||||
|
||||
//math
|
||||
inline void vmprim_bignum_to_fixnum();
|
||||
inline void vmprim_float_to_fixnum();
|
||||
inline void vmprim_fixnum_divint();
|
||||
inline void vmprim_fixnum_divmod();
|
||||
inline fixnum sign_mask(fixnum x);
|
||||
inline fixnum branchless_max(fixnum x, fixnum y);
|
||||
inline fixnum branchless_abs(fixnum x);
|
||||
inline void vmprim_fixnum_shift();
|
||||
inline void vmprim_fixnum_to_bignum();
|
||||
inline void vmprim_float_to_bignum();
|
||||
inline void vmprim_bignum_eq();
|
||||
inline void vmprim_bignum_add();
|
||||
inline void vmprim_bignum_subtract();
|
||||
inline void vmprim_bignum_multiply();
|
||||
inline void vmprim_bignum_divint();
|
||||
inline void vmprim_bignum_divmod();
|
||||
inline void vmprim_bignum_mod();
|
||||
inline void vmprim_bignum_and();
|
||||
inline void vmprim_bignum_or();
|
||||
inline void vmprim_bignum_xor();
|
||||
inline void vmprim_bignum_shift();
|
||||
inline void vmprim_bignum_less();
|
||||
inline void vmprim_bignum_lesseq();
|
||||
inline void vmprim_bignum_greater();
|
||||
inline void vmprim_bignum_greatereq();
|
||||
inline void vmprim_bignum_not();
|
||||
inline void vmprim_bignum_bitp();
|
||||
inline void vmprim_bignum_log2();
|
||||
unsigned int bignum_producer(unsigned int digit);
|
||||
inline void vmprim_byte_array_to_bignum();
|
||||
// next method here:
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue