Added mcs51 assembly float lib functions (add, sub, mul, div
authorpjs <pjs@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 27 Dec 2004 22:21:57 +0000 (22:21 +0000)
committerpjs <pjs@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 27 Dec 2004 22:21:57 +0000 (22:21 +0000)
and compares).
Always enable --float-reent for mcs51

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3616 4a8a32a2-be11-0410-ad9d-d568d2c75423

13 files changed:
ChangeLog
device/lib/Makefile.in
device/lib/_fsadd.c
device/lib/_fscmp.c [new file with mode: 0644]
device/lib/_fsdiv.c
device/lib/_fseq.c
device/lib/_fsgt.c
device/lib/_fslt.c
device/lib/_fsmul.c
device/lib/_fsneq.c
device/lib/_fssub.c
device/lib/libfloat.lib
src/SDCCmain.c

index ac10df987be19c39639ef1cb754e1698b7bd2fc0..be2937656fbd9a907b1b389d66d85810158c1a36 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2004-12-27 Paul Stoffregen <paul AT pjrc.com>
+
+       * src/SDCCmain.c: make --float-reent default for mcs51
+       * device/lib/_fsadd.c: added mcs51 assembly version
+       * device/lib/_fssub.c: added mcs51 assembly version
+       * device/lib/_fsmul.c: added mcs51 assembly version
+       * device/lib/_fsdiv.c: added mcs51 assembly version
+       * device/lib/_fseq.c: added mcs51 assembly version
+       * device/lib/_fsneq.c: added mcs51 assembly version
+       * device/lib/_fsgt.c: added mcs51 assembly version
+       * device/lib/_fslt.c: added mcs51 assembly version
+       * device/lib/_fscmp.c: shared code for fseq,fsgt,fslt,fsneq
+       * device/lib/Makefile.in: add _fscmp to build
+       * device/lib/libfloat.lib: add _fscmp to build
+
 2004-12-27 Paul Stoffregen <paul AT pjrc.com>
 
        * device/lib/_fs2slong.c: added mcs51 assembly version
index 7a301d600d2f9523279abdbe97672f684282f693..1e642e832e1a16c61c64e4c967278248d7a5f695 100644 (file)
@@ -46,7 +46,7 @@ SOURCES               = _atof.c _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
                  _decdptr.c _divsint.c _divslong.c _divuint.c \
                  _divulong.c _fs2schar.c _fs2sint.c _fs2slong.c \
                  _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \
-                 _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \
+                 _fsdiv.c _fseq.c _fsgt.c _fslt.c _fscmp.c _fsmul.c \
                  _fsneq.c _fssub.c _gptrget.c _gptrgetc.c _gptrput.c \
                  _sint2fs.c _iscntrl.c _isdigit.c _isgraph.c \
                  _islower.c _isprint.c _ispunct.c _isspace.c \
