Annotation of nono/fpe/README, revision 1.1

1.1     ! root        1: * $NetBSD: README,v 1.6 2013/04/20 03:26:11 isaki Exp $
        !             2: * NetBSD/m68k FPE (floating point emulation) README file
        !             3: * Created Oct/??/95 by [email protected] (Ken Nakata)
        !             4: * Last updated Oct/15/2011 by tsutsui
        !             5: 
        !             6: 1. INSTALLATION AND COMPILATION
        !             7: 
        !             8: To compile a kernel with FPE built-in, do the following:
        !             9: 
        !            10: 1) Add a line "options FPU_EMULATE" to your config file.  If you are
        !            11: going to use the resulted kernel on a machine with an FPU for
        !            12: debugging purpose, add "options DEBUG_WITH_FPU" as well.
        !            13: 
        !            14: 2) Follow the usual procedure to build a new kernel.
        !            15: 
        !            16: NOTE:  If you add "options DEBUG_WITH_FPU", FPE will accept cpID=6 as
        !            17: emulated FPU.  You will need a modified gas that generates cpID=6 for
        !            18: floating point instructions, instead of normal cpID=1.  Mount unionfs
        !            19: or copy the gas source directory and apply the following patch:
        !            20: 
        !            21: *** /usr/src/gnu/usr.bin/gas/config/tc-m68k.c   Mon Nov 21 16:30:41 1994
        !            22: --- gas/config/tc-m68k.c    Fri Sep 29 07:59:06 1995
        !            23: ***************
        !            24: *** 1275,1281 ****
        !            25:                 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
        !            26:                 memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
        !            27:                 the_ins.operands[0].mode=MSCR;
        !            28: !               the_ins.operands[0].reg=COPNUM;         /* COP #1 */
        !            29:                 opsfound++;
        !            30:         }
        !            31:   
        !            32: --- 1275,1281 ----
        !            33:                 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
        !            34:                 memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
        !            35:                 the_ins.operands[0].mode=MSCR;
        !            36: !               the_ins.operands[0].reg=COP5;           /* COP #6 */
        !            37:                 opsfound++;
        !            38:         }
        !            39:   
        !            40: 
        !            41: Also, with the DEBUG_WITH_FPU option, you will be able to run only ONE
        !            42: process that uses FPE at once to get correct results.
        !            43: 
        !            44: 
        !            45: 2. MISSING PARTS
        !            46: 
        !            47: For missing instructions, refer to the Section 3.  Other than that,
        !            48: there is one thing that is missing from this version of FPE: packed
        !            49: BCD support.
        !            50: 
        !            51: I have no plan to support it since it's rarely used.  However, all we
        !            52: need to support it is explosion/implosion functions between the
        !            53: internal FP representation and the m68k PBCD format, so you are more
        !            54: than welcome to write such functions if you wish to.
        !            55: 
        !            56: 
        !            57: 3. IMPLEMENTED INSTRUCTIONS
        !            58: 
        !            59: This is the list of implemented and unimplemented FPU instructions.
        !            60: All 040's directly supported type 0 instructions are already
        !            61: implemented except FSGLDIV and FSGLMUL.
        !            62: 
        !            63: Type field = bit 8-6 of opcode word
        !            64: 
        !            65: * Implemented Instructions
        !            66: 
        !            67: Type=0: FMOVE (mem->FPr), FINT, FINTRZ, FSQRT, FABS, FNEG, FGETEXP,
        !            68:        FGETMAN, FDIV, FADD, FMUL, FSGLDIV(*), FSCALE, FSGLMUL(*), FSUB,
        !            69:        FCMP, FTST, FMOVE (FPr->mem), FMOVEM (FPr), FMOVEM (FPcr),
        !            70:        FMOVECR, FLOGNP1, FLOGN, FLOG10, FLOG2, FMOD, FREM,
        !            71:        FCOSH, FSINH, FTANH, FCOS, FSIN, FTAN, FSINCOS,
        !            72:        FETOX, FETOXM1, FTENTOX, FTWOTOX, FATANH, FACOS, FASIN, FATAN
        !            73: 
        !            74: Type=1: FDBcc, FScc, FTRAPcc,
        !            75: 
        !            76: Type=2: FBcc (word, incl. FNOP)
        !            77: 
        !            78: Type=3: FBcc (long)
        !            79: 
        !            80: Type=4: none
        !            81: 
        !            82: Type=5: none
        !            83: 
        !            84:        *: currently FSGLMUL and FSGLDIV are just aliases of
        !            85:           FMUL and FDIV, respectively
        !            86: 
        !            87: * Unimplemented Instructions
        !            88: 
        !            89: Type=0: none
        !            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 operands 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 need not be calculated.  It's taken care of in
        !           155:        fpu_emul_arith().
        !           156: 
        !           157: Actually, after above was written, stubs for the missing functions were
        !           158: added to the source, so you do not have to change fpu_emul_arith() at
        !           159: all.  Function names and prototypes are in fpu_arith_proto.h, and all
        !           160: except fpu_sincos() follow the rules above.  fpu_sincos() is declared
        !           161: as
        !           162: 
        !           163:        struct fpn *fpu_sincos(struct fpemu *fe, int cosreg);
        !           164: 
        !           165: where cosreg is the FP register number to which cosine of the argument
        !           166: is calculated and assigned.  Sine of the argument is stored into the
        !           167: destination register in the same manner as the other arithmetic
        !           168: functions.

unix.superglobalmegacorp.com

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