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