index 5da97f0e947658747b0a08553ee2f9df9aad4b49..8d3c6ab3acd4cd9970139fdb0886e2e7cacd2851 100644 (file)
@@ -1,3 +1,139 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// float __fsadd (float a, float b) reentrant
+static void dummy(void) _naked
+{
+       _asm
+
+       // extract the two inputs, placing them into:
+       //      sign     exponent   mantiassa
+       //      ----     --------   ---------
+       //  a:  sign_a   exp_a      r4/r3/r2
+       //  b:  sign_b   exp_b      r7/r6/r5
+       //
+       // r1: used to extend precision of a's mantissa
+       // r0: general purpose loop counter
+
+       .globl  ___fsadd
+___fsadd:
+       lcall   fsgetargs
+
+       .globl  fsadd_direct_entry
+fsadd_direct_entry:
+       // we're going to extend mantissa to 32 bits temporarily
+       mov     r1, #0
+
+       // which exponent is greater?
+       mov     a, exp_b
+       cjne    a, exp_a, 00005$
+       sjmp    00011$
+00005$:        jnc     00010$
+
+       // a's exponent was greater, so shift b's mantissa
+       lcall   fs_swap_a_b
+
+00010$:
+       // b's exponent was greater, so shift a's mantissa
+       mov     a, exp_b
+       clr     c
+       subb    a, exp_a
+       lcall   fs_rshift_a     // acc has # of shifts to do
+
+00011$:
+       // decide if we need to add or subtract
+       // sign_a and sign_b are stored in the flag bits of psw,
+       // so this little trick checks if the arguements ave the
+       // same sign.
+       mov     a, psw
+       swap    a
+       xrl     a, psw
+       jb      acc.1, 00022$
+
+00020$:
+       // add the mantissas (both positive or both negative)
+       mov     a, r2
+       add     a, r5
+       mov     r2, a
+       mov     a, r3
+       addc    a, r6
+       mov     r3, a
+       mov     a, r4
+       addc    a, r7
+       mov     r4, a
+       // check for overflow past 24 bits
+       jnc     00021$
+       mov     a, #1
+       lcall   fs_rshift_a
+       mov     a, r4
+       orl     a, #0x80
+       mov     r4, a
+00021$:
+       ljmp    fs_round_and_return
+
+
+
+00022$:
+       // subtract the mantissas (one of them is negative)
+       clr     c
+       mov     a, r2
+       subb    a, r5
+       mov     r2, a
+       mov     a, r3
+       subb    a, r6
+       mov     r3, a
+       mov     a, r4
+       subb    a, r7
+       mov     r4, a
+       jnc     00025$
+       // if we get a negative result, turn it positive and
+       // flip the sign bit
+       clr     c
+       clr     a
+       subb    a, r1
+       mov     r1, a
+       clr     a
+       subb    a, r2
+       mov     r2, a
+       clr     a
+       subb    a, r3
+       mov     r3, a
+       clr     a
+       subb    a, r4
+       mov     r4, a
+       cpl     sign_a
+00025$:
+       lcall   fs_normalize_a
+       ljmp    fs_round_and_return
+
+       _endasm;
+}
+
+#else
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
 ** uunet!motown!pipeline!phw
 */
 
-#include <float.h>
 
 union float_long
   {
@@ -96,3 +231,6 @@ float __fsadd (float a1, float a2)
 
   return (fl1.f);
 }
