From 552b9ecd81215100934802895d7423386c33598f Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Mon, 17 Aug 2009 21:37:07 +0100 Subject: [PATCH] Dev checkpoint --- vm/math.cpp | 212 ++++++++++++++++++++++++++++++++++++++++++++-------- vm/vm.hpp | 32 ++++++++ 2 files changed, 213 insertions(+), 31 deletions(-) mode change 100644 => 100755 vm/math.cpp diff --git a/vm/math.cpp b/vm/math.cpp old mode 100644 new mode 100755 index b16557b8b7..30b32de7ed --- a/vm/math.cpp +++ b/vm/math.cpp @@ -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(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(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(float_to_bignum(dpeek()))); } +PRIMITIVE(float_to_bignum) +{ + PRIMITIVE_GETVM()->vmprim_float_to_bignum(); +} + #define POP_BIGNUMS(x,y) \ bignum * y = untag(dpop()); \ bignum * x = untag(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_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_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_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_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(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_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_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_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_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(dpop()); dpush(tag(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_bitwise_not(untag(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(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_integer_length(untag(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(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(result)); } +PRIMITIVE(byte_array_to_bignum) +{ + PRIMITIVE_GETVM()->vmprim_byte_array_to_bignum(); +} + cell unbox_array_size() { switch(tagged(dpeek()).type()) diff --git a/vm/vm.hpp b/vm/vm.hpp index c1dc417f83..3521978cae 100644 --- a/vm/vm.hpp +++ b/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: