|
|
1.1 root 1: /*
2: NetWinder Floating Point Emulator
3: (c) Rebel.COM, 1998,1999
4:
5: Direct questions, comments to Scott Bambrough <[email protected]>
6:
7: This program is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2 of the License, or
10: (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20: */
21:
22: #include "fpa11.h"
23: #include "softfloat.h"
24: #include "fpopcode.h"
25:
26: float64 float64_exp(float64 Fm);
27: float64 float64_ln(float64 Fm);
28: float64 float64_sin(float64 rFm);
29: float64 float64_cos(float64 rFm);
30: float64 float64_arcsin(float64 rFm);
31: float64 float64_arctan(float64 rFm);
32: float64 float64_log(float64 rFm);
33: float64 float64_tan(float64 rFm);
34: float64 float64_arccos(float64 rFm);
35: float64 float64_pow(float64 rFn,float64 rFm);
36: float64 float64_pol(float64 rFn,float64 rFm);
37:
38: unsigned int DoubleCPDO(const unsigned int opcode)
39: {
40: FPA11 *fpa11 = GET_FPA11();
41: float64 rFm, rFn = float64_zero;
42: unsigned int Fd, Fm, Fn, nRc = 1;
43:
44: //printk("DoubleCPDO(0x%08x)\n",opcode);
45:
46: Fm = getFm(opcode);
47: if (CONSTANT_FM(opcode))
48: {
49: rFm = getDoubleConstant(Fm);
50: }
51: else
52: {
53: switch (fpa11->fType[Fm])
54: {
55: case typeSingle:
56: rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
57: break;
58:
59: case typeDouble:
60: rFm = fpa11->fpreg[Fm].fDouble;
61: break;
62:
63: case typeExtended:
64: // !! patb
65: //printk("not implemented! why not?\n");
66: //!! ScottB
67: // should never get here, if extended involved
68: // then other operand should be promoted then
69: // ExtendedCPDO called.
70: break;
71:
72: default: return 0;
73: }
74: }
75:
76: if (!MONADIC_INSTRUCTION(opcode))
77: {
78: Fn = getFn(opcode);
79: switch (fpa11->fType[Fn])
80: {
81: case typeSingle:
82: rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
83: break;
84:
85: case typeDouble:
86: rFn = fpa11->fpreg[Fn].fDouble;
87: break;
88:
89: default: return 0;
90: }
91: }
92:
93: Fd = getFd(opcode);
94: /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
95: switch (opcode & MASK_ARITHMETIC_OPCODE)
96: {
97: /* dyadic opcodes */
98: case ADF_CODE:
99: fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status);
100: break;
101:
102: case MUF_CODE:
103: case FML_CODE:
104: fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status);
105: break;
106:
107: case SUF_CODE:
108: fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status);
109: break;
110:
111: case RSF_CODE:
112: fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status);
113: break;
114:
115: case DVF_CODE:
116: case FDV_CODE:
117: fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status);
118: break;
119:
120: case RDF_CODE:
121: case FRD_CODE:
122: fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
123: break;
124:
125: #if 0
126: case POW_CODE:
127: fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
128: break;
129:
130: case RPW_CODE:
131: fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
132: break;
133: #endif
134:
135: case RMF_CODE:
136: fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status);
137: break;
138:
139: #if 0
140: case POL_CODE:
141: fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
142: break;
143: #endif
144:
145: /* monadic opcodes */
146: case MVF_CODE:
147: fpa11->fpreg[Fd].fDouble = rFm;
148: break;
149:
150: case MNF_CODE:
151: {
152: unsigned int *p = (unsigned int*)&rFm;
153: #ifdef WORDS_BIGENDIAN
154: p[0] ^= 0x80000000;
155: #else
156: p[1] ^= 0x80000000;
157: #endif
158: fpa11->fpreg[Fd].fDouble = rFm;
159: }
160: break;
161:
162: case ABS_CODE:
163: {
164: unsigned int *p = (unsigned int*)&rFm;
165: #ifdef WORDS_BIGENDIAN
166: p[0] &= 0x7fffffff;
167: #else
168: p[1] &= 0x7fffffff;
169: #endif
170: fpa11->fpreg[Fd].fDouble = rFm;
171: }
172: break;
173:
174: case RND_CODE:
175: case URD_CODE:
176: fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status);
177: break;
178:
179: case SQT_CODE:
180: fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status);
181: break;
182:
183: #if 0
184: case LOG_CODE:
185: fpa11->fpreg[Fd].fDouble = float64_log(rFm);
186: break;
187:
188: case LGN_CODE:
189: fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
190: break;
191:
192: case EXP_CODE:
193: fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
194: break;
195:
196: case SIN_CODE:
197: fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
198: break;
199:
200: case COS_CODE:
201: fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
202: break;
203:
204: case TAN_CODE:
205: fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
206: break;
207:
208: case ASN_CODE:
209: fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
210: break;
211:
212: case ACS_CODE:
213: fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
214: break;
215:
216: case ATN_CODE:
217: fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
218: break;
219: #endif
220:
221: case NRM_CODE:
222: break;
223:
224: default:
225: {
226: nRc = 0;
227: }
228: }
229:
230: if (0 != nRc) fpa11->fType[Fd] = typeDouble;
231: return nRc;
232: }
233:
234: #if 0
235: float64 float64_exp(float64 rFm)
236: {
237: return rFm;
238: //series
239: }
240:
241: float64 float64_ln(float64 rFm)
242: {
243: return rFm;
244: //series
245: }
246:
247: float64 float64_sin(float64 rFm)
248: {
249: return rFm;
250: //series
251: }
252:
253: float64 float64_cos(float64 rFm)
254: {
255: return rFm;
256: //series
257: }
258:
259: #if 0
260: float64 float64_arcsin(float64 rFm)
261: {
262: //series
263: }
264:
265: float64 float64_arctan(float64 rFm)
266: {
267: //series
268: }
269: #endif
270:
271: float64 float64_log(float64 rFm)
272: {
273: return float64_div(float64_ln(rFm),getDoubleConstant(7));
274: }
275:
276: float64 float64_tan(float64 rFm)
277: {
278: return float64_div(float64_sin(rFm),float64_cos(rFm));
279: }
280:
281: float64 float64_arccos(float64 rFm)
282: {
283: return rFm;
284: //return float64_sub(halfPi,float64_arcsin(rFm));
285: }
286:
287: float64 float64_pow(float64 rFn,float64 rFm)
288: {
289: return float64_exp(float64_mul(rFm,float64_ln(rFn)));
290: }
291:
292: float64 float64_pol(float64 rFn,float64 rFm)
293: {
294: return float64_arctan(float64_div(rFn,rFm));
295: }
296: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.