+
+#endif
+
diff --git a/device/lib/_fscmp.c b/device/lib/_fscmp.c
new file mode 100644 (file)
index 0000000..c53a808
--- /dev/null
@@ -0,0 +1,93 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+static void dummy(void) _naked
+{
+       _asm
+
+       .globl  fs_compare_uint32
+fs_compare_uint32:
+       mov     r1, #1
+       mov     r2, dpl
+       mov     a, @r0
+       mov     dpl, r7
+       cjne    a, dpl, compare32_done
+       dec     r0
+       mov     a, @r0
+       cjne    a, b, compare32_done
+       dec     r0
+       mov     a, @r0
+       cjne    a, dph, compare32_done
+       dec     r0
+       mov     a, @r0
+       mov     dpl, r2
+       cjne    a, dpl, compare32_done
+       mov     r1, #0
+compare32_done:
+       ret
+
+
+       .globl  fs_check_negative_zeros
+fs_check_negative_zeros:
+a_check:
+       cjne    a, #0x80, a_not_neg_zero
+       mov     a, b
+       jnz     a_not_neg_zero_cleanup
+       mov     a, dph
+       jnz     a_not_neg_zero_cleanup
+       mov     a, dpl
+       jnz     a_not_neg_zero_cleanup
+       mov     r7, #0
+a_not_neg_zero_cleanup:
+       mov     a, r7
+a_not_neg_zero:
+
+b_check:
+       cjne    @r0, #0x80, b_not_neg_zero
+       dec     r0
+       cjne    @r0, #0, b_not_neg_zero_cleanup_1
+       dec     r0
+       cjne    @r0, #0, b_not_neg_zero_cleanup_2
+       dec     r0
+       cjne    @r0, #0, b_not_neg_zero_cleanup_3
+       inc     r0
+       inc     r0
+       inc     r0
+       mov     @r0, #0
+       ret
+b_not_neg_zero_cleanup_3:
+       inc     r0
+b_not_neg_zero_cleanup_2:
+       inc     r0
+b_not_neg_zero_cleanup_1:
+       inc     r0
+b_not_neg_zero:
+       ret
+
+       _endasm;
+}
+
+#endif
+
index a89d698b5f0d4efe93297d9ea775c69ee1a1c34d..1768ec46a9b21c9ee3d2e5c0b29d6f833e2f3e2a 100644 (file)
@@ -1,3 +1,211 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// float __fsdiv (float a, float b) reentrant
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fsdiv
+___fsdiv:
+       // extract the two inputs, placing them into:
+       //      sign     exponent   mantiassa
+       //      ----     --------   ---------
+       //  a:  sign_a   exp_a      r4/r3/r2
+       //  b:  sign_b   exp_b      r7/r6/r5
+
+       lcall   fsgetargs
+
+       // compute final sign bit
+       jnb     sign_b, 00001$
+       cpl     sign_a
+00001$:
+
+       // if divisor is zero, return infinity
+       cjne    r7, #0, 00002$
+       ljmp    fs_return_inf
+00002$:
+       // if dividend is zero, return zero
+       cjne    r4, #0, 00003$
+       ljmp    fs_return_zero
+00003$:
+
+       // subtract exponents
+       clr     c
+       mov     a, exp_a
+       subb    a, exp_b
+       add     a, #127
+       mov     exp_a, a
+
+       // need extra bits on a's mantissa
+#ifdef FLOAT_FULL_ACCURACY
+       clr     c
+       mov     a, r5
+       subb    a, r2
+       mov     a, r6
+       subb    a, r3
+       mov     a, r7
+       subb    a, r4
+       jc      00005$
+       dec     exp_a
+       clr     c
+       mov     a, r2
+       rlc     a
+       mov     r1, a
+       mov     a, r3
+       rlc     a
+       mov     r2, a
+       mov     a, r4
+       rlc     a
+       mov     r3, a
+       clr     a
+       rlc     a
+       mov     r4, a
+       sjmp    00006$
+00005$:
+#endif
+       clr     a
+       xch     a, r4
+       xch     a, r3
+       xch     a, r2
+       mov     r1, a
+00006$:
+
+       // begin long division
+       push    exp_a
+#ifdef FLOAT_FULL_ACCURACY
+       mov     b, #25
+#else
+       mov     b, #24
+#endif
+00010$:
+       // compare
+       clr     c
+       mov     a, r1
+       subb    a, r5
+       mov     a, r2
+       subb    a, r6
+       mov     a, r3
+       subb    a, r7
+       mov     a, r4
+       subb    a, #0           // carry==0 if mant1 >= mant2
+
+#ifdef FLOAT_FULL_ACCURACY
+       djnz    b, 00011$
+       sjmp    00015$
+00011$:
+#endif
+       jc      00012$
+       // subtract
+       mov     a, r1
+       subb    a, r5
+       mov     r1, a
+       mov     a, r2
+       subb    a, r6
+       mov     r2, a
+       mov     a, r3
+       subb    a, r7
+       mov     r3, a
+       mov     a, r4
+       subb    a, #0
+       mov     r4, a
+       clr     c
+
+00012$:
+       // shift result
+       cpl     c
+       mov     a, r0
+       rlc     a
+       mov     r0, a
+       mov     a, dpl
+       rlc     a
+       mov     dpl, a
+       mov     a, dph
+       rlc     a
+       mov     dph, a
+
+       // shift partial remainder
+       clr     c
+       mov     a, r1
+       rlc     a
+       mov     r1, a
+       mov     a, r2
+       rlc     a
+       mov     r2, a
+       mov     a, r3
+       rlc     a
+       mov     r3, a
+       mov     a, r4
+       rlc     a
+       mov     r4, a
+
+#ifdef FLOAT_FULL_ACCURACY
+       sjmp    00010$
+00015$:
+#else
+       djnz    b, 00010$
+#endif
+
+       // now we've got a division result, so all we need to do
+       // is round off properly, normalize and output a float
+
+#ifdef FLOAT_FULL_ACCURACY
+       cpl     c
+       clr     a
+       mov     r1, a
+       addc    a, r0
+       mov     r2, a
+       clr     a
+       addc    a, dpl
+       mov     r3, a
+       clr     a
+       addc    a, dph
+       mov     r4, a
+       pop     exp_a
+       jnc     00016$
+       inc     exp_a
+       mov     r4, #0x80
+00016$:
+#else
+       mov     r1, #0
+       mov     a, r0
+       mov     r2, a
+       mov     r3, dpl
+       mov     r4, dph
+       pop     exp_a
+#endif
+
+       lcall   fs_normalize_a
+       ljmp    fs_zerocheck_return
+       _endasm;
+}
+
+#else
+
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -93,3 +300,5 @@ float __fsdiv (float a1, float a2)
   return (fl1.f);
 }
 
