1#define ASSERT(EXPRESSION) \
2do { \
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
26static int flags;
27
28int8
29syst_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
72sim_fpu_round rounding_mode;
73
74void
75syst_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
95float32
96syst_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
106float64
107syst_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
116int32
117syst_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
126float64
127syst_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
137float32 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
162float32 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
186float32 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
213float32 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
227float32 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
249flag 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
260flag 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
271flag 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
282flag 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
293flag 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
304flag 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
315int32 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
324float32 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
343float64 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
369float64 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
395float64 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
422float64 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
449float64 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
473flag 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
484flag 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
495flag 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
506flag 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
517flag 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
528flag 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