Statistics
| Branch: | Revision:

root / target-arm / nwfpe / double_cpdo.c @ 3b46e624

History | View | Annotate | Download (6.4 kB)

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 "fpa11.h"
23
#include "softfloat.h"
24
#include "fpopcode.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 = 0;
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, &fpa11->fp_status);
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, &fpa11->fp_status);
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, &fpa11->fp_status);
100
      break;
101

    
102
      case MUF_CODE:
103
      case FML_CODE:
104
         fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status);
105
      break;
106

    
107
      case SUF_CODE:
108
         fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status);
109
      break;
110

    
111
      case RSF_CODE:
112
         fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status);
113
      break;
114

    
115
      case DVF_CODE:
116
      case FDV_CODE:
117
         fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status);
118
      break;
119

    
120
      case RDF_CODE:
121
      case FRD_CODE:
122
         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
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, &fpa11->fp_status);
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
#ifdef WORDS_BIGENDIAN
154
         p[0] ^= 0x80000000;
155
#else
156
         p[1] ^= 0x80000000;
157
#endif
158
         fpa11->fpreg[Fd].fDouble = rFm;
159
      }
160
      break;
161

    
162
      case ABS_CODE:
163
      {
164
         unsigned int *p = (unsigned int*)&rFm;
165
#ifdef WORDS_BIGENDIAN
166
         p[0] &= 0x7fffffff;
167
#else
168
         p[1] &= 0x7fffffff;
169
#endif
170
         fpa11->fpreg[Fd].fDouble = rFm;
171
      }
172
      break;
173

    
174
      case RND_CODE:
175
      case URD_CODE:
176
         fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status);
177
      break;
178

    
179
      case SQT_CODE:
180
         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status);
181
      break;
182

    
183
#if 0
184
      case LOG_CODE:
185
         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
186
      break;
187

188
      case LGN_CODE:
189
         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
190
      break;
191

192
      case EXP_CODE:
193
         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
194
      break;
195

196
      case SIN_CODE:
197
         fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
198
      break;
199

200
      case COS_CODE:
201
         fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
202
      break;
203

204
      case TAN_CODE:
205
         fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
206
      break;
207

208
      case ASN_CODE:
209
         fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
210
      break;
211

212
      case ACS_CODE:
213
         fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
214
      break;
215

216
      case ATN_CODE:
217
         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
218
      break;
219
#endif
220

    
221
      case NRM_CODE:
222
      break;
223

    
224
      default:
225
      {
226
        nRc = 0;
227
      }
228
   }
229

    
230
   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
231
   return nRc;
232
}
233

    
234
#if 0
235
float64 float64_exp(float64 rFm)
236
{
237
  return rFm;
238
//series
239
}
240

241
float64 float64_ln(float64 rFm)
242
{
243
  return rFm;
244
//series
245
}
246

247
float64 float64_sin(float64 rFm)
248
{
249
  return rFm;
250
//series
251
}
252

253
float64 float64_cos(float64 rFm)
254
{
255
   return rFm;
256
   //series
257
}
258

259
#if 0
260
float64 float64_arcsin(float64 rFm)
261
{
262
//series
263
}
264

265
float64 float64_arctan(float64 rFm)
266
{
267
  //series
268
}
269
#endif
270

    
271
float64 float64_log(float64 rFm)
272
{
273
  return float64_div(float64_ln(rFm),getDoubleConstant(7));
274
}
275

    
276
float64 float64_tan(float64 rFm)
277
{
278
  return float64_div(float64_sin(rFm),float64_cos(rFm));
279
}
280

    
281
float64 float64_arccos(float64 rFm)
282
{
283
return rFm;
284
   //return float64_sub(halfPi,float64_arcsin(rFm));
285
}
286

    
287
float64 float64_pow(float64 rFn,float64 rFm)
288
{
289
  return float64_exp(float64_mul(rFm,float64_ln(rFn)));
290
}
291

    
292
float64 float64_pol(float64 rFn,float64 rFm)
293
{
294
  return float64_arctan(float64_div(rFn,rFm));
295
}
296
#endif