]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-accfp.c
import gdb-1999-07-07 pre reformat
[thirdparty/binutils-gdb.git] / sim / common / cgen-accfp.c
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;
45
46 sim_fpu_32to (&op1, x);
47 sim_fpu_32to (&op2, y);
48 sim_fpu_sub (&ans, &op1, &op2);
49 sim_fpu_to32 (&res, &ans);
50
51 return res;
52 }
53
54 static SF
55 mulsf (CGEN_FPU* fpu, SF x, SF y)
56 {
57 sim_fpu op1;
58 sim_fpu op2;
59 sim_fpu ans;
60 unsigned32 res;
61
62 sim_fpu_32to (&op1, x);
63 sim_fpu_32to (&op2, y);
64 sim_fpu_mul (&ans, &op1, &op2);
65 sim_fpu_to32 (&res, &ans);
66
67 return res;
68 }
69
70 static SF
71 divsf (CGEN_FPU* fpu, SF x, SF y)
72 {
73 sim_fpu op1;
74 sim_fpu op2;
75 sim_fpu ans;
76 unsigned32 res;
77
78 sim_fpu_32to (&op1, x);
79 sim_fpu_32to (&op2, y);
80 sim_fpu_div (&ans, &op1, &op2);
81 sim_fpu_to32 (&res, &ans);
82
83 return res;
84 }
85
86 static SF
87 negsf (CGEN_FPU* fpu, SF x)
88 {
89 sim_fpu op1;
90 sim_fpu ans;
91 unsigned32 res;
92
93 sim_fpu_32to (&op1, x);
94 sim_fpu_neg (&ans, &op1);
95 sim_fpu_to32 (&res, &ans);
96
97 return res;
98 }
99
100 static SF
101 abssf (CGEN_FPU* fpu, SF x)
102 {
103 sim_fpu op1;
104 sim_fpu ans;
105 unsigned32 res;
106
107 sim_fpu_32to (&op1, x);
108 sim_fpu_abs (&ans, &op1);
109 sim_fpu_to32 (&res, &ans);
110
111 return res;
112 }
113
114 static SF
115 sqrtsf (CGEN_FPU* fpu, SF x)
116 {
117 sim_fpu op1;
118 sim_fpu ans;
119 unsigned32 res;
120
121 sim_fpu_32to (&op1, x);
122 sim_fpu_sqrt (&ans, &op1);
123 sim_fpu_to32 (&res, &ans);
124
125 return res;
126 }
127
128 static SF
129 invsf (CGEN_FPU* fpu, SF x)
130 {
131 sim_fpu op1;
132 sim_fpu ans;
133 unsigned32 res;
134
135 sim_fpu_32to (&op1, x);
136 sim_fpu_inv (&ans, &op1);
137 sim_fpu_to32 (&res, &ans);
138
139 return res;
140 }
141
142 static SF
143 minsf (CGEN_FPU* fpu, SF x, SF y)
144 {
145 sim_fpu op1;
146 sim_fpu op2;
147 sim_fpu ans;
148 unsigned32 res;
149
150 sim_fpu_32to (&op1, x);
151 sim_fpu_32to (&op2, y);
152 sim_fpu_min (&ans, &op1, &op2);
153 sim_fpu_to32 (&res, &ans);
154
155 return res;
156 }
157
158 static SF
159 maxsf (CGEN_FPU* fpu, SF x, SF y)
160 {
161 sim_fpu op1;
162 sim_fpu op2;
163 sim_fpu ans;
164 unsigned32 res;
165
166 sim_fpu_32to (&op1, x);
167 sim_fpu_32to (&op2, y);
168 sim_fpu_max (&ans, &op1, &op2);
169 sim_fpu_to32 (&res, &ans);
170
171 return res;
172 }
173
174 static CGEN_FP_CMP
175 cmpsf (CGEN_FPU* fpu, SF x, SF y)
176 {
177 sim_fpu op1;
178 sim_fpu op2;
179
180 sim_fpu_32to (&op1, x);
181 sim_fpu_32to (&op2, y);
182
183 if (sim_fpu_is_nan (&op1)
184 || sim_fpu_is_nan (&op2))
185 return FP_CMP_NAN;
186
187 if (x < y)
188 return FP_CMP_LT;
189 if (x > y)
190 return FP_CMP_GT;
191 return FP_CMP_EQ;
192 }
193
194 static int
195 eqsf (CGEN_FPU* fpu, SF x, SF y)
196 {
197 sim_fpu op1;
198 sim_fpu op2;
199
200 sim_fpu_32to (&op1, x);
201 sim_fpu_32to (&op2, y);
202 return sim_fpu_is_eq (&op1, &op2);
203 }
204
205 static int
206 nesf (CGEN_FPU* fpu, SF x, SF y)
207 {
208 sim_fpu op1;
209 sim_fpu op2;
210
211 sim_fpu_32to (&op1, x);
212 sim_fpu_32to (&op2, y);
213 return sim_fpu_is_ne (&op1, &op2);
214 }
215
216 static int
217 ltsf (CGEN_FPU* fpu, SF x, SF y)
218 {
219 sim_fpu op1;
220 sim_fpu op2;
221
222 sim_fpu_32to (&op1, x);
223 sim_fpu_32to (&op2, y);
224 return sim_fpu_is_lt (&op1, &op2);
225 }
226
227 static int
228 lesf (CGEN_FPU* fpu, SF x, SF y)
229 {
230 sim_fpu op1;
231 sim_fpu op2;
232
233 sim_fpu_32to (&op1, x);
234 sim_fpu_32to (&op2, y);
235 return sim_fpu_is_le (&op1, &op2);
236 }
237
238 static int
239 gtsf (CGEN_FPU* fpu, SF x, SF y)
240 {
241 sim_fpu op1;
242 sim_fpu op2;
243
244 sim_fpu_32to (&op1, x);
245 sim_fpu_32to (&op2, y);
246 return sim_fpu_is_gt (&op1, &op2);
247 }
248
249 static int
250 gesf (CGEN_FPU* fpu, SF x, SF y)
251 {
252 sim_fpu op1;
253 sim_fpu op2;
254
255 sim_fpu_32to (&op1, x);
256 sim_fpu_32to (&op2, y);
257 return sim_fpu_is_ge (&op1, &op2);
258 }
259
260 static SF
261 floatsisf (CGEN_FPU* fpu, SI x)
262 {
263 sim_fpu ans;
264 unsigned32 res;
265
266 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
267 sim_fpu_to32 (&res, &ans);
268 return res;
269 }
270
271 static DF
272 floatsidf (CGEN_FPU* fpu, SI x)
273 {
274 sim_fpu ans;
275 unsigned64 res;
276
277 sim_fpu_i32to (&ans, x, sim_fpu_round_near);
278 sim_fpu_to64 (&res, &ans);
279 return res;
280 }
281
282 static SF
283 ufloatsisf (CGEN_FPU* fpu, USI x)
284 {
285 sim_fpu ans;
286 unsigned32 res;
287
288 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
289 sim_fpu_to32 (&res, &ans);
290 return res;
291 }
292
293 static SI
294 fixsfsi (CGEN_FPU* fpu, SF x)
295 {
296 sim_fpu op1;
297 unsigned32 res;
298
299 sim_fpu_32to (&op1, x);
300 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
301 return res;
302 }
303
304 static SI
305 fixdfsi (CGEN_FPU* fpu, DF x)
306 {
307 sim_fpu op1;
308 unsigned32 res;
309
310 sim_fpu_64to (&op1, x);
311 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
312 return res;
313 }
314
315 static USI
316 ufixsfsi (CGEN_FPU* fpu, SF x)
317 {
318 sim_fpu op1;
319 unsigned32 res;
320
321 sim_fpu_32to (&op1, x);
322 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
323 return res;
324 }
325 \f
326 /* DF mode support */
327
328 static DF
329 adddf (CGEN_FPU* fpu, DF x, DF y)
330 {
331 sim_fpu op1;
332 sim_fpu op2;
333 sim_fpu ans;
334 unsigned64 res;
335 sim_fpu_status status;
336
337 sim_fpu_64to (&op1, x);
338 sim_fpu_64to (&op2, y);
339 status = sim_fpu_add (&ans, &op1, &op2);
340 if (status != 0)
341 (*fpu->ops->error) (fpu, status);
342 sim_fpu_to64 (&res, &ans);
343
344 return res;
345 }
346
347 static DF
348 subdf (CGEN_FPU* fpu, DF x, DF y)
349 {
350 sim_fpu op1;
351 sim_fpu op2;
352 sim_fpu ans;
353 unsigned64 res;
354
355 sim_fpu_64to (&op1, x);
356 sim_fpu_64to (&op2, y);
357 sim_fpu_sub (&ans, &op1, &op2);
358 sim_fpu_to64 (&res, &ans);
359
360 return res;
361 }
362
363 static DF
364 muldf (CGEN_FPU* fpu, DF x, DF y)
365 {
366 sim_fpu op1;
367 sim_fpu op2;
368 sim_fpu ans;
369 unsigned64 res;
370
371 sim_fpu_64to (&op1, x);
372 sim_fpu_64to (&op2, y);
373 sim_fpu_mul (&ans, &op1, &op2);
374 sim_fpu_to64 (&res, &ans);
375
376 return res;
377 }
378
379 static DF
380 divdf (CGEN_FPU* fpu, DF x, DF y)
381 {
382 sim_fpu op1;
383 sim_fpu op2;
384 sim_fpu ans;
385 unsigned64 res;
386
387 sim_fpu_64to (&op1, x);
388 sim_fpu_64to (&op2, y);
389 sim_fpu_div (&ans, &op1, &op2);
390 sim_fpu_to64 (&res, &ans);
391
392 return res;
393 }
394
395 static DF
396 negdf (CGEN_FPU* fpu, DF x)
397 {
398 sim_fpu op1;
399 sim_fpu ans;
400 unsigned64 res;
401
402 sim_fpu_64to (&op1, x);
403 sim_fpu_neg (&ans, &op1);
404 sim_fpu_to64 (&res, &ans);
405
406 return res;
407 }
408
409 static DF
410 absdf (CGEN_FPU* fpu, DF x)
411 {
412 sim_fpu op1;
413 sim_fpu ans;
414 unsigned64 res;
415
416 sim_fpu_64to (&op1, x);
417 sim_fpu_abs (&ans, &op1);
418 sim_fpu_to64 (&res, &ans);
419
420 return res;
421 }
422
423 static DF
424 sqrtdf (CGEN_FPU* fpu, DF x)
425 {
426 sim_fpu op1;
427 sim_fpu ans;
428 unsigned64 res;
429
430 sim_fpu_64to (&op1, x);
431 sim_fpu_sqrt (&ans, &op1);
432 sim_fpu_to64 (&res, &ans);
433
434 return res;
435 }
436
437 static DF
438 invdf (CGEN_FPU* fpu, DF x)
439 {
440 sim_fpu op1;
441 sim_fpu ans;
442 unsigned64 res;
443
444 sim_fpu_64to (&op1, x);
445 sim_fpu_inv (&ans, &op1);
446 sim_fpu_to64 (&res, &ans);
447
448 return res;
449 }
450
451 static DF
452 mindf (CGEN_FPU* fpu, DF x, DF y)
453 {
454 sim_fpu op1;
455 sim_fpu op2;
456 sim_fpu ans;
457 unsigned64 res;
458
459 sim_fpu_64to (&op1, x);
460 sim_fpu_64to (&op2, y);
461 sim_fpu_min (&ans, &op1, &op2);
462 sim_fpu_to64 (&res, &ans);
463
464 return res;
465 }
466
467 static DF
468 maxdf (CGEN_FPU* fpu, DF x, DF y)
469 {
470 sim_fpu op1;
471 sim_fpu op2;
472 sim_fpu ans;
473 unsigned64 res;
474
475 sim_fpu_64to (&op1, x);
476 sim_fpu_64to (&op2, y);
477 sim_fpu_max (&ans, &op1, &op2);
478 sim_fpu_to64 (&res, &ans);
479
480 return res;
481 }
482
483 static CGEN_FP_CMP
484 cmpdf (CGEN_FPU* fpu, DF x, DF y)
485 {
486 sim_fpu op1;
487 sim_fpu op2;
488
489 sim_fpu_64to (&op1, x);
490 sim_fpu_64to (&op2, y);
491
492 if (sim_fpu_is_nan (&op1)
493 || sim_fpu_is_nan (&op2))
494 return FP_CMP_NAN;
495
496 if (x < y)
497 return FP_CMP_LT;
498 if (x > y)
499 return FP_CMP_GT;
500 return FP_CMP_EQ;
501 }
502
503 static int
504 eqdf (CGEN_FPU* fpu, DF x, DF y)
505 {
506 sim_fpu op1;
507 sim_fpu op2;
508
509 sim_fpu_64to (&op1, x);
510 sim_fpu_64to (&op2, y);
511 return sim_fpu_is_eq (&op1, &op2);
512 }
513
514 static int
515 nedf (CGEN_FPU* fpu, DF x, DF y)
516 {
517 sim_fpu op1;
518 sim_fpu op2;
519
520 sim_fpu_64to (&op1, x);
521 sim_fpu_64to (&op2, y);
522 return sim_fpu_is_ne (&op1, &op2);
523 }
524
525 static int
526 ltdf (CGEN_FPU* fpu, DF x, DF y)
527 {
528 sim_fpu op1;
529 sim_fpu op2;
530
531 sim_fpu_64to (&op1, x);
532 sim_fpu_64to (&op2, y);
533 return sim_fpu_is_lt (&op1, &op2);
534 }
535
536 static int
537 ledf (CGEN_FPU* fpu, DF x, DF y)
538 {
539 sim_fpu op1;
540 sim_fpu op2;
541
542 sim_fpu_64to (&op1, x);
543 sim_fpu_64to (&op2, y);
544 return sim_fpu_is_le (&op1, &op2);
545 }
546
547 static int
548 gtdf (CGEN_FPU* fpu, DF x, DF y)
549 {
550 sim_fpu op1;
551 sim_fpu op2;
552
553 sim_fpu_64to (&op1, x);
554 sim_fpu_64to (&op2, y);
555 return sim_fpu_is_gt (&op1, &op2);
556 }
557
558 static int
559 gedf (CGEN_FPU* fpu, DF x, DF y)
560 {
561 sim_fpu op1;
562 sim_fpu op2;
563
564 sim_fpu_64to (&op1, x);
565 sim_fpu_64to (&op2, y);
566 return sim_fpu_is_ge (&op1, &op2);
567 }
568 \f
569 /* Initialize FP_OPS to use accurate library. */
570
571 void
572 cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
573 {
574 CGEN_FP_OPS* o;
575
576 fpu->owner = cpu;
577 /* ??? small memory leak, not freed by sim_close */
578 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
579
580 o = fpu->ops;
581 memset (o, 0, sizeof (*o));
582
583 o->error = error;
584
585 o->addsf = addsf;
586 o->subsf = subsf;
587 o->mulsf = mulsf;
588 o->divsf = divsf;
589 o->negsf = negsf;
590 o->abssf = abssf;
591 o->sqrtsf = sqrtsf;
592 o->invsf = invsf;
593 o->minsf = minsf;
594 o->maxsf = maxsf;
595 o->cmpsf = cmpsf;
596 o->eqsf = eqsf;
597 o->nesf = nesf;
598 o->ltsf = ltsf;
599 o->lesf = lesf;
600 o->gtsf = gtsf;
601 o->gesf = gesf;
602
603 o->adddf = adddf;
604 o->subdf = subdf;
605 o->muldf = muldf;
606 o->divdf = divdf;
607 o->negdf = negdf;
608 o->absdf = absdf;
609 o->sqrtdf = sqrtdf;
610 o->invdf = invdf;
611 o->mindf = mindf;
612 o->maxdf = maxdf;
613 o->cmpdf = cmpdf;
614 o->eqdf = eqdf;
615 o->nedf = nedf;
616 o->ltdf = ltdf;
617 o->ledf = ledf;
618 o->gtdf = gtdf;
619 o->gedf = gedf;
620 o->floatsisf = floatsisf;
621 o->floatsidf = floatsidf;
622 o->ufloatsisf = ufloatsisf;
623 o->fixsfsi = fixsfsi;
624 o->fixdfsi = fixdfsi;
625 o->ufixsfsi = ufixsfsi;
626 }