Commit | Line | Data |
---|---|---|
3535ad49 JM |
1 | /* Accurate fp support for CGEN-based simulators. |
2 | Copyright (C) 1999 Cygnus Solutions. | |
3 | ||
4 | This implemention assumes: | |
5 | typedef USI SF; | |
6 | typedef UDI DF; | |
7 | ||
8 | TODO: | |
9 | - lazy encoding/decoding | |
10 | - checking return code (say by callback) | |
11 | - proper rounding | |
12 | */ | |
13 | ||
14 | #include "sim-main.h" | |
15 | #include "sim-fpu.h" | |
16 | ||
17 | /* SF mode support */ | |
18 | ||
19 | static SF | |
20 | addsf (CGEN_FPU* fpu, SF x, SF y) | |
21 | { | |
22 | sim_fpu op1; | |
23 | sim_fpu op2; | |
24 | sim_fpu ans; | |
25 | unsigned32 res; | |
26 | sim_fpu_status status; | |
27 | ||
28 | sim_fpu_32to (&op1, x); | |
29 | sim_fpu_32to (&op2, y); | |
30 | status = sim_fpu_add (&ans, &op1, &op2); | |
31 | if (status != 0) | |
32 | (*fpu->ops->error) (fpu, status); | |
33 | sim_fpu_to32 (&res, &ans); | |
34 | ||
35 | return res; | |
36 | } | |
37 | ||
38 | static SF | |
39 | subsf (CGEN_FPU* fpu, SF x, SF y) | |
40 | { | |
41 | sim_fpu op1; | |
42 | sim_fpu op2; | |
43 | sim_fpu ans; | |
44 | unsigned32 res; | |
c2d11a7d | 45 | sim_fpu_status status; |
3535ad49 JM |
46 | |
47 | sim_fpu_32to (&op1, x); | |
48 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
49 | status = sim_fpu_sub (&ans, &op1, &op2); |
50 | if (status != 0) | |
51 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
52 | sim_fpu_to32 (&res, &ans); |
53 | ||
54 | return res; | |
55 | } | |
56 | ||
57 | static SF | |
58 | mulsf (CGEN_FPU* fpu, SF x, SF y) | |
59 | { | |
60 | sim_fpu op1; | |
61 | sim_fpu op2; | |
62 | sim_fpu ans; | |
63 | unsigned32 res; | |
c2d11a7d | 64 | sim_fpu_status status; |
3535ad49 JM |
65 | |
66 | sim_fpu_32to (&op1, x); | |
67 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
68 | status = sim_fpu_mul (&ans, &op1, &op2); |
69 | if (status != 0) | |
70 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
71 | sim_fpu_to32 (&res, &ans); |
72 | ||
73 | return res; | |
74 | } | |
75 | ||
76 | static SF | |
77 | divsf (CGEN_FPU* fpu, SF x, SF y) | |
78 | { | |
79 | sim_fpu op1; | |
80 | sim_fpu op2; | |
81 | sim_fpu ans; | |
82 | unsigned32 res; | |
917317f4 | 83 | sim_fpu_status status; |
3535ad49 JM |
84 | |
85 | sim_fpu_32to (&op1, x); | |
86 | sim_fpu_32to (&op2, y); | |
917317f4 JM |
87 | status = sim_fpu_div (&ans, &op1, &op2); |
88 | if (status != 0) | |
89 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
90 | sim_fpu_to32 (&res, &ans); |
91 | ||
92 | return res; | |
93 | } | |
94 | ||
07b95864 PG |
95 | static SF |
96 | remsf (CGEN_FPU* fpu, SF x, SF y) | |
97 | { | |
98 | sim_fpu op1; | |
99 | sim_fpu op2; | |
100 | sim_fpu ans; | |
101 | unsigned32 res; | |
102 | sim_fpu_status status; | |
103 | ||
104 | sim_fpu_32to (&op1, x); | |
105 | sim_fpu_32to (&op2, y); | |
106 | status = sim_fpu_rem (&ans, &op1, &op2); | |
107 | if (status != 0) | |
108 | (*fpu->ops->error) (fpu, status); | |
109 | sim_fpu_to32 (&res, &ans); | |
110 | ||
111 | return res; | |
112 | } | |
113 | ||
3535ad49 JM |
114 | static SF |
115 | negsf (CGEN_FPU* fpu, SF x) | |
116 | { | |
117 | sim_fpu op1; | |
118 | sim_fpu ans; | |
119 | unsigned32 res; | |
c2d11a7d | 120 | sim_fpu_status status; |
3535ad49 JM |
121 | |
122 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
123 | status = sim_fpu_neg (&ans, &op1); |
124 | if (status != 0) | |
125 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
126 | sim_fpu_to32 (&res, &ans); |
127 | ||
128 | return res; | |
129 | } | |
130 | ||
131 | static SF | |
132 | abssf (CGEN_FPU* fpu, SF x) | |
133 | { | |
134 | sim_fpu op1; | |
135 | sim_fpu ans; | |
136 | unsigned32 res; | |
c2d11a7d | 137 | sim_fpu_status status; |
3535ad49 JM |
138 | |
139 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
140 | status = sim_fpu_abs (&ans, &op1); |
141 | if (status != 0) | |
142 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
143 | sim_fpu_to32 (&res, &ans); |
144 | ||
145 | return res; | |
146 | } | |
147 | ||
148 | static SF | |
149 | sqrtsf (CGEN_FPU* fpu, SF x) | |
150 | { | |
151 | sim_fpu op1; | |
152 | sim_fpu ans; | |
153 | unsigned32 res; | |
c2d11a7d | 154 | sim_fpu_status status; |
3535ad49 JM |
155 | |
156 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
157 | status = sim_fpu_sqrt (&ans, &op1); |
158 | if (status != 0) | |
159 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
160 | sim_fpu_to32 (&res, &ans); |
161 | ||
162 | return res; | |
163 | } | |
164 | ||
165 | static SF | |
166 | invsf (CGEN_FPU* fpu, SF x) | |
167 | { | |
168 | sim_fpu op1; | |
169 | sim_fpu ans; | |
170 | unsigned32 res; | |
c2d11a7d | 171 | sim_fpu_status status; |
3535ad49 JM |
172 | |
173 | sim_fpu_32to (&op1, x); | |
c2d11a7d JM |
174 | status = sim_fpu_inv (&ans, &op1); |
175 | if (status != 0) | |
176 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
177 | sim_fpu_to32 (&res, &ans); |
178 | ||
179 | return res; | |
180 | } | |
181 | ||
182 | static SF | |
183 | minsf (CGEN_FPU* fpu, SF x, SF y) | |
184 | { | |
185 | sim_fpu op1; | |
186 | sim_fpu op2; | |
187 | sim_fpu ans; | |
188 | unsigned32 res; | |
c2d11a7d | 189 | sim_fpu_status status; |
3535ad49 JM |
190 | |
191 | sim_fpu_32to (&op1, x); | |
192 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
193 | status = sim_fpu_min (&ans, &op1, &op2); |
194 | if (status != 0) | |
195 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
196 | sim_fpu_to32 (&res, &ans); |
197 | ||
198 | return res; | |
199 | } | |
200 | ||
201 | static SF | |
202 | maxsf (CGEN_FPU* fpu, SF x, SF y) | |
203 | { | |
204 | sim_fpu op1; | |
205 | sim_fpu op2; | |
206 | sim_fpu ans; | |
207 | unsigned32 res; | |
c2d11a7d | 208 | sim_fpu_status status; |
3535ad49 JM |
209 | |
210 | sim_fpu_32to (&op1, x); | |
211 | sim_fpu_32to (&op2, y); | |
c2d11a7d JM |
212 | status = sim_fpu_max (&ans, &op1, &op2); |
213 | if (status != 0) | |
214 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
215 | sim_fpu_to32 (&res, &ans); |
216 | ||
217 | return res; | |
218 | } | |
219 | ||
220 | static CGEN_FP_CMP | |
221 | cmpsf (CGEN_FPU* fpu, SF x, SF y) | |
222 | { | |
223 | sim_fpu op1; | |
224 | sim_fpu op2; | |
225 | ||
226 | sim_fpu_32to (&op1, x); | |
227 | sim_fpu_32to (&op2, y); | |
228 | ||
229 | if (sim_fpu_is_nan (&op1) | |
230 | || sim_fpu_is_nan (&op2)) | |
231 | return FP_CMP_NAN; | |
232 | ||
233 | if (x < y) | |
234 | return FP_CMP_LT; | |
235 | if (x > y) | |
236 | return FP_CMP_GT; | |
237 | return FP_CMP_EQ; | |
238 | } | |
239 | ||
240 | static int | |
241 | eqsf (CGEN_FPU* fpu, SF x, SF y) | |
242 | { | |
243 | sim_fpu op1; | |
244 | sim_fpu op2; | |
245 | ||
246 | sim_fpu_32to (&op1, x); | |
247 | sim_fpu_32to (&op2, y); | |
248 | return sim_fpu_is_eq (&op1, &op2); | |
249 | } | |
250 | ||
251 | static int | |
252 | nesf (CGEN_FPU* fpu, SF x, SF y) | |
253 | { | |
254 | sim_fpu op1; | |
255 | sim_fpu op2; | |
256 | ||
257 | sim_fpu_32to (&op1, x); | |
258 | sim_fpu_32to (&op2, y); | |
259 | return sim_fpu_is_ne (&op1, &op2); | |
260 | } | |
261 | ||
262 | static int | |
263 | ltsf (CGEN_FPU* fpu, SF x, SF y) | |
264 | { | |
265 | sim_fpu op1; | |
266 | sim_fpu op2; | |
267 | ||
268 | sim_fpu_32to (&op1, x); | |
269 | sim_fpu_32to (&op2, y); | |
270 | return sim_fpu_is_lt (&op1, &op2); | |
271 | } | |
272 | ||
273 | static int | |
274 | lesf (CGEN_FPU* fpu, SF x, SF y) | |
275 | { | |
276 | sim_fpu op1; | |
277 | sim_fpu op2; | |
278 | ||
279 | sim_fpu_32to (&op1, x); | |
280 | sim_fpu_32to (&op2, y); | |
281 | return sim_fpu_is_le (&op1, &op2); | |
282 | } | |
283 | ||
284 | static int | |
285 | gtsf (CGEN_FPU* fpu, SF x, SF y) | |
286 | { | |
287 | sim_fpu op1; | |
288 | sim_fpu op2; | |
289 | ||
290 | sim_fpu_32to (&op1, x); | |
291 | sim_fpu_32to (&op2, y); | |
292 | return sim_fpu_is_gt (&op1, &op2); | |
293 | } | |
294 | ||
295 | static int | |
296 | gesf (CGEN_FPU* fpu, SF x, SF y) | |
297 | { | |
298 | sim_fpu op1; | |
299 | sim_fpu op2; | |
300 | ||
301 | sim_fpu_32to (&op1, x); | |
302 | sim_fpu_32to (&op2, y); | |
303 | return sim_fpu_is_ge (&op1, &op2); | |
304 | } | |
305 | ||
f1cc84f5 SH |
306 | static int |
307 | unorderedsf (CGEN_FPU* fpu, SF x, SF y) | |
308 | { | |
309 | sim_fpu op1; | |
310 | sim_fpu op2; | |
311 | ||
312 | sim_fpu_32to (&op1, x); | |
313 | sim_fpu_32to (&op2, y); | |
314 | return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); | |
315 | } | |
316 | ||
317 | ||
f8603f2f | 318 | static DF |
d2c7a1a6 | 319 | fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x) |
f8603f2f DB |
320 | { |
321 | sim_fpu op1; | |
322 | unsigned64 res; | |
323 | ||
324 | sim_fpu_32to (&op1, x); | |
325 | sim_fpu_to64 (&res, &op1); | |
326 | ||
327 | return res; | |
328 | } | |
329 | ||
330 | static SF | |
d2c7a1a6 | 331 | ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x) |
f8603f2f DB |
332 | { |
333 | sim_fpu op1; | |
334 | unsigned32 res; | |
335 | ||
336 | sim_fpu_64to (&op1, x); | |
337 | sim_fpu_to32 (&res, &op1); | |
338 | ||
339 | return res; | |
340 | } | |
341 | ||
3535ad49 | 342 | static SF |
d2c7a1a6 | 343 | floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x) |
3535ad49 JM |
344 | { |
345 | sim_fpu ans; | |
346 | unsigned32 res; | |
347 | ||
348 | sim_fpu_i32to (&ans, x, sim_fpu_round_near); | |
349 | sim_fpu_to32 (&res, &ans); | |
350 | return res; | |
351 | } | |
352 | ||
9846de1b | 353 | static DF |
d2c7a1a6 | 354 | floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x) |
9846de1b JM |
355 | { |
356 | sim_fpu ans; | |
357 | unsigned64 res; | |
358 | ||
359 | sim_fpu_i32to (&ans, x, sim_fpu_round_near); | |
360 | sim_fpu_to64 (&res, &ans); | |
361 | return res; | |
362 | } | |
363 | ||
688cea90 SH |
364 | static DF |
365 | floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x) | |
366 | { | |
367 | sim_fpu ans; | |
368 | unsigned64 res; | |
369 | ||
370 | sim_fpu_i64to (&ans, x, sim_fpu_round_near); | |
371 | sim_fpu_to64 (&res, &ans); | |
372 | return res; | |
373 | } | |
374 | ||
3535ad49 | 375 | static SF |
d2c7a1a6 | 376 | ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x) |
3535ad49 JM |
377 | { |
378 | sim_fpu ans; | |
379 | unsigned32 res; | |
380 | ||
381 | sim_fpu_u32to (&ans, x, sim_fpu_round_near); | |
382 | sim_fpu_to32 (&res, &ans); | |
383 | return res; | |
384 | } | |
385 | ||
386 | static SI | |
d2c7a1a6 | 387 | fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) |
3535ad49 JM |
388 | { |
389 | sim_fpu op1; | |
390 | unsigned32 res; | |
391 | ||
392 | sim_fpu_32to (&op1, x); | |
393 | sim_fpu_to32i (&res, &op1, sim_fpu_round_near); | |
394 | return res; | |
395 | } | |
396 | ||
9846de1b | 397 | static SI |
d2c7a1a6 | 398 | fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x) |
9846de1b JM |
399 | { |
400 | sim_fpu op1; | |
401 | unsigned32 res; | |
402 | ||
403 | sim_fpu_64to (&op1, x); | |
404 | sim_fpu_to32i (&res, &op1, sim_fpu_round_near); | |
405 | return res; | |
406 | } | |
407 | ||
688cea90 SH |
408 | static DI |
409 | fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x) | |
410 | { | |
411 | sim_fpu op1; | |
412 | unsigned64 res; | |
413 | ||
414 | sim_fpu_64to (&op1, x); | |
415 | sim_fpu_to64i (&res, &op1, sim_fpu_round_near); | |
416 | return res; | |
417 | } | |
418 | ||
3535ad49 | 419 | static USI |
d2c7a1a6 | 420 | ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) |
3535ad49 JM |
421 | { |
422 | sim_fpu op1; | |
423 | unsigned32 res; | |
424 | ||
425 | sim_fpu_32to (&op1, x); | |
426 | sim_fpu_to32u (&res, &op1, sim_fpu_round_near); | |
427 | return res; | |
428 | } | |
429 | \f | |
430 | /* DF mode support */ | |
431 | ||
432 | static DF | |
433 | adddf (CGEN_FPU* fpu, DF x, DF y) | |
434 | { | |
435 | sim_fpu op1; | |
436 | sim_fpu op2; | |
437 | sim_fpu ans; | |
438 | unsigned64 res; | |
439 | sim_fpu_status status; | |
440 | ||
441 | sim_fpu_64to (&op1, x); | |
442 | sim_fpu_64to (&op2, y); | |
443 | status = sim_fpu_add (&ans, &op1, &op2); | |
444 | if (status != 0) | |
445 | (*fpu->ops->error) (fpu, status); | |
446 | sim_fpu_to64 (&res, &ans); | |
447 | ||
448 | return res; | |
449 | } | |
450 | ||
451 | static DF | |
452 | subdf (CGEN_FPU* fpu, DF x, DF y) | |
453 | { | |
454 | sim_fpu op1; | |
455 | sim_fpu op2; | |
456 | sim_fpu ans; | |
457 | unsigned64 res; | |
c2d11a7d | 458 | sim_fpu_status status; |
3535ad49 JM |
459 | |
460 | sim_fpu_64to (&op1, x); | |
461 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
462 | status = sim_fpu_sub (&ans, &op1, &op2); |
463 | if (status != 0) | |
464 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
465 | sim_fpu_to64 (&res, &ans); |
466 | ||
467 | return res; | |
468 | } | |
469 | ||
470 | static DF | |
471 | muldf (CGEN_FPU* fpu, DF x, DF y) | |
472 | { | |
473 | sim_fpu op1; | |
474 | sim_fpu op2; | |
475 | sim_fpu ans; | |
476 | unsigned64 res; | |
c2d11a7d | 477 | sim_fpu_status status; |
3535ad49 JM |
478 | |
479 | sim_fpu_64to (&op1, x); | |
480 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
481 | status = sim_fpu_mul (&ans, &op1, &op2); |
482 | if (status != 0) | |
483 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
484 | sim_fpu_to64 (&res, &ans); |
485 | ||
486 | return res; | |
487 | } | |
488 | ||
489 | static DF | |
490 | divdf (CGEN_FPU* fpu, DF x, DF y) | |
491 | { | |
492 | sim_fpu op1; | |
493 | sim_fpu op2; | |
494 | sim_fpu ans; | |
495 | unsigned64 res; | |
c2d11a7d | 496 | sim_fpu_status status; |
3535ad49 JM |
497 | |
498 | sim_fpu_64to (&op1, x); | |
499 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
500 | status = sim_fpu_div (&ans, &op1, &op2); |
501 | if (status != 0) | |
502 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
503 | sim_fpu_to64 (&res, &ans); |
504 | ||
505 | return res; | |
506 | } | |
507 | ||
07b95864 PG |
508 | static DF |
509 | remdf (CGEN_FPU* fpu, DF x, DF y) | |
510 | { | |
511 | sim_fpu op1; | |
512 | sim_fpu op2; | |
513 | sim_fpu ans; | |
514 | unsigned64 res; | |
515 | sim_fpu_status status; | |
516 | ||
517 | sim_fpu_64to (&op1, x); | |
518 | sim_fpu_64to (&op2, y); | |
519 | status = sim_fpu_rem (&ans, &op1, &op2); | |
520 | if (status != 0) | |
521 | (*fpu->ops->error) (fpu, status); | |
522 | sim_fpu_to64(&res, &ans); | |
523 | ||
524 | return res; | |
525 | } | |
526 | ||
3535ad49 JM |
527 | static DF |
528 | negdf (CGEN_FPU* fpu, DF x) | |
529 | { | |
530 | sim_fpu op1; | |
531 | sim_fpu ans; | |
532 | unsigned64 res; | |
c2d11a7d | 533 | sim_fpu_status status; |
3535ad49 JM |
534 | |
535 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
536 | status = sim_fpu_neg (&ans, &op1); |
537 | if (status != 0) | |
538 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
539 | sim_fpu_to64 (&res, &ans); |
540 | ||
541 | return res; | |
542 | } | |
543 | ||
544 | static DF | |
545 | absdf (CGEN_FPU* fpu, DF x) | |
546 | { | |
547 | sim_fpu op1; | |
548 | sim_fpu ans; | |
549 | unsigned64 res; | |
c2d11a7d | 550 | sim_fpu_status status; |
3535ad49 JM |
551 | |
552 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
553 | status = sim_fpu_abs (&ans, &op1); |
554 | if (status != 0) | |
555 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
556 | sim_fpu_to64 (&res, &ans); |
557 | ||
558 | return res; | |
559 | } | |
560 | ||
561 | static DF | |
562 | sqrtdf (CGEN_FPU* fpu, DF x) | |
563 | { | |
564 | sim_fpu op1; | |
565 | sim_fpu ans; | |
566 | unsigned64 res; | |
c2d11a7d | 567 | sim_fpu_status status; |
3535ad49 JM |
568 | |
569 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
570 | status = sim_fpu_sqrt (&ans, &op1); |
571 | if (status != 0) | |
572 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
573 | sim_fpu_to64 (&res, &ans); |
574 | ||
575 | return res; | |
576 | } | |
577 | ||
578 | static DF | |
579 | invdf (CGEN_FPU* fpu, DF x) | |
580 | { | |
581 | sim_fpu op1; | |
582 | sim_fpu ans; | |
583 | unsigned64 res; | |
c2d11a7d | 584 | sim_fpu_status status; |
3535ad49 JM |
585 | |
586 | sim_fpu_64to (&op1, x); | |
c2d11a7d JM |
587 | status = sim_fpu_inv (&ans, &op1); |
588 | if (status != 0) | |
589 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
590 | sim_fpu_to64 (&res, &ans); |
591 | ||
592 | return res; | |
593 | } | |
594 | ||
595 | static DF | |
596 | mindf (CGEN_FPU* fpu, DF x, DF y) | |
597 | { | |
598 | sim_fpu op1; | |
599 | sim_fpu op2; | |
600 | sim_fpu ans; | |
601 | unsigned64 res; | |
c2d11a7d | 602 | sim_fpu_status status; |
3535ad49 JM |
603 | |
604 | sim_fpu_64to (&op1, x); | |
605 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
606 | status = sim_fpu_min (&ans, &op1, &op2); |
607 | if (status != 0) | |
608 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
609 | sim_fpu_to64 (&res, &ans); |
610 | ||
611 | return res; | |
612 | } | |
613 | ||
614 | static DF | |
615 | maxdf (CGEN_FPU* fpu, DF x, DF y) | |
616 | { | |
617 | sim_fpu op1; | |
618 | sim_fpu op2; | |
619 | sim_fpu ans; | |
620 | unsigned64 res; | |
c2d11a7d | 621 | sim_fpu_status status; |
3535ad49 JM |
622 | |
623 | sim_fpu_64to (&op1, x); | |
624 | sim_fpu_64to (&op2, y); | |
c2d11a7d JM |
625 | status = sim_fpu_max (&ans, &op1, &op2); |
626 | if (status != 0) | |
627 | (*fpu->ops->error) (fpu, status); | |
3535ad49 JM |
628 | sim_fpu_to64 (&res, &ans); |
629 | ||
630 | return res; | |
631 | } | |
632 | ||
633 | static CGEN_FP_CMP | |
634 | cmpdf (CGEN_FPU* fpu, DF x, DF y) | |
635 | { | |
636 | sim_fpu op1; | |
637 | sim_fpu op2; | |
638 | ||
639 | sim_fpu_64to (&op1, x); | |
640 | sim_fpu_64to (&op2, y); | |
641 | ||
642 | if (sim_fpu_is_nan (&op1) | |
643 | || sim_fpu_is_nan (&op2)) | |
644 | return FP_CMP_NAN; | |
645 | ||
646 | if (x < y) | |
647 | return FP_CMP_LT; | |
648 | if (x > y) | |
649 | return FP_CMP_GT; | |
650 | return FP_CMP_EQ; | |
651 | } | |
652 | ||
653 | static int | |
654 | eqdf (CGEN_FPU* fpu, DF x, DF y) | |
655 | { | |
656 | sim_fpu op1; | |
657 | sim_fpu op2; | |
658 | ||
659 | sim_fpu_64to (&op1, x); | |
660 | sim_fpu_64to (&op2, y); | |
661 | return sim_fpu_is_eq (&op1, &op2); | |
662 | } | |
663 | ||
664 | static int | |
665 | nedf (CGEN_FPU* fpu, DF x, DF y) | |
666 | { | |
667 | sim_fpu op1; | |
668 | sim_fpu op2; | |
669 | ||
670 | sim_fpu_64to (&op1, x); | |
671 | sim_fpu_64to (&op2, y); | |
672 | return sim_fpu_is_ne (&op1, &op2); | |
673 | } | |
674 | ||
675 | static int | |
676 | ltdf (CGEN_FPU* fpu, DF x, DF y) | |
677 | { | |
678 | sim_fpu op1; | |
679 | sim_fpu op2; | |
680 | ||
681 | sim_fpu_64to (&op1, x); | |
682 | sim_fpu_64to (&op2, y); | |
683 | return sim_fpu_is_lt (&op1, &op2); | |
684 | } | |
685 | ||
686 | static int | |
687 | ledf (CGEN_FPU* fpu, DF x, DF y) | |
688 | { | |
689 | sim_fpu op1; | |
690 | sim_fpu op2; | |
691 | ||
692 | sim_fpu_64to (&op1, x); | |
693 | sim_fpu_64to (&op2, y); | |
694 | return sim_fpu_is_le (&op1, &op2); | |
695 | } | |
696 | ||
697 | static int | |
698 | gtdf (CGEN_FPU* fpu, DF x, DF y) | |
699 | { | |
700 | sim_fpu op1; | |
701 | sim_fpu op2; | |
702 | ||
703 | sim_fpu_64to (&op1, x); | |
704 | sim_fpu_64to (&op2, y); | |
705 | return sim_fpu_is_gt (&op1, &op2); | |
706 | } | |
707 | ||
708 | static int | |
709 | gedf (CGEN_FPU* fpu, DF x, DF y) | |
710 | { | |
711 | sim_fpu op1; | |
712 | sim_fpu op2; | |
713 | ||
714 | sim_fpu_64to (&op1, x); | |
715 | sim_fpu_64to (&op2, y); | |
716 | return sim_fpu_is_ge (&op1, &op2); | |
717 | } | |
f1cc84f5 SH |
718 | |
719 | static int | |
720 | unordereddf (CGEN_FPU* fpu, DF x, DF y) | |
721 | { | |
722 | sim_fpu op1; | |
723 | sim_fpu op2; | |
724 | ||
725 | sim_fpu_64to (&op1, x); | |
726 | sim_fpu_64to (&op2, y); | |
727 | return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); | |
728 | } | |
3535ad49 JM |
729 | \f |
730 | /* Initialize FP_OPS to use accurate library. */ | |
731 | ||
732 | void | |
733 | cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error) | |
734 | { | |
735 | CGEN_FP_OPS* o; | |
736 | ||
737 | fpu->owner = cpu; | |
738 | /* ??? small memory leak, not freed by sim_close */ | |
739 | fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS)); | |
740 | ||
741 | o = fpu->ops; | |
742 | memset (o, 0, sizeof (*o)); | |
743 | ||
744 | o->error = error; | |
745 | ||
746 | o->addsf = addsf; | |
747 | o->subsf = subsf; | |
748 | o->mulsf = mulsf; | |
749 | o->divsf = divsf; | |
07b95864 | 750 | o->remsf = remsf; |
3535ad49 JM |
751 | o->negsf = negsf; |
752 | o->abssf = abssf; | |
753 | o->sqrtsf = sqrtsf; | |
754 | o->invsf = invsf; | |
755 | o->minsf = minsf; | |
756 | o->maxsf = maxsf; | |
757 | o->cmpsf = cmpsf; | |
758 | o->eqsf = eqsf; | |
759 | o->nesf = nesf; | |
760 | o->ltsf = ltsf; | |
761 | o->lesf = lesf; | |
762 | o->gtsf = gtsf; | |
763 | o->gesf = gesf; | |
f1cc84f5 | 764 | o->unorderedsf = unorderedsf; |
3535ad49 JM |
765 | |
766 | o->adddf = adddf; | |
767 | o->subdf = subdf; | |
768 | o->muldf = muldf; | |
769 | o->divdf = divdf; | |
07b95864 | 770 | o->remdf = remdf; |
3535ad49 JM |
771 | o->negdf = negdf; |
772 | o->absdf = absdf; | |
773 | o->sqrtdf = sqrtdf; | |
774 | o->invdf = invdf; | |
775 | o->mindf = mindf; | |
776 | o->maxdf = maxdf; | |
777 | o->cmpdf = cmpdf; | |
778 | o->eqdf = eqdf; | |
779 | o->nedf = nedf; | |
780 | o->ltdf = ltdf; | |
781 | o->ledf = ledf; | |
782 | o->gtdf = gtdf; | |
783 | o->gedf = gedf; | |
f1cc84f5 | 784 | o->unordereddf = unordereddf; |
f8603f2f DB |
785 | o->fextsfdf = fextsfdf; |
786 | o->ftruncdfsf = ftruncdfsf; | |
3535ad49 | 787 | o->floatsisf = floatsisf; |
9846de1b | 788 | o->floatsidf = floatsidf; |
688cea90 | 789 | o->floatdidf = floatdidf; |
3535ad49 JM |
790 | o->ufloatsisf = ufloatsisf; |
791 | o->fixsfsi = fixsfsi; | |
9846de1b | 792 | o->fixdfsi = fixdfsi; |
688cea90 | 793 | o->fixdfdi = fixdfdi; |
3535ad49 JM |
794 | o->ufixsfsi = ufixsfsi; |
795 | } |