1 /*
2     NetWinder Floating Point Emulator
3     (c) Rebel.COM, 1998,1999
4 
5     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
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, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "fpa11.h"
22 #include "softfloat.h"
23 #include "fpopcode.h"
24 
25 floatx80 floatx80_exp(floatx80 Fm);
26 floatx80 floatx80_ln(floatx80 Fm);
27 floatx80 floatx80_sin(floatx80 rFm);
28 floatx80 floatx80_cos(floatx80 rFm);
29 floatx80 floatx80_arcsin(floatx80 rFm);
30 floatx80 floatx80_arctan(floatx80 rFm);
31 floatx80 floatx80_log(floatx80 rFm);
32 floatx80 floatx80_tan(floatx80 rFm);
33 floatx80 floatx80_arccos(floatx80 rFm);
34 floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
35 floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
36 
37 unsigned int ExtendedCPDO(const unsigned int opcode)
38 {
39    FPA11 *fpa11 = GET_FPA11();
40    floatx80 rFm, rFn;
41    unsigned int Fd, Fm, Fn, nRc = 1;
42 
43    //printk("ExtendedCPDO(0x%08x)\n",opcode);
44 
45    Fm = getFm(opcode);
46    if (CONSTANT_FM(opcode))
47    {
48      rFm = getExtendedConstant(Fm);
49    }
50    else
51    {
52      switch (fpa11->fType[Fm])
53      {
54         case typeSingle:
55           rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
56         break;
57 
58         case typeDouble:
59           rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
60         break;
61 
62         case typeExtended:
63           rFm = fpa11->fpreg[Fm].fExtended;
64         break;
65 
66         default: return 0;
67      }
68    }
69 
70    if (!MONADIC_INSTRUCTION(opcode))
71    {
72       Fn = getFn(opcode);
73       switch (fpa11->fType[Fn])
74       {
75         case typeSingle:
76           rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
77         break;
78 
79         case typeDouble:
80           rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
81         break;
82 
83         case typeExtended:
84           rFn = fpa11->fpreg[Fn].fExtended;
85         break;
86 
87         default: return 0;
88       }
89    }
90 
91    Fd = getFd(opcode);
92    switch (opcode & MASK_ARITHMETIC_OPCODE)
93    {
94       /* dyadic opcodes */
95       case ADF_CODE:
96          fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm, &fpa11->fp_status);
97       break;
98 
99       case MUF_CODE:
100       case FML_CODE:
101          fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm, &fpa11->fp_status);
102       break;
103 
104       case SUF_CODE:
105          fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm, &fpa11->fp_status);
106       break;
107 
108       case RSF_CODE:
109          fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn, &fpa11->fp_status);
110       break;
111 
112       case DVF_CODE:
113       case FDV_CODE:
114          fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm, &fpa11->fp_status);
115       break;
116 
117       case RDF_CODE:
118       case FRD_CODE:
119          fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn, &fpa11->fp_status);
120       break;
121 
122 #if 0
123       case POW_CODE:
124          fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
125       break;
126 
127       case RPW_CODE:
128          fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
129       break;
130 #endif
131 
132       case RMF_CODE:
133          fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm, &fpa11->fp_status);
134       break;
135 
136 #if 0
137       case POL_CODE:
138          fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
139       break;
140 #endif
141 
142       /* monadic opcodes */
143       case MVF_CODE:
144          fpa11->fpreg[Fd].fExtended = rFm;
145       break;
146 
147       case MNF_CODE:
148          rFm.high ^= 0x8000;
149          fpa11->fpreg[Fd].fExtended = rFm;
150       break;
151 
152       case ABS_CODE:
153          rFm.high &= 0x7fff;
154          fpa11->fpreg[Fd].fExtended = rFm;
155       break;
156 
157       case RND_CODE:
158       case URD_CODE:
159          fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm, &fpa11->fp_status);
160       break;
161 
162       case SQT_CODE:
163          fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm, &fpa11->fp_status);
164       break;
165 
166 #if 0
167       case LOG_CODE:
168          fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
169       break;
170 
171       case LGN_CODE:
172          fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
173       break;
174 
175       case EXP_CODE:
176          fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
177       break;
178 
179       case SIN_CODE:
180          fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
181       break;
182 
183       case COS_CODE:
184          fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
185       break;
186 
187       case TAN_CODE:
188          fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
189       break;
190 
191       case ASN_CODE:
192          fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
193       break;
194 
195       case ACS_CODE:
196          fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
197       break;
198 
199       case ATN_CODE:
200          fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
201       break;
202 #endif
203 
204       case NRM_CODE:
205       break;
206 
207       default:
208       {
209         nRc = 0;
210       }
211    }
212 
213    if (0 != nRc) fpa11->fType[Fd] = typeExtended;
214    return nRc;
215 }
216 
217 #if 0
218 floatx80 floatx80_exp(floatx80 Fm)
219 {
220 //series
221 }
222 
223 floatx80 floatx80_ln(floatx80 Fm)
224 {
225 //series
226 }
227 
228 floatx80 floatx80_sin(floatx80 rFm)
229 {
230 //series
231 }
232 
233 floatx80 floatx80_cos(floatx80 rFm)
234 {
235 //series
236 }
237 
238 floatx80 floatx80_arcsin(floatx80 rFm)
239 {
240 //series
241 }
242 
243 floatx80 floatx80_arctan(floatx80 rFm)
244 {
245   //series
246 }
247 
248 floatx80 floatx80_log(floatx80 rFm)
249 {
250   return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
251 }
252 
253 floatx80 floatx80_tan(floatx80 rFm)
254 {
255   return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
256 }
257 
258 floatx80 floatx80_arccos(floatx80 rFm)
259 {
260    //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
261 }
262 
263 floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
264 {
265   return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
266 }
267 
268 floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
269 {
270   return floatx80_arctan(floatx80_div(rFn,rFm));
271 }
272 #endif
273