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

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

1.1       nbrk        1: /*     $OpenBSD: dfmpy.c,v 1.5 2002/05/07 22:19:30 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: /* @(#)dfmpy.c: Revision: 2.11.88.1 Date: 93/12/07 15:05:41 */
                     16:
                     17: #include "float.h"
                     18: #include "dbl_float.h"
                     19:
                     20: /*
                     21:  *  Double Precision Floating-point Multiply
                     22:  */
                     23:
                     24: int
                     25: dbl_fmpy(srcptr1,srcptr2,dstptr,status)
                     26:        dbl_floating_point *srcptr1, *srcptr2, *dstptr;
                     27:        unsigned int *status;
                     28: {
                     29:        register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
                     30:        register unsigned int opnd3p1, opnd3p2, resultp1, resultp2;
                     31:        register int dest_exponent, count;
                     32:        register int inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
                     33:        int is_tiny;
                     34:
                     35:        Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
                     36:        Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
                     37:
                     38:        /*
                     39:         * set sign bit of result
                     40:         */
                     41:        if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
                     42:                Dbl_setnegativezerop1(resultp1);
                     43:        else Dbl_setzerop1(resultp1);
                     44:        /*
                     45:         * check first operand for NaN's or infinity
                     46:         */
                     47:        if (Dbl_isinfinity_exponent(opnd1p1)) {
                     48:                if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
                     49:                        if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
                     50:                                if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
                     51:                                        /*
                     52:                                         * invalid since operands are infinity
                     53:                                         * and zero
                     54:                                         */
                     55:                                        if (Is_invalidtrap_enabled())
                     56:                                                return(INVALIDEXCEPTION);
                     57:                                        Set_invalidflag();
                     58:                                        Dbl_makequietnan(resultp1,resultp2);
                     59:                                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                     60:                                        return(NOEXCEPTION);
                     61:                                }
                     62:                                /*
                     63:                                 * return infinity
                     64:                                 */
                     65:                                Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
                     66:                                Dbl_copytoptr(resultp1,resultp2,dstptr);
                     67:                                return(NOEXCEPTION);
                     68:                        }
                     69:                }
                     70:                else {
                     71:                        /*
                     72:                         * is NaN; signaling or quiet?
                     73:                         */
                     74:                        if (Dbl_isone_signaling(opnd1p1)) {
                     75:                                /* trap if INVALIDTRAP enabled */
                     76:                                if (Is_invalidtrap_enabled())
                     77:                                        return(INVALIDEXCEPTION);
                     78:                                /* make NaN quiet */
                     79:                                Set_invalidflag();
                     80:                                Dbl_set_quiet(opnd1p1);
                     81:                        }
                     82:                        /*
                     83:                         * is second operand a signaling NaN?
                     84:                         */
                     85:                        else if (Dbl_is_signalingnan(opnd2p1)) {
                     86:                                /* trap if INVALIDTRAP enabled */
                     87:                                if (Is_invalidtrap_enabled())
                     88:                                        return(INVALIDEXCEPTION);
                     89:                                /* make NaN quiet */
                     90:                                Set_invalidflag();
                     91:                                Dbl_set_quiet(opnd2p1);
                     92:                                Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
                     93:                                return(NOEXCEPTION);
                     94:                        }
                     95:                        /*
                     96:                         * return quiet NaN
                     97:                         */
                     98:                        Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
                     99:                        return(NOEXCEPTION);
                    100:                }
                    101:        }
                    102:        /*
                    103:         * check second operand for NaN's or infinity
                    104:         */
                    105:        if (Dbl_isinfinity_exponent(opnd2p1)) {
                    106:                if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
                    107:                        if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
                    108:                                /* invalid since operands are zero & infinity */
                    109:                                if (Is_invalidtrap_enabled())
                    110:                                        return(INVALIDEXCEPTION);
                    111:                                Set_invalidflag();
                    112:                                Dbl_makequietnan(opnd2p1,opnd2p2);
                    113:                                Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
                    114:                                return(NOEXCEPTION);
                    115:                        }
                    116:                        /*
                    117:                         * return infinity
                    118:                         */
                    119:                        Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
                    120:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    121:                        return(NOEXCEPTION);
                    122:                }
                    123:                /*
                    124:                 * is NaN; signaling or quiet?
                    125:                 */
                    126:                if (Dbl_isone_signaling(opnd2p1)) {
                    127:                        /* trap if INVALIDTRAP enabled */
                    128:                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
                    129:                        /* make NaN quiet */
                    130:                        Set_invalidflag();
                    131:                        Dbl_set_quiet(opnd2p1);
                    132:                }
                    133:                /*
                    134:                 * return quiet NaN
                    135:                 */
                    136:                Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
                    137:                return(NOEXCEPTION);
                    138:        }
                    139:        /*
                    140:         * Generate exponent
                    141:         */
                    142:        dest_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) -DBL_BIAS;
                    143:
                    144:        /*
                    145:         * Generate mantissa
                    146:         */
                    147:        if (Dbl_isnotzero_exponent(opnd1p1)) {
                    148:                /* set hidden bit */
                    149:                Dbl_clear_signexponent_set_hidden(opnd1p1);
                    150:        }
                    151:        else {
                    152:                /* check for zero */
                    153:                if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
                    154:                        Dbl_setzero_exponentmantissa(resultp1,resultp2);
                    155:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    156:                        return(NOEXCEPTION);
                    157:                }
                    158:                /* is denormalized, adjust exponent */
                    159:                Dbl_clear_signexponent(opnd1p1);
                    160:                Dbl_leftshiftby1(opnd1p1,opnd1p2);
                    161:                Dbl_normalize(opnd1p1,opnd1p2,dest_exponent);
                    162:        }
                    163:        /* opnd2 needs to have hidden bit set with msb in hidden bit */
                    164:        if (Dbl_isnotzero_exponent(opnd2p1)) {
                    165:                Dbl_clear_signexponent_set_hidden(opnd2p1);
                    166:        }
                    167:        else {
                    168:                /* check for zero */
                    169:                if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
                    170:                        Dbl_setzero_exponentmantissa(resultp1,resultp2);
                    171:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    172:                        return(NOEXCEPTION);
                    173:                }
                    174:                /* is denormalized; want to normalize */
                    175:                Dbl_clear_signexponent(opnd2p1);
                    176:                Dbl_leftshiftby1(opnd2p1,opnd2p2);
                    177:                Dbl_normalize(opnd2p1,opnd2p2,dest_exponent);
                    178:        }
                    179:
                    180:        /* Multiply two source mantissas together */
                    181:
                    182:        /* make room for guard bits */
                    183:        Dbl_leftshiftby7(opnd2p1,opnd2p2);
                    184:        Dbl_setzero(opnd3p1,opnd3p2);
                    185:        /*
                    186:         * Four bits at a time are inspected in each loop, and a
                    187:         * simple shift and add multiply algorithm is used.
                    188:         */
                    189:        for (count=1;count<=DBL_P;count+=4) {
                    190:                stickybit |= Dlow4p2(opnd3p2);
                    191:                Dbl_rightshiftby4(opnd3p1,opnd3p2);
                    192:                if (Dbit28p2(opnd1p2)) {
                    193:                        /* Twoword_add should be an ADDC followed by an ADD. */
                    194:                        Twoword_add(opnd3p1, opnd3p2, opnd2p1<<3 | opnd2p2>>29,
                    195:                                    opnd2p2<<3);
                    196:                }
                    197:                if (Dbit29p2(opnd1p2)) {
                    198:                        Twoword_add(opnd3p1, opnd3p2, opnd2p1<<2 | opnd2p2>>30,
                    199:                                    opnd2p2<<2);
                    200:                }
                    201:                if (Dbit30p2(opnd1p2)) {
                    202:                        Twoword_add(opnd3p1, opnd3p2, opnd2p1<<1 | opnd2p2>>31,
                    203:                                    opnd2p2<<1);
                    204:                }
                    205:                if (Dbit31p2(opnd1p2)) {
                    206:                        Twoword_add(opnd3p1, opnd3p2, opnd2p1, opnd2p2);
                    207:                }
                    208:                Dbl_rightshiftby4(opnd1p1,opnd1p2);
                    209:        }
                    210:        if (Dbit3p1(opnd3p1)==0) {
                    211:                Dbl_leftshiftby1(opnd3p1,opnd3p2);
                    212:        }
                    213:        else {
                    214:                /* result mantissa >= 2. */
                    215:                dest_exponent++;
                    216:        }
                    217:        /* check for denormalized result */
                    218:        while (Dbit3p1(opnd3p1)==0) {
                    219:                Dbl_leftshiftby1(opnd3p1,opnd3p2);
                    220:                dest_exponent--;
                    221:        }
                    222:        /*
                    223:         * check for guard, sticky and inexact bits
                    224:         */
                    225:        stickybit |= Dallp2(opnd3p2) << 25;
                    226:        guardbit = (Dallp2(opnd3p2) << 24) >> 31;
                    227:        inexact = guardbit | stickybit;
                    228:
                    229:        /* align result mantissa */
                    230:        Dbl_rightshiftby8(opnd3p1,opnd3p2);
                    231:
                    232:        /*
                    233:         * round result
                    234:         */
                    235:        if (inexact && (dest_exponent>0 || Is_underflowtrap_enabled())) {
                    236:                Dbl_clear_signexponent(opnd3p1);
                    237:                switch (Rounding_mode()) {
                    238:                        case ROUNDPLUS:
                    239:                                if (Dbl_iszero_sign(resultp1))
                    240:                                        Dbl_increment(opnd3p1,opnd3p2);
                    241:                                break;
                    242:                        case ROUNDMINUS:
                    243:                                if (Dbl_isone_sign(resultp1))
                    244:                                        Dbl_increment(opnd3p1,opnd3p2);
                    245:                                break;
                    246:                        case ROUNDNEAREST:
                    247:                                if (guardbit &&
                    248:                                    (stickybit || Dbl_isone_lowmantissap2(opnd3p2)))
                    249:                                        Dbl_increment(opnd3p1,opnd3p2);
                    250:                                break;
                    251:                }
                    252:                if (Dbl_isone_hidden(opnd3p1)) dest_exponent++;
                    253:        }
                    254:        Dbl_set_mantissa(resultp1,resultp2,opnd3p1,opnd3p2);
                    255:
                    256:        /*
                    257:         * Test for overflow
                    258:         */
                    259:        if (dest_exponent >= DBL_INFINITY_EXPONENT) {
                    260:                /* trap if OVERFLOWTRAP enabled */
                    261:                if (Is_overflowtrap_enabled()) {
                    262:                        /*
                    263:                         * Adjust bias of result
                    264:                         */
                    265:                        Dbl_setwrapped_exponent(resultp1,dest_exponent,ovfl);
                    266:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    267:                        if (inexact) {
                    268:                            if (Is_inexacttrap_enabled())
                    269:                                return (OVERFLOWEXCEPTION | INEXACTEXCEPTION);
                    270:                            else
                    271:                                Set_inexactflag();
                    272:                        }
                    273:                        return (OVERFLOWEXCEPTION);
                    274:                }
                    275:                inexact = TRUE;
                    276:                Set_overflowflag();
                    277:                /* set result to infinity or largest number */
                    278:                Dbl_setoverflow(resultp1,resultp2);
                    279:        }
                    280:        /*
                    281:         * Test for underflow
                    282:         */
                    283:        else if (dest_exponent <= 0) {
                    284:                /* trap if UNDERFLOWTRAP enabled */
                    285:                if (Is_underflowtrap_enabled()) {
                    286:                        /*
                    287:                         * Adjust bias of result
                    288:                         */
                    289:                        Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
                    290:                        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    291:                        if (inexact) {
                    292:                            if (Is_inexacttrap_enabled())
                    293:                                return (UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
                    294:                            else
                    295:                                Set_inexactflag();
                    296:                        }
                    297:                        return (UNDERFLOWEXCEPTION);
                    298:                }
                    299:
                    300:                /* Determine if should set underflow flag */
                    301:                is_tiny = TRUE;
                    302:                if (dest_exponent == 0 && inexact) {
                    303:                        switch (Rounding_mode()) {
                    304:                        case ROUNDPLUS:
                    305:                                if (Dbl_iszero_sign(resultp1)) {
                    306:                                        Dbl_increment(opnd3p1,opnd3p2);
                    307:                                        if (Dbl_isone_hiddenoverflow(opnd3p1))
                    308:                                                is_tiny = FALSE;
                    309:                                        Dbl_decrement(opnd3p1,opnd3p2);
                    310:                                }
                    311:                                break;
                    312:                        case ROUNDMINUS:
                    313:                                if (Dbl_isone_sign(resultp1)) {
                    314:                                        Dbl_increment(opnd3p1,opnd3p2);
                    315:                                        if (Dbl_isone_hiddenoverflow(opnd3p1))
                    316:                                                is_tiny = FALSE;
                    317:                                        Dbl_decrement(opnd3p1,opnd3p2);
                    318:                                }
                    319:                                break;
                    320:                        case ROUNDNEAREST:
                    321:                                if (guardbit && (stickybit ||
                    322:                                    Dbl_isone_lowmantissap2(opnd3p2))) {
                    323:                                        Dbl_increment(opnd3p1,opnd3p2);
                    324:                                        if (Dbl_isone_hiddenoverflow(opnd3p1))
                    325:                                        is_tiny = FALSE;
                    326:                                        Dbl_decrement(opnd3p1,opnd3p2);
                    327:                                }
                    328:                                break;
                    329:                        }
                    330:                }
                    331:
                    332:                /*
                    333:                 * denormalize result or set to signed zero
                    334:                 */
                    335:                stickybit = inexact;
                    336:                Dbl_denormalize(opnd3p1,opnd3p2,dest_exponent,guardbit,
                    337:                 stickybit,inexact);
                    338:
                    339:                /* return zero or smallest number */
                    340:                if (inexact) {
                    341:                        switch (Rounding_mode()) {
                    342:                        case ROUNDPLUS:
                    343:                                if (Dbl_iszero_sign(resultp1)) {
                    344:                                        Dbl_increment(opnd3p1,opnd3p2);
                    345:                                }
                    346:                                break;
                    347:                        case ROUNDMINUS:
                    348:                                if (Dbl_isone_sign(resultp1)) {
                    349:                                        Dbl_increment(opnd3p1,opnd3p2);
                    350:                                }
                    351:                                break;
                    352:                        case ROUNDNEAREST:
                    353:                                if (guardbit && (stickybit ||
                    354:                                    Dbl_isone_lowmantissap2(opnd3p2))) {
                    355:                                        Dbl_increment(opnd3p1,opnd3p2);
                    356:                                }
                    357:                                break;
                    358:                        }
                    359:                        if (is_tiny) Set_underflowflag();
                    360:                }
                    361:                Dbl_set_exponentmantissa(resultp1,resultp2,opnd3p1,opnd3p2);
                    362:        }
                    363:        else Dbl_set_exponent(resultp1,dest_exponent);
                    364:        /* check for inexact */
                    365:        Dbl_copytoptr(resultp1,resultp2,dstptr);
                    366:        if (inexact) {
                    367:                if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
                    368:                else Set_inexactflag();
                    369:        }
                    370:        return(NOEXCEPTION);
                    371: }

CVSweb