xref: /qemu/linux-user/arm/nwfpe/double_cpdo.c (revision 3ebdd119)
1*3ebdd119Saurel32 /*
2*3ebdd119Saurel32     NetWinder Floating Point Emulator
3*3ebdd119Saurel32     (c) Rebel.COM, 1998,1999
4*3ebdd119Saurel32 
5*3ebdd119Saurel32     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6*3ebdd119Saurel32 
7*3ebdd119Saurel32     This program is free software; you can redistribute it and/or modify
8*3ebdd119Saurel32     it under the terms of the GNU General Public License as published by
9*3ebdd119Saurel32     the Free Software Foundation; either version 2 of the License, or
10*3ebdd119Saurel32     (at your option) any later version.
11*3ebdd119Saurel32 
12*3ebdd119Saurel32     This program is distributed in the hope that it will be useful,
13*3ebdd119Saurel32     but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3ebdd119Saurel32     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3ebdd119Saurel32     GNU General Public License for more details.
16*3ebdd119Saurel32 
17*3ebdd119Saurel32     You should have received a copy of the GNU General Public License
18*3ebdd119Saurel32     along with this program; if not, write to the Free Software
19*3ebdd119Saurel32     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*3ebdd119Saurel32 */
21*3ebdd119Saurel32 
22*3ebdd119Saurel32 #include "fpa11.h"
23*3ebdd119Saurel32 #include "softfloat.h"
24*3ebdd119Saurel32 #include "fpopcode.h"
25*3ebdd119Saurel32 
26*3ebdd119Saurel32 float64 float64_exp(float64 Fm);
27*3ebdd119Saurel32 float64 float64_ln(float64 Fm);
28*3ebdd119Saurel32 float64 float64_sin(float64 rFm);
29*3ebdd119Saurel32 float64 float64_cos(float64 rFm);
30*3ebdd119Saurel32 float64 float64_arcsin(float64 rFm);
31*3ebdd119Saurel32 float64 float64_arctan(float64 rFm);
32*3ebdd119Saurel32 float64 float64_log(float64 rFm);
33*3ebdd119Saurel32 float64 float64_tan(float64 rFm);
34*3ebdd119Saurel32 float64 float64_arccos(float64 rFm);
35*3ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm);
36*3ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm);
37*3ebdd119Saurel32 
38*3ebdd119Saurel32 unsigned int DoubleCPDO(const unsigned int opcode)
39*3ebdd119Saurel32 {
40*3ebdd119Saurel32    FPA11 *fpa11 = GET_FPA11();
41*3ebdd119Saurel32    float64 rFm, rFn = float64_zero;
42*3ebdd119Saurel32    unsigned int Fd, Fm, Fn, nRc = 1;
43*3ebdd119Saurel32 
44*3ebdd119Saurel32    //printk("DoubleCPDO(0x%08x)\n",opcode);
45*3ebdd119Saurel32 
46*3ebdd119Saurel32    Fm = getFm(opcode);
47*3ebdd119Saurel32    if (CONSTANT_FM(opcode))
48*3ebdd119Saurel32    {
49*3ebdd119Saurel32      rFm = getDoubleConstant(Fm);
50*3ebdd119Saurel32    }
51*3ebdd119Saurel32    else
52*3ebdd119Saurel32    {
53*3ebdd119Saurel32      switch (fpa11->fType[Fm])
54*3ebdd119Saurel32      {
55*3ebdd119Saurel32         case typeSingle:
56*3ebdd119Saurel32           rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
57*3ebdd119Saurel32         break;
58*3ebdd119Saurel32 
59*3ebdd119Saurel32         case typeDouble:
60*3ebdd119Saurel32           rFm = fpa11->fpreg[Fm].fDouble;
61*3ebdd119Saurel32           break;
62*3ebdd119Saurel32 
63*3ebdd119Saurel32         case typeExtended:
64*3ebdd119Saurel32             // !! patb
65*3ebdd119Saurel32 	    //printk("not implemented! why not?\n");
66*3ebdd119Saurel32             //!! ScottB
67*3ebdd119Saurel32             // should never get here, if extended involved
68*3ebdd119Saurel32             // then other operand should be promoted then
69*3ebdd119Saurel32             // ExtendedCPDO called.
70*3ebdd119Saurel32             break;
71*3ebdd119Saurel32 
72*3ebdd119Saurel32         default: return 0;
73*3ebdd119Saurel32      }
74*3ebdd119Saurel32    }
75*3ebdd119Saurel32 
76*3ebdd119Saurel32    if (!MONADIC_INSTRUCTION(opcode))
77*3ebdd119Saurel32    {
78*3ebdd119Saurel32       Fn = getFn(opcode);
79*3ebdd119Saurel32       switch (fpa11->fType[Fn])
80*3ebdd119Saurel32       {
81*3ebdd119Saurel32         case typeSingle:
82*3ebdd119Saurel32           rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
83*3ebdd119Saurel32         break;
84*3ebdd119Saurel32 
85*3ebdd119Saurel32         case typeDouble:
86*3ebdd119Saurel32           rFn = fpa11->fpreg[Fn].fDouble;
87*3ebdd119Saurel32         break;
88*3ebdd119Saurel32 
89*3ebdd119Saurel32         default: return 0;
90*3ebdd119Saurel32       }
91*3ebdd119Saurel32    }
92*3ebdd119Saurel32 
93*3ebdd119Saurel32    Fd = getFd(opcode);
94*3ebdd119Saurel32    /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
95*3ebdd119Saurel32    switch (opcode & MASK_ARITHMETIC_OPCODE)
96*3ebdd119Saurel32    {
97*3ebdd119Saurel32       /* dyadic opcodes */
98*3ebdd119Saurel32       case ADF_CODE:
99*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status);
100*3ebdd119Saurel32       break;
101*3ebdd119Saurel32 
102*3ebdd119Saurel32       case MUF_CODE:
103*3ebdd119Saurel32       case FML_CODE:
104*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status);
105*3ebdd119Saurel32       break;
106*3ebdd119Saurel32 
107*3ebdd119Saurel32       case SUF_CODE:
108*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status);
109*3ebdd119Saurel32       break;
110*3ebdd119Saurel32 
111*3ebdd119Saurel32       case RSF_CODE:
112*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status);
113*3ebdd119Saurel32       break;
114*3ebdd119Saurel32 
115*3ebdd119Saurel32       case DVF_CODE:
116*3ebdd119Saurel32       case FDV_CODE:
117*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status);
118*3ebdd119Saurel32       break;
119*3ebdd119Saurel32 
120*3ebdd119Saurel32       case RDF_CODE:
121*3ebdd119Saurel32       case FRD_CODE:
122*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
123*3ebdd119Saurel32       break;
124*3ebdd119Saurel32 
125*3ebdd119Saurel32 #if 0
126*3ebdd119Saurel32       case POW_CODE:
127*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
128*3ebdd119Saurel32       break;
129*3ebdd119Saurel32 
130*3ebdd119Saurel32       case RPW_CODE:
131*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
132*3ebdd119Saurel32       break;
133*3ebdd119Saurel32 #endif
134*3ebdd119Saurel32 
135*3ebdd119Saurel32       case RMF_CODE:
136*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status);
137*3ebdd119Saurel32       break;
138*3ebdd119Saurel32 
139*3ebdd119Saurel32 #if 0
140*3ebdd119Saurel32       case POL_CODE:
141*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
142*3ebdd119Saurel32       break;
143*3ebdd119Saurel32 #endif
144*3ebdd119Saurel32 
145*3ebdd119Saurel32       /* monadic opcodes */
146*3ebdd119Saurel32       case MVF_CODE:
147*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = rFm;
148*3ebdd119Saurel32       break;
149*3ebdd119Saurel32 
150*3ebdd119Saurel32       case MNF_CODE:
151*3ebdd119Saurel32       {
152*3ebdd119Saurel32          unsigned int *p = (unsigned int*)&rFm;
153*3ebdd119Saurel32 #ifdef WORDS_BIGENDIAN
154*3ebdd119Saurel32          p[0] ^= 0x80000000;
155*3ebdd119Saurel32 #else
156*3ebdd119Saurel32          p[1] ^= 0x80000000;
157*3ebdd119Saurel32 #endif
158*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = rFm;
159*3ebdd119Saurel32       }
160*3ebdd119Saurel32       break;
161*3ebdd119Saurel32 
162*3ebdd119Saurel32       case ABS_CODE:
163*3ebdd119Saurel32       {
164*3ebdd119Saurel32          unsigned int *p = (unsigned int*)&rFm;
165*3ebdd119Saurel32 #ifdef WORDS_BIGENDIAN
166*3ebdd119Saurel32          p[0] &= 0x7fffffff;
167*3ebdd119Saurel32 #else
168*3ebdd119Saurel32          p[1] &= 0x7fffffff;
169*3ebdd119Saurel32 #endif
170*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = rFm;
171*3ebdd119Saurel32       }
172*3ebdd119Saurel32       break;
173*3ebdd119Saurel32 
174*3ebdd119Saurel32       case RND_CODE:
175*3ebdd119Saurel32       case URD_CODE:
176*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status);
177*3ebdd119Saurel32       break;
178*3ebdd119Saurel32 
179*3ebdd119Saurel32       case SQT_CODE:
180*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status);
181*3ebdd119Saurel32       break;
182*3ebdd119Saurel32 
183*3ebdd119Saurel32 #if 0
184*3ebdd119Saurel32       case LOG_CODE:
185*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_log(rFm);
186*3ebdd119Saurel32       break;
187*3ebdd119Saurel32 
188*3ebdd119Saurel32       case LGN_CODE:
189*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
190*3ebdd119Saurel32       break;
191*3ebdd119Saurel32 
192*3ebdd119Saurel32       case EXP_CODE:
193*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
194*3ebdd119Saurel32       break;
195*3ebdd119Saurel32 
196*3ebdd119Saurel32       case SIN_CODE:
197*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
198*3ebdd119Saurel32       break;
199*3ebdd119Saurel32 
200*3ebdd119Saurel32       case COS_CODE:
201*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
202*3ebdd119Saurel32       break;
203*3ebdd119Saurel32 
204*3ebdd119Saurel32       case TAN_CODE:
205*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
206*3ebdd119Saurel32       break;
207*3ebdd119Saurel32 
208*3ebdd119Saurel32       case ASN_CODE:
209*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
210*3ebdd119Saurel32       break;
211*3ebdd119Saurel32 
212*3ebdd119Saurel32       case ACS_CODE:
213*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
214*3ebdd119Saurel32       break;
215*3ebdd119Saurel32 
216*3ebdd119Saurel32       case ATN_CODE:
217*3ebdd119Saurel32          fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
218*3ebdd119Saurel32       break;
219*3ebdd119Saurel32 #endif
220*3ebdd119Saurel32 
221*3ebdd119Saurel32       case NRM_CODE:
222*3ebdd119Saurel32       break;
223*3ebdd119Saurel32 
224*3ebdd119Saurel32       default:
225*3ebdd119Saurel32       {
226*3ebdd119Saurel32         nRc = 0;
227*3ebdd119Saurel32       }
228*3ebdd119Saurel32    }
229*3ebdd119Saurel32 
230*3ebdd119Saurel32    if (0 != nRc) fpa11->fType[Fd] = typeDouble;
231*3ebdd119Saurel32    return nRc;
232*3ebdd119Saurel32 }
233*3ebdd119Saurel32 
234*3ebdd119Saurel32 #if 0
235*3ebdd119Saurel32 float64 float64_exp(float64 rFm)
236*3ebdd119Saurel32 {
237*3ebdd119Saurel32   return rFm;
238*3ebdd119Saurel32 //series
239*3ebdd119Saurel32 }
240*3ebdd119Saurel32 
241*3ebdd119Saurel32 float64 float64_ln(float64 rFm)
242*3ebdd119Saurel32 {
243*3ebdd119Saurel32   return rFm;
244*3ebdd119Saurel32 //series
245*3ebdd119Saurel32 }
246*3ebdd119Saurel32 
247*3ebdd119Saurel32 float64 float64_sin(float64 rFm)
248*3ebdd119Saurel32 {
249*3ebdd119Saurel32   return rFm;
250*3ebdd119Saurel32 //series
251*3ebdd119Saurel32 }
252*3ebdd119Saurel32 
253*3ebdd119Saurel32 float64 float64_cos(float64 rFm)
254*3ebdd119Saurel32 {
255*3ebdd119Saurel32    return rFm;
256*3ebdd119Saurel32    //series
257*3ebdd119Saurel32 }
258*3ebdd119Saurel32 
259*3ebdd119Saurel32 #if 0
260*3ebdd119Saurel32 float64 float64_arcsin(float64 rFm)
261*3ebdd119Saurel32 {
262*3ebdd119Saurel32 //series
263*3ebdd119Saurel32 }
264*3ebdd119Saurel32 
265*3ebdd119Saurel32 float64 float64_arctan(float64 rFm)
266*3ebdd119Saurel32 {
267*3ebdd119Saurel32   //series
268*3ebdd119Saurel32 }
269*3ebdd119Saurel32 #endif
270*3ebdd119Saurel32 
271*3ebdd119Saurel32 float64 float64_log(float64 rFm)
272*3ebdd119Saurel32 {
273*3ebdd119Saurel32   return float64_div(float64_ln(rFm),getDoubleConstant(7));
274*3ebdd119Saurel32 }
275*3ebdd119Saurel32 
276*3ebdd119Saurel32 float64 float64_tan(float64 rFm)
277*3ebdd119Saurel32 {
278*3ebdd119Saurel32   return float64_div(float64_sin(rFm),float64_cos(rFm));
279*3ebdd119Saurel32 }
280*3ebdd119Saurel32 
281*3ebdd119Saurel32 float64 float64_arccos(float64 rFm)
282*3ebdd119Saurel32 {
283*3ebdd119Saurel32 return rFm;
284*3ebdd119Saurel32    //return float64_sub(halfPi,float64_arcsin(rFm));
285*3ebdd119Saurel32 }
286*3ebdd119Saurel32 
287*3ebdd119Saurel32 float64 float64_pow(float64 rFn,float64 rFm)
288*3ebdd119Saurel32 {
289*3ebdd119Saurel32   return float64_exp(float64_mul(rFm,float64_ln(rFn)));
290*3ebdd119Saurel32 }
291*3ebdd119Saurel32 
292*3ebdd119Saurel32 float64 float64_pol(float64 rFn,float64 rFm)
293*3ebdd119Saurel32 {
294*3ebdd119Saurel32   return float64_arctan(float64_div(rFn,rFm));
295*3ebdd119Saurel32 }
296*3ebdd119Saurel32 #endif
297