1 // SPDX-License-Identifier: GPL-2.0-or-later
3 NetWinder Floating Point Emulator
4 (c) Rebel.COM, 1998,1999
6 Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
11 #include "softfloat.h"
14 union float64_components
{
19 float64
float64_exp(float64 Fm
);
20 float64
float64_ln(float64 Fm
);
21 float64
float64_sin(float64 rFm
);
22 float64
float64_cos(float64 rFm
);
23 float64
float64_arcsin(float64 rFm
);
24 float64
float64_arctan(float64 rFm
);
25 float64
float64_log(float64 rFm
);
26 float64
float64_tan(float64 rFm
);
27 float64
float64_arccos(float64 rFm
);
28 float64
float64_pow(float64 rFn
, float64 rFm
);
29 float64
float64_pol(float64 rFn
, float64 rFm
);
31 static float64
float64_rsf(struct roundingData
*roundData
, float64 rFn
, float64 rFm
)
33 return float64_sub(roundData
, rFm
, rFn
);
36 static float64
float64_rdv(struct roundingData
*roundData
, float64 rFn
, float64 rFm
)
38 return float64_div(roundData
, rFm
, rFn
);
41 static float64 (*const dyadic_double
[16])(struct roundingData
*, float64 rFn
, float64 rFm
) = {
42 [ADF_CODE
>> 20] = float64_add
,
43 [MUF_CODE
>> 20] = float64_mul
,
44 [SUF_CODE
>> 20] = float64_sub
,
45 [RSF_CODE
>> 20] = float64_rsf
,
46 [DVF_CODE
>> 20] = float64_div
,
47 [RDF_CODE
>> 20] = float64_rdv
,
48 [RMF_CODE
>> 20] = float64_rem
,
50 /* strictly, these opcodes should not be implemented */
51 [FML_CODE
>> 20] = float64_mul
,
52 [FDV_CODE
>> 20] = float64_div
,
53 [FRD_CODE
>> 20] = float64_rdv
,
56 static float64
float64_mvf(struct roundingData
*roundData
,float64 rFm
)
61 static float64
float64_mnf(struct roundingData
*roundData
,float64 rFm
)
63 union float64_components u
;
75 static float64
float64_abs(struct roundingData
*roundData
,float64 rFm
)
77 union float64_components u
;
89 static float64 (*const monadic_double
[16])(struct roundingData
*, float64 rFm
) = {
90 [MVF_CODE
>> 20] = float64_mvf
,
91 [MNF_CODE
>> 20] = float64_mnf
,
92 [ABS_CODE
>> 20] = float64_abs
,
93 [RND_CODE
>> 20] = float64_round_to_int
,
94 [URD_CODE
>> 20] = float64_round_to_int
,
95 [SQT_CODE
>> 20] = float64_sqrt
,
96 [NRM_CODE
>> 20] = float64_mvf
,
99 unsigned int DoubleCPDO(struct roundingData
*roundData
, const unsigned int opcode
, FPREG
* rFd
)
101 FPA11
*fpa11
= GET_FPA11();
103 unsigned int Fm
, opc_mask_shift
;
106 if (CONSTANT_FM(opcode
)) {
107 rFm
= getDoubleConstant(Fm
);
109 switch (fpa11
->fType
[Fm
]) {
111 rFm
= float32_to_float64(fpa11
->fpreg
[Fm
].fSingle
);
115 rFm
= fpa11
->fpreg
[Fm
].fDouble
;
123 opc_mask_shift
= (opcode
& MASK_ARITHMETIC_OPCODE
) >> 20;
124 if (!MONADIC_INSTRUCTION(opcode
)) {
125 unsigned int Fn
= getFn(opcode
);
128 switch (fpa11
->fType
[Fn
]) {
130 rFn
= float32_to_float64(fpa11
->fpreg
[Fn
].fSingle
);
134 rFn
= fpa11
->fpreg
[Fn
].fDouble
;
141 if (dyadic_double
[opc_mask_shift
]) {
142 rFd
->fDouble
= dyadic_double
[opc_mask_shift
](roundData
, rFn
, rFm
);
147 if (monadic_double
[opc_mask_shift
]) {
148 rFd
->fDouble
= monadic_double
[opc_mask_shift
](roundData
, rFm
);