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

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

1.1       nbrk        1: /*     $OpenBSD: sfrem.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: /* @(#)sfrem.c: Revision: 1.7.88.1 Date: 93/12/07 15:07:10 */
                     16:
                     17: #include "float.h"
                     18: #include "sgl_float.h"
                     19:
                     20: /*
                     21:  *  Single Precision Floating-point Remainder
                     22:  */
                     23: int
                     24: sgl_frem(srcptr1,srcptr2,dstptr,status)
                     25:        sgl_floating_point *srcptr1, *srcptr2, *dstptr;
                     26:        unsigned int *status;
                     27: {
                     28:        register unsigned int opnd1, opnd2, result;
                     29:        register int opnd1_exponent, opnd2_exponent, dest_exponent, stepcount;
                     30:        register int roundup = FALSE;
                     31:
                     32:        opnd1 = *srcptr1;
                     33:        opnd2 = *srcptr2;
                     34:        /*
                     35:         * check first operand for NaN's or infinity
                     36:         */
                     37:        if ((opnd1_exponent = Sgl_exponent(opnd1)) == SGL_INFINITY_EXPONENT) {
                     38:                if (Sgl_iszero_mantissa(opnd1)) {
                     39:                        if (Sgl_isnotnan(opnd2)) {
                     40:                                /* invalid since first operand is infinity */
                     41:                                if (Is_invalidtrap_enabled())
                     42:                                        return(INVALIDEXCEPTION);
                     43:                                Set_invalidflag();
                     44:                                Sgl_makequietnan(result);
                     45:                                *dstptr = result;
                     46:                                return(NOEXCEPTION);
                     47:                        }
                     48:                }
                     49:                else {
                     50:                        /*
                     51:                         * is NaN; signaling or quiet?
                     52:                         */
                     53:                        if (Sgl_isone_signaling(opnd1)) {
                     54:                                /* trap if INVALIDTRAP enabled */
                     55:                                if (Is_invalidtrap_enabled())
                     56:                                        return(INVALIDEXCEPTION);
                     57:                                /* make NaN quiet */
                     58:                                Set_invalidflag();
                     59:                                Sgl_set_quiet(opnd1);
                     60:                        }
                     61:                        /*
                     62:                         * is second operand a signaling NaN?
                     63:                         */
                     64:                        else if (Sgl_is_signalingnan(opnd2)) {
                     65:                                /* trap if INVALIDTRAP enabled */
                     66:                                if (Is_invalidtrap_enabled())
                     67:                                        return(INVALIDEXCEPTION);
                     68:                                /* make NaN quiet */
                     69:                                Set_invalidflag();
                     70:                                Sgl_set_quiet(opnd2);
                     71:                                *dstptr = opnd2;
                     72:                                return(NOEXCEPTION);
                     73:                        }
                     74:                        /*
                     75:                         * return quiet NaN
                     76:                         */
                     77:                        *dstptr = opnd1;
                     78:                        return(NOEXCEPTION);
                     79:                }
                     80:        }
                     81:        /*
                     82:         * check second operand for NaN's or infinity
                     83:         */
                     84:        if ((opnd2_exponent = Sgl_exponent(opnd2)) == SGL_INFINITY_EXPONENT) {
                     85:                if (Sgl_iszero_mantissa(opnd2)) {
                     86:                        /*
                     87:                         * return first operand
                     88:                         */
                     89:                        *dstptr = opnd1;
                     90:                        return(NOEXCEPTION);
                     91:                }
                     92:                /*
                     93:                 * is NaN; signaling or quiet?
                     94:                 */
                     95:                if (Sgl_isone_signaling(opnd2)) {
                     96:                        /* trap if INVALIDTRAP enabled */
                     97:                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
                     98:                        /* make NaN quiet */
                     99:                        Set_invalidflag();
                    100:                        Sgl_set_quiet(opnd2);
                    101:                }
                    102:                /*
                    103:                 * return quiet NaN
                    104:                 */
                    105:                *dstptr = opnd2;
                    106:                return(NOEXCEPTION);
                    107:        }
                    108:        /*
                    109:         * check second operand for zero
                    110:         */
                    111:        if (Sgl_iszero_exponentmantissa(opnd2)) {
                    112:                /* invalid since second operand is zero */
                    113:                if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
                    114:                Set_invalidflag();
                    115:                Sgl_makequietnan(result);
                    116:                *dstptr = result;
                    117:                return(NOEXCEPTION);
                    118:        }
                    119:
                    120:        /*
                    121:         * get sign of result
                    122:         */
                    123:        result = opnd1;
                    124:
                    125:        /*
                    126:         * check for denormalized operands
                    127:         */
                    128:        if (opnd1_exponent == 0) {
                    129:                /* check for zero */
                    130:                if (Sgl_iszero_mantissa(opnd1)) {
                    131:                        *dstptr = opnd1;
                    132:                        return(NOEXCEPTION);
                    133:                }
                    134:                /* normalize, then continue */
                    135:                opnd1_exponent = 1;
                    136:                Sgl_normalize(opnd1,opnd1_exponent);
                    137:        }
                    138:        else {
                    139:                Sgl_clear_signexponent_set_hidden(opnd1);
                    140:        }
                    141:        if (opnd2_exponent == 0) {
                    142:                /* normalize, then continue */
                    143:                opnd2_exponent = 1;
                    144:                Sgl_normalize(opnd2,opnd2_exponent);
                    145:        }
                    146:        else {
                    147:                Sgl_clear_signexponent_set_hidden(opnd2);
                    148:        }
                    149:
                    150:        /* find result exponent and divide step loop count */
                    151:        dest_exponent = opnd2_exponent - 1;
                    152:        stepcount = opnd1_exponent - opnd2_exponent;
                    153:
                    154:        /*
                    155:         * check for opnd1/opnd2 < 1
                    156:         */
                    157:        if (stepcount < 0) {
                    158:                /*
                    159:                 * check for opnd1/opnd2 > 1/2
                    160:                 *
                    161:                 * In this case n will round to 1, so
                    162:                 *    r = opnd1 - opnd2
                    163:                 */
                    164:                if (stepcount == -1 && Sgl_isgreaterthan(opnd1,opnd2)) {
                    165:                        Sgl_all(result) = ~Sgl_all(result);   /* set sign */
                    166:                        /* align opnd2 with opnd1 */
                    167:                        Sgl_leftshiftby1(opnd2);
                    168:                        Sgl_subtract(opnd2,opnd1,opnd2);
                    169:                        /* now normalize */
                    170:                        while (Sgl_iszero_hidden(opnd2)) {
                    171:                                Sgl_leftshiftby1(opnd2);
                    172:                                dest_exponent--;
                    173:                        }
                    174:                        Sgl_set_exponentmantissa(result,opnd2);
                    175:                        goto testforunderflow;
                    176:                }
                    177:                /*
                    178:                 * opnd1/opnd2 <= 1/2
                    179:                 *
                    180:                 * In this case n will round to zero, so
                    181:                 *    r = opnd1
                    182:                 */
                    183:                Sgl_set_exponentmantissa(result,opnd1);
                    184:                dest_exponent = opnd1_exponent;
                    185:                goto testforunderflow;
                    186:        }
                    187:
                    188:        /*
                    189:         * Generate result
                    190:         *
                    191:         * Do iterative subtract until remainder is less than operand 2.
                    192:         */
                    193:        while (stepcount-- > 0 && Sgl_all(opnd1)) {
                    194:                if (Sgl_isnotlessthan(opnd1,opnd2))
                    195:                        Sgl_subtract(opnd1,opnd2,opnd1);
                    196:                Sgl_leftshiftby1(opnd1);
                    197:        }
                    198:        /*
                    199:         * Do last subtract, then determine which way to round if remainder
                    200:         * is exactly 1/2 of opnd2
                    201:         */
                    202:        if (Sgl_isnotlessthan(opnd1,opnd2)) {
                    203:                Sgl_subtract(opnd1,opnd2,opnd1);
                    204:                roundup = TRUE;
                    205:        }
                    206:        if (stepcount > 0 || Sgl_iszero(opnd1)) {
                    207:                /* division is exact, remainder is zero */
                    208:                Sgl_setzero_exponentmantissa(result);
                    209:                *dstptr = result;
                    210:                return(NOEXCEPTION);
                    211:        }
                    212:
                    213:        /*
                    214:         * Check for cases where opnd1/opnd2 < n
                    215:         *
                    216:         * In this case the result's sign will be opposite that of
                    217:         * opnd1.  The mantissa also needs some correction.
                    218:         */
                    219:        Sgl_leftshiftby1(opnd1);
                    220:        if (Sgl_isgreaterthan(opnd1,opnd2)) {
                    221:                Sgl_invert_sign(result);
                    222:                Sgl_subtract((opnd2<<1),opnd1,opnd1);
                    223:        }
                    224:        /* check for remainder being exactly 1/2 of opnd2 */
                    225:        else if (Sgl_isequal(opnd1,opnd2) && roundup) {
                    226:                Sgl_invert_sign(result);
                    227:        }
                    228:
                    229:        /* normalize result's mantissa */
                    230:        while (Sgl_iszero_hidden(opnd1)) {
                    231:                dest_exponent--;
                    232:                Sgl_leftshiftby1(opnd1);
                    233:        }
                    234:        Sgl_set_exponentmantissa(result,opnd1);
                    235:
                    236:        /*
                    237:         * Test for underflow
                    238:         */
                    239:     testforunderflow:
                    240:        if (dest_exponent <= 0) {
                    241:                /* trap if UNDERFLOWTRAP enabled */
                    242:                if (Is_underflowtrap_enabled()) {
                    243:                        /*
                    244:                         * Adjust bias of result
                    245:                         */
                    246:                        Sgl_setwrapped_exponent(result,dest_exponent,unfl);
                    247:                        *dstptr = result;
                    248:                        /* frem is always exact */
                    249:                        return(UNDERFLOWEXCEPTION);
                    250:                }
                    251:                /*
                    252:                 * denormalize result or set to signed zero
                    253:                 */
                    254:                if (dest_exponent >= (1 - SGL_P)) {
                    255:                        Sgl_rightshift_exponentmantissa(result,1-dest_exponent);
                    256:                } else {
                    257:                        Sgl_setzero_exponentmantissa(result);
                    258:                }
                    259:        }
                    260:        else Sgl_set_exponent(result,dest_exponent);
                    261:        *dstptr = result;
                    262:        return(NOEXCEPTION);
                    263: }

CVSweb