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 float32 float32_exp(float32 Fm);
26 float32 float32_ln(float32 Fm);
27 float32 float32_sin(float32 rFm);
28 float32 float32_cos(float32 rFm);
29 float32 float32_arcsin(float32 rFm);
30 float32 float32_arctan(float32 rFm);
31 float32 float32_log(float32 rFm);
32 float32 float32_tan(float32 rFm);
33 float32 float32_arccos(float32 rFm);
34 float32 float32_pow(float32 rFn,float32 rFm);
35 float32 float32_pol(float32 rFn,float32 rFm);
36 
37 unsigned int SingleCPDO(const unsigned int opcode)
38 {
39    FPA11 *fpa11 = GET_FPA11();
40    float32 rFm, rFn = float32_zero;
41    unsigned int Fd, Fm, Fn, nRc = 1;
42 
43    Fm = getFm(opcode);
44    if (CONSTANT_FM(opcode))
45    {
46      rFm = getSingleConstant(Fm);
47    }
48    else
49    {
50      switch (fpa11->fType[Fm])
51      {
52         case typeSingle:
53           rFm = fpa11->fpreg[Fm].fSingle;
54         break;
55 
56         default: return 0;
57      }
58    }
59 
60    if (!MONADIC_INSTRUCTION(opcode))
61    {
62       Fn = getFn(opcode);
63       switch (fpa11->fType[Fn])
64       {
65         case typeSingle:
66           rFn = fpa11->fpreg[Fn].fSingle;
67         break;
68 
69         default: return 0;
70       }
71    }
72 
73    Fd = getFd(opcode);
74    switch (opcode & MASK_ARITHMETIC_OPCODE)
75    {
76       /* dyadic opcodes */
77       case ADF_CODE:
78          fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm, &fpa11->fp_status);
79       break;
80 
81       case MUF_CODE:
82       case FML_CODE:
83         fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm, &fpa11->fp_status);
84       break;
85 
86       case SUF_CODE:
87          fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm, &fpa11->fp_status);
88       break;
89 
90       case RSF_CODE:
91          fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn, &fpa11->fp_status);
92       break;
93 
94       case DVF_CODE:
95       case FDV_CODE:
96          fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm, &fpa11->fp_status);
97       break;
98 
99       case RDF_CODE:
100       case FRD_CODE:
101          fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn, &fpa11->fp_status);
102       break;
103 
104 #if 0
105       case POW_CODE:
106          fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
107       break;
108 
109       case RPW_CODE:
110          fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
111       break;
112 #endif
113 
114       case RMF_CODE:
115          fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm, &fpa11->fp_status);
116       break;
117 
118 #if 0
119       case POL_CODE:
120          fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
121       break;
122 #endif
123 
124       /* monadic opcodes */
125       case MVF_CODE:
126          fpa11->fpreg[Fd].fSingle = rFm;
127       break;
128 
129       case MNF_CODE:
130          fpa11->fpreg[Fd].fSingle = float32_chs(rFm);
131       break;
132 
133       case ABS_CODE:
134          fpa11->fpreg[Fd].fSingle = float32_abs(rFm);
135       break;
136 
137       case RND_CODE:
138       case URD_CODE:
139          fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status);
140       break;
141 
142       case SQT_CODE:
143          fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status);
144       break;
145 
146 #if 0
147       case LOG_CODE:
148          fpa11->fpreg[Fd].fSingle = float32_log(rFm);
149       break;
150 
151       case LGN_CODE:
152          fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
153       break;
154 
155       case EXP_CODE:
156          fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
157       break;
158 
159       case SIN_CODE:
160          fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
161       break;
162 
163       case COS_CODE:
164          fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
165       break;
166 
167       case TAN_CODE:
168          fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
169       break;
170 
171       case ASN_CODE:
172          fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
173       break;
174 
175       case ACS_CODE:
176          fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
177       break;
178 
179       case ATN_CODE:
180          fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
181       break;
182 #endif
183 
184       case NRM_CODE:
185       break;
186 
187       default:
188       {
189         nRc = 0;
190       }
191    }
192 
193    if (0 != nRc) fpa11->fType[Fd] = typeSingle;
194    return nRc;
195 }
196 
197 #if 0
198 float32 float32_exp(float32 Fm)
199 {
200 //series
201 }
202 
203 float32 float32_ln(float32 Fm)
204 {
205 //series
206 }
207 
208 float32 float32_sin(float32 rFm)
209 {
210 //series
211 }
212 
213 float32 float32_cos(float32 rFm)
214 {
215 //series
216 }
217 
218 float32 float32_arcsin(float32 rFm)
219 {
220 //series
221 }
222 
223 float32 float32_arctan(float32 rFm)
224 {
225   //series
226 }
227 
228 float32 float32_arccos(float32 rFm)
229 {
230    //return float32_sub(halfPi,float32_arcsin(rFm));
231 }
232 
233 float32 float32_log(float32 rFm)
234 {
235   return float32_div(float32_ln(rFm),getSingleConstant(7));
236 }
237 
238 float32 float32_tan(float32 rFm)
239 {
240   return float32_div(float32_sin(rFm),float32_cos(rFm));
241 }
242 
243 float32 float32_pow(float32 rFn,float32 rFm)
244 {
245   return float32_exp(float32_mul(rFm,float32_ln(rFn)));
246 }
247 
248 float32 float32_pol(float32 rFn,float32 rFm)
249 {
250   return float32_arctan(float32_div(rFn,rFm));
251 }
252 #endif
253