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