diff --git a/test/float/Makefile b/test/float/Makefile index 7b5e75d92..b9c3551b5 100644 --- a/test/float/Makefile +++ b/test/float/Makefile @@ -12,14 +12,17 @@ FILES=\ float-minimal.prg \ float-minimal.bin \ float-minimal.woz.bin \ + float-minimal.soft.bin \ \ float-basic.prg \ float-basic.bin \ float-basic.woz.bin \ + float-basic.soft.bin \ \ float-basic-cmp.prg \ float-basic-cmp.bin \ - float-basic-cmp.woz.bin + float-basic-cmp.woz.bin \ + float-basic-cmp.soft.bin # # floattest.prg @@ -35,6 +38,11 @@ CBMRUNTIME=\ cbmkernal/ffloor.c \ cbmkernal/cc65wrapper.s +SOFTFLOAT=\ + softfloat/softfloat.c \ + softfloat/ftostr.c \ + softfloat/cc65wrapper.s + IEEERUNTIME=\ ieee754/feaxint.s \ ieee754/feaxlong.s \ @@ -115,6 +123,22 @@ float-basic-cmp.woz.s: float-basic-cmp.c $(HEADER) $(WOZRUNTIME) float-basic-cmp.woz.bin: float-basic-cmp.woz.s $(HEADER) $(WOZRUNTIME) $(CL65) $(OPT) -t sim6502 -I ./include -o float-basic-cmp.woz.bin float-basic-cmp.woz.s $(WOZRUNTIME) +############################################################################### +float-minimal.soft.s: float-minimal.c $(HEADER) $(SOFTFLOAT) + $(CC65) $(OPT) -t sim6502 -I ./include --add-source -o float-minimal.soft.s float-minimal.c +float-minimal.soft.bin: float-minimal.soft.s $(HEADER) $(SOFTFLOAT) + $(CL65) $(OPT) -t sim6502 -I ./include -o float-minimal.soft.bin float-minimal.soft.s $(SOFTFLOAT) + +float-basic.soft.s: float-basic.c $(HEADER) $(SOFTFLOAT) + $(CC65) $(OPT) -t sim6502 -I ./include --add-source -o float-basic.soft.s float-basic.c +float-basic.soft.bin: float-basic.soft.s $(HEADER) $(SOFTFLOAT) + $(CL65) $(OPT) -t sim6502 -I ./include -o float-basic.soft.bin float-basic.soft.s $(SOFTFLOAT) + +float-basic-cmp.soft.s: float-basic-cmp.c $(HEADER) $(SOFTFLOAT) + $(CC65) $(OPT) -t sim6502 -I ./include --add-source -o float-basic-cmp.soft.s float-basic-cmp.c +float-basic-cmp.soft.bin: float-basic-cmp.soft.s $(HEADER) $(SOFTFLOAT) + $(CL65) $(OPT) -t sim6502 -I ./include -o float-basic-cmp.soft.bin float-basic-cmp.soft.s $(SOFTFLOAT) + ############################################################################### float-minimal.c64.s: float-minimal.c $(HEADER) $(CBMRUNTIME) $(CC65) $(OPT) -DCONIO -t c64 -I ./include -I ./cbmkernal --add-source -o float-minimal.c64.s float-minimal.c @@ -177,6 +201,18 @@ runwoz: float-minimal.woz.bin float-basic.woz.bin float-basic-cmp.woz.bin $(SIM65) float-basic.woz.bin $(SIM65) float-basic-cmp.woz.bin +runsoft-minimal: float-minimal.soft.bin + $(SIM65) float-minimal.soft.bin +runsoft-basic: float-basic.soft.bin + $(SIM65) float-basic.soft.bin +runsoft-cmp: float-basic-cmp.soft.bin + $(SIM65) float-basic-cmp.soft.bin + +runsoft: float-minimal.soft.bin float-basic.soft.bin float-basic-cmp.soft.bin + $(SIM65) float-minimal.soft.bin + $(SIM65) float-basic.soft.bin + $(SIM65) float-basic-cmp.soft.bin + ############################################################################### clean: diff --git a/test/float/float-basic-cmp.c b/test/float/float-basic-cmp.c index 3f7e75155..4252915ea 100644 --- a/test/float/float-basic-cmp.c +++ b/test/float/float-basic-cmp.c @@ -21,10 +21,150 @@ unsigned int var_uint; signed long var_slong; unsigned long var_ulong; +int result = 0; + int main(void) { printf("float-basic-cmp\n"); + //------------------------------------------------------------------------- + // float constant vs float const + printf("const vs const\n"); + + printf("1.5f == 1.6f is "); + if (1.5f == 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + printf("1.6f == 1.6f is "); + if (1.6f == 1.6f) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + + printf("1.5f != 1.6f is "); + if (1.5f != 1.6f) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + + printf("1.6f != 1.6f is "); + if (1.6f != 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + printf("1.5f < 1.6f is "); + if (1.5f < 1.6f) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + printf("1.6f < 1.6f is "); + if (1.6f < 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + printf("1.5f > 1.6f is "); + if (1.5f > 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + printf("1.6f > 1.6f is "); + if (1.6f > 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + //------------------------------------------------------------------------- + // float constant vs float variable + printf("const vs var\n"); + + fp1 = 1.6f; + printf("1.5f == 1.6f is "); + if (1.5f == fp1) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + fp1 = 1.6f; + printf("1.6f == 1.6f is "); + if (1.6f == fp1) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + fp1 = 1.6f; + printf("1.5f != 1.6f is "); + if (1.5f != fp1) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + + fp1 = 1.6f; + printf("1.6f != 1.6f is "); + if (1.6f != fp1) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + fp1 = 1.6f; + printf("1.5f < 1.6f is "); + if (1.5f < fp1) { + printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + fp1 = 1.6f; + printf("1.6f < 1.6f is "); + if (1.6f < fp1) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + fp1 = 1.6f; + printf("1.5f > 1.6f is "); + if (1.5f > fp1) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + fp1 = 1.6f; + printf("1.6f > 1.6f is "); + if (1.6f > fp1) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + //------------------------------------------------------------------------- // float variable vs float constant printf("var vs const\n"); @@ -33,16 +173,19 @@ int main(void) fp1 = 1.5f; printf("1.5f == 1.6f is "); if (fp1 == 1.6f) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } - fp1 = 1.5f; - printf("1.5f == 1.5f is "); - if (1.5f == fp1) { + + fp1 = 1.6f; + printf("1.6f == 1.6f is "); + if (fp1 == 1.6f) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } //FIXME: compiles, but is wrong, the constant in the comparison becomes 0 @@ -51,12 +194,15 @@ int main(void) if (fp1 != 1.6f) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } - fp1 = 1.5f; - printf("1.5f != 1.5f is "); - if (1.5f != fp1) { - printf("true\n"); + + fp1 = 1.6f; + printf("1.6f != 1.6f is "); + if (fp1 != 1.6f) { + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -66,13 +212,34 @@ int main(void) printf("1.5f < 1.6f is "); if (fp1 < 1.6f) { printf("true\n"); + } else { + printf("false (failed)\n"); + result++; + } + + fp1 = 1.6f; + printf("1.6f < 1.6f is "); + if (fp1 < 1.6f) { + printf("true (failed)\n"); + result++; } else { printf("false\n"); } - fp1 = 1.7f; - printf("1.7f < 1.5f is "); - if (1.7f < fp1) { - printf("true\n"); + + fp1 = 1.5f; + printf("1.5f > 1.6f is "); + if (fp1 > 1.6f) { + printf("true (failed)\n"); + result++; + } else { + printf("false\n"); + } + + fp1 = 1.6f; + printf("1.6f > 1.6f is "); + if (fp1 > 1.6f) { + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -84,7 +251,8 @@ int main(void) fp2 = 1.6f; printf("1.5f == 1.6f is "); if (fp1 == fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -92,17 +260,20 @@ int main(void) if (fp1 != fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } printf("1.5f < 1.6f is "); if (fp1 < fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } printf("1.5f > 1.6f is "); if (fp1 > fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -110,11 +281,13 @@ int main(void) if (fp1 <= fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } printf("1.5f >= 1.6f is "); if (fp1 >= fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -124,23 +297,27 @@ int main(void) if (fp1 == fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } printf("1.6f != 1.6f is "); if (fp1 != fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } printf("1.6f < 1.6f is "); if (fp1 < fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } printf("1.6f > 1.6f is "); if (fp1 > fp2) { - printf("true\n"); + printf("true (failed)\n"); + result++; } else { printf("false\n"); } @@ -148,14 +325,16 @@ int main(void) if (fp1 <= fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } printf("1.6f >= 1.6f is "); if (fp1 >= fp2) { printf("true\n"); } else { - printf("false\n"); + printf("false (failed)\n"); + result++; } - - return 0; + printf("float-basic-cmp errors: %d\n", result); + return result; } diff --git a/test/float/float-minimal.c b/test/float/float-minimal.c index 12408e9ab..6abd597ac 100644 --- a/test/float/float-minimal.c +++ b/test/float/float-minimal.c @@ -7,6 +7,9 @@ #ifdef CONIO #include +#define WAIT() cgetc() +#else +#define WAIT() #endif #include @@ -15,6 +18,10 @@ #include <_float.h> +#define TEST_8 +#define TEST_16 +#define TEST_32 + float fp1 = 42.01002f; float fp2; // non initialized float *fp_p; // non initialized @@ -33,14 +40,11 @@ unsigned int var_uint; signed long var_slong; unsigned long var_ulong; -int main(void) -{ +void references(void) { float fp2 = 23.1234f; - printf("float-minimal\n"); - - printf("fp2:0x%08lx [0x41b8f5c3] %s (23.1234)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); - printf("fp4:0x%08lx [0x41b8f5c3] %s (23.12)\n", *((uint32_t*)&fp4), _ftostr(buf, fp4)); + printf("fp2:0x%08lx [exp:0x41b8fcb9] %s (23.1234)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); + printf("fp4:0x%08lx [exp:0x41b8f5c3] %s (23.12)\n", *((uint32_t*)&fp4), _ftostr(buf, fp4)); #if 1 printf("(global) get address, read via ptr\n"); // get address of global (works) @@ -49,8 +53,8 @@ int main(void) // read fp via pointer and assign local fp2 = *fp_p; - printf("fp1:0x%08lx [0x42280a43] %s (42.01002)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); - printf("fp2:0x%08lx [0x42280a43] %s (42.01002)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); + printf("fp1:0x%08lx [exp:0x42280a43] %s (42.01002)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); + printf("fp2:0x%08lx [exp:0x42280a43] %s (42.01002)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); #endif #if 1 printf("(local) get address, read via ptr\n"); @@ -62,9 +66,57 @@ int main(void) // read fp via pointer and assign global fp3 = *fp_p; - printf("fp2:0x%08lx [] %s (23.1234)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); - printf("fp3:0x%08lx [] %s (23.1234)\n", *((uint32_t*)&fp3), _ftostr(buf, fp3)); + printf("fp2:0x%08lx [exp:] %s (23.1234)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); + printf("fp3:0x%08lx [exp:] %s (23.1234)\n", *((uint32_t*)&fp3), _ftostr(buf, fp3)); #endif +} + +void conversions(void) +{ + // conversions + printf("conversions (integer constant to float)\n"); +#ifdef TEST_8 + fp1 = -12; + fp2 = 199; + printf("fp1 0x%08lx [] %s (-12)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); + printf("fp2 0x%08lx [] %s (199)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); +#endif +#ifdef TEST_16 + fp1 = -4711; + fp2 = 42000; + printf("fp1 0x%08lx [] %s (-4711)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); + printf("fp2 0x%08lx [] %s (42000)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); +#endif +#ifdef TEST_32 + fp1 = -321198; + fp2 = 3200098; + printf("fp1 0x%08lx [] %s (-321198)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); + printf("fp2 0x%08lx [] %s (3200098)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); +#endif + + printf("conversions (float constant to integer)\n"); +#ifdef TEST_8 + var_schar = (signed char)12.3f; + printf("%s (12.3) schar:%d (12)\n", _ftostr(buf, 12.3f), (int)var_schar); + var_uchar = (unsigned char)19.9f; + printf("%s (19.9) uchar:%u (19)\n", _ftostr(buf, 19.9f), (int)var_uchar); +#endif +#ifdef TEST_16 + var_sint = (signed short)1234.5f; + printf("%s (1234.5) sint:%d (1234)\n", _ftostr(buf, 1234.5f), var_sint); + var_uint = (unsigned short)1999.9f; + printf("%s (1999.9) uint:%u (1999)\n", _ftostr(buf, 1999.9f), var_uint); +#endif +#ifdef TEST_32 + var_slong = (signed long)123456.5f; + printf("%s (123456.5f) slong:%ld (123456)\n", _ftostr(buf, 123456.5f), var_slong); + var_ulong = (unsigned long)199988.9f; + printf("%s (199988.9) ulong:%lu (199988)\n", _ftostr(buf, 199988.9f), var_ulong); +#endif +} + +void arithmetics(void) +{ // addition #if 1 printf("constant + constant\n"); @@ -88,7 +140,7 @@ int main(void) printf("fp3:0x%08lx [] %s (0.3)\n", *((uint32_t*)&fp3), _ftostr(buf, fp3)); #endif // multiplication -#if 0 +#if 1 printf("constant * constant\n"); fp1 = 0.1f; fp2 = 0.2f; @@ -100,7 +152,7 @@ int main(void) #endif // division -#if 0 +#if 1 printf("constant / constant\n"); fp1 = 0.1f; fp2 = 0.2f; @@ -110,10 +162,9 @@ int main(void) printf(" 0x%08lx [] %s (0.2)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); printf("fp3:0x%08lx [] %s (0.3)\n", *((uint32_t*)&fp3), _ftostr(buf, fp3)); #endif -#ifdef CONIO - cgetc(); -#endif +} +void comparisons(void) { // comparisons #if 1 /* FIXME: this does not work yet */ @@ -123,38 +174,25 @@ int main(void) printf("0.2f != 0.1f is "); if (0.2f != 0.1f) { printf("true\n"); } else { printf("false\n"); } #endif -#ifdef CONIO - cgetc(); -#endif +} - // conversions -#if 1 - printf("conversions (integer constant to float)\n"); - fp1 = -12; - fp2 = 199; - printf("fp1 0x%08lx [] %s (-12)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); - printf("fp2 0x%08lx [] %s (199)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); - fp1 = -4711; - fp2 = 42000; - printf("fp1 0x%08lx [] %s (-4711)\n", *((uint32_t*)&fp1), _ftostr(buf, fp1)); - printf("fp2 0x%08lx [] %s (42000)\n", *((uint32_t*)&fp2), _ftostr(buf, fp2)); -#endif -#if 1 - printf("conversions (float constant to integer)\n"); - var_schar = (signed char)12.3f; - printf("%s (12.3) schar:%d (12)\n", _ftostr(buf, 12.3f), (int)var_schar); - var_uchar = (unsigned char)19.9f; - printf("%s (19.9) uchar:%u (19)\n", _ftostr(buf, 19.9f), (int)var_uchar); +int main(void) +{ + printf("float-minimal\n"); - var_sint = (signed short)1234.5f; - printf("%s (1234.5) sint:%d (1234)\n", _ftostr(buf, 1234.5f), var_sint); - var_uint = (unsigned short)1999.9f; - printf("%s (1999.9) uint:%u (1999)\n", _ftostr(buf, 1999.9f), var_uint); + references(); + WAIT(); + + conversions(); + WAIT(); + + comparisons(); + WAIT(); + + arithmetics(); + WAIT(); + + printf("float-minimal done\n"); - var_slong = (signed long)123456.5f; - printf("%s (123456.5f) slong:%ld (123456)\n", _ftostr(buf, 123456.5f), var_slong); - var_ulong = (unsigned long)199988.9f; - printf("%s (199988.9) ulong:%lu (199988)\n", _ftostr(buf, 199988.9f), var_ulong); -#endif return 0; } diff --git a/test/float/softfloat/cc65wrapper.s b/test/float/softfloat/cc65wrapper.s new file mode 100644 index 000000000..3e29df689 --- /dev/null +++ b/test/float/softfloat/cc65wrapper.s @@ -0,0 +1,106 @@ + + + .import _int32_to_float32 + + ; 16bit signed -> float + .export axfloat +axfloat: + ; FIXME + jmp _int32_to_float32 + + ; 16bit unsigned -> float + .export axufloat +axufloat: + ; FIXME + jmp _int32_to_float32 + + ; 32bit signed -> float + .export eaxfloat +eaxfloat: + ; FIXME + jmp _int32_to_float32 + + ; 32bit unsigned -> float + .export eaxufloat +eaxufloat: + ; FIXME + jmp _int32_to_float32 + + .import _float32_to_int32 + + ; float -> 16bit int + .export feaxint +feaxint: + ; FIXME + jmp _float32_to_int32 + ; float -> 32bit int + .export feaxlong +feaxlong: + jmp _float32_to_int32 + + .export fbnegeax +fbnegeax: + + .import _float32_add + .import _float32_sub + .import _float32_mul + .import _float32_div + + .export ftosaddeax +ftosaddeax: + jmp _float32_add + .export ftossubeax +ftossubeax: + jmp _float32_sub + .export ftosmuleax +ftosmuleax: + jmp _float32_mul + .export ftosdiveax +ftosdiveax: + jmp _float32_div + + + .import _float32_eq + .import _float32_le + .import _float32_lt + + ; test for equal + .export ftoseqeax +ftoseqeax: + ; arg0: a/x/sreg/sreg+1 + ; arg1: (sp),y (y=0..3) + jmp _float32_eq + + ; test for not equal + .export ftosneeax +ftosneeax: + ; arg0: a/x/sreg/sreg+1 + ; arg1: (sp),y (y=0..3) + jsr _float32_eq + eor #1 + rts + + + ; Test for less than or equal to + .export ftosleeax +ftosleeax: + jmp _float32_le + + .export ftosgteax +ftosgteax: + jsr _float32_le + eor #1 + rts + + ; Test for less than + .export ftoslteax +ftoslteax: + jmp _float32_lt + + ; Test for "not less than" -> "equal or greater than" + ; Test for greater than or equal to + .export ftosgeeax +ftosgeeax: + jsr _float32_lt + eor #1 + rts diff --git a/test/float/softfloat/ftostr.c b/test/float/softfloat/ftostr.c new file mode 100644 index 000000000..130d87480 --- /dev/null +++ b/test/float/softfloat/ftostr.c @@ -0,0 +1,11 @@ + +#include +#include + +char *_ftostr(char *buffer, float f) { + signed long intpart = (signed long)f; + float fracpart; + fracpart = f - (float)(intpart); + sprintf(buffer, "<0x%08lx:%ld.%ld>", *((unsigned long*)(&f)), intpart, fracpart * 1000); + return &buffer[0]; +}