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