1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | #include "fpa11.h" |
22 | #include "fpu/softfloat.h" |
23 | #include "fpopcode.h" |
24 | |
25 | float64 float64_exp(float64 Fm); |
26 | float64 float64_ln(float64 Fm); |
27 | float64 float64_sin(float64 rFm); |
28 | float64 float64_cos(float64 rFm); |
29 | float64 float64_arcsin(float64 rFm); |
30 | float64 float64_arctan(float64 rFm); |
31 | float64 float64_log(float64 rFm); |
32 | float64 float64_tan(float64 rFm); |
33 | float64 float64_arccos(float64 rFm); |
34 | float64 float64_pow(float64 rFn,float64 rFm); |
35 | float64 float64_pol(float64 rFn,float64 rFm); |
36 | |
37 | unsigned int DoubleCPDO(const unsigned int opcode) |
38 | { |
39 | FPA11 *fpa11 = GET_FPA11()(qemufpa); |
40 | float64 rFm, rFn = float64_zero(0); |
41 | unsigned int Fd, Fm, Fn, nRc = 1; |
42 | |
43 | |
44 | |
45 | Fm = getFm(opcode)(opcode & 0x00000007); |
46 | if (CONSTANT_FM(opcode)((opcode & 0x00000008) != 0)) |
| |
47 | { |
48 | rFm = getDoubleConstant(Fm); |
49 | } |
50 | else |
51 | { |
52 | switch (fpa11->fType[Fm]) |
| 2 | | Control jumps to 'case 3:' at line 62 | |
|
53 | { |
54 | case typeSingle0x01: |
55 | rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); |
56 | break; |
57 | |
58 | case typeDouble0x02: |
59 | rFm = fpa11->fpreg[Fm].fDouble; |
60 | break; |
61 | |
62 | case typeExtended0x03: |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | break; |
| 3 | | Execution continues on line 75 | |
|
70 | |
71 | default: return 0; |
72 | } |
73 | } |
74 | |
75 | if (!MONADIC_INSTRUCTION(opcode)((opcode & 0x00008000) != 0)) |
| |
76 | { |
77 | Fn = getFn(opcode)((opcode & 0x00070000) >> 16); |
78 | switch (fpa11->fType[Fn]) |
79 | { |
80 | case typeSingle0x01: |
81 | rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); |
82 | break; |
83 | |
84 | case typeDouble0x02: |
85 | rFn = fpa11->fpreg[Fn].fDouble; |
86 | break; |
87 | |
88 | default: return 0; |
89 | } |
90 | } |
91 | |
92 | Fd = getFd(opcode)((opcode & 0x00007000) >> 12); |
93 | |
94 | switch (opcode & MASK_ARITHMETIC_OPCODE0x00f08000) |
| 5 | | Control jumps to 'case 2129920:' at line 161 | |
|
95 | { |
96 | |
97 | case ADF_CODE0x00000000: |
98 | fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status); |
99 | break; |
100 | |
101 | case MUF_CODE0x00100000: |
102 | case FML_CODE0x00900000: |
103 | fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status); |
104 | break; |
105 | |
106 | case SUF_CODE0x00200000: |
107 | fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status); |
108 | break; |
109 | |
110 | case RSF_CODE0x00300000: |
111 | fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status); |
112 | break; |
113 | |
114 | case DVF_CODE0x00400000: |
115 | case FDV_CODE0x00a00000: |
116 | fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status); |
117 | break; |
118 | |
119 | case RDF_CODE0x00500000: |
120 | case FRD_CODE0x00b00000: |
121 | fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status); |
122 | break; |
123 | |
124 | #if 0 |
125 | case POW_CODE0x00600000: |
126 | fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); |
127 | break; |
128 | |
129 | case RPW_CODE0x00700000: |
130 | fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); |
131 | break; |
132 | #endif |
133 | |
134 | case RMF_CODE0x00800000: |
135 | fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status); |
136 | break; |
137 | |
138 | #if 0 |
139 | case POL_CODE0x00c00000: |
140 | fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); |
141 | break; |
142 | #endif |
143 | |
144 | |
145 | case MVF_CODE0x00008000: |
146 | fpa11->fpreg[Fd].fDouble = rFm; |
147 | break; |
148 | |
149 | case MNF_CODE0x00108000: |
150 | { |
151 | unsigned int *p = (unsigned int*)&rFm; |
152 | #ifdef HOST_WORDS_BIGENDIAN |
153 | p[0] ^= 0x80000000; |
154 | #else |
155 | p[1] ^= 0x80000000; |
156 | #endif |
157 | fpa11->fpreg[Fd].fDouble = rFm; |
158 | } |
159 | break; |
160 | |
161 | case ABS_CODE0x00208000: |
162 | { |
163 | unsigned int *p = (unsigned int*)&rFm; |
164 | #ifdef HOST_WORDS_BIGENDIAN |
165 | p[0] &= 0x7fffffff; |
166 | #else |
167 | p[1] &= 0x7fffffff; |
| 6 | | The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage |
|
168 | #endif |
169 | fpa11->fpreg[Fd].fDouble = rFm; |
170 | } |
171 | break; |
172 | |
173 | case RND_CODE0x00308000: |
174 | case URD_CODE0x00e08000: |
175 | fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status); |
176 | break; |
177 | |
178 | case SQT_CODE0x00408000: |
179 | fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status); |
180 | break; |
181 | |
182 | #if 0 |
183 | case LOG_CODE0x00508000: |
184 | fpa11->fpreg[Fd].fDouble = float64_log(rFm); |
185 | break; |
186 | |
187 | case LGN_CODE0x00608000: |
188 | fpa11->fpreg[Fd].fDouble = float64_ln(rFm); |
189 | break; |
190 | |
191 | case EXP_CODE0x00708000: |
192 | fpa11->fpreg[Fd].fDouble = float64_exp(rFm); |
193 | break; |
194 | |
195 | case SIN_CODE0x00808000: |
196 | fpa11->fpreg[Fd].fDouble = float64_sin(rFm); |
197 | break; |
198 | |
199 | case COS_CODE0x00908000: |
200 | fpa11->fpreg[Fd].fDouble = float64_cos(rFm); |
201 | break; |
202 | |
203 | case TAN_CODE0x00a08000: |
204 | fpa11->fpreg[Fd].fDouble = float64_tan(rFm); |
205 | break; |
206 | |
207 | case ASN_CODE0x00b08000: |
208 | fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); |
209 | break; |
210 | |
211 | case ACS_CODE0x00c08000: |
212 | fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); |
213 | break; |
214 | |
215 | case ATN_CODE0x00d08000: |
216 | fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); |
217 | break; |
218 | #endif |
219 | |
220 | case NRM_CODE0x00f08000: |
221 | break; |
222 | |
223 | default: |
224 | { |
225 | nRc = 0; |
226 | } |
227 | } |
228 | |
229 | if (0 != nRc) fpa11->fType[Fd] = typeDouble0x02; |
230 | return nRc; |
231 | } |
232 | |
233 | #if 0 |
234 | float64 float64_exp(float64 rFm) |
235 | { |
236 | return rFm; |
237 | |
238 | } |
239 | |
240 | float64 float64_ln(float64 rFm) |
241 | { |
242 | return rFm; |
243 | |
244 | } |
245 | |
246 | float64 float64_sin(float64 rFm) |
247 | { |
248 | return rFm; |
249 | |
250 | } |
251 | |
252 | float64 float64_cos(float64 rFm) |
253 | { |
254 | return rFm; |
255 | |
256 | } |
257 | |
258 | #if 0 |
259 | float64 float64_arcsin(float64 rFm) |
260 | { |
261 | |
262 | } |
263 | |
264 | float64 float64_arctan(float64 rFm) |
265 | { |
266 | |
267 | } |
268 | #endif |
269 | |
270 | float64 float64_log(float64 rFm) |
271 | { |
272 | return float64_div(float64_ln(rFm),getDoubleConstant(7)); |
273 | } |
274 | |
275 | float64 float64_tan(float64 rFm) |
276 | { |
277 | return float64_div(float64_sin(rFm),float64_cos(rFm)); |
278 | } |
279 | |
280 | float64 float64_arccos(float64 rFm) |
281 | { |
282 | return rFm; |
283 | |
284 | } |
285 | |
286 | float64 float64_pow(float64 rFn,float64 rFm) |
287 | { |
288 | return float64_exp(float64_mul(rFm,float64_ln(rFn))); |
289 | } |
290 | |
291 | float64 float64_pol(float64 rFn,float64 rFm) |
292 | { |
293 | return float64_arctan(float64_div(rFn,rFm)); |
294 | } |
295 | #endif |