From b3c77578dc408e024f1a38edfb03f3fb78bb11b6 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Fri, 3 Oct 1997 00:03:35 +0000 Subject: [PATCH] Rewrite simulator floating point module. Do not rely on host FP implementation. Add preliminary support for different IEEE-754 rounding modes. Implement SQRT in software. Update TiC80 simulator. Add sim-fpu -> TestFloat interface for testing. --- sim/testsuite/common/fpu-tst.c | 538 +++++++++++++++++++++++++++++++++ sim/tic80/ChangeLog | 9 + sim/tic80/insns | 80 +++-- sim/tic80/misc.c | 16 +- 4 files changed, 602 insertions(+), 41 deletions(-) create mode 100644 sim/testsuite/common/fpu-tst.c diff --git a/sim/testsuite/common/fpu-tst.c b/sim/testsuite/common/fpu-tst.c new file mode 100644 index 0000000000..d347e12727 --- /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; +} + diff --git a/sim/tic80/ChangeLog b/sim/tic80/ChangeLog index 77655dd0eb..b4462c74a7 100644 --- a/sim/tic80/ChangeLog +++ b/sim/tic80/ChangeLog @@ -1,3 +1,12 @@ +Mon Sep 29 12:49:06 1997 Andrew Cagney + + * insns (get_fp_reg, set_fp_reg): Update to use changed sim_fpu + interface. + (do_fadd, do_fcmp, do_fdiv, do_fmpy, do_frnd, do_fsub): Ditto. + + * misc.c (tic80_trace_fpu3, tic80_trace_fpu2, tic80_trace_fpu1, + tic80_trace_fpu2i) Update to use changed sim_fpu interface. + Fri Oct 3 09:28:00 1997 Andrew Cagney * configure.in (SIM_AC_OPTIONS_BITSIZE): Define. diff --git a/sim/tic80/insns b/sim/tic80/insns index dfe70c5bde..84cca391f0 100644 --- a/sim/tic80/insns +++ b/sim/tic80/insns @@ -434,10 +434,12 @@ void::function::do_dst:int Source, unsigned32 base, unsigned32 *rBase, int m , i sim_fpu::function::get_fp_reg:int reg, unsigned32 val, int precision + sim_fpu ans; switch (precision) { case 0: /* single */ - return sim_fpu_32to (val); + sim_fpu_32to (&ans, val); + break; case 1: /* double */ if (reg < 0) sim_engine_abort (SD, CPU, cia, "DP immediate invalid"); @@ -445,43 +447,43 @@ sim_fpu::function::get_fp_reg:int reg, unsigned32 val, int precision sim_engine_abort (SD, CPU, cia, "DP FP register must be even"); if (reg <= 1) sim_engine_abort (SD, CPU, cia, "DP FP register must be >= 2"); - return sim_fpu_64to (INSERTED64 (GPR (reg + 1), 63, 32) - | INSERTED64 (GPR (reg), 31, 0)); + sim_fpu_232to (&ans, GPR (reg), GPR (reg + 1)); + break; case 2: /* 32 bit signed integer */ - return sim_fpu_i32to (val); + sim_fpu_i32to (&ans, val, 0); + break; case 3: /* 32 bit unsigned integer */ - return sim_fpu_u32to (val); + sim_fpu_u32to (&ans, val, 0); + break; default: sim_engine_abort (SD, CPU, cia, "Unsupported FP precision"); } - return sim_fpu_i32to (0); + return ans; void::function::set_fp_reg:int Dest, sim_fpu val, int PD switch (PD) { case 0: /* single */ { - GPR (Dest) = sim_fpu_to32 (val); + sim_fpu_to32 (&GPR (Dest), &val); break; } case 1: /* double */ { - unsigned64 v = sim_fpu_to64 (val); if (Dest & 1) sim_engine_abort (SD, CPU, cia, "DP FP Dest register must be even"); if (Dest <= 1) sim_engine_abort (SD, CPU, cia, "DP FP Dest register must be >= 2"); - GPR (Dest + 0) = VL4_8 (v); - GPR (Dest + 1) = VH4_8 (v); + sim_fpu_to232 (&GPR (Dest + 0), &GPR (Dest + 1), &val); break; } case 2: /* signed */ { - GPR (Dest) = sim_fpu_to32i (val); + sim_fpu_to32i (&GPR (Dest), &val, 0); break; } case 3: /* unsigned */ { - GPR (Dest) = sim_fpu_to32u (val); + sim_fpu_to32u (&GPR (Dest), &val, 0); break; } default: @@ -490,7 +492,8 @@ void::function::set_fp_reg:int Dest, sim_fpu val, int PD // fadd.{s|d}{s|d}{s|d} void::function::do_fadd:int Dest, int PD, sim_fpu s1, sim_fpu s2 - sim_fpu ans = sim_fpu_add (s1, s2); + sim_fpu ans; + sim_fpu_add (&ans, &s1, &s2); TRACE_FPU3 (ans, s1, s2); set_fp_reg (_SD, Dest, ans, PD); const char *::function::str_PX:int PX @@ -517,25 +520,25 @@ const char *::function::str_PX:int PX // fcmp.{s|d}{s|d}{s|d} void::function::do_fcmp:unsigned32 *rDest, sim_fpu s1, sim_fpu s2 unsigned32 result = 0; - if (sim_fpu_is_nan (s1) || sim_fpu_is_nan (s2)) + if (sim_fpu_is_nan (&s1) || sim_fpu_is_nan (&s2)) result |= BIT32 (30); else { result |= BIT32 (31); - if (sim_fpu_is_eq (s1, s2)) result |= BIT32(20); - if (sim_fpu_is_ne (s1, s2)) result |= BIT32(21); - if (sim_fpu_is_gt (s1, s2)) result |= BIT32(22); - if (sim_fpu_is_le (s1, s2)) result |= BIT32(23); - if (sim_fpu_is_lt (s1, s2)) result |= BIT32(24); - if (sim_fpu_is_ge (s1, s2)) result |= BIT32(25); - if (sim_fpu_is_lt (s1, sim_fpu_i32to (0)) - || sim_fpu_is_gt (s1, s2)) result |= BIT32(26); - if (sim_fpu_is_lt (sim_fpu_i32to (0), s1) - && sim_fpu_is_lt (s1, s2)) result |= BIT32(27); - if (sim_fpu_is_le (sim_fpu_i32to (0), s1) - && sim_fpu_is_le (s1, s2)) result |= BIT32(28); - if (sim_fpu_is_le (s1, sim_fpu_i32to (0)) - || sim_fpu_is_ge (s1, s2)) result |= BIT32(29); + if (sim_fpu_is_eq (&s1, &s2)) result |= BIT32(20); + if (sim_fpu_is_ne (&s1, &s2)) result |= BIT32(21); + if (sim_fpu_is_gt (&s1, &s2)) result |= BIT32(22); + if (sim_fpu_is_le (&s1, &s2)) result |= BIT32(23); + if (sim_fpu_is_lt (&s1, &s2)) result |= BIT32(24); + if (sim_fpu_is_ge (&s1, &s2)) result |= BIT32(25); + if (sim_fpu_is_lt (&s1, &sim_fpu_zero) + || sim_fpu_is_gt (&s1, &s2)) result |= BIT32(26); + if (sim_fpu_is_lt (&sim_fpu_zero, &s1) + && sim_fpu_is_lt (&s1, &s2)) result |= BIT32(27); + if (sim_fpu_is_le (&sim_fpu_zero, &s1) + && sim_fpu_is_le (&s1, &s2)) result |= BIT32(28); + if (sim_fpu_is_le (&s1, &sim_fpu_zero) + || sim_fpu_is_ge (&s1, &s2)) result |= BIT32(29); } *rDest = result; TRACE_FPU2I (result, s1, s2); @@ -554,7 +557,8 @@ void::function::do_fcmp:unsigned32 *rDest, sim_fpu s1, sim_fpu s2 // fdiv.{s|d}{s|d}{s|d} void::function::do_fdiv:int Dest, int PD, sim_fpu s1, sim_fpu s2 - sim_fpu ans = sim_fpu_div (s1, s2); + sim_fpu ans; + sim_fpu_div (&ans, &s1, &s2); TRACE_FPU3 (ans, s1, s2); set_fp_reg (_SD, Dest, ans, PD); 31.Dest,26.Source2,21.0b111110011,12.0,11./,10.PD,8.P2,6.P1,4.Source1::f::fdiv r @@ -575,19 +579,28 @@ void::function::do_fmpy:int Dest, int PD, sim_fpu s1, sim_fpu s2 { case 2: /* signed */ { - GPR (Dest) = sim_fpu_to64i (s1) * sim_fpu_to64i (s2); + signed64 i1; + signed64 i2; + sim_fpu_to64i (&i1, &s1, 0); + sim_fpu_to64i (&i2, &s2, 0); + GPR (Dest) = i1 * i2; TRACE_FPU2I (GPR (Dest), s1, s2); break; } case 3: /* unsigned */ { - GPR (Dest) = sim_fpu_to64u (s1) * sim_fpu_to64u (s2); + unsigned64 u1; + unsigned64 u2; + sim_fpu_to64u (&u1, &s1, 0); + sim_fpu_to64u (&u2, &s2, 0); + GPR (Dest) = u1 * u2; TRACE_FPU2I (GPR (Dest), s1, s2); break; } default: { - sim_fpu ans = sim_fpu_mul (s1, s2); + sim_fpu ans; + sim_fpu_mul (&ans, &s1, &s2); set_fp_reg (_SD, Dest, ans, PD); TRACE_FPU3 (ans, s1, s2); } @@ -664,7 +677,8 @@ void::function::do_frnd:int Dest, int PD, sim_fpu s1 // fsub.{s|d}{s|d}{s|d} void::function::do_fsub:int Dest, int PD, sim_fpu s1, sim_fpu s2 - sim_fpu ans = sim_fpu_sub (s1, s2); + sim_fpu ans; + sim_fpu_sub (&ans, &s1, &s2); TRACE_FPU3 (ans, s1, s2); set_fp_reg (_SD, Dest, ans, PD); 31.Dest,26.Source2,21.0b111110001,12.0,11.r,10.PD,8.P2,6.P1,4.Source1::f::fsub r diff --git a/sim/tic80/misc.c b/sim/tic80/misc.c index a741c484fd..beb0c68d9f 100644 --- a/sim/tic80/misc.c +++ b/sim/tic80/misc.c @@ -241,9 +241,9 @@ tic80_trace_fpu3 (SIM_DESC sd, itable[indx].file, itable[indx].line_nr, "fpu", "%-*s %*g %*g => %*g", tic80_size_name, itable[indx].name, - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1), - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2), - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (result)); + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&input1), + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&input2), + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&result)); } /* Trace the result of an FPU operation with 1 floating point input and a floating point output */ @@ -262,9 +262,9 @@ tic80_trace_fpu2 (SIM_DESC sd, itable[indx].file, itable[indx].line_nr, "fpu", "%-*s %*g %-*s => %*g", tic80_size_name, itable[indx].name, - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input), + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&input), SIZE_HEX + SIZE_DECIMAL + 3, "", - SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result)); + SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (&result)); } /* Trace the result of an FPU operation with 1 floating point input and a floating point output */ @@ -284,7 +284,7 @@ tic80_trace_fpu1 (SIM_DESC sd, tic80_size_name, itable[indx].name, SIZE_HEX + SIZE_DECIMAL + 3, "", SIZE_HEX + SIZE_DECIMAL + 3, "", - SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result)); + SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (&result)); } /* Trace the result of an FPU operation with 1 integer input and an integer output */ @@ -304,8 +304,8 @@ tic80_trace_fpu2i (SIM_DESC sd, itable[indx].file, itable[indx].line_nr, "fpu", "%-*s %*f %*f => 0x%.*lx %-*ld", tic80_size_name, itable[indx].name, - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1), - SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2), + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&input1), + SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (&input2), SIZE_HEX, result, SIZE_DECIMAL, (long)(signed32)result); }