[BACK]Return to README CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpe

Annotation of sys/arch/m68k/fpe/README, Revision 1.1.1.1

1.1       nbrk        1: # $OpenBSD: README,v 1.3 2006/01/16 22:08:26 miod Exp $
                      2: * $NetBSD: README,v 1.4 1995/11/05 04:23:00 briggs Exp $
                      3: * NetBSD/m68k FPE (floating point emulation) README file
                      4: * Created Oct/??/95 by kenn@remus.rutgers.edu (Ken Nakata)
                      5: * Last updated Nov/04/95 by kenn
                      6:
                      7: 1. INSTALLATION AND COMPILATION
                      8:
                      9: To compile a kernel with FPE built-in, do the following:
                     10:
                     11: 1) Add a line "options FPU_EMULATE" to your config file.  If you are
                     12: going to use the resulted kernel on a machine with an FPU for
                     13: debugging purpose, add "options DEBUG_WITH_FPU" as well.
                     14:
                     15: 2) Follow the usual procedure to build a new kernel.
                     16:
                     17: NOTE:  If you add "options DEBUG_WITH_FPU", FPE will accept cpID=6 as
                     18: emulated FPU.  You will need a modified gas that generates cpID=6 for
                     19: floating point instructions, instead of normal cpID=1.  Apply the
                     20: following patch to the gas source:
                     21:
                     22: *** /usr/src/gnu/usr.bin/gas/config/tc-m68k.c   Mon Nov 21 16:30:41 1994
                     23: --- gas/config/tc-m68k.c    Fri Sep 29 07:59:06 1995
                     24: ***************
                     25: *** 1275,1281 ****
                     26:                 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
                     27:                 memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
                     28:                 the_ins.operands[0].mode=MSCR;
                     29: !               the_ins.operands[0].reg=COPNUM;         /* COP #1 */
                     30:                 opsfound++;
                     31:         }
                     32:
                     33: --- 1275,1281 ----
                     34:                 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
                     35:                 memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
                     36:                 the_ins.operands[0].mode=MSCR;
                     37: !               the_ins.operands[0].reg=COP5;           /* COP #6 */
                     38:                 opsfound++;
                     39:         }
                     40:
                     41:
                     42: Also, with the DEBUG_WITH_FPU option, you will be able to run only ONE
                     43: process that uses FPE at once to get correct results.
                     44:
                     45:
                     46: 2. MISSING PARTS
                     47:
                     48: For missing instructions, refer to the Section 3.  Other than that,
                     49: there is one thing that is missing from this version of FPE: packed
                     50: BCD support.
                     51:
                     52: I have no plan to support it since it's rarely used.  However, all we
                     53: need to support it is explosion/implosion functions between the
                     54: internal FP representation and the m68k PBCD format, so you are more
                     55: than welcome to write such functions if you wish to.
                     56:
                     57:
                     58: 3. IMPLEMENTED INSTRUCTIONS
                     59:
                     60: This is the list of implemented and unimplemented FPU instructions.
                     61: All 040's directly supported type 0 instructions are already
                     62: implemented except FSGLDIV and FSGLMUL.
                     63:
                     64: Type field = bit 8-6 of opcode word
                     65:
                     66: * Implemented Instructions
                     67:
                     68: Type=0: FMOVE (mem->FPr), FINT, FINTRZ, FSQRT, FABS, FNEG, FGETEXP,
                     69:        FGETMAN, FDIV, FADD, FMUL, FSGLDIV(*), FSCALE, FSGLMUL(*), FSUB,
                     70:        FCMP, FTST, FMOVE (FPr->mem), FMOVEM (FPr), FMOVEM (FPcr),
                     71:        FMOVECR, FLOGNP1, FLOGN, FLOG10, FLOG2, FMOD, FREM
                     72:
                     73: Type=1: FDBcc, FScc, FTRAPcc,
                     74:
                     75: Type=2: FBcc (word, incl. FNOP)
                     76:
                     77: Type=3: FBcc (long)
                     78:
                     79: Type=4: none
                     80:
                     81: Type=5: none
                     82:
                     83:        *: currently FSGLMUL and FSGLDIV are just aliases of
                     84:           FMUL and FDIV, respectively
                     85:
                     86: * Unimplemented Instructions
                     87:
                     88: Type=0: FSINH, FETOXM1, FTANH, FATAN, FASIN, FATANH, FSIN, FTAN,
                     89:        FETOX, FTWOTOX, FTENTOX, FCOSH, FACOS, FCOS, FSINCOS
                     90:
                     91: Type=1: none
                     92:
                     93: Type=2: none
                     94:
                     95: Type=3: none
                     96:
                     97: Type=4: FSAVE
                     98:
                     99: Type=5: FRESTORE
                    100:
                    101:
                    102: 4. HOW TO ADD A NEW INSTRUCTION SUPPORT
                    103:
                    104: Since we need not support FSAVE and FRESTORE operations, all
                    105: instructions we have to implement are type 0, all of which are
                    106: arithmetic operations.  It is particularly easy to add a new
                    107: arithmetic instruction to the existing ones (not that it is easy to
                    108: write a "stable" function to perform floating point operation. That's
                    109: entirely another matter).  In "fpu_emulate.c", there's a function
                    110: fpu_emul_arith() which calls emulation functions for all arithmetic
                    111: operations.  In it, there's a large switch() { case ... } which
                    112: dispatches each instruction emulator.  An emulation function of any
                    113: type 0 arithmetic instruction follows this prototype:
                    114:
                    115:        struct fpn *fpu_op(struct fpemu *fe);
                    116:
                    117: Where fe is a pointer to a struct fpemu in which frame, fpframe, and
                    118: fetched operands are accessible.  That's right, you don't have to
                    119: fetch the operands by yourself in your emulation funtion.  For
                    120: instance, the parts calling FSQRT, FSUB, FADD and FTST look like:
                    121:
                    122:        switch(word1 & 0x3F) {
                    123: [...]
                    124:        case 0x04:      /* fsqrt */
                    125:                res = fpu_sqrt(fe);
                    126:                break;
                    127: [...]
                    128:        case 0x28:      /* fsub */
                    129:                fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign; /* f2 = -f2 */
                    130:        case 0x22:      /* fadd */
                    131:                res = fpu_add(fe);
                    132:                break;
                    133: [...]
                    134:        case 0x3A:      /* ftst */
                    135:                res = &fe->fe_f2;
                    136:                no_store = 1;
                    137:                break;
                    138: [...]
                    139:        default:
                    140:                sig = SIGILL;
                    141:        } /* switch */
                    142:
                    143: Here, fe->fe_f1 and fe->fe_f2 are fetched operands.  You can use
                    144: fe->fe_f3 for storing the result, or you can return a pointer to
                    145: either operand if you want to.  At any rate, you have to follow
                    146: the following rules:
                    147:
                    148:        1) A dyadic instruction takes two operands fe->fe_f1 and fe->fe_f2.
                    149:        2) A monadic instruction takes one operand fe->fe_f2 (NOT fe_f1).
                    150:        3) Must return a pointer to struct fpn where the result is stored,
                    151:        and assign the pointer to the variable "res".
                    152:        4) If exceptions are detected, set corresponding bits in fe->fe_fpsr.
                    153:        The rest is taken care of in fpu_emul_arith().
                    154:        5) Condition code does not need to be calculated.  It's taken care of in
                    155:        fpu_emul_arith().

CVSweb