Add qemu 2.4.0
[kvmfornfv.git] / qemu / linux-user / arm / nwfpe / extended_cpdo.c
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 "fpu/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