1 #define ASSERT(EXPRESSION) \
2 do { \
3   if (!(EXPRESSION)) { \
4     fprintf (stderr, "%s:%d: assertion failed - %s\n", \
5              __FILE__, __LINE__, #EXPRESSION); \
6     abort (); \
7   } \
8 } while (0)
9 
10 #define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
11 
12 #include "milieu.h"
13 #include "softfloat.h"
14 #include "systfloat.h"
15 #include "systmodes.h"
16 
17 /* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */
18 
19 
20 #include "sim-bits.h"
21 #include "sim-fpu.h"
22 #include "sim-fpu.c"
23 
24 
25 
26 static int flags;
27 
28 int8
syst_float_flags_clear()29 syst_float_flags_clear ()
30 {
31   int old_flags = 0;
32   int i = 1;
33   while (flags >= i)
34     {
35       switch ((sim_fpu_status) (flags & i))
36 	{
37 	case sim_fpu_status_denorm:
38 	  break;
39 	case sim_fpu_status_invalid_snan:
40 	case sim_fpu_status_invalid_qnan:
41 	case sim_fpu_status_invalid_isi:
42 	case sim_fpu_status_invalid_idi:
43 	case sim_fpu_status_invalid_zdz:
44 	case sim_fpu_status_invalid_imz:
45 	case sim_fpu_status_invalid_cvi:
46 	case sim_fpu_status_invalid_cmp:
47 	case sim_fpu_status_invalid_sqrt:
48 	  old_flags |= float_flag_invalid; /* v */
49 	  break;
50 	case sim_fpu_status_inexact:
51 	  old_flags |= float_flag_inexact; /* x */
52 	  break;
53 	case sim_fpu_status_overflow:
54 	  old_flags |= float_flag_overflow; /* o */
55 	  break;
56 	case sim_fpu_status_underflow:
57 	  old_flags |= float_flag_underflow; /* u */
58 	  break;
59 	case sim_fpu_status_invalid_div0:
60 	  old_flags |= float_flag_divbyzero; /* z */
61 	  break;
62 	case sim_fpu_status_rounded:
63 	  break;
64 	}
65       i <<= 1;
66     }
67   flags = 0;
68   return old_flags;
69 }
70 
71 
72 sim_fpu_round rounding_mode;
73 
74 void
syst_float_set_rounding_mode(int8 mode)75 syst_float_set_rounding_mode(int8 mode)
76 {
77   switch (mode)
78     {
79     case float_round_nearest_even:
80       rounding_mode = sim_fpu_round_near;
81       break;
82     case float_round_down:
83       rounding_mode = sim_fpu_round_down;
84       break;
85     case float_round_up:
86       rounding_mode = sim_fpu_round_up;
87       break;
88     case float_round_to_zero:
89       rounding_mode = sim_fpu_round_zero;
90       break;
91     }
92 }
93 
94 
95 float32
syst_int32_to_float32(int32 a)96 syst_int32_to_float32(int32 a)
97 {
98   float32 z;
99   sim_fpu s;
100   flags |= sim_fpu_i32to (&s, a, rounding_mode);
101   flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
102   sim_fpu_to32 (&z, &s);
103   return z;
104 }
105 
106 float64
syst_int32_to_float64(int32 a)107 syst_int32_to_float64( int32 a )
108 {
109   float64 z;
110   sim_fpu s;
111   flags |= sim_fpu_i32to (&s, a, rounding_mode);
112   sim_fpu_to64 (&z, &s);
113   return z;
114 }
115 
116 int32
syst_float32_to_int32_round_to_zero(float32 a)117 syst_float32_to_int32_round_to_zero( float32 a )
118 {
119   int32 z;
120   sim_fpu s;
121   sim_fpu_32to (&s, a);
122   flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
123   return z;
124 }
125 
126 float64
syst_float32_to_float64(float32 a)127 syst_float32_to_float64 (float32 a)
128 {
129   float64 z;
130   sim_fpu s;
131   sim_fpu_32to (&s, a);
132   flags |= sim_fpu_round_64 (&s, rounding_mode, 0);
133   sim_fpu_to64 (&z, &s);
134   return z;
135 }
136 
syst_float32_add(float32 a,float32 b)137 float32 syst_float32_add( float32 a, float32 b )
138 {
139   float32 z;
140   sim_fpu A;
141   sim_fpu B;
142   sim_fpu ans;
143   sim_fpu_32to (&A, a);
144   sim_fpu_32to (&B, b);
145 #if 0
146   fprintf (stdout, "\n  ");
147   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
148   fprintf (stdout, "\n+ ");
149   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
150   fprintf (stdout, "\n= ");
151 #endif
152   flags |= sim_fpu_add (&ans, &A, &B);
153   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
154 #if 0
155   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
156   fprintf (stdout, "\n");
157 #endif
158   sim_fpu_to32 (&z, &ans);
159   return z;
160 }
161 
syst_float32_sub(float32 a,float32 b)162 float32 syst_float32_sub( float32 a, float32 b )
163 {
164   float32 z;
165   sim_fpu A;
166   sim_fpu B;
167   sim_fpu ans;
168   sim_fpu_32to (&A, a);
169   sim_fpu_32to (&B, b);
170 #if 0
171   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
172   fprintf (stdout, " + ");
173   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
174   fprintf (stdout, " = ");
175 #endif
176   flags |= sim_fpu_sub (&ans, &A, &B);
177   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
178 #if 0
179   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
180   fprintf (stdout, "\n");
181 #endif
182   sim_fpu_to32 (&z, &ans);
183   return z;
184 }
185 
syst_float32_mul(float32 a,float32 b)186 float32 syst_float32_mul( float32 a, float32 b )
187 {
188   float32 z;
189   sim_fpu A;
190   sim_fpu B;
191   sim_fpu ans;
192   sim_fpu_32to (&A, a);
193   sim_fpu_32to (&B, b);
194 #if 0
195   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
196   fprintf (stdout, " + ");
197   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
198   fprintf (stdout, " = ");
199 #endif
200   flags |= sim_fpu_mul (&ans, &A, &B);
201 #if 0
202   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
203 #endif
204   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
205 #if 0
206   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
207   fprintf (stdout, "\n");
208 #endif
209   sim_fpu_to32 (&z, &ans);
210   return z;
211 }
212 
syst_float32_div(float32 a,float32 b)213 float32 syst_float32_div( float32 a, float32 b )
214 {
215   float32 z;
216   sim_fpu A;
217   sim_fpu B;
218   sim_fpu ans;
219   sim_fpu_32to (&A, a);
220   sim_fpu_32to (&B, b);
221   flags |= sim_fpu_div (&ans, &A, &B);
222   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
223   sim_fpu_to32 (&z, &ans);
224   return z;
225 }
226 
syst_float32_sqrt(float32 a)227 float32 syst_float32_sqrt( float32 a )
228 {
229   float32 z;
230   sim_fpu A;
231   sim_fpu ans;
232   sim_fpu_32to (&A, a);
233 #if 0
234   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
235   fprintf (stdout, " sqrt> ");
236 #endif
237   flags |= sim_fpu_sqrt (&ans, &A);
238 #if 0
239   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
240 #endif
241   flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
242 #if 0
243   fprintf (stdout, " (%x)\n", flags);
244 #endif
245   sim_fpu_to32 (&z, &ans);
246   return z;
247 }
248 
syst_float32_eq(float32 a,float32 b)249 flag syst_float32_eq( float32 a, float32 b )
250 {
251   sim_fpu A;
252   sim_fpu B;
253   int is;
254   sim_fpu_32to (&A, a);
255   sim_fpu_32to (&B, b);
256   flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
257   return is;
258 }
259 
syst_float32_eq_signaling(float32 a,float32 b)260 flag syst_float32_eq_signaling( float32 a, float32 b )
261 {
262   sim_fpu A;
263   sim_fpu B;
264   int is;
265   sim_fpu_32to (&A, a);
266   sim_fpu_32to (&B, b);
267   flags |= sim_fpu_eq (&is, &A, &B);
268   return is;
269 }
270 
syst_float32_le(float32 a,float32 b)271 flag syst_float32_le( float32 a, float32 b )
272 {
273   sim_fpu A;
274   sim_fpu B;
275   int is;
276   sim_fpu_32to (&A, a);
277   sim_fpu_32to (&B, b);
278   flags |= sim_fpu_le (&is, &A, &B);
279   return is;
280 }
281 
syst_float32_le_quiet(float32 a,float32 b)282 flag syst_float32_le_quiet( float32 a, float32 b )
283 {
284   sim_fpu A;
285   sim_fpu B;
286   int is;
287   sim_fpu_32to (&A, a);
288   sim_fpu_32to (&B, b);
289   flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
290   return is;
291 }
292 
syst_float32_lt(float32 a,float32 b)293 flag syst_float32_lt( float32 a, float32 b )
294 {
295   sim_fpu A;
296   sim_fpu B;
297   int is;
298   sim_fpu_32to (&A, a);
299   sim_fpu_32to (&B, b);
300   flags |= sim_fpu_lt (&is, &A, &B);
301   return is;
302 }
303 
syst_float32_lt_quiet(float32 a,float32 b)304 flag syst_float32_lt_quiet( float32 a, float32 b )
305 {
306   sim_fpu A;
307   sim_fpu B;
308   int is;
309   sim_fpu_32to (&A, a);
310   sim_fpu_32to (&B, b);
311   flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
312   return is;
313 }
314 
syst_float64_to_int32_round_to_zero(float64 a)315 int32 syst_float64_to_int32_round_to_zero( float64 a )
316 {
317   int32 z;
318   sim_fpu s;
319   sim_fpu_64to (&s, a);
320   flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
321   return z;
322 }
323 
syst_float64_to_float32(float64 a)324 float32 syst_float64_to_float32( float64 a )
325 {
326   float32 z;
327   sim_fpu s;
328   sim_fpu_64to (&s, a);
329 #if 0
330   sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
331   fprintf (stdout, " -> ");
332 #endif
333   flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
334 #if 0
335   sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
336   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
337   printf ("\n");
338 #endif
339   sim_fpu_to32 (&z, &s);
340   return z;
341 }
342 
syst_float64_add(float64 a,float64 b)343 float64 syst_float64_add( float64 a, float64 b )
344 {
345   float64 z;
346   sim_fpu A;
347   sim_fpu B;
348   sim_fpu ans;
349   sim_fpu_64to (&A, a);
350   sim_fpu_64to (&B, b);
351 #if 0
352   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
353   fprintf (stdout, " + ");
354   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
355   fprintf (stdout, " = ");
356 #endif
357   flags |= sim_fpu_add (&ans, &A, &B);
358 #if 0
359   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
360 #endif
361   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
362 #if 0
363   fprintf (stdout, " (%x)\n", flags);
364 #endif
365   sim_fpu_to64 (&z, &ans);
366   return z;
367 }
368 
syst_float64_sub(float64 a,float64 b)369 float64 syst_float64_sub( float64 a, float64 b )
370 {
371   float64 z;
372   sim_fpu A;
373   sim_fpu B;
374   sim_fpu ans;
375   sim_fpu_64to (&A, a);
376   sim_fpu_64to (&B, b);
377 #if 0
378   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
379   fprintf (stdout, " + ");
380   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
381   fprintf (stdout, " = ");
382 #endif
383   flags |= sim_fpu_sub (&ans, &A, &B);
384 #if 0
385   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
386 #endif
387   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
388 #if 0
389   fprintf (stdout, " (%x)\n", flags);
390 #endif
391   sim_fpu_to64 (&z, &ans);
392   return z;
393 }
394 
syst_float64_mul(float64 a,float64 b)395 float64 syst_float64_mul( float64 a, float64 b )
396 {
397   float64 z;
398   sim_fpu A;
399   sim_fpu B;
400   sim_fpu ans;
401   sim_fpu_64to (&A, a);
402   sim_fpu_64to (&B, b);
403 #if 0
404   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
405   fprintf (stdout, " * ");
406   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
407   fprintf (stdout, " = ");
408 #endif
409   flags |= sim_fpu_mul (&ans, &A, &B);
410 #if 0
411   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
412 #endif
413   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
414 #if 0
415   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
416   fprintf (stdout, "\n");
417 #endif
418   sim_fpu_to64 (&z, &ans);
419   return z;
420 }
421 
syst_float64_div(float64 a,float64 b)422 float64 syst_float64_div( float64 a, float64 b )
423 {
424   float64 z;
425   sim_fpu A;
426   sim_fpu B;
427   sim_fpu ans;
428   sim_fpu_64to (&A, a);
429   sim_fpu_64to (&B, b);
430 #if 0
431   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
432   fprintf (stdout, " + ");
433   sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
434   fprintf (stdout, " = ");
435 #endif
436   flags |= sim_fpu_div (&ans, &A, &B);
437 #if 0
438   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
439 #endif
440   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
441 #if 0
442   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
443   fprintf (stdout, "\n");
444 #endif
445   sim_fpu_to64 (&z, &ans);
446   return z;
447 }
448 
syst_float64_sqrt(float64 a)449 float64 syst_float64_sqrt( float64 a )
450 {
451   float64 z;
452   sim_fpu A;
453   sim_fpu ans;
454   sim_fpu_64to (&A, a);
455 #if 0
456   sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
457   printf (" sqrt> ");
458   printf ("\n");
459 #endif
460   flags |= sim_fpu_sqrt (&ans, &A);
461 #if 0
462   sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
463 #endif
464   flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
465 #if 0
466   sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
467   fprintf (stdout, "\n");
468 #endif
469   sim_fpu_to64 (&z, &ans);
470   return z;
471 }
472 
syst_float64_eq(float64 a,float64 b)473 flag syst_float64_eq( float64 a, float64 b )
474 {
475   sim_fpu A;
476   sim_fpu B;
477   int is;
478   sim_fpu_64to (&A, a);
479   sim_fpu_64to (&B, b);
480   flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
481   return is;
482 }
483 
syst_float64_eq_signaling(float64 a,float64 b)484 flag syst_float64_eq_signaling( float64 a, float64 b )
485 {
486   sim_fpu A;
487   sim_fpu B;
488   int is;
489   sim_fpu_64to (&A, a);
490   sim_fpu_64to (&B, b);
491   flags |= sim_fpu_eq (&is, &A, &B);
492   return is;
493 }
494 
syst_float64_le(float64 a,float64 b)495 flag syst_float64_le( float64 a, float64 b )
496 {
497   sim_fpu A;
498   sim_fpu B;
499   int is;
500   sim_fpu_64to (&A, a);
501   sim_fpu_64to (&B, b);
502   flags |= sim_fpu_le (&is, &A, &B);
503   return is;
504 }
505 
syst_float64_le_quiet(float64 a,float64 b)506 flag syst_float64_le_quiet( float64 a, float64 b )
507 {
508   sim_fpu A;
509   sim_fpu B;
510   int is;
511   sim_fpu_64to (&A, a);
512   sim_fpu_64to (&B, b);
513   flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
514   return is;
515 }
516 
syst_float64_lt(float64 a,float64 b)517 flag syst_float64_lt( float64 a, float64 b )
518 {
519   sim_fpu A;
520   sim_fpu B;
521   int is;
522   sim_fpu_64to (&A, a);
523   sim_fpu_64to (&B, b);
524   flags |= sim_fpu_lt (&is, &A, &B);
525   return is;
526 }
527 
syst_float64_lt_quiet(float64 a,float64 b)528 flag syst_float64_lt_quiet( float64 a, float64 b )
529 {
530   sim_fpu A;
531   sim_fpu B;
532   int is;
533   sim_fpu_64to (&A, a);
534   sim_fpu_64to (&B, b);
535   flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
536   return is;
537 }
538 
539