+#endif
+
index b73cd060f76c598fc177f91c4db0eb55bade3b87..ee744d8a50306d0913a73a198a3a364fc8a4eed6 100644 (file)
@@ -1,3 +1,52 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// char __fseq (float a, float b)
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fseq
+___fseq:
+       mov     r7, a
+       mov     r0, sp
+       dec     r0
+       dec     r0
+       lcall   fs_check_negative_zeros
+       lcall   fs_compare_uint32
+       mov     a, r1
+       xrl     a, #1
+       mov     dpl, a
+       ret
+       _endasm;
+}
+
+#else
+
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
@@ -16,7 +65,6 @@
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -38,3 +86,5 @@ __fseq (float a1, float a2)
   return (0);
 }
 
+#endif
+
index 2397df7b7acd7f7617038d19e84a6b953ed5bc2b..81b7cc8a76521fb3da115322ac5ccd5c4e095b30 100644 (file)
@@ -1,3 +1,77 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// char __fsgt (float a, float b) reentrant
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fsgt
+___fsgt:
+       mov     r7, a
+       mov     r0, sp
+       dec     r0
+       dec     r0
+       lcall   fs_check_negative_zeros
+       setb    sign_a
+       rlc     a
+       mov     a, @r0
+       jc      a_negative
+a_positive:
+       jnb     acc.7, ab_positive
+       // a is positive and b is negative, so a > b
+       mov     dpl, #1
+       ret
+a_negative:
+       jb      acc.7, ab_negative
+       // a is negative and b is positive, so a < b
+       mov     dpl, #0
+       ret
+ab_positive:
+       clr     sign_a
+ab_negative:
+       lcall   fs_compare_uint32
+       mov     a, r1
+       jnz     ab_different
+       // a and b are equal
+       mov     dpl, a
+       ret
+ab_different:
+       jnb     sign_a, skip_invert
+       cpl     c
+skip_invert:
+       clr     a
+       rlc     a
+       mov     dpl, a
+       ret
+       _endasm;
+}
+
+#else
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
@@ -16,7 +90,6 @@
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -42,3 +115,5 @@ char __fsgt (float a1, float a2)
     return (1);
   return (0);
 }
