aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2015-08-13 03:56:36 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-09-03 06:08:14 -0400
commita79f5f9ba5088f157482feaa6ae2bacc9da0f5db (patch)
treec36121b8b1d714a96c96e07a2b6d6c3b64bb2e05
parent4e9561b20e2f5c1170704a81ec7e1ac961ba5e68 (diff)
MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction
MIPS R6 introduced the following instruction: Scalar Floating-Point Maximum and Scalar Floating-Point argument with Maximum Absolute Value MAX.fmt writes the maximum value of the inputs fs and ft to the destination fd. MAXA.fmt takes input arguments fs and ft and writes the argument with the maximum absolute value to the destination fd. Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10961/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/math-emu/Makefile4
-rw-r--r--arch/mips/math-emu/cp1emu.c48
-rw-r--r--arch/mips/math-emu/dp_fmax.c213
-rw-r--r--arch/mips/math-emu/ieee754.h4
-rw-r--r--arch/mips/math-emu/sp_fmax.c213
5 files changed, 480 insertions, 2 deletions
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
index b9946322804e..a19641d3ac23 100644
--- a/arch/mips/math-emu/Makefile
+++ b/arch/mips/math-emu/Makefile
@@ -4,9 +4,9 @@
4 4
5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ 5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ 6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
7 dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o dp_2008class.o dp_fmin.o \ 7 dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o dp_2008class.o dp_fmin.o dp_fmax.o \
8 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ 8 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
9 sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o sp_2008class.o sp_fmin.o \ 9 sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o sp_2008class.o sp_fmin.o sp_fmax.o \
10 dsemul.o 10 dsemul.o
11 11
12lib-y += ieee754d.o \ 12lib-y += ieee754d.o \
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index f397bdfd93fb..32f0e19a0d7f 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -1839,6 +1839,30 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1839 break; 1839 break;
1840 } 1840 }
1841 1841
1842 case fmax_op: {
1843 union ieee754sp fs, ft;
1844
1845 if (!cpu_has_mips_r6)
1846 return SIGILL;
1847
1848 SPFROMREG(ft, MIPSInst_FT(ir));
1849 SPFROMREG(fs, MIPSInst_FS(ir));
1850 rv.s = ieee754sp_fmax(fs, ft);
1851 break;
1852 }
1853
1854 case fmaxa_op: {
1855 union ieee754sp fs, ft;
1856
1857 if (!cpu_has_mips_r6)
1858 return SIGILL;
1859
1860 SPFROMREG(ft, MIPSInst_FT(ir));
1861 SPFROMREG(fs, MIPSInst_FS(ir));
1862 rv.s = ieee754sp_fmaxa(fs, ft);
1863 break;
1864 }
1865
1842 case fabs_op: 1866 case fabs_op:
1843 handler.u = ieee754sp_abs; 1867 handler.u = ieee754sp_abs;
1844 goto scopuop; 1868 goto scopuop;
@@ -2133,6 +2157,30 @@ copcsr:
2133 break; 2157 break;
2134 } 2158 }
2135 2159
2160 case fmax_op: {
2161 union ieee754dp fs, ft;
2162
2163 if (!cpu_has_mips_r6)
2164 return SIGILL;
2165
2166 DPFROMREG(ft, MIPSInst_FT(ir));
2167 DPFROMREG(fs, MIPSInst_FS(ir));
2168 rv.d = ieee754dp_fmax(fs, ft);
2169 break;
2170 }
2171
2172 case fmaxa_op: {
2173 union ieee754dp fs, ft;
2174
2175 if (!cpu_has_mips_r6)
2176 return SIGILL;
2177
2178 DPFROMREG(ft, MIPSInst_FT(ir));
2179 DPFROMREG(fs, MIPSInst_FS(ir));
2180 rv.d = ieee754dp_fmaxa(fs, ft);
2181 break;
2182 }
2183
2136 case fabs_op: 2184 case fabs_op:
2137 handler.u = ieee754dp_abs; 2185 handler.u = ieee754dp_abs;
2138 goto dcopuop; 2186 goto dcopuop;
diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c
new file mode 100644
index 000000000000..fd71b8daaaf2
--- /dev/null
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -0,0 +1,213 @@
1/*
2 * IEEE754 floating point arithmetic
3 * double precision: MIN{,A}.f
4 * MIN : Scalar Floating-Point Minimum
5 * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6 *
7 * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
8 * MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9 *
10 * MIPS floating point support
11 * Copyright (C) 2015 Imagination Technologies, Ltd.
12 * Author: Markos Chandras <markos.chandras@imgtec.com>
13 *
14 * This program is free software; you can distribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; version 2 of the License.
17 */
18
19#include "ieee754dp.h"
20
21union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
22{
23 COMPXDP;
24 COMPYDP;
25
26 EXPLODEXDP;
27 EXPLODEYDP;
28
29 FLUSHXDP;
30 FLUSHYDP;
31
32 ieee754_clearcx();
33
34 switch (CLPAIR(xc, yc)) {
35 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40 return ieee754dp_nanxcpt(y);
41
42 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754dp_nanxcpt(x);
49
50 /* numbers are preferred to NaNs */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x;
56
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62 return y;
63
64 /*
65 * Infinity and zero handling
66 */
67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72 return xs ? y : x;
73
74 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80 return ys ? x : y;
81
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys)
84 return x;
85 return ieee754dp_zero(1);
86
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 DPDNORMX;
89
90 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91 DPDNORMY;
92 break;
93
94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95 DPDNORMX;
96 }
97
98 /* Finally get to do some computation */
99
100 assert(xm & DP_HIDDEN_BIT);
101 assert(ym & DP_HIDDEN_BIT);
102
103 /* Compare signs */
104 if (xs > ys)
105 return y;
106 else if (xs < ys)
107 return x;
108
109 /* Compare exponent */
110 if (xe > ye)
111 return x;
112 else if (xe < ye)
113 return y;
114
115 /* Compare mantissa */
116 if (xm <= ym)
117 return y;
118 return x;
119}
120
121union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
122{
123 COMPXDP;
124 COMPYDP;
125
126 EXPLODEXDP;
127 EXPLODEYDP;
128
129 FLUSHXDP;
130 FLUSHYDP;
131
132 ieee754_clearcx();
133
134 switch (CLPAIR(xc, yc)) {
135 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140 return ieee754dp_nanxcpt(y);
141
142 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754dp_nanxcpt(x);
149
150 /* numbers are preferred to NaNs */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x;
156
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162 return y;
163
164 /*
165 * Infinity and zero handling
166 */
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x;
173
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180 return y;
181
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys)
184 return x;
185 return ieee754dp_zero(1);
186
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 DPDNORMX;
189
190 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191 DPDNORMY;
192 break;
193
194 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195 DPDNORMX;
196 }
197
198 /* Finally get to do some computation */
199
200 assert(xm & DP_HIDDEN_BIT);
201 assert(ym & DP_HIDDEN_BIT);
202
203 /* Compare exponent */
204 if (xe > ye)
205 return x;
206 else if (xe < ye)
207 return y;
208
209 /* Compare mantissa */
210 if (xm <= ym)
211 return y;
212 return x;
213}
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index 6a16357a1ddd..df94720714c7 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -82,6 +82,8 @@ union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
82int ieee754sp_2008class(union ieee754sp x); 82int ieee754sp_2008class(union ieee754sp x);
83union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y); 83union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y);
84union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y); 84union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y);
85union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y);
86union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y);
85 87
86/* 88/*
87 * double precision (often aka double) 89 * double precision (often aka double)
@@ -114,6 +116,8 @@ union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
114int ieee754dp_2008class(union ieee754dp x); 116int ieee754dp_2008class(union ieee754dp x);
115union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y); 117union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y);
116union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y); 118union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y);
119union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y);
120union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y);
117 121
118 122
119/* 5 types of floating point number 123/* 5 types of floating point number
diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c
new file mode 100644
index 000000000000..4d000844e48e
--- /dev/null
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -0,0 +1,213 @@
1/*
2 * IEEE754 floating point arithmetic
3 * single precision: MAX{,A}.f
4 * MAX : Scalar Floating-Point Maximum
5 * MAXA: Scalar Floating-Point argument with Maximum Absolute Value
6 *
7 * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
8 * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9 *
10 * MIPS floating point support
11 * Copyright (C) 2015 Imagination Technologies, Ltd.
12 * Author: Markos Chandras <markos.chandras@imgtec.com>
13 *
14 * This program is free software; you can distribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; version 2 of the License.
17 */
18
19#include "ieee754sp.h"
20
21union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
22{
23 COMPXSP;
24 COMPYSP;
25
26 EXPLODEXSP;
27 EXPLODEYSP;
28
29 FLUSHXSP;
30 FLUSHYSP;
31
32 ieee754_clearcx();
33
34 switch (CLPAIR(xc, yc)) {
35 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40 return ieee754sp_nanxcpt(y);
41
42 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754sp_nanxcpt(x);
49
50 /* numbers are preferred to NaNs */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x;
56
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62 return y;
63
64 /*
65 * Infinity and zero handling
66 */
67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72 return xs ? y : x;
73
74 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80 return ys ? x : y;
81
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys)
84 return x;
85 return ieee754sp_zero(1);
86
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 SPDNORMX;
89
90 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91 SPDNORMY;
92 break;
93
94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95 SPDNORMX;
96 }
97
98 /* Finally get to do some computation */
99
100 assert(xm & SP_HIDDEN_BIT);
101 assert(ym & SP_HIDDEN_BIT);
102
103 /* Compare signs */
104 if (xs > ys)
105 return y;
106 else if (xs < ys)
107 return x;
108
109 /* Compare exponent */
110 if (xe > ye)
111 return x;
112 else if (xe < ye)
113 return y;
114
115 /* Compare mantissa */
116 if (xm <= ym)
117 return y;
118 return x;
119}
120
121union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
122{
123 COMPXSP;
124 COMPYSP;
125
126 EXPLODEXSP;
127 EXPLODEYSP;
128
129 FLUSHXSP;
130 FLUSHYSP;
131
132 ieee754_clearcx();
133
134 switch (CLPAIR(xc, yc)) {
135 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140 return ieee754sp_nanxcpt(y);
141
142 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754sp_nanxcpt(x);
149
150 /* numbers are preferred to NaNs */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x;
156
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162 return y;
163
164 /*
165 * Infinity and zero handling
166 */
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x;
173
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180 return y;
181
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys)
184 return x;
185 return ieee754sp_zero(1);
186
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 SPDNORMX;
189
190 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191 SPDNORMY;
192 break;
193
194 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195 SPDNORMX;
196 }
197
198 /* Finally get to do some computation */
199
200 assert(xm & SP_HIDDEN_BIT);
201 assert(ym & SP_HIDDEN_BIT);
202
203 /* Compare exponent */
204 if (xe > ye)
205 return x;
206 else if (xe < ye)
207 return y;
208
209 /* Compare mantissa */
210 if (xm <= ym)
211 return y;
212 return x;
213}