diff options
Diffstat (limited to 'arch/arm/nwfpe/single_cpdo.c')
-rw-r--r-- | arch/arm/nwfpe/single_cpdo.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c new file mode 100644 index 000000000000..705808e88d9d --- /dev/null +++ b/arch/arm/nwfpe/single_cpdo.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | NetWinder Floating Point Emulator | ||
3 | (c) Rebel.COM, 1998,1999 | ||
4 | (c) Philip Blundell, 2001 | ||
5 | |||
6 | Direct questions, comments to Scott Bambrough <scottb@netwinder.org> | ||
7 | |||
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. | ||
12 | |||
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. | ||
17 | |||
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. | ||
21 | */ | ||
22 | |||
23 | #include "fpa11.h" | ||
24 | #include "softfloat.h" | ||
25 | #include "fpopcode.h" | ||
26 | |||
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); | ||
38 | |||
39 | static float32 float32_rsf(float32 rFn, float32 rFm) | ||
40 | { | ||
41 | return float32_sub(rFm, rFn); | ||
42 | } | ||
43 | |||
44 | static float32 float32_rdv(float32 rFn, float32 rFm) | ||
45 | { | ||
46 | return float32_div(rFm, rFn); | ||
47 | } | ||
48 | |||
49 | static float32 (*const dyadic_single[16])(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, | ||
57 | |||
58 | [FML_CODE >> 20] = float32_mul, | ||
59 | [FDV_CODE >> 20] = float32_div, | ||
60 | [FRD_CODE >> 20] = float32_rdv, | ||
61 | }; | ||
62 | |||
63 | static float32 float32_mvf(float32 rFm) | ||
64 | { | ||
65 | return rFm; | ||
66 | } | ||
67 | |||
68 | static float32 float32_mnf(float32 rFm) | ||
69 | { | ||
70 | return rFm ^ 0x80000000; | ||
71 | } | ||
72 | |||
73 | static float32 float32_abs(float32 rFm) | ||
74 | { | ||
75 | return rFm & 0x7fffffff; | ||
76 | } | ||
77 | |||
78 | static float32 (*const monadic_single[16])(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, | ||
86 | }; | ||
87 | |||
88 | unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) | ||
89 | { | ||
90 | FPA11 *fpa11 = GET_FPA11(); | ||
91 | float32 rFm; | ||
92 | unsigned int Fm, opc_mask_shift; | ||
93 | |||
94 | Fm = getFm(opcode); | ||
95 | if (CONSTANT_FM(opcode)) { | ||
96 | rFm = getSingleConstant(Fm); | ||
97 | } else if (fpa11->fType[Fm] == typeSingle) { | ||
98 | rFm = fpa11->fpreg[Fm].fSingle; | ||
99 | } else { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; | ||
104 | if (!MONADIC_INSTRUCTION(opcode)) { | ||
105 | unsigned int Fn = getFn(opcode); | ||
106 | float32 rFn; | ||
107 | |||
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](rFn, rFm); | ||
112 | } else { | ||
113 | return 0; | ||
114 | } | ||
115 | } else { | ||
116 | if (monadic_single[opc_mask_shift]) { | ||
117 | rFd->fSingle = monadic_single[opc_mask_shift](rFm); | ||
118 | } else { | ||
119 | return 0; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | return 1; | ||
124 | } | ||