+
+#endif
index 510d6352126cc2c87c47f9d84dec8dcfffbcb2b7..b5e4311f0a90b07c6532e22835847f158fed6d6f 100644 (file)
@@ -1,3 +1,77 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// char __fslt (float a, float b)
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fslt
+___fslt:
+       mov     r7, a
+       mov     r0, sp
+       dec     r0
+       dec     r0
+       lcall   fs_check_negative_zeros
+       setb    sign_a
+       rlc     a
+       mov     a, @r0
+       jc      a_negative
+a_positive:
+       jnb     acc.7, ab_positive
+       // a is positive and b is negative, so a > b
+       mov     dpl, #0
+       ret
+a_negative:
+       jb      acc.7, ab_negative
+       // a is negative and b is positive, so a < b
+       mov     dpl, #1
+       ret
+ab_positive:
+       clr     sign_a
+ab_negative:
+       lcall   fs_compare_uint32
+       mov     a, r1
+       jnz     ab_different
+       // a and b are equal
+       mov     dpl, a
+       ret
+ab_different:
+       jb      sign_a, skip_invert
+       cpl     c
+skip_invert:
+       clr     a
+       rlc     a
+       mov     dpl, a
+       ret
+       _endasm;
+}
+
+#else
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
@@ -16,7 +90,6 @@
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -42,3 +115,6 @@ char __fslt (float a1, float a2)
     return (1);
   return (0);
 }
+
+#endif
+
index 09fd00a4fdba9092114e4d52538f139a366be3da..95c12f110b3f8a20c4b1abd51fec47435e5ff443 100644 (file)
@@ -1,3 +1,189 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// float __fsmul (float a, float b) reentrant
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fsmul
+___fsmul:
+       // extract the two inputs, placing them into:
+       //      sign     exponent   mantiassa
+       //      ----     --------   ---------
+       //  a:  sign_a   exp_a      r4/r3/r2
+       //  b:  sign_b   exp_b      r7/r6/r5
+
+       lcall   fsgetargs
+
+       // first check if either input is zero
+       cjne    r4, #0, 00002$
+00001$:
+       ljmp    fs_return_zero
+
+00002$:
+       mov     a, r7
+       jz      00001$
+
+       // compute final sign bit
+       jnb     sign_b, 00003$
+       cpl     sign_a
+00003$:
+
+       // add the exponents
+       mov     a, exp_a
+       add     a, exp_b
+       add     a, #130
+       mov     exp_a, a
+
+
+       // now we need to multipy r4/r3/r2 * r7/r6/r5
+       // ------------------------------------------
+       //                              r2 * r5         << 0
+       //                  r3 * r5  +  r2 * r6         << 8
+       //      r4 * r5  +  r3 * r6  +  r2 * r7         << 16
+       //      r4 * r6  +  r3 * r7                     << 24
+       //      r4 * r7                                 << 32
+       //
+       // This adds quite a bit of code, but it is a LOT faster
+       // that three calls to __mululong...
+
+       // output goes into r4/r3/r2/r1/r0/xx
+
+       mov     a, r2
+       mov     b, r5
+       mul     ab                      // r2 * r5
+       // discard lowest 8 bits
+       mov     r0, b
+       // range 0-FE
+
+       mov     a, r2
+       mov     b, r6
+       mul     ab                      // r2 * r6
+       add     a, r0
+       mov     r0, a
+       clr     a
+       addc    a, b
+       mov     r1, a
+       // range 0-FEFF
+
+       mov     a, r3
+       mov     b, r5
+       mul     ab                      // r3 * r5
+       add     a, r0
+       // discard lowest 8 bits
+       mov     a, r1
+       addc    a, b
+       mov     r1, a
+       clr     a
+       rlc     a
+       xch     a, r2
+       // range 0-1FD
+
+       mov     b, r7
+       mul     ab                      // r2 * r7
+       add     a, r1
+       mov     r1, a
+       mov     a, r2
+       addc    a, b
+       mov     r2, a
+       // range 0-FFFE
+
+       mov     a, r3
+       mov     r0, a
+       mov     b, r6
+       mul     ab                      // r3 * r6
+       add     a, r1
+       mov     r1, a
+       mov     a, r2
+       addc    a, b
+       mov     r2, a
+       clr     a
+       rlc     a
+       mov     r3, a
+       // range 0-1FDFF
+
+       mov     a, r4
+       mov     b, r5
+       mul     ab                      // r4 * r5
+       add     a, r1
+       mov     r1, a
+       mov     a, r2
+       addc    a, b
+       mov     r2, a
+       clr     a
+       addc    a, r3
+       mov     r3, a
+       // range 0-2FC00
+
+       mov     a, r0 // r3
+       mov     b, r7
+       mul     ab                      // r3 * r7
+       add     a, r2
+       mov     r2, a
+       mov     a, r3
+       addc    a, b
+       mov     r3, a
+       clr     a
+       rlc     a
+       xch     a, r4
+       // range 0-100FD00
+
+       mov     r5, a
+       mov     b, r6
+       mul     ab                      // r4 * r6
+       add     a, r2
+       mov     r2, a
+       mov     a, r3
+       addc    a, b
+       mov     r3, a
+       clr     a
+       addc    a, r4
+       mov     r4, a
+       // range 0-1FEFE00
+
+       mov     a, r5 // r4
+       mov     b, r7
+       mul     ab                      // r4 * r7
+       add     a, r3
+       mov     r3, a
+       mov     a, r4
+       addc    a, b
+       mov     r4, a
+       // range 40000000-FFFFFE00
+
+       jb      acc.7, 00010$
+       lcall   fs_normalize_a
+
+00010$:
+       ljmp    fs_round_and_return
+       _endasm;
+}
+
+#else
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -71,6 +256,5 @@ float __fsmul (float a1, float a2) {
   return (fl1.f);
 }
 
