~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to linux-user/arm/nwfpe/double_cpdo.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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