#ifdef FLOAT_ASM_MCS51
-// float __fsdiv (float a, float b) reentrant
-static void dummy(void) _naked
+// float __fsdiv (float a, float b) __reentrant
+static void dummy(void) __naked
{
- _asm
+ __asm
.globl ___fsdiv
___fsdiv:
// extract the two inputs, placing them into:
cpl sign_a
00001$:
- // if divisor is zero, return infinity
- cjne r7, #0, 00002$
- ljmp fs_return_inf
+ // if divisor is zero, ...
+ cjne r7, #0, 00003$
+ // if dividend is also zero, return NaN
+ cjne r4, #0, 00002$
+ ljmp fs_return_nan
00002$:
+ // but dividend is non-zero, return infinity
+ ljmp fs_return_inf
+00003$:
// if dividend is zero, return zero
- cjne r4, #0, 00003$
+ cjne r4, #0, 00004$
ljmp fs_return_zero
-00003$:
+00004$:
+ // if divisor is infinity, ...
+ mov a, exp_b
+ cjne a, #0xFF, 00006$
+ // and dividend is also infinity, return NaN
+ mov a, exp_a
+ cjne a, #0xFF, 00005$
+ ljmp fs_return_nan
+00005$:
+ // but dividend is not infinity, return zero
+ ljmp fs_return_zero
+00006$:
+ // if dividend is infinity, return infinity
+ mov a, exp_a
+ cjne a, #0xFF, 00007$
+ ljmp fs_return_inf
+00007$:
// subtract exponents
clr c
- mov a, exp_a
subb a, exp_b
+ // if no carry then no underflow
+ jnc 00008$
add a, #127
+ jc 00009$
+ ljmp fs_return_zero
+
+00008$:
+ add a, #128
+ dec a
+ jnc 00009$
+ ljmp fs_return_inf
+
+00009$:
mov exp_a, a
// need extra bits on a's mantissa
subb a, r3
mov a, r7
subb a, r4
- jc 00005$
+ jc 00010$
dec exp_a
clr c
mov a, r2
clr a
rlc a
mov r4, a
- sjmp 00006$
-00005$:
+ sjmp 00011$
+00010$:
#endif
clr a
xch a, r4
xch a, r3
xch a, r2
mov r1, a
-00006$:
+00011$:
// begin long division
push exp_a
#else
mov b, #24
#endif
-00010$:
+00012$:
// compare
clr c
mov a, r1
subb a, #0 // carry==0 if mant1 >= mant2
#ifdef FLOAT_FULL_ACCURACY
- djnz b, 00011$
+ djnz b, 00013$
sjmp 00015$
-00011$:
+00013$:
#endif
- jc 00012$
+ jc 00014$
// subtract
mov a, r1
subb a, r5
mov r4, a
clr c
-00012$:
+00014$:
// shift result
cpl c
mov a, r0
mov r4, a
#ifdef FLOAT_FULL_ACCURACY
- sjmp 00010$
+ sjmp 00012$
00015$:
#else
- djnz b, 00010$
+ djnz b, 00012$
#endif
// now we've got a division result, so all we need to do
pop exp_a
jnc 00016$
inc exp_a
+ // incrementing exp_a without checking carry is dangerous
mov r4, #0x80
00016$:
#else
lcall fs_normalize_a
ljmp fs_zerocheck_return
- _endasm;
+ __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 */
-
union float_long
{
float f;
volatile long result;
volatile unsigned long mask;
volatile long mant1, mant2;
- volatile int exp ;
+ volatile int exp;
char sign;
fl1.f = a1;
/* divide by zero??? */
if (!fl2.l)
- /* return NaN or -NaN */
- return (-1.0);
+ {/* return NaN or -NaN */
+ fl2.l = 0x7FC00000;
+ return (fl2.f);
+ }
/* numerator zero??? */
if (!fl1.l)
result &= ~HIDDEN;
/* pack up and go home */
- fl1.l = PACK (sign ? 1ul<<31 : 0, (unsigned long) exp, result);
+ if (exp >= 0x100)
+ fl1.l = (sign ? SIGNBIT : 0) | __INFINITY;
+ else if (exp < 0)
+ fl1.l = 0;
+ else
+ fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result);
return (fl1.f);
}
#endif
-