File: /usr/src/linux/arch/arm/nwfpe/double_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, write to the Free Software
19         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21     
22     #include "softfloat.h"
23     #include "fpopcode.h"
24     #include "fpa11.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;
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);
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);
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);
100           break;
101     
102           case MUF_CODE:
103           case FML_CODE:
104              fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
105           break;
106     
107           case SUF_CODE:
108              fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
109           break;
110     
111           case RSF_CODE:
112              fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
113           break;
114     
115           case DVF_CODE:
116           case FDV_CODE:
117              fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
118           break;
119     
120           case RDF_CODE:
121           case FRD_CODE:
122              fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
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);
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              p[1] ^= 0x80000000;
154              fpa11->fpreg[Fd].fDouble = rFm;
155           }
156           break;
157     
158           case ABS_CODE:
159           {
160              unsigned int *p = (unsigned int*)&rFm;
161              p[1] &= 0x7fffffff;
162              fpa11->fpreg[Fd].fDouble = rFm;
163           }
164           break;
165     
166           case RND_CODE:
167           case URD_CODE:
168              fpa11->fpreg[Fd].fDouble = 
169                  int32_to_float64(float64_to_int32(rFm));
170           break;
171     
172           case SQT_CODE:
173              fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
174           break;
175     
176     #if 0
177           case LOG_CODE:
178              fpa11->fpreg[Fd].fDouble = float64_log(rFm);
179           break;
180     
181           case LGN_CODE:
182              fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
183           break;
184     
185           case EXP_CODE:
186              fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
187           break;
188     
189           case SIN_CODE:
190              fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
191           break;
192     
193           case COS_CODE:
194              fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
195           break;
196     
197           case TAN_CODE:
198              fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
199           break;
200     
201           case ASN_CODE:
202              fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
203           break;
204     
205           case ACS_CODE:
206              fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
207           break;
208     
209           case ATN_CODE:
210              fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
211           break;
212     #endif
213     
214           case NRM_CODE:
215           break;
216           
217           default:
218           {
219             nRc = 0;
220           }
221        }
222     
223        if (0 != nRc) fpa11->fType[Fd] = typeDouble;
224        return nRc;
225     }
226     
227     #if 0
228     float64 float64_exp(float64 rFm)
229     {
230       return rFm;
231     //series
232     }
233     
234     float64 float64_ln(float64 rFm)
235     {
236       return rFm;
237     //series
238     }
239     
240     float64 float64_sin(float64 rFm)
241     {
242       return rFm;
243     //series
244     }
245     
246     float64 float64_cos(float64 rFm)
247     {
248        return rFm;
249        //series
250     }
251     
252     #if 0
253     float64 float64_arcsin(float64 rFm)
254     {
255     //series
256     }
257     
258     float64 float64_arctan(float64 rFm)
259     {
260       //series
261     }
262     #endif
263     
264     float64 float64_log(float64 rFm)
265     {
266       return float64_div(float64_ln(rFm),getDoubleConstant(7));
267     }
268     
269     float64 float64_tan(float64 rFm)
270     {
271       return float64_div(float64_sin(rFm),float64_cos(rFm));
272     }
273     
274     float64 float64_arccos(float64 rFm)
275     {
276     return rFm;
277        //return float64_sub(halfPi,float64_arcsin(rFm));
278     }
279     
280     float64 float64_pow(float64 rFn,float64 rFm)
281     {
282       return float64_exp(float64_mul(rFm,float64_ln(rFn))); 
283     }
284     
285     float64 float64_pol(float64 rFn,float64 rFm)
286     {
287       return float64_arctan(float64_div(rFn,rFm)); 
288     }
289     #endif
290