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 floatx80
floatx80_exp(floatx80 Fm
);
27 floatx80
floatx80_ln(floatx80 Fm
);
28 floatx80
floatx80_sin(floatx80 rFm
);
29 floatx80
floatx80_cos(floatx80 rFm
);
30 floatx80
floatx80_arcsin(floatx80 rFm
);
31 floatx80
floatx80_arctan(floatx80 rFm
);
32 floatx80
floatx80_log(floatx80 rFm
);
33 floatx80
floatx80_tan(floatx80 rFm
);
34 floatx80
floatx80_arccos(floatx80 rFm
);
35 floatx80
floatx80_pow(floatx80 rFn
, floatx80 rFm
);
36 floatx80
floatx80_pol(floatx80 rFn
, floatx80 rFm
);
38 static floatx80
floatx80_rsf(struct roundingData
*roundData
, floatx80 rFn
, floatx80 rFm
)
40 return floatx80_sub(roundData
, rFm
, rFn
);
43 static floatx80
floatx80_rdv(struct roundingData
*roundData
, floatx80 rFn
, floatx80 rFm
)
45 return floatx80_div(roundData
, rFm
, rFn
);
48 static floatx80 (*const dyadic_extended
[16])(struct roundingData
*, floatx80 rFn
, floatx80 rFm
) = {
49 [ADF_CODE
>> 20] = floatx80_add
,
50 [MUF_CODE
>> 20] = floatx80_mul
,
51 [SUF_CODE
>> 20] = floatx80_sub
,
52 [RSF_CODE
>> 20] = floatx80_rsf
,
53 [DVF_CODE
>> 20] = floatx80_div
,
54 [RDF_CODE
>> 20] = floatx80_rdv
,
55 [RMF_CODE
>> 20] = floatx80_rem
,
57 /* strictly, these opcodes should not be implemented */
58 [FML_CODE
>> 20] = floatx80_mul
,
59 [FDV_CODE
>> 20] = floatx80_div
,
60 [FRD_CODE
>> 20] = floatx80_rdv
,
63 static floatx80
floatx80_mvf(struct roundingData
*roundData
, floatx80 rFm
)
68 static floatx80
floatx80_mnf(struct roundingData
*roundData
, floatx80 rFm
)
74 static floatx80
floatx80_abs(struct roundingData
*roundData
, floatx80 rFm
)
80 static floatx80 (*const monadic_extended
[16])(struct roundingData
*, floatx80 rFm
) = {
81 [MVF_CODE
>> 20] = floatx80_mvf
,
82 [MNF_CODE
>> 20] = floatx80_mnf
,
83 [ABS_CODE
>> 20] = floatx80_abs
,
84 [RND_CODE
>> 20] = floatx80_round_to_int
,
85 [URD_CODE
>> 20] = floatx80_round_to_int
,
86 [SQT_CODE
>> 20] = floatx80_sqrt
,
87 [NRM_CODE
>> 20] = floatx80_mvf
,
90 unsigned int ExtendedCPDO(struct roundingData
*roundData
, const unsigned int opcode
, FPREG
* rFd
)
92 FPA11
*fpa11
= GET_FPA11();
94 unsigned int Fm
, opc_mask_shift
;
97 if (CONSTANT_FM(opcode
)) {
98 rFm
= getExtendedConstant(Fm
);
100 switch (fpa11
->fType
[Fm
]) {
102 rFm
= float32_to_floatx80(fpa11
->fpreg
[Fm
].fSingle
);
106 rFm
= float64_to_floatx80(fpa11
->fpreg
[Fm
].fDouble
);
110 rFm
= fpa11
->fpreg
[Fm
].fExtended
;
118 opc_mask_shift
= (opcode
& MASK_ARITHMETIC_OPCODE
) >> 20;
119 if (!MONADIC_INSTRUCTION(opcode
)) {
120 unsigned int Fn
= getFn(opcode
);
123 switch (fpa11
->fType
[Fn
]) {
125 rFn
= float32_to_floatx80(fpa11
->fpreg
[Fn
].fSingle
);
129 rFn
= float64_to_floatx80(fpa11
->fpreg
[Fn
].fDouble
);
133 rFn
= fpa11
->fpreg
[Fn
].fExtended
;
140 if (dyadic_extended
[opc_mask_shift
]) {
141 rFd
->fExtended
= dyadic_extended
[opc_mask_shift
](roundData
, rFn
, rFm
);
146 if (monadic_extended
[opc_mask_shift
]) {
147 rFd
->fExtended
= monadic_extended
[opc_mask_shift
](roundData
, rFm
);