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
26float32 float32_exp(float32 Fm);
27float32 float32_ln(float32 Fm);
28float32 float32_sin(float32 rFm);
29float32 float32_cos(float32 rFm);
30float32 float32_arcsin(float32 rFm);
31float32 float32_arctan(float32 rFm);
32float32 float32_log(float32 rFm);
33float32 float32_tan(float32 rFm);
34float32 float32_arccos(float32 rFm);
35float32 float32_pow(float32 rFn,float32 rFm);
36float32 float32_pol(float32 rFn,float32 rFm);
37
38unsigned int SingleCPDO(const unsigned int opcode)
39{
40   FPA11 *fpa11 = GET_FPA11();
41   float32 rFm, rFn = 0;
42   unsigned int Fd, Fm, Fn, nRc = 1;
43
44   Fm = getFm(opcode);
45   if (CONSTANT_FM(opcode))
46   {
47     rFm = getSingleConstant(Fm);
48   }
49   else
50   {
51     switch (fpa11->fType[Fm])
52     {
53        case typeSingle:
54          rFm = fpa11->fpreg[Fm].fSingle;
55        break;
56
57        default: return 0;
58     }
59   }
60
61   if (!MONADIC_INSTRUCTION(opcode))
62   {
63      Fn = getFn(opcode);
64      switch (fpa11->fType[Fn])
65      {
66        case typeSingle:
67          rFn = fpa11->fpreg[Fn].fSingle;
68        break;
69
70        default: return 0;
71      }
72   }
73
74   Fd = getFd(opcode);
75   switch (opcode & MASK_ARITHMETIC_OPCODE)
76   {
77      /* dyadic opcodes */
78      case ADF_CODE:
79         fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
80      break;
81
82      case MUF_CODE:
83      case FML_CODE:
84        fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
85      break;
86
87      case SUF_CODE:
88         fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
89      break;
90
91      case RSF_CODE:
92         fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
93      break;
94
95      case DVF_CODE:
96      case FDV_CODE:
97         fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
98      break;
99
100      case RDF_CODE:
101      case FRD_CODE:
102         fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
103      break;
104
105
106      case RMF_CODE:
107         fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
108      break;
109
110
111      /* monadic opcodes */
112      case MVF_CODE:
113         fpa11->fpreg[Fd].fSingle = rFm;
114      break;
115
116      case MNF_CODE:
117         rFm ^= 0x80000000;
118         fpa11->fpreg[Fd].fSingle = rFm;
119      break;
120
121      case ABS_CODE:
122         rFm &= 0x7fffffff;
123         fpa11->fpreg[Fd].fSingle = rFm;
124      break;
125
126      case RND_CODE:
127      case URD_CODE:
128         fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm);
129      break;
130
131      case SQT_CODE:
132         fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
133      break;
134
135
136      case NRM_CODE:
137      break;
138
139      default:
140      {
141        nRc = 0;
142      }
143   }
144
145   if (0 != nRc) fpa11->fType[Fd] = typeSingle;
146   return nRc;
147}
148