-
-
+#endif
 
index cf397fb14739b0b93f05731f6cb41e5f67da9a88..68ed7fdeca764cda8e140bbcdd15bda1bcf137a4 100644 (file)
@@ -1,3 +1,49 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+// char __fsneq (float a, float b)
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fsneq
+___fsneq:
+       mov     r7, a
+       mov     r0, sp
+       dec     r0
+       dec     r0
+       lcall   fs_check_negative_zeros
+       lcall   fs_compare_uint32
+       mov     dpl, r1
+       ret
+       _endasm;
+}
+
+#else
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
@@ -16,7 +62,6 @@
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -44,3 +89,6 @@ char __fsneq (float a1, float a2)
     return (0);
   return (1);
 }
+
+#endif
+
index b9f453fb3a1d38ea7b8277929965ff232fa44201..f0856748e318ca1e64bb61b22d33403f2e1c55c5 100644 (file)
@@ -1,3 +1,49 @@
+/* Floating point library in optimized assembly for 8051
+ * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#define SDCC_FLOAT_LIB
+#include <float.h>
+
+
+#ifdef FLOAT_ASM_MCS51
+
+//float __fssub (float a, float b) reentrant
+static void dummy(void) _naked
+{
+       _asm
+       .globl  ___fssub
+___fssub:
+       mov     r0, sp
+       dec     r0
+       dec     r0
+       xch     a, @r0
+       cpl     acc.7
+       xch     a, @r0
+       ljmp    ___fsadd
+       _endasm;
+}
+
+#else
+
+
+
+
 /*
 ** libgcc support for software floating point.
 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
@@ -16,7 +62,6 @@
 
 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <float.h>
 
 union float_long
   {
@@ -42,3 +87,6 @@ float __fssub (float a1, float a2)
   fl2.l ^= SIGNBIT;
   return fl1.f + fl2.f; 
 }
+
+#endif
+
index 07854aedf77b201f72f22bd63e82faef6b985f8c..59abc3c50541817587894bfeeee0831c2d28247c 100644 (file)
@@ -4,6 +4,7 @@ _fsdiv
 _fseq
 _fsgt
 _fslt
+_fscmp
 _fsmul
 _fsneq
 _fssub
index 092502f7c5d8821afa501cab6ea80dbf32bd028b..86440ad3e0adf447826de80b97ba6cbe1a5036c1 100644 (file)
@@ -1351,6 +1351,12 @@ parseCmdLine (int argc, char **argv)
       options.float_rent++;
     }
 
+  /* mcs51 has an assembly coded float library that's always reentrant */
+  if (TARGET_IS_MCS51)
+    {
+      options.float_rent++;
+    }
+
   /* set up external stack location if not explicitly specified */
   if (!options.xstack_loc)
     options.xstack_loc = options.xdata_loc;