From bf1925f901a9f45ad2529874f41e1e2b01f5bc9f Mon Sep 17 00:00:00 2001 From: pjs Date: Mon, 27 Dec 2004 22:21:57 +0000 Subject: [PATCH] Added mcs51 assembly float lib functions (add, sub, mul, div 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 --- ChangeLog | 15 +++ device/lib/Makefile.in | 2 +- device/lib/_fsadd.c | 140 +++++++++++++++++++++++++- device/lib/_fscmp.c | 93 ++++++++++++++++++ device/lib/_fsdiv.c | 211 +++++++++++++++++++++++++++++++++++++++- device/lib/_fseq.c | 52 +++++++++- device/lib/_fsgt.c | 77 ++++++++++++++- device/lib/_fslt.c | 78 ++++++++++++++- device/lib/_fsmul.c | 190 +++++++++++++++++++++++++++++++++++- device/lib/_fsneq.c | 50 +++++++++- device/lib/_fssub.c | 50 +++++++++- device/lib/libfloat.lib | 1 + src/SDCCmain.c | 6 ++ 13 files changed, 954 insertions(+), 11 deletions(-) create mode 100644 device/lib/_fscmp.c diff --git a/ChangeLog b/ChangeLog index ac10df98..be293765 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-12-27 Paul Stoffregen + + * 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 * device/lib/_fs2slong.c: added mcs51 assembly version diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index 7a301d60..1e642e83 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -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 \ diff --git a/device/lib/_fsadd.c b/device/lib/_fsadd.c index 5da97f0e..8d3c6ab3 100644 --- a/device/lib/_fsadd.c +++ b/device/lib/_fsadd.c @@ -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 + + +#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. @@ -14,7 +150,6 @@ ** uunet!motown!pipeline!phw */ -#include 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 index 00000000..c53a8081 --- /dev/null +++ b/device/lib/_fscmp.c @@ -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 + + +#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 + diff --git a/device/lib/_fsdiv.c b/device/lib/_fsdiv.c index a89d698b..1768ec46 100644 --- a/device/lib/_fsdiv.c +++ b/device/lib/_fsdiv.c @@ -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 + + +#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. @@ -16,7 +224,6 @@ /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ -#include union float_long { @@ -93,3 +300,5 @@ float __fsdiv (float a1, float a2) return (fl1.f); } +#endif + diff --git a/device/lib/_fseq.c b/device/lib/_fseq.c index b73cd060..ee744d8a 100644 --- a/device/lib/_fseq.c +++ b/device/lib/_fseq.c @@ -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 + + +#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 union float_long { @@ -38,3 +86,5 @@ __fseq (float a1, float a2) return (0); } +#endif + diff --git a/device/lib/_fsgt.c b/device/lib/_fsgt.c index 2397df7b..81b7cc8a 100644 --- a/device/lib/_fsgt.c +++ b/device/lib/_fsgt.c @@ -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 + + +#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 union float_long { @@ -42,3 +115,5 @@ char __fsgt (float a1, float a2) return (1); return (0); } + +#endif diff --git a/device/lib/_fslt.c b/device/lib/_fslt.c index 510d6352..b5e4311f 100644 --- a/device/lib/_fslt.c +++ b/device/lib/_fslt.c @@ -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 + + +#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 union float_long { @@ -42,3 +115,6 @@ char __fslt (float a1, float a2) return (1); return (0); } + +#endif + diff --git a/device/lib/_fsmul.c b/device/lib/_fsmul.c index 09fd00a4..95c12f11 100644 --- a/device/lib/_fsmul.c +++ b/device/lib/_fsmul.c @@ -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 + + +#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. @@ -16,7 +202,6 @@ /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ -#include union float_long { @@ -71,6 +256,5 @@ float __fsmul (float a1, float a2) { return (fl1.f); } - - +#endif diff --git a/device/lib/_fsneq.c b/device/lib/_fsneq.c index cf397fb1..68ed7fde 100644 --- a/device/lib/_fsneq.c +++ b/device/lib/_fsneq.c @@ -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 + + +#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 union float_long { @@ -44,3 +89,6 @@ char __fsneq (float a1, float a2) return (0); return (1); } + +#endif + diff --git a/device/lib/_fssub.c b/device/lib/_fssub.c index b9f453fb..f0856748 100644 --- a/device/lib/_fssub.c +++ b/device/lib/_fssub.c @@ -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 + + +#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 union float_long { @@ -42,3 +87,6 @@ float __fssub (float a1, float a2) fl2.l ^= SIGNBIT; return fl1.f + fl2.f; } + +#endif + diff --git a/device/lib/libfloat.lib b/device/lib/libfloat.lib index 07854aed..59abc3c5 100644 --- a/device/lib/libfloat.lib +++ b/device/lib/libfloat.lib @@ -4,6 +4,7 @@ _fsdiv _fseq _fsgt _fslt +_fscmp _fsmul _fsneq _fssub diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 092502f7..86440ad3 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -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; -- 2.30.2