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