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"
26 union float64_components
{
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 static float64
float64_rsf(struct roundingData
*roundData
, float64 rFn
, float64 rFm
)
45 return float64_sub(roundData
, rFm
, rFn
);
48 static float64
float64_rdv(struct roundingData
*roundData
, float64 rFn
, float64 rFm
)
50 return float64_div(roundData
, rFm
, rFn
);
53 static float64 (*const dyadic_double
[16])(struct roundingData
*, float64 rFn
, float64 rFm
) = {
54 [ADF_CODE
>> 20] = float64_add
,
55 [MUF_CODE
>> 20] = float64_mul
,
56 [SUF_CODE
>> 20] = float64_sub
,
57 [RSF_CODE
>> 20] = float64_rsf
,
58 [DVF_CODE
>> 20] = float64_div
,
59 [RDF_CODE
>> 20] = float64_rdv
,
60 [RMF_CODE
>> 20] = float64_rem
,
62 /* strictly, these opcodes should not be implemented */
63 [FML_CODE
>> 20] = float64_mul
,
64 [FDV_CODE
>> 20] = float64_div
,
65 [FRD_CODE
>> 20] = float64_rdv
,
68 static float64
float64_mvf(struct roundingData
*roundData
,float64 rFm
)
73 static float64
float64_mnf(struct roundingData
*roundData
,float64 rFm
)
75 union float64_components u
;
87 static float64
float64_abs(struct roundingData
*roundData
,float64 rFm
)
89 union float64_components u
;
101 static float64 (*const monadic_double
[16])(struct roundingData
*, float64 rFm
) = {
102 [MVF_CODE
>> 20] = float64_mvf
,
103 [MNF_CODE
>> 20] = float64_mnf
,
104 [ABS_CODE
>> 20] = float64_abs
,
105 [RND_CODE
>> 20] = float64_round_to_int
,
106 [URD_CODE
>> 20] = float64_round_to_int
,
107 [SQT_CODE
>> 20] = float64_sqrt
,
108 [NRM_CODE
>> 20] = float64_mvf
,
111 unsigned int DoubleCPDO(struct roundingData
*roundData
, const unsigned int opcode
, FPREG
* rFd
)
113 FPA11
*fpa11
= GET_FPA11();
115 unsigned int Fm
, opc_mask_shift
;
118 if (CONSTANT_FM(opcode
)) {
119 rFm
= getDoubleConstant(Fm
);
121 switch (fpa11
->fType
[Fm
]) {
123 rFm
= float32_to_float64(fpa11
->fpreg
[Fm
].fSingle
);
127 rFm
= fpa11
->fpreg
[Fm
].fDouble
;
135 opc_mask_shift
= (opcode
& MASK_ARITHMETIC_OPCODE
) >> 20;
136 if (!MONADIC_INSTRUCTION(opcode
)) {
137 unsigned int Fn
= getFn(opcode
);
140 switch (fpa11
->fType
[Fn
]) {
142 rFn
= float32_to_float64(fpa11
->fpreg
[Fn
].fSingle
);
146 rFn
= fpa11
->fpreg
[Fn
].fDouble
;
153 if (dyadic_double
[opc_mask_shift
]) {
154 rFd
->fDouble
= dyadic_double
[opc_mask_shift
](roundData
, rFn
, rFm
);
159 if (monadic_double
[opc_mask_shift
]) {
160 rFd
->fDouble
= monadic_double
[opc_mask_shift
](roundData
, rFm
);