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, see <http://www.gnu.org/licenses/>.
22 #include "softfloat.h"
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
);
37 unsigned int DoubleCPDO(const unsigned int opcode
)
39 FPA11
*fpa11
= GET_FPA11();
40 float64 rFm
, rFn
= float64_zero
;
41 unsigned int Fd
, Fm
, Fn
, nRc
= 1;
43 //printk("DoubleCPDO(0x%08x)\n",opcode);
46 if (CONSTANT_FM(opcode
))
48 rFm
= getDoubleConstant(Fm
);
52 switch (fpa11
->fType
[Fm
])
55 rFm
= float32_to_float64(fpa11
->fpreg
[Fm
].fSingle
, &fpa11
->fp_status
);
59 rFm
= fpa11
->fpreg
[Fm
].fDouble
;
64 //printk("not implemented! why not?\n");
66 // should never get here, if extended involved
67 // then other operand should be promoted then
68 // ExtendedCPDO called.
75 if (!MONADIC_INSTRUCTION(opcode
))
78 switch (fpa11
->fType
[Fn
])
81 rFn
= float32_to_float64(fpa11
->fpreg
[Fn
].fSingle
, &fpa11
->fp_status
);
85 rFn
= fpa11
->fpreg
[Fn
].fDouble
;
93 /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
94 switch (opcode
& MASK_ARITHMETIC_OPCODE
)
98 fpa11
->fpreg
[Fd
].fDouble
= float64_add(rFn
,rFm
, &fpa11
->fp_status
);
103 fpa11
->fpreg
[Fd
].fDouble
= float64_mul(rFn
,rFm
, &fpa11
->fp_status
);
107 fpa11
->fpreg
[Fd
].fDouble
= float64_sub(rFn
,rFm
, &fpa11
->fp_status
);
111 fpa11
->fpreg
[Fd
].fDouble
= float64_sub(rFm
,rFn
, &fpa11
->fp_status
);
116 fpa11
->fpreg
[Fd
].fDouble
= float64_div(rFn
,rFm
, &fpa11
->fp_status
);
121 fpa11
->fpreg
[Fd
].fDouble
= float64_div(rFm
,rFn
, &fpa11
->fp_status
);
126 fpa11
->fpreg
[Fd
].fDouble
= float64_pow(rFn
,rFm
);
130 fpa11
->fpreg
[Fd
].fDouble
= float64_pow(rFm
,rFn
);
135 fpa11
->fpreg
[Fd
].fDouble
= float64_rem(rFn
,rFm
, &fpa11
->fp_status
);
140 fpa11
->fpreg
[Fd
].fDouble
= float64_pol(rFn
,rFm
);
144 /* monadic opcodes */
146 fpa11
->fpreg
[Fd
].fDouble
= rFm
;
151 unsigned int *p
= (unsigned int*)&rFm
;
152 #ifdef HOST_WORDS_BIGENDIAN
157 fpa11
->fpreg
[Fd
].fDouble
= rFm
;
163 unsigned int *p
= (unsigned int*)&rFm
;
164 #ifdef HOST_WORDS_BIGENDIAN
169 fpa11
->fpreg
[Fd
].fDouble
= rFm
;
175 fpa11
->fpreg
[Fd
].fDouble
= float64_round_to_int(rFm
, &fpa11
->fp_status
);
179 fpa11
->fpreg
[Fd
].fDouble
= float64_sqrt(rFm
, &fpa11
->fp_status
);
184 fpa11
->fpreg
[Fd
].fDouble
= float64_log(rFm
);
188 fpa11
->fpreg
[Fd
].fDouble
= float64_ln(rFm
);
192 fpa11
->fpreg
[Fd
].fDouble
= float64_exp(rFm
);
196 fpa11
->fpreg
[Fd
].fDouble
= float64_sin(rFm
);
200 fpa11
->fpreg
[Fd
].fDouble
= float64_cos(rFm
);
204 fpa11
->fpreg
[Fd
].fDouble
= float64_tan(rFm
);
208 fpa11
->fpreg
[Fd
].fDouble
= float64_arcsin(rFm
);
212 fpa11
->fpreg
[Fd
].fDouble
= float64_arccos(rFm
);
216 fpa11
->fpreg
[Fd
].fDouble
= float64_arctan(rFm
);
229 if (0 != nRc
) fpa11
->fType
[Fd
] = typeDouble
;
234 float64
float64_exp(float64 rFm
)
240 float64
float64_ln(float64 rFm
)
246 float64
float64_sin(float64 rFm
)
252 float64
float64_cos(float64 rFm
)
259 float64
float64_arcsin(float64 rFm
)
264 float64
float64_arctan(float64 rFm
)
270 float64
float64_log(float64 rFm
)
272 return float64_div(float64_ln(rFm
),getDoubleConstant(7));
275 float64
float64_tan(float64 rFm
)
277 return float64_div(float64_sin(rFm
),float64_cos(rFm
));
280 float64
float64_arccos(float64 rFm
)
283 //return float64_sub(halfPi,float64_arcsin(rFm));
286 float64
float64_pow(float64 rFn
,float64 rFm
)
288 return float64_exp(float64_mul(rFm
,float64_ln(rFn
)));
291 float64
float64_pol(float64 rFn
,float64 rFm
)
293 return float64_arctan(float64_div(rFn
,rFm
));