Statistics
| Branch: | Revision:

root / target-arm / nwfpe / double_cpdo.c @ d3c61721

History | View | Annotate | Download (6.1 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);
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 = float64_round_to_int(rFm);
169
      break;
170

    
171
      case SQT_CODE:
172
         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
173
      break;
174

    
175
#if 0
176
      case LOG_CODE:
177
         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
178
      break;
179

180
      case LGN_CODE:
181
         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
182
      break;
183

184
      case EXP_CODE:
185
         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
186
      break;
187

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

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

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

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

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

208
      case ATN_CODE:
209
         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
210
      break;
211
#endif
212

    
213
      case NRM_CODE:
214
      break;
215
      
216
      default:
217
      {
218
        nRc = 0;
219
      }
220
   }
221

    
222
   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
223
   return nRc;
224
}
225

    
226
#if 0
227
float64 float64_exp(float64 rFm)
228
{
229
  return rFm;
230
//series
231
}
232

233
float64 float64_ln(float64 rFm)
234
{
235
  return rFm;
236
//series
237
}
238

239
float64 float64_sin(float64 rFm)
240
{
241
  return rFm;
242
//series
243
}
244

245
float64 float64_cos(float64 rFm)
246
{
247
   return rFm;
248
   //series
249
}
250

251
#if 0
252
float64 float64_arcsin(float64 rFm)
253
{
254
//series
255
}
256

257
float64 float64_arctan(float64 rFm)
258
{
259
  //series
260
}
261
#endif
262

    
263
float64 float64_log(float64 rFm)
264
{
265
  return float64_div(float64_ln(rFm),getDoubleConstant(7));
266
}
267

    
268
float64 float64_tan(float64 rFm)
269
{
270
  return float64_div(float64_sin(rFm),float64_cos(rFm));
271
}
272

    
273
float64 float64_arccos(float64 rFm)
274
{
275
return rFm;
276
   //return float64_sub(halfPi,float64_arcsin(rFm));
277
}
278

    
279
float64 float64_pow(float64 rFn,float64 rFm)
280
{
281
  return float64_exp(float64_mul(rFm,float64_ln(rFn))); 
282
}
283

    
284
float64 float64_pol(float64 rFn,float64 rFm)
285
{
286
  return float64_arctan(float64_div(rFn,rFm)); 
287
}
288
#endif