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

Annotation of sys/arch/hppa/spmath/fcnvfx.c, Revision 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