Annotation of sys/arch/hppa/spmath/fcnvfx.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: fcnvfx.c,v 1.7 2003/04/10 17:27:58 mickey Exp $ */
2: /*
3: (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4: To anyone who acknowledges that this file is provided "AS IS"
5: without any express or implied warranty:
6: permission to use, copy, modify, and distribute this file
7: for any purpose is hereby granted without fee, provided that
8: the above copyright notice and this notice appears in all
9: copies, and that the name of Hewlett-Packard Company not be
10: used in advertising or publicity pertaining to distribution
11: of the software without specific, written prior permission.
12: Hewlett-Packard Company makes no representations about the
13: suitability of this software for any purpose.
14: */
15: /* @(#)fcnvfx.c: Revision: 2.8.88.2 Date: 93/12/08 13:27:29 */
16:
17: #include "float.h"
18: #include "sgl_float.h"
19: #include "dbl_float.h"
20: #include "cnv_float.h"
21:
22: /*
23: * Single Floating-point to Single Fixed-point
24: */
25: /*ARGSUSED*/
26: int
27: sgl_to_sgl_fcnvfx(srcptr, null, dstptr, status)
28: sgl_floating_point *srcptr, *null;
29: int *dstptr;
30: unsigned int *status;
31: {
32: register unsigned int src, temp;
33: register int src_exponent, result;
34: register int inexact = FALSE;
35:
36: src = *srcptr;
37: src_exponent = Sgl_exponent(src) - SGL_BIAS;
38:
39: /*
40: * Test for overflow
41: */
42: if (src_exponent > SGL_FX_MAX_EXP) {
43: /* check for MININT */
44: if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
45: Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
46: if( Sgl_isnan(src) )
47: /*
48: * On NaN go unimplemented.
49: */
50: return(UNIMPLEMENTEDEXCEPTION);
51: else {
52: if (Sgl_iszero_sign(src)) result = 0x7fffffff;
53: else result = 0x80000000;
54:
55: if (Is_overflowtrap_enabled()) {
56: if (Is_inexacttrap_enabled())
57: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
58: else Set_inexactflag();
59: return(OVERFLOWEXCEPTION);
60: }
61: Set_overflowflag();
62: *dstptr = result;
63: if (Is_inexacttrap_enabled() )
64: return(INEXACTEXCEPTION);
65: else Set_inexactflag();
66: return(NOEXCEPTION);
67: }
68: }
69: }
70: /*
71: * Generate result
72: */
73: if (src_exponent >= 0) {
74: temp = src;
75: Sgl_clear_signexponent_set_hidden(temp);
76: Int_from_sgl_mantissa(temp,src_exponent);
77: if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
78: else result = Sgl_all(temp);
79:
80: /* check for inexact */
81: if (Sgl_isinexact_to_fix(src,src_exponent)) {
82: inexact = TRUE;
83: /* round result */
84: switch (Rounding_mode()) {
85: case ROUNDPLUS:
86: if (Sgl_iszero_sign(src)) result++;
87: break;
88: case ROUNDMINUS:
89: if (Sgl_isone_sign(src)) result--;
90: break;
91: case ROUNDNEAREST:
92: if (Sgl_isone_roundbit(src,src_exponent)) {
93: if (Sgl_isone_stickybit(src,src_exponent)
94: || (Sgl_isone_lowmantissa(temp))) {
95: if (Sgl_iszero_sign(src)) result++;
96: else result--;
97: }
98: }
99: }
100: }
101: }
102: else {
103: result = 0;
104:
105: /* check for inexact */
106: if (Sgl_isnotzero_exponentmantissa(src)) {
107: inexact = TRUE;
108: /* round result */
109: switch (Rounding_mode()) {
110: case ROUNDPLUS:
111: if (Sgl_iszero_sign(src)) result++;
112: break;
113: case ROUNDMINUS:
114: if (Sgl_isone_sign(src)) result--;
115: break;
116: case ROUNDNEAREST:
117: if (src_exponent == -1)
118: if (Sgl_isnotzero_mantissa(src)) {
119: if (Sgl_iszero_sign(src)) result++;
120: else result--;
121: }
122: }
123: }
124: }
125: *dstptr = result;
126: if (inexact) {
127: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
128: else Set_inexactflag();
129: }
130: return(NOEXCEPTION);
131: }
132:
133: /*
134: * Single Floating-point to Double Fixed-point
135: */
136: /*ARGSUSED*/
137: int
138: sgl_to_dbl_fcnvfx(srcptr, null, dstptr, status)
139: sgl_floating_point *srcptr, *null;
140: dbl_integer *dstptr;
141: unsigned int *status;
142: {
143: register int src_exponent, resultp1;
144: register unsigned int src, temp, resultp2;
145: register int inexact = FALSE;
146:
147: src = *srcptr;
148: src_exponent = Sgl_exponent(src) - SGL_BIAS;
149:
150: /*
151: * Test for overflow
152: */
153: if (src_exponent > DBL_FX_MAX_EXP) {
154: /* check for MININT */
155: if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
156: Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
157: if( Sgl_isnan(src) )
158: /*
159: * On NaN go unimplemented.
160: */
161: return(UNIMPLEMENTEDEXCEPTION);
162: else {
163: if (Sgl_iszero_sign(src)) {
164: resultp1 = 0x7fffffff;
165: resultp2 = 0xffffffff;
166: }
167: else {
168: resultp1 = 0x80000000;
169: resultp2 = 0;
170: }
171: if (Is_overflowtrap_enabled()) {
172: if (Is_inexacttrap_enabled())
173: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
174: else Set_inexactflag();
175: return(OVERFLOWEXCEPTION);
176: }
177: Set_overflowflag();
178: Dint_copytoptr(resultp1,resultp2,dstptr);
179: if (Is_inexacttrap_enabled() )
180: return(INEXACTEXCEPTION);
181: else Set_inexactflag();
182: return(NOEXCEPTION);
183: }
184: }
185: Dint_set_minint(resultp1,resultp2);
186: Dint_copytoptr(resultp1,resultp2,dstptr);
187: return(NOEXCEPTION);
188: }
189: /*
190: * Generate result
191: */
192: if (src_exponent >= 0) {
193: temp = src;
194: Sgl_clear_signexponent_set_hidden(temp);
195: Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
196: if (Sgl_isone_sign(src)) {
197: Dint_setone_sign(resultp1,resultp2);
198: }
199:
200: /* check for inexact */
201: if (Sgl_isinexact_to_fix(src,src_exponent)) {
202: inexact = TRUE;
203: /* round result */
204: switch (Rounding_mode()) {
205: case ROUNDPLUS:
206: if (Sgl_iszero_sign(src)) {
207: Dint_increment(resultp1,resultp2);
208: }
209: break;
210: case ROUNDMINUS:
211: if (Sgl_isone_sign(src)) {
212: Dint_decrement(resultp1,resultp2);
213: }
214: break;
215: case ROUNDNEAREST:
216: if (Sgl_isone_roundbit(src,src_exponent))
217: if (Sgl_isone_stickybit(src,src_exponent) ||
218: (Dint_isone_lowp2(resultp2))) {
219: if (Sgl_iszero_sign(src)) {
220: Dint_increment(resultp1,resultp2);
221: }
222: else {
223: Dint_decrement(resultp1,resultp2);
224: }
225: }
226: }
227: }
228: }
229: else {
230: Dint_setzero(resultp1,resultp2);
231:
232: /* check for inexact */
233: if (Sgl_isnotzero_exponentmantissa(src)) {
234: inexact = TRUE;
235: /* round result */
236: switch (Rounding_mode()) {
237: case ROUNDPLUS:
238: if (Sgl_iszero_sign(src)) {
239: Dint_increment(resultp1,resultp2);
240: }
241: break;
242: case ROUNDMINUS:
243: if (Sgl_isone_sign(src)) {
244: Dint_decrement(resultp1,resultp2);
245: }
246: break;
247: case ROUNDNEAREST:
248: if (src_exponent == -1)
249: if (Sgl_isnotzero_mantissa(src)) {
250: if (Sgl_iszero_sign(src)) {
251: Dint_increment(resultp1,resultp2);
252: }
253: else {
254: Dint_decrement(resultp1,resultp2);
255: }
256: }
257: }
258: }
259: }
260: Dint_copytoptr(resultp1,resultp2,dstptr);
261: if (inexact) {
262: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
263: else Set_inexactflag();
264: }
265: return(NOEXCEPTION);
266: }
267:
268: /*
269: * Double Floating-point to Single Fixed-point
270: */
271: /*ARGSUSED*/
272: int
273: dbl_to_sgl_fcnvfx(srcptr, null, dstptr, status)
274: dbl_floating_point *srcptr, *null;
275: int *dstptr;
276: unsigned int *status;
277: {
278: register unsigned int srcp1,srcp2, tempp1,tempp2;
279: register int src_exponent, result;
280: register int inexact = FALSE;
281:
282: Dbl_copyfromptr(srcptr,srcp1,srcp2);
283: src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
284:
285: /*
286: * Test for overflow
287: */
288: if (src_exponent > SGL_FX_MAX_EXP) {
289: /* check for MININT */
290: if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
291: if( Dbl_isnan(srcp1,srcp2) )
292: /*
293: * On NaN go unimplemented.
294: */
295: return(UNIMPLEMENTEDEXCEPTION);
296: else {
297: if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
298: else result = 0x80000000;
299:
300: if (Is_overflowtrap_enabled()) {
301: if (Is_inexacttrap_enabled())
302: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
303: else Set_inexactflag();
304: return(OVERFLOWEXCEPTION);
305: }
306: Set_overflowflag();
307: *dstptr = result;
308: if (Is_inexacttrap_enabled() )
309: return(INEXACTEXCEPTION);
310: else Set_inexactflag();
311: return(NOEXCEPTION);
312: }
313: }
314: }
315: /*
316: * Generate result
317: */
318: if (src_exponent >= 0) {
319: tempp1 = srcp1;
320: tempp2 = srcp2;
321: Dbl_clear_signexponent_set_hidden(tempp1);
322: Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
323: if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
324: result = -Dbl_allp1(tempp1);
325: else result = Dbl_allp1(tempp1);
326:
327: /* check for inexact */
328: if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
329: inexact = TRUE;
330: /* round result */
331: switch (Rounding_mode()) {
332: case ROUNDPLUS:
333: if (Dbl_iszero_sign(srcp1))
334: result++;
335: break;
336: case ROUNDMINUS:
337: if (Dbl_isone_sign(srcp1)) result--;
338: break;
339: case ROUNDNEAREST:
340: if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
341: if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
342: (Dbl_isone_lowmantissap1(tempp1))) {
343: if (Dbl_iszero_sign(srcp1)) result++;
344: else result--;
345: }
346: }
347: /* check for overflow */
348: if ((Dbl_iszero_sign(srcp1) && result < 0) ||
349: (Dbl_isone_sign(srcp1) && result > 0)) {
350:
351: if (Dbl_iszero_sign(srcp1))
352: result = 0x7fffffff;
353: else
354: result = 0x80000000;
355:
356: if (Is_overflowtrap_enabled()) {
357: if (Is_inexacttrap_enabled())
358: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
359: else Set_inexactflag();
360: return(OVERFLOWEXCEPTION);
361: }
362: Set_overflowflag();
363: *dstptr = result;
364: if (Is_inexacttrap_enabled() )
365: return(INEXACTEXCEPTION);
366: else Set_inexactflag();
367: return(NOEXCEPTION);
368: }
369: }
370: }
371: else {
372: result = 0;
373:
374: /* check for inexact */
375: if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
376: inexact = TRUE;
377: /* round result */
378: switch (Rounding_mode()) {
379: case ROUNDPLUS:
380: if (Dbl_iszero_sign(srcp1)) result++;
381: break;
382: case ROUNDMINUS:
383: if (Dbl_isone_sign(srcp1)) result--;
384: break;
385: case ROUNDNEAREST:
386: if (src_exponent == -1)
387: if (Dbl_isnotzero_mantissa(srcp1,srcp2)) {
388: if (Dbl_iszero_sign(srcp1)) result++;
389: else result--;
390: }
391: }
392: }
393: }
394: *dstptr = result;
395: if (inexact) {
396: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
397: else Set_inexactflag();
398: }
399: return(NOEXCEPTION);
400: }
401:
402: /*
403: * Double Floating-point to Double Fixed-point
404: */
405: /*ARGSUSED*/
406: int
407: dbl_to_dbl_fcnvfx(srcptr, null, dstptr, status)
408: dbl_floating_point *srcptr, *null;
409: dbl_integer *dstptr;
410: unsigned int *status;
411: {
412: register int src_exponent, resultp1;
413: register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
414: register int inexact = FALSE;
415:
416: Dbl_copyfromptr(srcptr,srcp1,srcp2);
417: src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
418:
419: /*
420: * Test for overflow
421: */
422: if (src_exponent > DBL_FX_MAX_EXP) {
423: /* check for MININT */
424: if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
425: Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
426: if( Dbl_isnan(srcp1,srcp2) )
427: /*
428: * On NaN go unimplemented.
429: */
430: return(UNIMPLEMENTEDEXCEPTION);
431: else {
432: if (Dbl_iszero_sign(srcp1)) {
433: resultp1 = 0x7fffffff;
434: resultp2 = 0xffffffff;
435: }
436: else {
437: resultp1 = 0x80000000;
438: resultp2 = 0;
439: }
440: if (Is_overflowtrap_enabled()) {
441: if (Is_inexacttrap_enabled())
442: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
443: else Set_inexactflag();
444: return(OVERFLOWEXCEPTION);
445: }
446: Set_overflowflag();
447: Dint_copytoptr(resultp1,resultp2,dstptr);
448: if (Is_inexacttrap_enabled() )
449: return(INEXACTEXCEPTION);
450: else Set_inexactflag();
451: return(NOEXCEPTION);
452: }
453: }
454: }
455:
456: /*
457: * Generate result
458: */
459: if (src_exponent >= 0) {
460: tempp1 = srcp1;
461: tempp2 = srcp2;
462: Dbl_clear_signexponent_set_hidden(tempp1);
463: Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
464: resultp1, resultp2);
465: if (Dbl_isone_sign(srcp1)) {
466: Dint_setone_sign(resultp1,resultp2);
467: }
468:
469: /* check for inexact */
470: if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
471: inexact = TRUE;
472: /* round result */
473: switch (Rounding_mode()) {
474: case ROUNDPLUS:
475: if (Dbl_iszero_sign(srcp1)) {
476: Dint_increment(resultp1,resultp2);
477: }
478: break;
479: case ROUNDMINUS:
480: if (Dbl_isone_sign(srcp1)) {
481: Dint_decrement(resultp1,resultp2);
482: }
483: break;
484: case ROUNDNEAREST:
485: if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
486: if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
487: (Dint_isone_lowp2(resultp2))) {
488: if (Dbl_iszero_sign(srcp1)) {
489: Dint_increment(resultp1,resultp2);
490: }
491: else {
492: Dint_decrement(resultp1,resultp2);
493: }
494: }
495: }
496: }
497: }
498: else {
499: Dint_setzero(resultp1,resultp2);
500:
501: /* check for inexact */
502: if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
503: inexact = TRUE;
504: /* round result */
505: switch (Rounding_mode()) {
506: case ROUNDPLUS:
507: if (Dbl_iszero_sign(srcp1)) {
508: Dint_increment(resultp1,resultp2);
509: }
510: break;
511: case ROUNDMINUS:
512: if (Dbl_isone_sign(srcp1)) {
513: Dint_decrement(resultp1,resultp2);
514: }
515: break;
516: case ROUNDNEAREST:
517: if (src_exponent == -1)
518: if (Dbl_isnotzero_mantissa(srcp1,srcp2)) {
519: if (Dbl_iszero_sign(srcp1)) {
520: Dint_increment(resultp1,resultp2);
521: }
522: else {
523: Dint_decrement(resultp1,resultp2);
524: }
525: }
526: }
527: }
528: }
529: Dint_copytoptr(resultp1,resultp2,dstptr);
530: if (inexact) {
531: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
532: else Set_inexactflag();
533: }
534: return(NOEXCEPTION);
535: }
CVSweb