moved math functions to vm

db4
Phil Dawes 2009-08-17 21:37:07 +01:00
parent 552b9ecd81
commit 10e5dc9b3c
2 changed files with 279 additions and 37 deletions

View File

@ -380,7 +380,7 @@ PRIMITIVE(byte_array_to_bignum)
PRIMITIVE_GETVM()->vmprim_byte_array_to_bignum(); PRIMITIVE_GETVM()->vmprim_byte_array_to_bignum();
} }
cell unbox_array_size() cell factorvm::unbox_array_size()
{ {
switch(tagged<object>(dpeek()).type()) switch(tagged<object>(dpeek()).type())
{ {
@ -413,17 +413,32 @@ cell unbox_array_size()
return 0; /* can't happen */ return 0; /* can't happen */
} }
PRIMITIVE(fixnum_to_float) cell unbox_array_size()
{
return vm->unbox_array_size();
}
inline void factorvm::vmprim_fixnum_to_float()
{ {
drepl(allot_float(fixnum_to_float(dpeek()))); drepl(allot_float(fixnum_to_float(dpeek())));
} }
PRIMITIVE(bignum_to_float) PRIMITIVE(fixnum_to_float)
{
PRIMITIVE_GETVM()->vmprim_fixnum_to_float();
}
inline void factorvm::vmprim_bignum_to_float()
{ {
drepl(allot_float(bignum_to_float(dpeek()))); drepl(allot_float(bignum_to_float(dpeek())));
} }
PRIMITIVE(str_to_float) PRIMITIVE(bignum_to_float)
{
PRIMITIVE_GETVM()->vmprim_bignum_to_float();
}
inline void factorvm::vmprim_str_to_float()
{ {
byte_array *bytes = untag_check<byte_array>(dpeek()); byte_array *bytes = untag_check<byte_array>(dpeek());
cell capacity = array_capacity(bytes); cell capacity = array_capacity(bytes);
@ -437,98 +452,178 @@ PRIMITIVE(str_to_float)
drepl(F); drepl(F);
} }
PRIMITIVE(float_to_str) PRIMITIVE(str_to_float)
{
PRIMITIVE_GETVM()->vmprim_str_to_float();
}
inline void factorvm::vmprim_float_to_str()
{ {
byte_array *array = allot_byte_array(33); byte_array *array = allot_byte_array(33);
snprintf((char *)(array + 1),32,"%.16g",untag_float_check(dpop())); snprintf((char *)(array + 1),32,"%.16g",untag_float_check(dpop()));
dpush(tag<byte_array>(array)); dpush(tag<byte_array>(array));
} }
PRIMITIVE(float_to_str)
{
PRIMITIVE_GETVM()->vmprim_float_to_str();
}
#define POP_FLOATS(x,y) \ #define POP_FLOATS(x,y) \
double y = untag_float(dpop()); \ double y = untag_float(dpop()); \
double x = untag_float(dpop()); double x = untag_float(dpop());
PRIMITIVE(float_eq) inline void factorvm::vmprim_float_eq()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_boolean(x == y); box_boolean(x == y);
} }
PRIMITIVE(float_add) PRIMITIVE(float_eq)
{
PRIMITIVE_GETVM()->vmprim_float_eq();
}
inline void factorvm::vmprim_float_add()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_double(x + y); box_double(x + y);
} }
PRIMITIVE(float_subtract) PRIMITIVE(float_add)
{
PRIMITIVE_GETVM()->vmprim_float_add();
}
inline void factorvm::vmprim_float_subtract()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_double(x - y); box_double(x - y);
} }
PRIMITIVE(float_multiply) PRIMITIVE(float_subtract)
{
PRIMITIVE_GETVM()->vmprim_float_subtract();
}
inline void factorvm::vmprim_float_multiply()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_double(x * y); box_double(x * y);
} }
PRIMITIVE(float_divfloat) PRIMITIVE(float_multiply)
{
PRIMITIVE_GETVM()->vmprim_float_multiply();
}
inline void factorvm::vmprim_float_divfloat()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_double(x / y); box_double(x / y);
} }
PRIMITIVE(float_mod) PRIMITIVE(float_divfloat)
{
PRIMITIVE_GETVM()->vmprim_float_divfloat();
}
inline void factorvm::vmprim_float_mod()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_double(fmod(x,y)); box_double(fmod(x,y));
} }
PRIMITIVE(float_less) PRIMITIVE(float_mod)
{
PRIMITIVE_GETVM()->vmprim_float_mod();
}
inline void factorvm::vmprim_float_less()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_boolean(x < y); box_boolean(x < y);
} }
PRIMITIVE(float_lesseq) PRIMITIVE(float_less)
{
PRIMITIVE_GETVM()->vmprim_float_less();
}
inline void factorvm::vmprim_float_lesseq()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_boolean(x <= y); box_boolean(x <= y);
} }
PRIMITIVE(float_greater) PRIMITIVE(float_lesseq)
{
PRIMITIVE_GETVM()->vmprim_float_lesseq();
}
inline void factorvm::vmprim_float_greater()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_boolean(x > y); box_boolean(x > y);
} }
PRIMITIVE(float_greatereq) PRIMITIVE(float_greater)
{
PRIMITIVE_GETVM()->vmprim_float_greater();
}
inline void factorvm::vmprim_float_greatereq()
{ {
POP_FLOATS(x,y); POP_FLOATS(x,y);
box_boolean(x >= y); box_boolean(x >= y);
} }
PRIMITIVE(float_bits) PRIMITIVE(float_greatereq)
{
PRIMITIVE_GETVM()->vmprim_float_greatereq();
}
inline void factorvm::vmprim_float_bits()
{ {
box_unsigned_4(float_bits(untag_float_check(dpop()))); box_unsigned_4(float_bits(untag_float_check(dpop())));
} }
PRIMITIVE(bits_float) PRIMITIVE(float_bits)
{
PRIMITIVE_GETVM()->vmprim_float_bits();
}
inline void factorvm::vmprim_bits_float()
{ {
box_float(bits_float(to_cell(dpop()))); box_float(bits_float(to_cell(dpop())));
} }
PRIMITIVE(double_bits) PRIMITIVE(bits_float)
{
PRIMITIVE_GETVM()->vmprim_bits_float();
}
inline void factorvm::vmprim_double_bits()
{ {
box_unsigned_8(double_bits(untag_float_check(dpop()))); box_unsigned_8(double_bits(untag_float_check(dpop())));
} }
PRIMITIVE(bits_double) PRIMITIVE(double_bits)
{
PRIMITIVE_GETVM()->vmprim_double_bits();
}
inline void factorvm::vmprim_bits_double()
{ {
box_double(bits_double(to_unsigned_8(dpop()))); box_double(bits_double(to_unsigned_8(dpop())));
} }
VM_C_API fixnum to_fixnum(cell tagged) PRIMITIVE(bits_double)
{
PRIMITIVE_GETVM()->vmprim_bits_double();
}
fixnum factorvm::to_fixnum(cell tagged)
{ {
switch(TAG(tagged)) switch(TAG(tagged))
{ {
@ -542,52 +637,102 @@ VM_C_API fixnum to_fixnum(cell tagged)
} }
} }
VM_C_API cell to_cell(cell tagged) VM_C_API fixnum to_fixnum(cell tagged)
{
return vm->to_fixnum(tagged);
}
cell factorvm::to_cell(cell tagged)
{ {
return (cell)to_fixnum(tagged); return (cell)to_fixnum(tagged);
} }
VM_C_API cell to_cell(cell tagged)
{
return vm->to_cell(tagged);
}
void factorvm::box_signed_1(s8 n)
{
dpush(tag_fixnum(n));
}
VM_C_API void box_signed_1(s8 n) VM_C_API void box_signed_1(s8 n)
{
return vm->box_signed_1(n);
}
void factorvm::box_unsigned_1(u8 n)
{ {
dpush(tag_fixnum(n)); dpush(tag_fixnum(n));
} }
VM_C_API void box_unsigned_1(u8 n) VM_C_API void box_unsigned_1(u8 n)
{
return vm->box_unsigned_1(n);
}
void factorvm::box_signed_2(s16 n)
{ {
dpush(tag_fixnum(n)); dpush(tag_fixnum(n));
} }
VM_C_API void box_signed_2(s16 n) VM_C_API void box_signed_2(s16 n)
{
return vm->box_signed_2(n);
}
void factorvm::box_unsigned_2(u16 n)
{ {
dpush(tag_fixnum(n)); dpush(tag_fixnum(n));
} }
VM_C_API void box_unsigned_2(u16 n) VM_C_API void box_unsigned_2(u16 n)
{ {
dpush(tag_fixnum(n)); return vm->box_unsigned_2(n);
} }
VM_C_API void box_signed_4(s32 n) void factorvm::box_signed_4(s32 n)
{ {
dpush(allot_integer(n)); dpush(allot_integer(n));
} }
VM_C_API void box_unsigned_4(u32 n) VM_C_API void box_signed_4(s32 n)
{
return vm->box_signed_4(n);
}
void factorvm::box_unsigned_4(u32 n)
{ {
dpush(allot_cell(n)); dpush(allot_cell(n));
} }
VM_C_API void box_signed_cell(fixnum integer) VM_C_API void box_unsigned_4(u32 n)
{
return vm->box_unsigned_4(n);
}
void factorvm::box_signed_cell(fixnum integer)
{ {
dpush(allot_integer(integer)); dpush(allot_integer(integer));
} }
VM_C_API void box_unsigned_cell(cell cell) VM_C_API void box_signed_cell(fixnum integer)
{
return vm->box_signed_cell(integer);
}
void factorvm::box_unsigned_cell(cell cell)
{ {
dpush(allot_cell(cell)); dpush(allot_cell(cell));
} }
VM_C_API void box_signed_8(s64 n) VM_C_API void box_unsigned_cell(cell cell)
{
return vm->box_unsigned_cell(cell);
}
void factorvm::box_signed_8(s64 n)
{ {
if(n < fixnum_min || n > fixnum_max) if(n < fixnum_min || n > fixnum_max)
dpush(tag<bignum>(long_long_to_bignum(n))); dpush(tag<bignum>(long_long_to_bignum(n)));
@ -595,7 +740,12 @@ VM_C_API void box_signed_8(s64 n)
dpush(tag_fixnum(n)); dpush(tag_fixnum(n));
} }
VM_C_API s64 to_signed_8(cell obj) VM_C_API void box_signed_8(s64 n)
{
return vm->box_signed_8(n);
}
s64 factorvm::to_signed_8(cell obj)
{ {
switch(tagged<object>(obj).type()) switch(tagged<object>(obj).type())
{ {
@ -609,7 +759,12 @@ VM_C_API s64 to_signed_8(cell obj)
} }
} }
VM_C_API void box_unsigned_8(u64 n) VM_C_API s64 to_signed_8(cell obj)
{
return vm->to_signed_8(obj);
}
void factorvm::box_unsigned_8(u64 n)
{ {
if(n > (u64)fixnum_max) if(n > (u64)fixnum_max)
dpush(tag<bignum>(ulong_long_to_bignum(n))); dpush(tag<bignum>(ulong_long_to_bignum(n)));
@ -617,7 +772,12 @@ VM_C_API void box_unsigned_8(u64 n)
dpush(tag_fixnum(n)); dpush(tag_fixnum(n));
} }
VM_C_API u64 to_unsigned_8(cell obj) VM_C_API void box_unsigned_8(u64 n)
{
return vm->box_unsigned_8(n);
}
u64 factorvm::to_unsigned_8(cell obj)
{ {
switch(tagged<object>(obj).type()) switch(tagged<object>(obj).type())
{ {
@ -631,41 +791,76 @@ VM_C_API u64 to_unsigned_8(cell obj)
} }
} }
VM_C_API void box_float(float flo) VM_C_API u64 to_unsigned_8(cell obj)
{
return vm->to_unsigned_8(obj);
}
void factorvm::box_float(float flo)
{ {
dpush(allot_float(flo)); dpush(allot_float(flo));
} }
VM_C_API void box_float(float flo)
{
return vm->box_float(flo);
}
float factorvm::to_float(cell value)
{
return untag_float_check(value);
}
VM_C_API float to_float(cell value) VM_C_API float to_float(cell value)
{ {
return untag_float_check(value); return vm->to_float(value);
} }
VM_C_API void box_double(double flo) void factorvm::box_double(double flo)
{ {
dpush(allot_float(flo)); dpush(allot_float(flo));
} }
VM_C_API double to_double(cell value) VM_C_API void box_double(double flo)
{
return vm->box_double(flo);
}
double factorvm::to_double(cell value)
{ {
return untag_float_check(value); return untag_float_check(value);
} }
VM_C_API double to_double(cell value)
{
return vm->to_double(value);
}
/* The fixnum+, fixnum- and fixnum* primitives are defined in cpu_*.S. On /* The fixnum+, fixnum- and fixnum* primitives are defined in cpu_*.S. On
overflow, they call these functions. */ overflow, they call these functions. */
VM_ASM_API void overflow_fixnum_add(fixnum x, fixnum y) void factorvm::overflow_fixnum_add(fixnum x, fixnum y)
{ {
drepl(tag<bignum>(fixnum_to_bignum( drepl(tag<bignum>(fixnum_to_bignum(
untag_fixnum(x) + untag_fixnum(y)))); untag_fixnum(x) + untag_fixnum(y))));
} }
VM_ASM_API void overflow_fixnum_subtract(fixnum x, fixnum y) VM_ASM_API void overflow_fixnum_add(fixnum x, fixnum y)
{
return vm->overflow_fixnum_add(x,y);
}
void factorvm::overflow_fixnum_subtract(fixnum x, fixnum y)
{ {
drepl(tag<bignum>(fixnum_to_bignum( drepl(tag<bignum>(fixnum_to_bignum(
untag_fixnum(x) - untag_fixnum(y)))); untag_fixnum(x) - untag_fixnum(y))));
} }
VM_ASM_API void overflow_fixnum_multiply(fixnum x, fixnum y) VM_ASM_API void overflow_fixnum_subtract(fixnum x, fixnum y)
{
return vm->overflow_fixnum_subtract(x,y);
}
void factorvm::overflow_fixnum_multiply(fixnum x, fixnum y)
{ {
bignum *bx = fixnum_to_bignum(x); bignum *bx = fixnum_to_bignum(x);
GC_BIGNUM(bx); GC_BIGNUM(bx);
@ -674,4 +869,9 @@ VM_ASM_API void overflow_fixnum_multiply(fixnum x, fixnum y)
drepl(tag<bignum>(bignum_multiply(bx,by))); drepl(tag<bignum>(bignum_multiply(bx,by)));
} }
VM_ASM_API void overflow_fixnum_multiply(fixnum x, fixnum y)
{
return vm->overflow_fixnum_multiply(x,y);
}
} }

