* ld-elfvers/vers.exp: Add new tests vers17 to vers19.
[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
271static SF
272ufloatsisf (CGEN_FPU* fpu, USI x)
273{
274 sim_fpu ans;
275 unsigned32 res;
276
277 sim_fpu_u32to (&ans, x, sim_fpu_round_near);
278 sim_fpu_to32 (&res, &ans);
279 return res;
280}
281
282static SI
283fixsfsi (CGEN_FPU* fpu, SF x)
284{
285 sim_fpu op1;
286 unsigned32 res;
287
288 sim_fpu_32to (&op1, x);
289 sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
290 return res;
291}
292
293static USI
294ufixsfsi (CGEN_FPU* fpu, SF x)
295{
296 sim_fpu op1;
297 unsigned32 res;
298
299 sim_fpu_32to (&op1, x);
300 sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
301 return res;
302}
303\f
304/* DF mode support */
305
306static DF
307adddf (CGEN_FPU* fpu, DF x, DF y)
308{
309 sim_fpu op1;
310 sim_fpu op2;
311 sim_fpu ans;
312 unsigned64 res;
313 sim_fpu_status status;
314
315 sim_fpu_64to (&op1, x);
316 sim_fpu_64to (&op2, y);
317 status = sim_fpu_add (&ans, &op1, &op2);
318 if (status != 0)
319 (*fpu->ops->error) (fpu, status);
320 sim_fpu_to64 (&res, &ans);
321
322 return res;
323}
324
325static DF
326subdf (CGEN_FPU* fpu, DF x, DF y)
327{
328 sim_fpu op1;
329 sim_fpu op2;
330 sim_fpu ans;
331 unsigned64 res;
332
333 sim_fpu_64to (&op1, x);
334 sim_fpu_64to (&op2, y);
335 sim_fpu_sub (&ans, &op1, &op2);
336 sim_fpu_to64 (&res, &ans);
337
338 return res;
339}
340
341static DF
342muldf (CGEN_FPU* fpu, DF x, DF y)
343{
344 sim_fpu op1;
345 sim_fpu op2;
346 sim_fpu ans;
347 unsigned64 res;
348
349 sim_fpu_64to (&op1, x);
350 sim_fpu_64to (&op2, y);
351 sim_fpu_mul (&ans, &op1, &op2);
352 sim_fpu_to64 (&res, &ans);
353
354 return res;
355}
356
357static DF
358divdf (CGEN_FPU* fpu, DF x, DF y)
359{
360 sim_fpu op1;
361 sim_fpu op2;
362 sim_fpu ans;
363 unsigned64 res;
364
365 sim_fpu_64to (&op1, x);
366 sim_fpu_64to (&op2, y);
367 sim_fpu_div (&ans, &op1, &op2);
368 sim_fpu_to64 (&res, &ans);
369
370 return res;
371}
372
373static DF
374negdf (CGEN_FPU* fpu, DF x)
375{
376 sim_fpu op1;
377 sim_fpu ans;
378 unsigned64 res;
379
380 sim_fpu_64to (&op1, x);
381 sim_fpu_neg (&ans, &op1);
382 sim_fpu_to64 (&res, &ans);
383
384 return res;
385}
386
387static DF
388absdf (CGEN_FPU* fpu, DF x)
389{
390 sim_fpu op1;
391 sim_fpu ans;
392 unsigned64 res;
393
394 sim_fpu_64to (&op1, x);
395 sim_fpu_abs (&ans, &op1);
396 sim_fpu_to64 (&res, &ans);
397
398 return res;
399}
400
401static DF
402sqrtdf (CGEN_FPU* fpu, DF x)
403{
404 sim_fpu op1;
405 sim_fpu ans;
406 unsigned64 res;
407
408 sim_fpu_64to (&op1, x);
409 sim_fpu_sqrt (&ans, &op1);
410 sim_fpu_to64 (&res, &ans);
411
412 return res;
413}
414
415static DF
416invdf (CGEN_FPU* fpu, DF x)
417{
418 sim_fpu op1;
419 sim_fpu ans;
420 unsigned64 res;
421
422 sim_fpu_64to (&op1, x);
423 sim_fpu_inv (&ans, &op1);
424 sim_fpu_to64 (&res, &ans);
425
426 return res;
427}
428
429static DF
430mindf (CGEN_FPU* fpu, DF x, DF y)
431{
432 sim_fpu op1;
433 sim_fpu op2;
434 sim_fpu ans;
435 unsigned64 res;
436
437 sim_fpu_64to (&op1, x);
438 sim_fpu_64to (&op2, y);
439 sim_fpu_min (&ans, &op1, &op2);
440 sim_fpu_to64 (&res, &ans);
441
442 return res;
443}
444
445static DF
446maxdf (CGEN_FPU* fpu, DF x, DF y)
447{
448 sim_fpu op1;
449 sim_fpu op2;
450 sim_fpu ans;
451 unsigned64 res;
452
453 sim_fpu_64to (&op1, x);
454 sim_fpu_64to (&op2, y);
455 sim_fpu_max (&ans, &op1, &op2);
456 sim_fpu_to64 (&res, &ans);
457
458 return res;
459}
460
461static CGEN_FP_CMP
462cmpdf (CGEN_FPU* fpu, DF x, DF y)
463{
464 sim_fpu op1;
465 sim_fpu op2;
466
467 sim_fpu_64to (&op1, x);
468 sim_fpu_64to (&op2, y);
469
470 if (sim_fpu_is_nan (&op1)
471 || sim_fpu_is_nan (&op2))
472 return FP_CMP_NAN;
473
474 if (x < y)
475 return FP_CMP_LT;
476 if (x > y)
477 return FP_CMP_GT;
478 return FP_CMP_EQ;
479}
480
481static int
482eqdf (CGEN_FPU* fpu, DF x, DF y)
483{
484 sim_fpu op1;
485 sim_fpu op2;
486
487 sim_fpu_64to (&op1, x);
488 sim_fpu_64to (&op2, y);
489 return sim_fpu_is_eq (&op1, &op2);
490}
491
492static int
493nedf (CGEN_FPU* fpu, DF x, DF y)
494{
495 sim_fpu op1;
496 sim_fpu op2;
497
498 sim_fpu_64to (&op1, x);
499 sim_fpu_64to (&op2, y);
500 return sim_fpu_is_ne (&op1, &op2);
501}
502
503static int
504ltdf (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_lt (&op1, &op2);
512}
513
514static int
515ledf (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_le (&op1, &op2);
523}
524
525static int
526gtdf (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_gt (&op1, &op2);
534}
535
536static int
537gedf (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_ge (&op1, &op2);
545}
546\f
547/* Initialize FP_OPS to use accurate library. */
548
549void
550cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
551{
552 CGEN_FP_OPS* o;
553
554 fpu->owner = cpu;
555 /* ??? small memory leak, not freed by sim_close */
556 fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
557
558 o = fpu->ops;
559 memset (o, 0, sizeof (*o));
560
561 o->error = error;
562
563 o->addsf = addsf;
564 o->subsf = subsf;
565 o->mulsf = mulsf;
566 o->divsf = divsf;
567 o->negsf = negsf;
568 o->abssf = abssf;
569 o->sqrtsf = sqrtsf;
570 o->invsf = invsf;
571 o->minsf = minsf;
572 o->maxsf = maxsf;
573 o->cmpsf = cmpsf;
574 o->eqsf = eqsf;
575 o->nesf = nesf;
576 o->ltsf = ltsf;
577 o->lesf = lesf;
578 o->gtsf = gtsf;
579 o->gesf = gesf;
580
581 o->adddf = adddf;
582 o->subdf = subdf;
583 o->muldf = muldf;
584 o->divdf = divdf;
585 o->negdf = negdf;
586 o->absdf = absdf;
587 o->sqrtdf = sqrtdf;
588 o->invdf = invdf;
589 o->mindf = mindf;
590 o->maxdf = maxdf;
591 o->cmpdf = cmpdf;
592 o->eqdf = eqdf;
593 o->nedf = nedf;
594 o->ltdf = ltdf;
595 o->ledf = ledf;
596 o->gtdf = gtdf;
597 o->gedf = gedf;
598 o->floatsisf = floatsisf;
599 o->ufloatsisf = ufloatsisf;
600 o->fixsfsi = fixsfsi;
601 o->ufixsfsi = ufixsfsi;
602}
This page took 0.061221 seconds and 4 git commands to generate.