123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- #define ASSERT(EXPRESSION) \
- do { \
- if (!(EXPRESSION)) { \
- fprintf (stderr, "%s:%d: assertion failed - %s\n", \
- __FILE__, __LINE__, #EXPRESSION); \
- abort (); \
- } \
- } while (0)
- #define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
- #include "milieu.h"
- #include "softfloat.h"
- #include "systfloat.h"
- #include "systmodes.h"
- /* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */
- #include "sim-bits.h"
- #include "sim-fpu.h"
- #include "sim-fpu.c"
- static int flags;
- int8_t
- syst_float_flags_clear ()
- {
- int old_flags = 0;
- int i = 1;
- while (flags >= i)
- {
- switch ((sim_fpu_status) (flags & i))
- {
- case sim_fpu_status_denorm:
- break;
- case sim_fpu_status_invalid_snan:
- case sim_fpu_status_invalid_qnan:
- case sim_fpu_status_invalid_isi:
- case sim_fpu_status_invalid_idi:
- case sim_fpu_status_invalid_zdz:
- case sim_fpu_status_invalid_imz:
- case sim_fpu_status_invalid_cvi:
- case sim_fpu_status_invalid_cmp:
- case sim_fpu_status_invalid_sqrt:
- old_flags |= float_flag_invalid; /* v */
- break;
- case sim_fpu_status_inexact:
- old_flags |= float_flag_inexact; /* x */
- break;
- case sim_fpu_status_overflow:
- old_flags |= float_flag_overflow; /* o */
- break;
- case sim_fpu_status_underflow:
- old_flags |= float_flag_underflow; /* u */
- break;
- case sim_fpu_status_invalid_div0:
- old_flags |= float_flag_divbyzero; /* z */
- break;
- case sim_fpu_status_rounded:
- break;
- }
- i <<= 1;
- }
- flags = 0;
- return old_flags;
- }
- sim_fpu_round rounding_mode;
- void
- syst_float_set_rounding_mode(int8_t mode)
- {
- switch (mode)
- {
- case float_round_nearest_even:
- rounding_mode = sim_fpu_round_near;
- break;
- case float_round_down:
- rounding_mode = sim_fpu_round_down;
- break;
- case float_round_up:
- rounding_mode = sim_fpu_round_up;
- break;
- case float_round_to_zero:
- rounding_mode = sim_fpu_round_zero;
- break;
- }
- }
- float32
- syst_int32_to_float32(int32_t a)
- {
- float32 z;
- sim_fpu s;
- flags |= sim_fpu_i32to (&s, a, rounding_mode);
- flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
- sim_fpu_to32 (&z, &s);
- return z;
- }
- float64
- syst_int32_to_float64( int32_t a )
- {
- float64 z;
- sim_fpu s;
- flags |= sim_fpu_i32to (&s, a, rounding_mode);
- sim_fpu_to64 (&z, &s);
- return z;
- }
- int32_t
- syst_float32_to_int32_round_to_zero( float32 a )
- {
- int32_t z;
- sim_fpu s;
- sim_fpu_32to (&s, a);
- flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
- return z;
- }
- float64
- syst_float32_to_float64 (float32 a)
- {
- float64 z;
- sim_fpu s;
- sim_fpu_32to (&s, a);
- flags |= sim_fpu_round_64 (&s, rounding_mode, 0);
- sim_fpu_to64 (&z, &s);
- return z;
- }
- float32 syst_float32_add( float32 a, float32 b )
- {
- float32 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- #if 0
- fprintf (stdout, "\n ");
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n+ ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n= ");
- #endif
- flags |= sim_fpu_add (&ans, &A, &B);
- flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to32 (&z, &ans);
- return z;
- }
- float32 syst_float32_sub( float32 a, float32 b )
- {
- float32 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " + ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_sub (&ans, &A, &B);
- flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to32 (&z, &ans);
- return z;
- }
- float32 syst_float32_mul( float32 a, float32 b )
- {
- float32 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " + ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_mul (&ans, &A, &B);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to32 (&z, &ans);
- return z;
- }
- float32 syst_float32_div( float32 a, float32 b )
- {
- float32 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= sim_fpu_div (&ans, &A, &B);
- flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
- sim_fpu_to32 (&z, &ans);
- return z;
- }
- float32 syst_float32_sqrt( float32 a )
- {
- float32 z;
- sim_fpu A;
- sim_fpu ans;
- sim_fpu_32to (&A, a);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " sqrt> ");
- #endif
- flags |= sim_fpu_sqrt (&ans, &A);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
- #if 0
- fprintf (stdout, " (%x)\n", flags);
- #endif
- sim_fpu_to32 (&z, &ans);
- return z;
- }
- flag syst_float32_eq( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
- flag syst_float32_eq_signaling( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= sim_fpu_eq (&is, &A, &B);
- return is;
- }
- flag syst_float32_le( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= sim_fpu_le (&is, &A, &B);
- return is;
- }
- flag syst_float32_le_quiet( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
- flag syst_float32_lt( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= sim_fpu_lt (&is, &A, &B);
- return is;
- }
- flag syst_float32_lt_quiet( float32 a, float32 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_32to (&A, a);
- sim_fpu_32to (&B, b);
- flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
- int32_t syst_float64_to_int32_round_to_zero( float64 a )
- {
- int32_t z;
- sim_fpu s;
- sim_fpu_64to (&s, a);
- flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
- return z;
- }
- float32 syst_float64_to_float32( float64 a )
- {
- float32 z;
- sim_fpu s;
- sim_fpu_64to (&s, a);
- #if 0
- sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " -> ");
- #endif
- flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
- #if 0
- sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
- sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
- printf ("\n");
- #endif
- sim_fpu_to32 (&z, &s);
- return z;
- }
- float64 syst_float64_add( float64 a, float64 b )
- {
- float64 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " + ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_add (&ans, &A, &B);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
- #if 0
- fprintf (stdout, " (%x)\n", flags);
- #endif
- sim_fpu_to64 (&z, &ans);
- return z;
- }
- float64 syst_float64_sub( float64 a, float64 b )
- {
- float64 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " + ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_sub (&ans, &A, &B);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
- #if 0
- fprintf (stdout, " (%x)\n", flags);
- #endif
- sim_fpu_to64 (&z, &ans);
- return z;
- }
- float64 syst_float64_mul( float64 a, float64 b )
- {
- float64 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " * ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_mul (&ans, &A, &B);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to64 (&z, &ans);
- return z;
- }
- float64 syst_float64_div( float64 a, float64 b )
- {
- float64 z;
- sim_fpu A;
- sim_fpu B;
- sim_fpu ans;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " + ");
- sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, " = ");
- #endif
- flags |= sim_fpu_div (&ans, &A, &B);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to64 (&z, &ans);
- return z;
- }
- float64 syst_float64_sqrt( float64 a )
- {
- float64 z;
- sim_fpu A;
- sim_fpu ans;
- sim_fpu_64to (&A, a);
- #if 0
- sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
- printf (" sqrt> ");
- printf ("\n");
- #endif
- flags |= sim_fpu_sqrt (&ans, &A);
- #if 0
- sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
- #endif
- flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
- #if 0
- sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
- fprintf (stdout, "\n");
- #endif
- sim_fpu_to64 (&z, &ans);
- return z;
- }
- flag syst_float64_eq( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
- flag syst_float64_eq_signaling( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= sim_fpu_eq (&is, &A, &B);
- return is;
- }
- flag syst_float64_le( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= sim_fpu_le (&is, &A, &B);
- return is;
- }
- flag syst_float64_le_quiet( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
- flag syst_float64_lt( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= sim_fpu_lt (&is, &A, &B);
- return is;
- }
- flag syst_float64_lt_quiet( float64 a, float64 b )
- {
- sim_fpu A;
- sim_fpu B;
- int is;
- sim_fpu_64to (&A, a);
- sim_fpu_64to (&B, b);
- flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
- return is;
- }
|