View File

@ -276,9 +276,51 @@ struct factorvm {
inline void vmprim_bignum_log2(); inline void vmprim_bignum_log2();
unsigned int bignum_producer(unsigned int digit); unsigned int bignum_producer(unsigned int digit);
inline void vmprim_byte_array_to_bignum(); inline void vmprim_byte_array_to_bignum();
cell unbox_array_size();
inline void vmprim_fixnum_to_float();
inline void vmprim_bignum_to_float();
inline void vmprim_str_to_float();
inline void vmprim_float_to_str();
inline void vmprim_float_eq();
inline void vmprim_float_add();
inline void vmprim_float_subtract();
inline void vmprim_float_multiply();
inline void vmprim_float_divfloat();
inline void vmprim_float_mod();
inline void vmprim_float_less();
inline void vmprim_float_lesseq();
inline void vmprim_float_greater();
inline void vmprim_float_greatereq();
inline void vmprim_float_bits();
inline void vmprim_bits_float();
inline void vmprim_double_bits();
inline void vmprim_bits_double();
fixnum to_fixnum(cell tagged);
cell to_cell(cell tagged);
void box_signed_1(s8 n);
void box_unsigned_1(u8 n);
void box_signed_2(s16 n);
void box_unsigned_2(u16 n);
void box_signed_4(s32 n);
void box_unsigned_4(u32 n);
void box_signed_cell(fixnum integer);
void box_unsigned_cell(cell cell);
void box_signed_8(s64 n);
s64 to_signed_8(cell obj);
void box_unsigned_8(u64 n);
u64 to_unsigned_8(cell obj);
void box_float(float flo);
float to_float(cell value);
void box_double(double flo);
double to_double(cell value);
void overflow_fixnum_add(fixnum x, fixnum y);
void overflow_fixnum_subtract(fixnum x, fixnum y);
void overflow_fixnum_multiply(fixnum x, fixnum y);
// next method here: // next method here:
}; };
extern factorvm *vm; extern factorvm *vm;