Annotation of Net2/arch/tahoe/math/fpe.c, revision 1.1.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.