Statistics
| Branch: | Revision:

root / linux-user / arm / nwfpe / double_cpdo.c @ 70539e18

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, see <http://www.gnu.org/licenses/>.
19
*/
20

    
21
#include "fpa11.h"
22
#include "softfloat.h"
23
#include "fpopcode.h"
24

    
25
float64 float64_exp(float64 Fm);
26
float64 float64_ln(float64 Fm);
27
float64 float64_sin(float64 rFm);
28
float64 float64_cos(float64 rFm);
29
float64 float64_arcsin(float64 rFm);
30
float64 float64_arctan(float64 rFm);
31
float64 float64_log(float64 rFm);
32
float64 float64_tan(float64 rFm);
33
float64 float64_arccos(float64 rFm);
34
float64 float64_pow(float64 rFn,float64 rFm);
35
float64 float64_pol(float64 rFn,float64 rFm);
36

    
37
unsigned int DoubleCPDO(const unsigned int opcode)
38
{
39
   FPA11 *fpa11 = GET_FPA11();
40
   float64 rFm, rFn = float64_zero;
41
   unsigned int Fd, Fm, Fn, nRc = 1;
42

    
43
   //printk("DoubleCPDO(0x%08x)\n",opcode);
44

    
45
   Fm = getFm(opcode);
46
   if (CONSTANT_FM(opcode))
47
   {
48
     rFm = getDoubleConstant(Fm);
49
   }
50
   else
51
   {
52
     switch (fpa11->fType[Fm])
53
     {
54
        case typeSingle:
55
          rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
56
        break;
57

    
58
        case typeDouble:
59
          rFm = fpa11->fpreg[Fm].fDouble;
60
          break;
61

    
62
        case typeExtended:
63
            // !! patb
64
            //printk("not implemented! why not?\n");
65
            //!! ScottB
66
            // should never get here, if extended involved
67
            // then other operand should be promoted then
68
            // ExtendedCPDO called.
69
            break;
70

    
71
        default: return 0;
72
     }
73
   }
74

    
75
   if (!MONADIC_INSTRUCTION(opcode))
76
   {
77
      Fn = getFn(opcode);
78
      switch (fpa11->fType[Fn])
79
      {
80
        case typeSingle:
81
          rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
82
        break;
83

    
84
        case typeDouble:
85
          rFn = fpa11->fpreg[Fn].fDouble;
86
        break;
87

    
88
        default: return 0;
89
      }
90
   }
91

    
92
   Fd = getFd(opcode);
93
   /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
94
   switch (opcode & MASK_ARITHMETIC_OPCODE)
95
   {
96
      /* dyadic opcodes */
97
      case ADF_CODE:
98
         fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status);
99
      break;
100

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

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

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

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

    
119
      case RDF_CODE:
120
      case FRD_CODE:
121
         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
122
      break;
123

    
124
#if 0
125
      case POW_CODE:
126
         fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
127
      break;
128

129
      case RPW_CODE:
130
         fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
131
      break;
132
#endif
133

    
134
      case RMF_CODE:
135
         fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status);
136
      break;
137

    
138
#if 0
139
      case POL_CODE:
140
         fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
141
      break;
142
#endif
143

    
144
      /* monadic opcodes */
145
      case MVF_CODE:
146
         fpa11->fpreg[Fd].fDouble = rFm;
147
      break;
148

    
149
      case MNF_CODE:
150
      {
151
         unsigned int *p = (unsigned int*)&rFm;
152
#ifdef HOST_WORDS_BIGENDIAN
153
         p[0] ^= 0x80000000;
154
#else
155
         p[1] ^= 0x80000000;
156
#endif
157
         fpa11->fpreg[Fd].fDouble = rFm;
158
      }
159
      break;
160

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

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

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

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

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

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

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

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

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

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

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

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

    
220
      case NRM_CODE:
221
      break;
222

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

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

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

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

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

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

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

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

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

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

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

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

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