Name
Date
Size
#Lines
LOC

..--

READMEH A D21-Aug-20215.7 KiB169125

files.fpeH A D19-Apr-20131 KiB2623

fpu_add.cH A D26-Mar-20136.8 KiB20783

fpu_arith.hH A D01-Apr-20136.1 KiB17171

fpu_arith_proto.hH A D14-Mar-20093.3 KiB9532

fpu_calcea.cH A D28-Dec-202417.9 KiB704530

fpu_cordic.cH A D06-Dec-201610.2 KiB413281

fpu_div.cH A D01-Jan-20147.7 KiB26786

fpu_emulate.cH A D06-Jan-202528.8 KiB1,150819

fpu_emulate.hH A D06-Dec-201610.3 KiB285127

fpu_exp.cH A D15-Jan-20175.1 KiB229116

fpu_explode.cH A D08-Mar-20217.7 KiB270141

fpu_fmovecr.cH A D26-Mar-20134.3 KiB12072

fpu_fscale.cH A D06-Jan-20259.5 KiB343247

fpu_fstore.cH A D06-Jan-20254.2 KiB13585

fpu_getexp.cH A D18-Jul-20112.7 KiB7735

fpu_hyperb.cH A D05-Dec-20166.1 KiB256115

fpu_implode.cH A D26-Mar-201313.3 KiB485277

fpu_int.cH A D19-Mar-20132.6 KiB10650

fpu_log.cH A D04-Jan-201418.4 KiB610447

fpu_mul.cH A D06-Dec-20166.8 KiB21175

fpu_rem.cH A D19-Nov-20235.3 KiB228110

fpu_sqrt.cH A D24-May-202211 KiB362129

fpu_subr.cH A D21-Apr-20135.9 KiB231131

fpu_trig.cH A D16-Jan-20178.8 KiB446211

README

1* $NetBSD: README,v 1.7 2021/08/21 23:00:31 andvar Exp $
2* NetBSD/m68k FPE (floating point emulation) README file
3* Created Oct/??/95 by kenn@remus.rutgers.edu (Ken Nakata)
4* Last updated Oct/15/2011 by tsutsui
5
61. INSTALLATION AND COMPILATION
7
8To compile a kernel with FPE built-in, do the following:
9
101) Add a line "options FPU_EMULATE" to your config file.  If you are
11going to use the resulted kernel on a machine with an FPU for
12debugging purpose, add "options DEBUG_WITH_FPU" as well.
13
142) Follow the usual procedure to build a new kernel.
15
16NOTE:  If you add "options DEBUG_WITH_FPU", FPE will accept cpID=6 as
17emulated FPU.  You will need a modified gas that generates cpID=6 for
18floating point instructions, instead of normal cpID=1.  Mount unionfs
19or 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
41Also, with the DEBUG_WITH_FPU option, you will be able to run only ONE
42process that uses FPE at once to get correct results.
43
44
452. MISSING PARTS
46
47For missing instructions, refer to the Section 3.  Other than that,
48there is one thing that is missing from this version of FPE: packed
49BCD support.
50
51I have no plan to support it since it's rarely used.  However, all we
52need to support it is explosion/implosion functions between the
53internal FP representation and the m68k PBCD format, so you are more
54than welcome to write such functions if you wish to.
55
56
573. IMPLEMENTED INSTRUCTIONS
58
59This is the list of implemented and unimplemented FPU instructions.
60All 040's directly supported type 0 instructions are already
61implemented except FSGLDIV and FSGLMUL.
62
63Type field = bit 8-6 of opcode word
64
65* Implemented Instructions
66
67Type=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
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: none
90
91Type=1: none
92
93Type=2: none
94
95Type=3: none
96
97Type=4: FSAVE
98
99Type=5: FRESTORE
100
101
1024. HOW TO ADD A NEW INSTRUCTION SUPPORT
103
104Since we need not support FSAVE and FRESTORE operations, all
105instructions we have to implement are type 0, all of which are
106arithmetic operations.  It is particularly easy to add a new
107arithmetic instruction to the existing ones (not that it is easy to
108write a "stable" function to perform floating point operation. That's
109entirely another matter).  In "fpu_emulate.c", there's a function
110fpu_emul_arith() which calls emulation functions for all arithmetic
111operations.  In it, there's a large switch() { case ... } which
112dispatches each instruction emulator.  An emulation function of any
113type 0 arithmetic instruction follows this prototype:
114
115	struct fpn *fpu_op(struct fpemu *fe);
116
117Where fe is a pointer to a struct fpemu in which frame, fpframe, and
118fetched operands are accessible.  That's right, you don't have to
119fetch the operands by yourself in your emulation function.  For
120instance, 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
143Here, fe->fe_f1 and fe->fe_f2 are fetched operands.  You can use
144fe->fe_f3 for storing the result, or you can return a pointer to
145either operand if you want to.  At any rate, you have to follow
146the 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
157Actually, after above was written, stubs for the missing functions were
158added to the source, so you do not have to change fpu_emul_arith() at
159all.  Function names and prototypes are in fpu_arith_proto.h, and all
160except fpu_sincos() follow the rules above.  fpu_sincos() is declared
161as
162
163	struct fpn *fpu_sincos(struct fpemu *fe, int cosreg);
164
165where cosreg is the FP register number to which cosine of the argument
166is calculated and assigned.  Sine of the argument is stored into the
167destination register in the same manner as the other arithmetic
168functions.
169