File: /usr/src/linux/arch/mips64/math-emu/ieee754.c

1     /* ieee754 floating point arithmetic
2      * single and double precision
3      *
4      * BUGS
5      * not much dp done
6      * doesnt generate IEEE754_INEXACT
7      *
8      */
9     /*
10      * MIPS floating point support
11      * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
12      * http://www.algor.co.uk
13      *
14      * ########################################################################
15      *
16      *  This program is free software; you can distribute it and/or modify it
17      *  under the terms of the GNU General Public License (Version 2) as
18      *  published by the Free Software Foundation.
19      *
20      *  This program is distributed in the hope it will be useful, but WITHOUT
21      *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22      *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23      *  for more details.
24      *
25      *  You should have received a copy of the GNU General Public License along
26      *  with this program; if not, write to the Free Software Foundation, Inc.,
27      *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
28      *
29      * ########################################################################
30      */
31     
32     
33     #include "ieee754int.h"
34     
35     #define DP_EBIAS	1023
36     #define DP_EMIN		(-1022)
37     #define DP_EMAX		1023
38     
39     #define SP_EBIAS	127
40     #define SP_EMIN		(-126)
41     #define SP_EMAX		127
42     
43     /* indexed by class */
44     const char *const ieee754_cname[] = {
45     	"Normal",
46     	"Zero",
47     	"Denormal",
48     	"Infinity",
49     	"QNaN",
50     	"SNaN",
51     };
52     
53     /* the control status register 
54     */
55     struct ieee754_csr ieee754_csr;
56     
57     /* special constants
58     */
59     
60     
61     #if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
62     #define SPSTR(s,b,m) {m,b,s}
63     #define DPSTR(s,b,mh,ml) {ml,mh,b,s}
64     #endif
65     
66     #ifdef __MIPSEB__
67     #define SPSTR(s,b,m) {s,b,m}
68     #define DPSTR(s,b,mh,ml) {s,b,mh,ml}
69     #endif
70     
71     const struct ieee754dp_konst __ieee754dp_spcvals[] = {
72     	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* + zero   */
73     	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* - zero   */
74     	DPSTR(0, DP_EBIAS, 0, 0),	/* + 1.0   */
75     	DPSTR(1, DP_EBIAS, 0, 0),	/* - 1.0   */
76     	DPSTR(0, 3 + DP_EBIAS, 0x40000, 0),	/* + 10.0   */
77     	DPSTR(1, 3 + DP_EBIAS, 0x40000, 0),	/* - 10.0   */
78     	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* + infinity */
79     	DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* - infinity */
80     	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x40000, 0),	/* + indef quiet Nan */
81     	DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* + max */
82     	DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* - max */
83     	DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0),	/* + min normal */
84     	DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0),	/* - min normal */
85     	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* + min denormal */
86     	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* - min denormal */
87     	DPSTR(0, 31 + DP_EBIAS, 0, 0),	/* + 1.0e31 */
88     	DPSTR(0, 63 + DP_EBIAS, 0, 0),	/* + 1.0e63 */
89     };
90     
91     const struct ieee754sp_konst __ieee754sp_spcvals[] = {
92     	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0),	/* + zero   */
93     	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0),	/* - zero   */
94     	SPSTR(0, SP_EBIAS, 0),	/* + 1.0   */
95     	SPSTR(1, SP_EBIAS, 0),	/* - 1.0   */
96     	SPSTR(0, 3 + SP_EBIAS, 0x200000),	/* + 10.0   */
97     	SPSTR(1, 3 + SP_EBIAS, 0x200000),	/* - 10.0   */
98     	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0),	/* + infinity */
99     	SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0),	/* - infinity */
100     	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x200000),	/* + indef quiet Nan  */
101     	SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* + max normal */
102     	SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* - max normal */
103     	SPSTR(0, SP_EMIN + SP_EBIAS, 0),	/* + min normal */
104     	SPSTR(1, SP_EMIN + SP_EBIAS, 0),	/* - min normal */
105     	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1),	/* + min denormal */
106     	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1),	/* - min denormal */
107     	SPSTR(0, 31 + SP_EBIAS, 0),	/* + 1.0e31 */
108     	SPSTR(0, 63 + SP_EBIAS, 0),	/* + 1.0e63 */
109     };
110     
111     
112     int ieee754si_xcpt(int r, const char *op, ...)
113     {
114     	struct ieee754xctx ax;
115     
116     	if (!TSTX())
117     		return r;
118     	ax.op = op;
119     	ax.rt = IEEE754_RT_SI;
120     	ax.rv.si = r;
121     	va_start(ax.ap, op);
122     	ieee754_xcpt(&ax);
123     	return ax.rv.si;
124     }
125     
126     long long ieee754di_xcpt(long long r, const char *op, ...)
127     {
128     	struct ieee754xctx ax;
129     
130     	if (!TSTX())
131     		return r;
132     	ax.op = op;
133     	ax.rt = IEEE754_RT_DI;
134     	ax.rv.di = r;
135     	va_start(ax.ap, op);
136     	ieee754_xcpt(&ax);
137     	return ax.rv.di;
138     }
139