diff options
Diffstat (limited to 'sim/testsuite/common/fpu-tst.c')
-rw-r--r-- | sim/testsuite/common/fpu-tst.c | 538 |
1 files changed, 538 insertions, 0 deletions
diff --git a/sim/testsuite/common/fpu-tst.c b/sim/testsuite/common/fpu-tst.c new file mode 100644 index 0000000..d347e12 --- /dev/null +++ b/sim/testsuite/common/fpu-tst.c @@ -0,0 +1,538 @@ +#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 +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 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 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 a ) +{ + float64 z; + sim_fpu s; + flags |= sim_fpu_i32to (&s, a, rounding_mode); + sim_fpu_to64 (&z, &s); + return z; +} + +int32 +syst_float32_to_int32_round_to_zero( float32 a ) +{ + int32 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 syst_float64_to_int32_round_to_zero( float64 a ) +{ + int32 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; +} + |