blob: 1611176aae483a5a3139c454f3f991ab49830fd5 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2** libgcc support for software floating point.
3** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved.
4** Permission is granted to do *anything* you want with this file,
5** commercial or otherwise, provided this message remains intact. So there!
6** I would appreciate receiving any updates/patches/changes that anyone
7** makes, and am willing to be the repository for said changes (am I
8** making a big mistake?).
9
10Warning! Only single-precision is actually implemented. This file
11won't really be much use until double-precision is supported.
12
13However, once that is done, this file might eventually become a
14replacement for libgcc1.c. It might also make possible
15cross-compilation for an IEEE target machine from a non-IEEE
16host such as a VAX.
17
18If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
19
20--> Double precision floating support added by James Carlson on 20 April 1998.
21
22**
23** Pat Wood
24** Pipeline Associates, Inc.
25** pipeline!phw@motown.com or
26** sun!pipeline!phw or
27** uunet!motown!pipeline!phw
28**
29** 05/01/91 -- V1.0 -- first release to gcc mailing lists
30** 05/04/91 -- V1.1 -- added float and double prototypes and return values
31** -- fixed problems with adding and subtracting zero
32** -- fixed rounding in truncdfsf2
33** -- fixed SWAP define and tested on 386
34*/
35
36/*
37** The following are routines that replace the libgcc soft floating point
38** routines that are called automatically when -msoft-float is selected.
39** The support single and double precision IEEE format, with provisions
40** for byte-swapped machines (tested on 386). Some of the double-precision
41** routines work at full precision, but most of the hard ones simply punt
42** and call the single precision routines, producing a loss of accuracy.
43** long long support is not assumed or included.
44** Overall accuracy is close to IEEE (actually 68882) for single-precision
45** arithmetic. I think there may still be a 1 in 1000 chance of a bit
46** being rounded the wrong way during a multiply. I'm not fussy enough to
47** bother with it, but if anyone is, knock yourself out.
48**
49** Efficiency has only been addressed where it was obvious that something
50** would make a big difference. Anyone who wants to do this right for
51** best speed should go in and rewrite in assembler.
52**
53** I have tested this only on a 68030 workstation and 386/ix integrated
54** in with -msoft-float.
55*/
56
57#include "floatlib.h"
58
59/* convert double to int */
60long
61__fixdfsi (double a1)
62{
63 register union double_long dl1;
64 register int exp;
65 register long l;
66
67 dl1.d = a1;
68
69 if (!dl1.l.upper && !dl1.l.lower)
70 return (0);
71
72 exp = EXPD (dl1) - EXCESSD - 31;
73 l = MANTD (dl1);
74
75 if (exp > 0)
76 return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
77
78 /* shift down until exp = 0 or l = 0 */
79 if (exp < 0 && exp > -32 && l)
80 l >>= -exp;
81 else
82 return (0);
83
84 return (SIGND (dl1) ? -l : l);
85}