[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

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