]> git.gag.com Git - fw/sdcc/blob - device/lib/_fs2slong.c
Better handling of floats between -1.0 and 0.0
[fw/sdcc] / device / lib / _fs2slong.c
1 /* Floating point library in optimized assembly for 8051
2  * Copyright (c) 2004, Paul Stoffregen, paul@pjrc.com
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19
20 #define SDCC_FLOAT_LIB
21 #include <float.h>
22
23
24 #ifdef FLOAT_ASM_MCS51
25
26 // long __fs2slong (float x)
27 static void dummy(void) _naked
28 {
29         _asm
30         .globl  ___fs2slong
31 ___fs2slong:
32         lcall   fsgetarg
33         clr     c
34         mov     a, #158
35         subb    a, exp_a
36         jc      fs2slong_maxval         //  |x| >= 2^32
37 fs2slong_int_ok:
38         mov     r1, #0
39         lcall   fs_rshift_a
40         jnb     sign_a, fs2slong_pos
41 fs2slong_neg:
42         mov     a, r1
43         cpl     a
44         add     a, #1
45         mov     dpl, a
46         mov     a, r2
47         cpl     a
48         addc    a, #0
49         mov     dph, a
50         mov     a, r3
51         cpl     a
52         addc    a, #0
53         mov     b, a
54         mov     a, r4
55         cpl     a
56         addc    a, #0
57         //Check for zero
58         push acc
59         jnz fs2slong_not_zero
60         mov a, dpl
61         jnz fs2slong_not_zero
62         mov a, dph
63         jnz fs2slong_not_zero
64         mov a, b
65         jnz fs2slong_not_zero
66     pop acc
67     ret
68 fs2slong_not_zero:
69         pop acc
70         jnb acc.7, fs2slong_maxval_neg  // x < -0x80000000
71         ret
72 fs2slong_pos:
73         mov     a, r4
74         jb      acc.7, fs2slong_maxval_pos  //  x > 0x7FFFFFFF
75         mov     dpl, r1
76         mov     dph, r2
77         mov     b, r3
78         ret
79 fs2slong_maxval:
80         jnb     sign_a, fs2slong_maxval_pos
81 fs2slong_maxval_neg:
82         clr     a
83         mov     dpl, a
84         mov     dph, a
85         mov     b, a
86         mov     a, #0x80
87         ret
88 fs2slong_maxval_pos:
89         mov     a, #0xFF
90         mov     dpl, a
91         mov     dph, a
92         mov     b, a
93         mov     a, #0x7F
94         ret
95         _endasm;
96 }
97
98 #else
99
100
101 /* convert float to signed long */
102 signed long __fs2slong (float f) {
103
104   if (!f)
105     return 0;
106
107   if (f<0) {
108     return -__fs2ulong(-f);
109   } else {
110     return __fs2ulong(f);
111   }
112 }
113
114 #endif