* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / arm / nwfpe / extended_cpdo.c
blob4f55333fc7312bbdc85a0e00d6fe52eebb83a58c
1 /*
2 NetWinder Floating Point Emulator
3 (c) Rebel.com, 1998-1999
5 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
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.
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.
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.
22 #include "config.h"
23 #include "softfloat.h"
24 #include "fpopcode.h"
25 #include "fpa11.h"
27 floatx80 getExtendedConstant(unsigned int);
29 floatx80 floatx80_exp(floatx80 Fm);
30 floatx80 floatx80_ln(floatx80 Fm);
31 floatx80 floatx80_sin(floatx80 rFm);
32 floatx80 floatx80_cos(floatx80 rFm);
33 floatx80 floatx80_arcsin(floatx80 rFm);
34 floatx80 floatx80_arctan(floatx80 rFm);
35 floatx80 floatx80_log(floatx80 rFm);
36 floatx80 floatx80_tan(floatx80 rFm);
37 floatx80 floatx80_arccos(floatx80 rFm);
38 floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
39 floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
41 unsigned int ExtendedCPDO(const unsigned int opcode)
43 floatx80 rFm, rFn;
44 unsigned int Fd, Fm, Fn, nRc = 1;
46 //fp_printk("ExtendedCPDO(0x%08x)\n",opcode);
48 Fm = getFm(opcode);
49 if (CONSTANT_FM(opcode))
51 rFm = getExtendedConstant(Fm);
53 else
55 switch (fpa11->fpreg[Fm].fType)
57 case typeSingle:
58 rFm = float32_to_floatx80(fpa11->fpreg[Fm].fValue.fSingle);
59 break;
61 case typeDouble:
62 rFm = float64_to_floatx80(fpa11->fpreg[Fm].fValue.fDouble);
63 break;
65 case typeExtended:
66 rFm = fpa11->fpreg[Fm].fValue.fExtended;
67 break;
69 default: return 0;
73 if (!MONADIC_INSTRUCTION(opcode))
75 Fn = getFn(opcode);
76 switch (fpa11->fpreg[Fn].fType)
78 case typeSingle:
79 rFn = float32_to_floatx80(fpa11->fpreg[Fn].fValue.fSingle);
80 break;
82 case typeDouble:
83 rFn = float64_to_floatx80(fpa11->fpreg[Fn].fValue.fDouble);
84 break;
86 case typeExtended:
87 rFn = fpa11->fpreg[Fn].fValue.fExtended;
88 break;
90 default: return 0;
94 Fd = getFd(opcode);
95 switch (opcode & MASK_ARITHMETIC_OPCODE)
97 /* dyadic opcodes */
98 case ADF_CODE:
99 fpa11->fpreg[Fd].fValue.fExtended = floatx80_add(rFn,rFm);
100 break;
102 case MUF_CODE:
103 case FML_CODE:
104 fpa11->fpreg[Fd].fValue.fExtended = floatx80_mul(rFn,rFm);
105 break;
107 case SUF_CODE:
108 fpa11->fpreg[Fd].fValue.fExtended = floatx80_sub(rFn,rFm);
109 break;
111 case RSF_CODE:
112 fpa11->fpreg[Fd].fValue.fExtended = floatx80_sub(rFm,rFn);
113 break;
115 case DVF_CODE:
116 case FDV_CODE:
117 fpa11->fpreg[Fd].fValue.fExtended = floatx80_div(rFn,rFm);
118 break;
120 case RDF_CODE:
121 case FRD_CODE:
122 fpa11->fpreg[Fd].fValue.fExtended = floatx80_div(rFm,rFn);
123 break;
125 #if 0
126 case POW_CODE:
127 fpa11->fpreg[Fd].fValue.fExtended = floatx80_pow(rFn,rFm);
128 break;
130 case RPW_CODE:
131 fpa11->fpreg[Fd].fValue.fExtended = floatx80_pow(rFm,rFn);
132 break;
133 #endif
135 case RMF_CODE:
136 fpa11->fpreg[Fd].fValue.fExtended = floatx80_rem(rFn,rFm);
137 break;
139 #if 0
140 case POL_CODE:
141 fpa11->fpreg[Fd].fValue.fExtended = floatx80_pol(rFn,rFm);
142 break;
143 #endif
145 /* monadic opcodes */
146 case MVF_CODE:
147 fpa11->fpreg[Fd].fValue.fExtended = rFm;
148 break;
150 case MNF_CODE:
151 rFm.high ^= 0x8000;
152 fpa11->fpreg[Fd].fValue.fExtended = rFm;
153 break;
155 case ABS_CODE:
156 rFm.high &= 0x7fff;
157 fpa11->fpreg[Fd].fValue.fExtended = rFm;
158 break;
160 case RND_CODE:
161 case URD_CODE:
162 fpa11->fpreg[Fd].fValue.fExtended =
163 int32_to_floatx80(floatx80_to_int32(rFm));
164 break;
166 case SQT_CODE:
167 fpa11->fpreg[Fd].fValue.fExtended = floatx80_sqrt(rFm);
168 break;
170 #if 0
171 case LOG_CODE:
172 fpa11->fpreg[Fd].fValue.fExtended = floatx80_log(rFm);
173 break;
175 case LGN_CODE:
176 fpa11->fpreg[Fd].fValue.fExtended = floatx80_ln(rFm);
177 break;
179 case EXP_CODE:
180 fpa11->fpreg[Fd].fValue.fExtended = floatx80_exp(rFm);
181 break;
183 case SIN_CODE:
184 fpa11->fpreg[Fd].fValue.fExtended = floatx80_sin(rFm);
185 break;
187 case COS_CODE:
188 fpa11->fpreg[Fd].fValue.fExtended = floatx80_cos(rFm);
189 break;
191 case TAN_CODE:
192 fpa11->fpreg[Fd].fValue.fExtended = floatx80_tan(rFm);
193 break;
195 case ASN_CODE:
196 fpa11->fpreg[Fd].fValue.fExtended = floatx80_arcsin(rFm);
197 break;
199 case ACS_CODE:
200 fpa11->fpreg[Fd].fValue.fExtended = floatx80_arccos(rFm);
201 break;
203 case ATN_CODE:
204 fpa11->fpreg[Fd].fValue.fExtended = floatx80_arctan(rFm);
205 break;
206 #endif
208 case NRM_CODE:
209 break;
211 default:
213 nRc = 0;
217 if (0 != nRc) fpa11->fpreg[Fd].fType = typeExtended;
218 return nRc;
221 #if 0
222 floatx80 floatx80_exp(floatx80 Fm)
224 //series
227 floatx80 floatx80_ln(floatx80 Fm)
229 //series
232 floatx80 floatx80_sin(floatx80 rFm)
234 //series
237 floatx80 floatx80_cos(floatx80 rFm)
239 //series
242 floatx80 floatx80_arcsin(floatx80 rFm)
244 //series
247 floatx80 floatx80_arctan(floatx80 rFm)
249 //series
252 floatx80 floatx80_log(floatx80 rFm)
254 return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
257 floatx80 floatx80_tan(floatx80 rFm)
259 return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
262 floatx80 floatx80_arccos(floatx80 rFm)
264 //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
267 floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
269 return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
272 floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
274 return floatx80_arctan(floatx80_div(rFn,rFm));
276 #endif