Add md expression support; Cleanup alpha warnings
[deliverable/binutils-gdb.git] / sim / common / cgen-accfp.c
CommitLineData
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
19static SF
20addsf (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
38static SF
39subsf (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
54static SF
55mulsf (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
70static SF
71divsf (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
86static SF
87negsf (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
100static SF
101abssf (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
114static SF
115sqrtsf (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
128static SF
129invsf (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
142static SF
143minsf (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
158static SF
159maxsf (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
174static CGEN_FP_CMP
175cmpsf (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
194static int
195eqsf (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
205static int
206nesf (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
216static int
217ltsf (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
227static int
228lesf (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
238static int
239gtsf (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
249static int
250gesf (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
260static SF
261floatsisf (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
9846de1b
JM
271static DF
272floatsidf (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
3535ad49
JM
282static SF
283ufloatsisf (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
293static SI
294fixsfsi (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
9846de1b
JM
304static SI
305fixdfsi (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
3535ad49
JM
315static USI
316ufixsfsi (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
328static DF
329adddf (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
347static DF
348subdf (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
363static DF
364muldf (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
379static DF
380divdf (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
395static DF
396negdf (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
409static DF
410absdf (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
423static DF
424sqrtdf (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
437static DF
438invdf (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
451static DF
452mindf (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
467static DF
468maxdf (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
483static CGEN_FP_CMP
484cmpdf (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
503static int
504eqdf (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
514static int
515nedf (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
525static int
526ltdf (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
536static int
537ledf (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
547static int
548gtdf (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
558static int
559gedf (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
571void
572cgen_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;
9846de1b 621 o->floatsidf = floatsidf;
3535ad49
JM
622 o->ufloatsisf = ufloatsisf;
623 o->fixsfsi = fixsfsi;
9846de1b 624 o->fixdfsi = fixdfsi;
3535ad49
JM
625 o->ufixsfsi = ufixsfsi;
626}
This page took 0.109212 seconds and 4 git commands to generate.