[BACK]Return to fcnvff.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa / spmath

Annotation of sys/arch/hppa/spmath/fcnvff.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: fcnvff.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: /* @(#)fcnvff.c: Revision: 2.8.88.1 Date: 93/12/07 15:06:09 */
                     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 Double Floating-point
                     24:  */
                     25: /*ARGSUSED*/
                     26: int
                     27: sgl_to_dbl_fcnvff(srcptr, null, dstptr, status)
                     28:        sgl_floating_point *srcptr, *null;
                     29:        dbl_floating_point *dstptr;
                     30:        unsigned int *status;
                     31: {
                     32:        register unsigned int src, resultp1, resultp2;
                     33:        register int src_exponent;
                     34:
                     35:        src = *srcptr;
                     36:        src_exponent = Sgl_exponent(src);
                     37:        Dbl_allp1(resultp1) = Sgl_all(src);  /* set sign of result */
                     38:        /*
                     39:         * Test for NaN or infinity
                     40:         */
                     41:        if (src_exponent == SGL_INFINITY_EXPONENT) {
                     42:                /*
                     43:                 * determine if NaN or infinity
                     44:                 */
                     45:                if (Sgl_iszero_mantissa(src)) {
                     46:                        /*
                     47:                         * is infinity; want to return double infinity
                     48:                         */
                     49:                        Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
                     50:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                     51:                        return(NOEXCEPTION);
                     52:                }
                     53:                else {
                     54:                        /*
                     55:                         * is NaN; signaling or quiet?
                     56:                         */
                     57:                        if (Sgl_isone_signaling(src)) {
                     58:                                /* trap if INVALIDTRAP enabled */
                     59:                                if (Is_invalidtrap_enabled())
                     60:                                        return(INVALIDEXCEPTION);
                     61:                                /* make NaN quiet */
                     62:                                else {
                     63:                                        Set_invalidflag();
                     64:                                        Sgl_set_quiet(src);
                     65:                                }
                     66:                        }
                     67:                        /*
                     68:                         * NaN is quiet, return as double NaN
                     69:                         */
                     70:                        Dbl_setinfinity_exponent(resultp1);
                     71:                        Sgl_to_dbl_mantissa(src,resultp1,resultp2);
                     72:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                     73:                        return(NOEXCEPTION);
                     74:                }
                     75:        }
                     76:        /*
                     77:         * Test for zero or denormalized
                     78:         */
                     79:        if (src_exponent == 0) {
                     80:                /*
                     81:                 * determine if zero or denormalized
                     82:                 */
                     83:                if (Sgl_isnotzero_mantissa(src)) {
                     84:                        /*
                     85:                         * is denormalized; want to normalize
                     86:                         */
                     87:                        Sgl_clear_signexponent(src);
                     88:                        Sgl_leftshiftby1(src);
                     89:                        Sgl_normalize(src,src_exponent);
                     90:                        Sgl_to_dbl_exponent(src_exponent,resultp1);
                     91:                        Sgl_to_dbl_mantissa(src,resultp1,resultp2);
                     92:                }
                     93:                else {
                     94:                        Dbl_setzero_exponentmantissa(resultp1,resultp2);
                     95:                }
                     96:                Dbl_copytoptr(resultp1,resultp2,dstptr);
                     97:                return(NOEXCEPTION);
                     98:        }
                     99:        /*
                    100:         * No special cases, just complete the conversion
                    101:         */
                    102:        Sgl_to_dbl_exponent(src_exponent, resultp1);
                    103:        Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
                    104:        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    105:        return(NOEXCEPTION);
                    106: }
                    107:
                    108: /*
                    109:  *  Double Floating-point to Single Floating-point
                    110:  */
                    111: /*ARGSUSED*/
                    112: int
                    113: dbl_to_sgl_fcnvff(srcptr, null, dstptr, status)
                    114:        dbl_floating_point *srcptr, *null;
                    115:        sgl_floating_point *dstptr;
                    116:        unsigned int *status;
                    117: {
                    118:        register unsigned int srcp1, srcp2, result;
                    119:        register int src_exponent, dest_exponent, dest_mantissa;
                    120:        register int inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
                    121:        register int lsb_odd = FALSE;
                    122:        int is_tiny;
                    123:
                    124:        Dbl_copyfromptr(srcptr,srcp1,srcp2);
                    125:        src_exponent = Dbl_exponent(srcp1);
                    126:        Sgl_all(result) = Dbl_allp1(srcp1);  /* set sign of result */
                    127:        /*
                    128:         * Test for NaN or infinity
                    129:         */
                    130:        if (src_exponent == DBL_INFINITY_EXPONENT) {
                    131:                /*
                    132:                 * determine if NaN or infinity
                    133:                 */
                    134:                if (Dbl_iszero_mantissa(srcp1,srcp2)) {
                    135:                        /*
                    136:                         * is infinity; want to return single infinity
                    137:                         */
                    138:                        Sgl_setinfinity_exponentmantissa(result);
                    139:                        *dstptr = result;
                    140:                        return(NOEXCEPTION);
                    141:                }
                    142:                /*
                    143:                 * is NaN; signaling or quiet?
                    144:                 */
                    145:                if (Dbl_isone_signaling(srcp1)) {
                    146:                        /* trap if INVALIDTRAP enabled */
                    147:                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
                    148:                        else {
                    149:                                Set_invalidflag();
                    150:                                /* make NaN quiet */
                    151:                                Dbl_set_quiet(srcp1);
                    152:                        }
                    153:                }
                    154:                /*
                    155:                 * NaN is quiet, return as single NaN
                    156:                 */
                    157:                Sgl_setinfinity_exponent(result);
                    158:                Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
                    159:                if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
                    160:                *dstptr = result;
                    161:                return(NOEXCEPTION);
                    162:        }
                    163:        /*
                    164:         * Generate result
                    165:         */
                    166:        Dbl_to_sgl_exponent(src_exponent,dest_exponent);
                    167:        if (dest_exponent > 0) {
                    168:                Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit,
                    169:                stickybit,lsb_odd);
                    170:        }
                    171:        else {
                    172:                if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
                    173:                        Sgl_setzero_exponentmantissa(result);
                    174:                        *dstptr = result;
                    175:                        return(NOEXCEPTION);
                    176:                }
                    177:                if (Is_underflowtrap_enabled()) {
                    178:                        Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
                    179:                        guardbit,stickybit,lsb_odd);
                    180:                }
                    181:                else {
                    182:                        /* compute result, determine inexact info,
                    183:                         * and set Underflowflag if appropriate
                    184:                         */
                    185:                        Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
                    186:                        dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
                    187:                        is_tiny);
                    188:                }
                    189:        }
                    190:        /*
                    191:         * Now round result if not exact
                    192:         */
                    193:        if (inexact) {
                    194:                switch (Rounding_mode()) {
                    195:                        case ROUNDPLUS:
                    196:                                if (Sgl_iszero_sign(result)) dest_mantissa++;
                    197:                                break;
                    198:                        case ROUNDMINUS:
                    199:                                if (Sgl_isone_sign(result)) dest_mantissa++;
                    200:                                break;
                    201:                        case ROUNDNEAREST:
                    202:                                if (guardbit) {
                    203:                                   if (stickybit || lsb_odd) dest_mantissa++;
                    204:                                   }
                    205:                }
                    206:        }
                    207:        Sgl_set_exponentmantissa(result,dest_mantissa);
                    208:
                    209:        /*
                    210:         * check for mantissa overflow after rounding
                    211:         */
                    212:        if ((dest_exponent>0 || Is_underflowtrap_enabled()) &&
                    213:            Sgl_isone_hidden(result)) dest_exponent++;
                    214:
                    215:        /*
                    216:         * Test for overflow
                    217:         */
                    218:        if (dest_exponent >= SGL_INFINITY_EXPONENT) {
                    219:                /* trap if OVERFLOWTRAP enabled */
                    220:                if (Is_overflowtrap_enabled()) {
                    221:                        /*
                    222:                         * Check for gross overflow
                    223:                         */
                    224:                        if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP)
                    225:                                return(UNIMPLEMENTEDEXCEPTION);
                    226:
                    227:                        /*
                    228:                         * Adjust bias of result
                    229:                         */
                    230:                        Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
                    231:                        *dstptr = result;
                    232:                        if (inexact) {
                    233:                            if (Is_inexacttrap_enabled())
                    234:                                return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
                    235:                            else
                    236:                                Set_inexactflag();
                    237:                        }
                    238:                        return(OVERFLOWEXCEPTION);
                    239:                }
                    240:                Set_overflowflag();
                    241:                inexact = TRUE;
                    242:                /* set result to infinity or largest number */
                    243:                Sgl_setoverflow(result);
                    244:        }
                    245:        /*
                    246:         * Test for underflow
                    247:         */
                    248:        else if (dest_exponent <= 0) {
                    249:                /* trap if UNDERFLOWTRAP enabled */
                    250:                if (Is_underflowtrap_enabled()) {
                    251:                        /*
                    252:                         * Check for gross underflow
                    253:                         */
                    254:                        if (dest_exponent <= -(SGL_WRAP))
                    255:                                return(UNIMPLEMENTEDEXCEPTION);
                    256:                        /*
                    257:                         * Adjust bias of result
                    258:                         */
                    259:                        Sgl_setwrapped_exponent(result,dest_exponent,unfl);
                    260:                        *dstptr = result;
                    261:                        if (inexact) {
                    262:                            if (Is_inexacttrap_enabled())
                    263:                                return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
                    264:                            else
                    265:                                Set_inexactflag();
                    266:                        }
                    267:                        return(UNDERFLOWEXCEPTION);
                    268:                }
                    269:                 /*
                    270:                  * result is denormalized or signed zero
                    271:                  */
                    272:               if (inexact && is_tiny) Set_underflowflag();
                    273:
                    274:        }
                    275:        else Sgl_set_exponent(result,dest_exponent);
                    276:        *dstptr = result;
                    277:        /*
                    278:         * Trap if inexact trap is enabled
                    279:         */
                    280:        if (inexact) {
                    281:                if (Is_inexacttrap_enabled())
                    282:                        return(INEXACTEXCEPTION);
                    283:                else
                    284:                        Set_inexactflag();
                    285:        }
                    286:        return(NOEXCEPTION);
                    287: }

CVSweb