This source file includes following definitions.
- sgl_fmpy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "float.h"
30 #include "sgl_float.h"
31
32
33
34
35
36 int
37 sgl_fmpy(
38 sgl_floating_point *srcptr1,
39 sgl_floating_point *srcptr2,
40 sgl_floating_point *dstptr,
41 unsigned int *status)
42 {
43 register unsigned int opnd1, opnd2, opnd3, result;
44 register int dest_exponent, count;
45 register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
46 boolean is_tiny;
47
48 opnd1 = *srcptr1;
49 opnd2 = *srcptr2;
50
51
52
53 if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) Sgl_setnegativezero(result);
54 else Sgl_setzero(result);
55
56
57
58 if (Sgl_isinfinity_exponent(opnd1)) {
59 if (Sgl_iszero_mantissa(opnd1)) {
60 if (Sgl_isnotnan(opnd2)) {
61 if (Sgl_iszero_exponentmantissa(opnd2)) {
62
63
64
65
66 if (Is_invalidtrap_enabled())
67 return(INVALIDEXCEPTION);
68 Set_invalidflag();
69 Sgl_makequietnan(result);
70 *dstptr = result;
71 return(NOEXCEPTION);
72 }
73
74
75
76 Sgl_setinfinity_exponentmantissa(result);
77 *dstptr = result;
78 return(NOEXCEPTION);
79 }
80 }
81 else {
82
83
84
85 if (Sgl_isone_signaling(opnd1)) {
86
87 if (Is_invalidtrap_enabled())
88 return(INVALIDEXCEPTION);
89
90 Set_invalidflag();
91 Sgl_set_quiet(opnd1);
92 }
93
94
95
96 else if (Sgl_is_signalingnan(opnd2)) {
97
98 if (Is_invalidtrap_enabled())
99 return(INVALIDEXCEPTION);
100
101 Set_invalidflag();
102 Sgl_set_quiet(opnd2);
103 *dstptr = opnd2;
104 return(NOEXCEPTION);
105 }
106
107
108
109 *dstptr = opnd1;
110 return(NOEXCEPTION);
111 }
112 }
113
114
115
116 if (Sgl_isinfinity_exponent(opnd2)) {
117 if (Sgl_iszero_mantissa(opnd2)) {
118 if (Sgl_iszero_exponentmantissa(opnd1)) {
119
120 if (Is_invalidtrap_enabled())
121 return(INVALIDEXCEPTION);
122 Set_invalidflag();
123 Sgl_makequietnan(opnd2);
124 *dstptr = opnd2;
125 return(NOEXCEPTION);
126 }
127
128
129
130 Sgl_setinfinity_exponentmantissa(result);
131 *dstptr = result;
132 return(NOEXCEPTION);
133 }
134
135
136
137 if (Sgl_isone_signaling(opnd2)) {
138
139 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
140
141
142 Set_invalidflag();
143 Sgl_set_quiet(opnd2);
144 }
145
146
147
148 *dstptr = opnd2;
149 return(NOEXCEPTION);
150 }
151
152
153
154 dest_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS;
155
156
157
158
159 if (Sgl_isnotzero_exponent(opnd1)) {
160
161 Sgl_clear_signexponent_set_hidden(opnd1);
162 }
163 else {
164
165 if (Sgl_iszero_mantissa(opnd1)) {
166 Sgl_setzero_exponentmantissa(result);
167 *dstptr = result;
168 return(NOEXCEPTION);
169 }
170
171 Sgl_clear_signexponent(opnd1);
172 Sgl_leftshiftby1(opnd1);
173 Sgl_normalize(opnd1,dest_exponent);
174 }
175
176 if (Sgl_isnotzero_exponent(opnd2)) {
177 Sgl_clear_signexponent_set_hidden(opnd2);
178 }
179 else {
180
181 if (Sgl_iszero_mantissa(opnd2)) {
182 Sgl_setzero_exponentmantissa(result);
183 *dstptr = result;
184 return(NOEXCEPTION);
185 }
186
187 Sgl_clear_signexponent(opnd2);
188 Sgl_leftshiftby1(opnd2);
189 Sgl_normalize(opnd2,dest_exponent);
190 }
191
192
193
194 Sgl_leftshiftby4(opnd2);
195 Sgl_setzero(opnd3);
196
197
198
199
200 for (count=1;count<SGL_P;count+=4) {
201 stickybit |= Slow4(opnd3);
202 Sgl_rightshiftby4(opnd3);
203 if (Sbit28(opnd1)) Sall(opnd3) += (Sall(opnd2) << 3);
204 if (Sbit29(opnd1)) Sall(opnd3) += (Sall(opnd2) << 2);
205 if (Sbit30(opnd1)) Sall(opnd3) += (Sall(opnd2) << 1);
206 if (Sbit31(opnd1)) Sall(opnd3) += Sall(opnd2);
207 Sgl_rightshiftby4(opnd1);
208 }
209
210 if (Sgl_iszero_sign(opnd3)) {
211 Sgl_leftshiftby1(opnd3);
212 }
213 else {
214
215 dest_exponent++;
216 }
217
218 while (Sgl_iszero_sign(opnd3)) {
219 Sgl_leftshiftby1(opnd3);
220 dest_exponent--;
221 }
222
223
224
225 stickybit |= Sgl_all(opnd3) << (SGL_BITLENGTH - SGL_EXP_LENGTH + 1);
226 guardbit = Sbit24(opnd3);
227 inexact = guardbit | stickybit;
228
229
230 Sgl_rightshiftby8(opnd3);
231
232
233
234
235 if (inexact && (dest_exponent>0 || Is_underflowtrap_enabled())) {
236 Sgl_clear_signexponent(opnd3);
237 switch (Rounding_mode()) {
238 case ROUNDPLUS:
239 if (Sgl_iszero_sign(result))
240 Sgl_increment(opnd3);
241 break;
242 case ROUNDMINUS:
243 if (Sgl_isone_sign(result))
244 Sgl_increment(opnd3);
245 break;
246 case ROUNDNEAREST:
247 if (guardbit) {
248 if (stickybit || Sgl_isone_lowmantissa(opnd3))
249 Sgl_increment(opnd3);
250 }
251 }
252 if (Sgl_isone_hidden(opnd3)) dest_exponent++;
253 }
254 Sgl_set_mantissa(result,opnd3);
255
256
257
258
259 if (dest_exponent >= SGL_INFINITY_EXPONENT) {
260
261 if (Is_overflowtrap_enabled()) {
262
263
264
265 Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
266 *dstptr = result;
267 if (inexact)
268 if (Is_inexacttrap_enabled())
269 return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
270 else Set_inexactflag();
271 return(OVERFLOWEXCEPTION);
272 }
273 inexact = TRUE;
274 Set_overflowflag();
275
276 Sgl_setoverflow(result);
277 }
278
279
280
281 else if (dest_exponent <= 0) {
282
283 if (Is_underflowtrap_enabled()) {
284
285
286
287 Sgl_setwrapped_exponent(result,dest_exponent,unfl);
288 *dstptr = result;
289 if (inexact)
290 if (Is_inexacttrap_enabled())
291 return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
292 else Set_inexactflag();
293 return(UNDERFLOWEXCEPTION);
294 }
295
296
297 is_tiny = TRUE;
298 if (dest_exponent == 0 && inexact) {
299 switch (Rounding_mode()) {
300 case ROUNDPLUS:
301 if (Sgl_iszero_sign(result)) {
302 Sgl_increment(opnd3);
303 if (Sgl_isone_hiddenoverflow(opnd3))
304 is_tiny = FALSE;
305 Sgl_decrement(opnd3);
306 }
307 break;
308 case ROUNDMINUS:
309 if (Sgl_isone_sign(result)) {
310 Sgl_increment(opnd3);
311 if (Sgl_isone_hiddenoverflow(opnd3))
312 is_tiny = FALSE;
313 Sgl_decrement(opnd3);
314 }
315 break;
316 case ROUNDNEAREST:
317 if (guardbit && (stickybit ||
318 Sgl_isone_lowmantissa(opnd3))) {
319 Sgl_increment(opnd3);
320 if (Sgl_isone_hiddenoverflow(opnd3))
321 is_tiny = FALSE;
322 Sgl_decrement(opnd3);
323 }
324 break;
325 }
326 }
327
328
329
330
331 stickybit = inexact;
332 Sgl_denormalize(opnd3,dest_exponent,guardbit,stickybit,inexact);
333
334
335 if (inexact) {
336 switch (Rounding_mode()) {
337 case ROUNDPLUS:
338 if (Sgl_iszero_sign(result)) {
339 Sgl_increment(opnd3);
340 }
341 break;
342 case ROUNDMINUS:
343 if (Sgl_isone_sign(result)) {
344 Sgl_increment(opnd3);
345 }
346 break;
347 case ROUNDNEAREST:
348 if (guardbit && (stickybit ||
349 Sgl_isone_lowmantissa(opnd3))) {
350 Sgl_increment(opnd3);
351 }
352 break;
353 }
354 if (is_tiny) Set_underflowflag();
355 }
356 Sgl_set_exponentmantissa(result,opnd3);
357 }
358 else Sgl_set_exponent(result,dest_exponent);
359 *dstptr = result;
360
361
362 if (inexact) {
363 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
364 else Set_inexactflag();
365 }
366 return(NOEXCEPTION);
367 }