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.
23 #include "softfloat.h"
29 float64
getDoubleConstant(unsigned int);
31 float64
float64_exp(float64 Fm
);
32 float64
float64_ln(float64 Fm
);
33 float64
float64_sin(float64 rFm
);
34 float64
float64_cos(float64 rFm
);
35 float64
float64_arcsin(float64 rFm
);
36 float64
float64_arctan(float64 rFm
);
37 float64
float64_log(float64 rFm
);
38 float64
float64_tan(float64 rFm
);
39 float64
float64_arccos(float64 rFm
);
40 float64
float64_pow(float64 rFn
,float64 rFm
);
41 float64
float64_pol(float64 rFn
,float64 rFm
);
43 unsigned int DoubleCPDO(const unsigned int opcode
)
46 unsigned int Fd
, Fm
, Fn
, nRc
= 1;
48 //fp_printk("DoubleCPDO(0x%08x)\n",opcode);
51 if (CONSTANT_FM(opcode
))
53 rFm
= getDoubleConstant(Fm
);
57 switch (fpa11
->fpreg
[Fm
].fType
)
60 rFm
= float32_to_float64(fpa11
->fpreg
[Fm
].fValue
.fSingle
);
64 rFm
= fpa11
->fpreg
[Fm
].fValue
.fDouble
;
69 //fp_printk("not implemented! why not?\n");
71 // should never get here, if extended involved
72 // then other operand should be promoted then
73 // ExtendedCPDO called.
80 if (!MONADIC_INSTRUCTION(opcode
))
83 switch (fpa11
->fpreg
[Fn
].fType
)
86 rFn
= float32_to_float64(fpa11
->fpreg
[Fn
].fValue
.fSingle
);
90 rFn
= fpa11
->fpreg
[Fn
].fValue
.fDouble
;
98 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
99 switch (opcode
& MASK_ARITHMETIC_OPCODE
)
103 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_add(rFn
,rFm
);
108 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_mul(rFn
,rFm
);
112 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_sub(rFn
,rFm
);
116 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_sub(rFm
,rFn
);
121 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_div(rFn
,rFm
);
126 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_div(rFm
,rFn
);
131 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_pow(rFn
,rFm
);
135 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_pow(rFm
,rFn
);
140 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_rem(rFn
,rFm
);
145 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_pol(rFn
,rFm
);
149 /* monadic opcodes */
151 fpa11
->fpreg
[Fd
].fValue
.fDouble
= rFm
;
156 unsigned int *p
= (unsigned int*)&rFm
;
158 fpa11
->fpreg
[Fd
].fValue
.fDouble
= rFm
;
164 unsigned int *p
= (unsigned int*)&rFm
;
166 fpa11
->fpreg
[Fd
].fValue
.fDouble
= rFm
;
172 fpa11
->fpreg
[Fd
].fValue
.fDouble
=
173 int32_to_float64(float64_to_int32(rFm
));
177 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_sqrt(rFm
);
182 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_log(rFm
);
186 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_ln(rFm
);
190 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_exp(rFm
);
194 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_sin(rFm
);
198 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_cos(rFm
);
202 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_tan(rFm
);
206 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_arcsin(rFm
);
210 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_arccos(rFm
);
214 fpa11
->fpreg
[Fd
].fValue
.fDouble
= float64_arctan(rFm
);
227 if (0 != nRc
) fpa11
->fpreg
[Fd
].fType
= typeDouble
;
232 float64
float64_exp(float64 rFm
)
238 float64
float64_ln(float64 rFm
)
244 float64
float64_sin(float64 rFm
)
250 float64
float64_cos(float64 rFm
)
257 float64
float64_arcsin(float64 rFm
)
262 float64
float64_arctan(float64 rFm
)
268 float64
float64_log(float64 rFm
)
270 return float64_div(float64_ln(rFm
),getDoubleConstant(7));
273 float64
float64_tan(float64 rFm
)
275 return float64_div(float64_sin(rFm
),float64_cos(rFm
));
278 float64
float64_arccos(float64 rFm
)
281 //return float64_sub(halfPi,float64_arcsin(rFm));
284 float64
float64_pow(float64 rFn
,float64 rFm
)
286 return float64_exp(float64_mul(rFm
,float64_ln(rFn
)));
289 float64
float64_pol(float64 rFn
,float64 rFm
)
291 return float64_arctan(float64_div(rFn
,rFm
));