2 NetWinder Floating Point Emulator
3 (c) Rebel.COM, 1998,1999
4 (c) Philip Blundell, 2001
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "softfloat.h"
27 float32
float32_exp(float32 Fm
);
28 float32
float32_ln(float32 Fm
);
29 float32
float32_sin(float32 rFm
);
30 float32
float32_cos(float32 rFm
);
31 float32
float32_arcsin(float32 rFm
);
32 float32
float32_arctan(float32 rFm
);
33 float32
float32_log(float32 rFm
);
34 float32
float32_tan(float32 rFm
);
35 float32
float32_arccos(float32 rFm
);
36 float32
float32_pow(float32 rFn
, float32 rFm
);
37 float32
float32_pol(float32 rFn
, float32 rFm
);
39 static float32
float32_rsf(struct roundingData
*roundData
, float32 rFn
, float32 rFm
)
41 return float32_sub(roundData
, rFm
, rFn
);
44 static float32
float32_rdv(struct roundingData
*roundData
, float32 rFn
, float32 rFm
)
46 return float32_div(roundData
, rFm
, rFn
);
49 static float32 (*const dyadic_single
[16])(struct roundingData
*, float32 rFn
, float32 rFm
) = {
50 [ADF_CODE
>> 20] = float32_add
,
51 [MUF_CODE
>> 20] = float32_mul
,
52 [SUF_CODE
>> 20] = float32_sub
,
53 [RSF_CODE
>> 20] = float32_rsf
,
54 [DVF_CODE
>> 20] = float32_div
,
55 [RDF_CODE
>> 20] = float32_rdv
,
56 [RMF_CODE
>> 20] = float32_rem
,
58 [FML_CODE
>> 20] = float32_mul
,
59 [FDV_CODE
>> 20] = float32_div
,
60 [FRD_CODE
>> 20] = float32_rdv
,
63 static float32
float32_mvf(struct roundingData
*roundData
, float32 rFm
)
68 static float32
float32_mnf(struct roundingData
*roundData
, float32 rFm
)
70 return rFm
^ 0x80000000;
73 static float32
float32_abs(struct roundingData
*roundData
, float32 rFm
)
75 return rFm
& 0x7fffffff;
78 static float32 (*const monadic_single
[16])(struct roundingData
*, float32 rFm
) = {
79 [MVF_CODE
>> 20] = float32_mvf
,
80 [MNF_CODE
>> 20] = float32_mnf
,
81 [ABS_CODE
>> 20] = float32_abs
,
82 [RND_CODE
>> 20] = float32_round_to_int
,
83 [URD_CODE
>> 20] = float32_round_to_int
,
84 [SQT_CODE
>> 20] = float32_sqrt
,
85 [NRM_CODE
>> 20] = float32_mvf
,
88 unsigned int SingleCPDO(struct roundingData
*roundData
, const unsigned int opcode
, FPREG
* rFd
)
90 FPA11
*fpa11
= GET_FPA11();
92 unsigned int Fm
, opc_mask_shift
;
95 if (CONSTANT_FM(opcode
)) {
96 rFm
= getSingleConstant(Fm
);
97 } else if (fpa11
->fType
[Fm
] == typeSingle
) {
98 rFm
= fpa11
->fpreg
[Fm
].fSingle
;
103 opc_mask_shift
= (opcode
& MASK_ARITHMETIC_OPCODE
) >> 20;
104 if (!MONADIC_INSTRUCTION(opcode
)) {
105 unsigned int Fn
= getFn(opcode
);
108 if (fpa11
->fType
[Fn
] == typeSingle
&&
109 dyadic_single
[opc_mask_shift
]) {
110 rFn
= fpa11
->fpreg
[Fn
].fSingle
;
111 rFd
->fSingle
= dyadic_single
[opc_mask_shift
](roundData
, rFn
, rFm
);
116 if (monadic_single
[opc_mask_shift
]) {
117 rFd
->fSingle
= monadic_single
[opc_mask_shift
](roundData
, rFm
);