Annotation of Net2/arch/tahoe/math/fpe.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1985 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Computer Consoles Inc.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *     This product includes software developed by the University of
        !            19:  *     California, Berkeley and its contributors.
        !            20:  * 4. Neither the name of the University nor the names of its contributors
        !            21:  *    may be used to endorse or promote products derived from this software
        !            22:  *    without specific prior written permission.
        !            23:  *
        !            24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            34:  * SUCH DAMAGE.
        !            35:  *
        !            36:  *     @(#)fpe.c       7.1 (Berkeley) 12/6/90
        !            37:  */
        !            38: 
        !            39: #include "../include/psl.h"
        !            40: #include "../include/reg.h"
        !            41: #include "../include/pte.h"
        !            42: #include "../include/mtpr.h"
        !            43: #include "../math/Kfp.h"
        !            44: 
        !            45: #include "sys/param.h"
        !            46: #include "sys/systm.h"
        !            47: #include "sys/user.h"
        !            48: #include "sys/proc.h"
        !            49: #include "sys/seg.h"
        !            50: #include "sys/acct.h"
        !            51: #include "sys/kernel.h"
        !            52: 
        !            53: /*
        !            54:  * Floating point emulation support.
        !            55:  */
        !            56: extern float Kcvtlf(), Kaddf(), Ksubf(), Kmulf(), Kdivf();
        !            57: extern double Kcvtld(), Kaddd(), Ksubd(), Kmuld(), Kdivd();
        !            58: extern float Ksinf(), Kcosf(), Katanf(), Klogf(), Ksqrtf(), Kexpf();
        !            59: 
        !            60: #define        OP(dop)         ((dop) &~ 01)   /* precision-less version of opcode */
        !            61: #define        isdouble(op)    ((op) & 01)     /* is opcode double or float */
        !            62: 
        !            63: struct fpetab {
        !            64:        int     fpe_op;         /* base opcode emulating */
        !            65:        float   (*fpe_ffunc)(); /* float version of op */
        !            66:        double  (*fpe_dfunc)(); /* double version of op */
        !            67: } fpetab[] = {
        !            68:        { OP(CVLD),     Kcvtlf, Kcvtld },
        !            69:        { OP(ADDD),     Kaddf,  Kaddd },
        !            70:        { OP(SUBD),     Ksubf,  Ksubd },
        !            71:        { OP(MULD),     Kmulf,  Kmuld },
        !            72:        { OP(DIVD),     Kdivf,  Kdivd },
        !            73:        { SINF,         Ksinf,  0 },
        !            74:        { COSF,         Kcosf,  0 },
        !            75:        { ATANF,        Katanf, 0 },
        !            76:        { LOGF,         Klogf,  0 },
        !            77:        { SQRTF,        Ksqrtf, 0 },
        !            78:        { EXPF,         Kexpf,  0 },
        !            79: };
        !            80: #define        NFPETAB (sizeof (fpetab) / sizeof (fpetab[0]))
        !            81: 
        !            82: /*
        !            83:  * Emulate the FP opcode. Update psl as necessary.
        !            84:  * If OK, set opcode to 0, else to the FP exception #.
        !            85:  * Not all parameter longwords are relevant, depends on opcode.
        !            86:  *
        !            87:  * The entry mask is set by locore.s so ALL registers are saved.
        !            88:  * This enables FP opcodes to change user registers on return.
        !            89:  */
        !            90: /* WARNING!!!! THIS CODE MUST NOT PRODUCE ANY FLOATING POINT EXCEPTIONS */
        !            91: /*ARGSUSED*/
        !            92: fpemulate(hfsreg, acc_most, acc_least, dbl, op_most, op_least, opcode, pc, psl)
        !            93: {
        !            94:        int r0, r1;                     /* must reserve space */
        !            95:        register int *locr0 = ((int *)&psl)-PS;
        !            96:        register struct fpetab *fp;
        !            97:        int hfs = 0;                    /* returned data about exceptions */
        !            98:        int type;                       /* opcode type, FLOAT or DOUBLE */
        !            99:        union { float ff; int fi; } f_res;
        !           100:        union { double dd; int di[2]; } d_res;
        !           101:        int error = 0;
        !           102: 
        !           103: #ifdef lint
        !           104:        r0 = 0; r0 = r0; r1 = 0; r1 = r1;
        !           105: #endif
        !           106:        type = isdouble(opcode) ? DOUBLE : FLOAT;
        !           107:        for (fp = fpetab; fp < &fpetab[NFPETAB]; fp++)
        !           108:                if ((opcode & 0xfe) == fp->fpe_op)
        !           109:                        break;
        !           110:        if (type == DOUBLE) {
        !           111:                if (fp->fpe_dfunc == 0)
        !           112:                        fp = &fpetab[NFPETAB];
        !           113:                else
        !           114:                        locr0[PS] &= ~PSL_DBL;
        !           115:        }
        !           116:        if (fp >= &fpetab[NFPETAB]) {
        !           117:                opcode = DIV0_EXC;      /* generate SIGILL - XXX */
        !           118:                return (0);
        !           119:        }
        !           120:        switch (type) {
        !           121: 
        !           122:        case DOUBLE:
        !           123:                d_res.dd = (*fp->fpe_dfunc)(acc_most, acc_least, op_most,
        !           124:                    op_least, &hfs);
        !           125:                if (d_res.di[0] == 0 && d_res.di[1] == 0)
        !           126:                        locr0[PS] |= PSL_Z;
        !           127:                if (d_res.di[0] < 0)
        !           128:                        locr0[PS] |= PSL_N;
        !           129:                break;
        !           130: 
        !           131:        case FLOAT:
        !           132:                f_res.ff = (*fp->fpe_ffunc)(acc_most, acc_least, op_most,
        !           133:                    op_least, &hfs);
        !           134:                if (f_res.fi == 0)
        !           135:                        locr0[PS] |= PSL_Z;
        !           136:                if (f_res.fi ==  0)
        !           137:                        locr0[PS] |= PSL_N;
        !           138:                break;
        !           139:        }
        !           140:        if (hfs & HFS_OVF) {
        !           141:                locr0[PS] |= PSL_V;     /* turn on overflow bit */
        !           142: #ifdef notdef
        !           143:                if (locr0[PS] & PSL_IV)   {  /* overflow enabled? */
        !           144: #endif
        !           145:                        opcode = OVF_EXC;
        !           146:                        return ((hfs & HFS_DOM) ? EDOM : ERANGE);
        !           147: #ifdef notdef
        !           148:                }
        !           149: #endif
        !           150:        } else if (hfs & HFS_UNDF) {
        !           151:                if (locr0[PS] &  PSL_FU) {  /* underflow enabled? */
        !           152:                        opcode = UNDF_EXC;
        !           153:                        return ((hfs & HFS_DOM) ? EDOM : ERANGE);
        !           154:                } 
        !           155:        } else if (hfs & HFS_DIVZ) {
        !           156:                opcode = DIV0_EXC;
        !           157:                return (0);
        !           158:        } else if (hfs & HFS_DOM)
        !           159:                error = EDOM;
        !           160:        else if (hfs & HFS_RANGE)
        !           161:                error = ERANGE;
        !           162:        switch (type) {
        !           163: 
        !           164:        case DOUBLE:
        !           165:                if (hfs & (HFS_OVF|HFS_UNDF)) {
        !           166:                        d_res.dd = 0.0;
        !           167:                        locr0[PS] |= PSL_Z;
        !           168:                }
        !           169:                mvtodacc(d_res.di[0], d_res.di[1], &acc_most);
        !           170:                break;
        !           171: 
        !           172:        case FLOAT:
        !           173:                if (hfs & (HFS_OVF|HFS_UNDF)) {
        !           174:                        f_res.ff = 0.0;
        !           175:                        locr0[PS] |= PSL_Z;
        !           176:                }
        !           177:                mvtofacc(f_res.ff, &acc_most);
        !           178:                break;
        !           179:        }
        !           180:        opcode = 0;
        !           181:        return (error);
        !           182: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.