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
30
31
32
33
34
35
36
37
38
39
40
41
42#include "float.h"
43#include "sgl_float.h"
44
45
46
47
48int
49sgl_fadd(
50 sgl_floating_point *leftptr,
51 sgl_floating_point *rightptr,
52 sgl_floating_point *dstptr,
53 unsigned int *status)
54 {
55 register unsigned int left, right, result, extent;
56 register unsigned int signless_upper_left, signless_upper_right, save;
57
58
59 register int result_exponent, right_exponent, diff_exponent;
60 register int sign_save, jumpsize;
61 register boolean inexact = FALSE;
62 register boolean underflowtrap;
63
64
65 left = *leftptr;
66 right = *rightptr;
67
68
69
70 Sgl_xortointp1(left,right,save);
71
72
73
74
75 if ((result_exponent = Sgl_exponent(left)) == SGL_INFINITY_EXPONENT)
76 {
77 if (Sgl_iszero_mantissa(left))
78 {
79 if (Sgl_isnotnan(right))
80 {
81 if (Sgl_isinfinity(right) && save!=0)
82 {
83
84
85
86 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
87 Set_invalidflag();
88 Sgl_makequietnan(result);
89 *dstptr = result;
90 return(NOEXCEPTION);
91 }
92
93
94
95 *dstptr = left;
96 return(NOEXCEPTION);
97 }
98 }
99 else
100 {
101
102
103
104 if (Sgl_isone_signaling(left))
105 {
106
107 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
108
109 Set_invalidflag();
110 Sgl_set_quiet(left);
111 }
112
113
114
115 else if (Sgl_is_signalingnan(right))
116 {
117
118 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
119
120 Set_invalidflag();
121 Sgl_set_quiet(right);
122 *dstptr = right;
123 return(NOEXCEPTION);
124 }
125
126
127
128 *dstptr = left;
129 return(NOEXCEPTION);
130 }
131 }
132
133
134
135 if (Sgl_isinfinity_exponent(right))
136 {
137 if (Sgl_iszero_mantissa(right))
138 {
139
140 *dstptr = right;
141 return(NOEXCEPTION);
142 }
143
144
145
146 if (Sgl_isone_signaling(right))
147 {
148
149 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
150
151 Set_invalidflag();
152 Sgl_set_quiet(right);
153 }
154
155
156
157 *dstptr = right;
158 return(NOEXCEPTION);
159 }
160
161
162
163
164 Sgl_copytoint_exponentmantissa(left,signless_upper_left);
165 Sgl_copytoint_exponentmantissa(right,signless_upper_right);
166
167
168 if(Sgl_ismagnitudeless(signless_upper_left,signless_upper_right))
169 {
170
171
172 Sgl_xorfromintp1(save,right,right);
173 Sgl_xorfromintp1(save,left,left);
174 result_exponent = Sgl_exponent(left);
175 }
176
177
178 if((right_exponent = Sgl_exponent(right)) == 0)
179 {
180
181 if(Sgl_iszero_mantissa(right))
182 {
183
184 if(Sgl_iszero_exponentmantissa(left))
185 {
186
187 if(Is_rounding_mode(ROUNDMINUS))
188 {
189 Sgl_or_signs(left,right);
190 }
191 else
192 {
193 Sgl_and_signs(left,right);
194 }
195 }
196 else
197 {
198
199
200
201 if( (result_exponent == 0) && Is_underflowtrap_enabled() )
202 {
203
204 sign_save = Sgl_signextendedsign(left);
205 Sgl_leftshiftby1(left);
206 Sgl_normalize(left,result_exponent);
207 Sgl_set_sign(left,sign_save);
208 Sgl_setwrapped_exponent(left,result_exponent,unfl);
209 *dstptr = left;
210 return(UNDERFLOWEXCEPTION);
211 }
212 }
213 *dstptr = left;
214 return(NOEXCEPTION);
215 }
216
217
218 Sgl_clear_sign(right);
219 if(result_exponent == 0 )
220 {
221
222
223
224 if( (int) save < 0 )
225 {
226 Sgl_subtract(left,right,result);
227 if(Sgl_iszero_mantissa(result))
228 {
229 if(Is_rounding_mode(ROUNDMINUS))
230 {
231 Sgl_setone_sign(result);
232 }
233 else
234 {
235 Sgl_setzero_sign(result);
236 }
237 *dstptr = result;
238 return(NOEXCEPTION);
239 }
240 }
241 else
242 {
243 Sgl_addition(left,right,result);
244 if(Sgl_isone_hidden(result))
245 {
246 *dstptr = result;
247 return(NOEXCEPTION);
248 }
249 }
250 if(Is_underflowtrap_enabled())
251 {
252
253 sign_save = Sgl_signextendedsign(result);
254 Sgl_leftshiftby1(result);
255 Sgl_normalize(result,result_exponent);
256 Sgl_set_sign(result,sign_save);
257 Sgl_setwrapped_exponent(result,result_exponent,unfl);
258 *dstptr = result;
259 return(UNDERFLOWEXCEPTION);
260 }
261 *dstptr = result;
262 return(NOEXCEPTION);
263 }
264 right_exponent = 1;
265
266 }
267 else
268 {
269 Sgl_clear_signexponent_set_hidden(right);
270 }
271 Sgl_clear_exponent_set_hidden(left);
272 diff_exponent = result_exponent - right_exponent;
273
274
275
276
277
278
279
280 if(diff_exponent > SGL_THRESHOLD)
281 {
282 diff_exponent = SGL_THRESHOLD;
283 }
284
285
286 Sgl_right_align(right,diff_exponent,
287 extent);
288
289
290 if( (int) save < 0 )
291 {
292
293
294
295
296
297 Sgl_subtract_withextension(left,right,extent,result);
298 if(Sgl_iszero_hidden(result))
299 {
300
301
302
303
304
305
306
307
308
309
310 sign_save = Sgl_signextendedsign(result);
311 Sgl_leftshiftby1_withextent(result,extent,result);
312
313
314
315
316
317 if(Sgl_iszero(result))
318
319 {
320 if(Is_rounding_mode(ROUNDMINUS)) Sgl_setone_sign(result);
321 *dstptr = result;
322 return(NOEXCEPTION);
323 }
324 result_exponent--;
325
326 if(Sgl_isone_hidden(result))
327 {
328 if(result_exponent==0)
329 {
330
331
332 goto underflow;
333 }
334 else
335 {
336
337 Sgl_set_sign(result,sign_save);
338 Ext_leftshiftby1(extent);
339 goto round;
340 }
341 }
342
343
344
345 if(!(underflowtrap = Is_underflowtrap_enabled()) &&
346 result_exponent==0) goto underflow;
347
348
349
350 Ext_leftshiftby1(extent);
351
352
353
354
355
356
357 while(Sgl_iszero_hiddenhigh7mantissa(result))
358 {
359 Sgl_leftshiftby8(result);
360 if((result_exponent -= 8) <= 0 && !underflowtrap)
361 goto underflow;
362 }
363
364 if(Sgl_iszero_hiddenhigh3mantissa(result))
365 {
366
367 Sgl_leftshiftby4(result);
368 if((result_exponent -= 4) <= 0 && !underflowtrap)
369 goto underflow;
370 }
371
372
373 if((jumpsize = Sgl_hiddenhigh3mantissa(result)) > 7)
374 {
375
376 if(result_exponent <= 0) goto underflow;
377 Sgl_set_sign(result,sign_save);
378 Sgl_set_exponent(result,result_exponent);
379 *dstptr = result;
380 return(NOEXCEPTION);
381 }
382 Sgl_sethigh4bits(result,sign_save);
383 switch(jumpsize)
384 {
385 case 1:
386 {
387 Sgl_leftshiftby3(result);
388 result_exponent -= 3;
389 break;
390 }
391 case 2:
392 case 3:
393 {
394 Sgl_leftshiftby2(result);
395 result_exponent -= 2;
396 break;
397 }
398 case 4:
399 case 5:
400 case 6:
401 case 7:
402 {
403 Sgl_leftshiftby1(result);
404 result_exponent -= 1;
405 break;
406 }
407 }
408 if(result_exponent > 0)
409 {
410 Sgl_set_exponent(result,result_exponent);
411 *dstptr = result;
412 return(NOEXCEPTION);
413 }
414
415 underflow:
416 if(Is_underflowtrap_enabled())
417 {
418 Sgl_set_sign(result,sign_save);
419 Sgl_setwrapped_exponent(result,result_exponent,unfl);
420 *dstptr = result;
421
422 return(UNDERFLOWEXCEPTION);
423 }
424
425
426
427
428 Sgl_right_align(result,(1-result_exponent),extent);
429 Sgl_clear_signexponent(result);
430 Sgl_set_sign(result,sign_save);
431 *dstptr = result;
432 return(NOEXCEPTION);
433 }
434
435 }
436 else
437 {
438
439 Sgl_addition(left,right,result);
440 if(Sgl_isone_hiddenoverflow(result))
441 {
442
443 Sgl_rightshiftby1_withextent(result,extent,extent);
444 Sgl_arithrightshiftby1(result);
445 result_exponent++;
446 }
447 }
448
449
450
451
452
453 round:
454 if(Ext_isnotzero(extent))
455 {
456 inexact = TRUE;
457 switch(Rounding_mode())
458 {
459 case ROUNDNEAREST:
460 if(Ext_isone_sign(extent))
461 {
462
463 if(Ext_isnotzero_lower(extent) ||
464 Sgl_isone_lowmantissa(result))
465 {
466
467 Sgl_increment(result);
468 }
469 }
470 break;
471
472 case ROUNDPLUS:
473 if(Sgl_iszero_sign(result))
474 {
475
476 Sgl_increment(result);
477 }
478 break;
479
480 case ROUNDMINUS:
481 if(Sgl_isone_sign(result))
482 {
483
484 Sgl_increment(result);
485 }
486
487 case ROUNDZERO:;
488
489 }
490 if(Sgl_isone_hiddenoverflow(result)) result_exponent++;
491 }
492 if(result_exponent == SGL_INFINITY_EXPONENT)
493 {
494
495 if(Is_overflowtrap_enabled())
496 {
497 Sgl_setwrapped_exponent(result,result_exponent,ovfl);
498 *dstptr = result;
499 if (inexact)
500 if (Is_inexacttrap_enabled())
501 return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
502 else Set_inexactflag();
503 return(OVERFLOWEXCEPTION);
504 }
505 else
506 {
507 Set_overflowflag();
508 inexact = TRUE;
509 Sgl_setoverflow(result);
510 }
511 }
512 else Sgl_set_exponent(result,result_exponent);
513 *dstptr = result;
514 if(inexact)
515 if(Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
516 else Set_inexactflag();
517 return(NOEXCEPTION);
518 }
519