Fix double conversion problem.

This commit is contained in:
Andrew Cagney 1997-05-15 02:21:11 +00:00
parent 2310e3c2b5
commit aa3a044769
4 changed files with 76 additions and 45 deletions

View file

@ -1,4 +1,17 @@
Thu May 15 10:14:06 1997 Andrew Cagney <cagney@b1.cygnus.com> Thu May 15 11:45:37 1997 Andrew Cagney <cagney@b1.cygnus.com>
* insns (get_fp_reg): Use sim_fpu_u32to to perform unsigned
conversion.
(do_fcmp): Update to use new fp compare functions. Make reg nr arg
instead of reg. Stops fp overflow.
(get_fp_reg): Assume val is valid when reg == 0.
(set_fp_reg): Fix double conversion.
* misc.c (tic80_trace_fpu1): New function, trace simple fp op.
* insns (do_frnd): Add tracing.
* cpu.h (TRACE_FPU1): Ditto.
* insns (do_trap): Printf formatting. * insns (do_trap): Printf formatting.

View file

@ -161,12 +161,10 @@ struct _sim_cpu {
extern char *tic80_trace_alu3 PARAMS ((int, unsigned32, unsigned32, unsigned32)); extern char *tic80_trace_alu3 PARAMS ((int, unsigned32, unsigned32, unsigned32));
extern char *tic80_trace_alu2 PARAMS ((int, unsigned32, unsigned32)); extern char *tic80_trace_alu2 PARAMS ((int, unsigned32, unsigned32));
extern char *tic80_trace_shift PARAMS ((int, unsigned32, unsigned32, int, int, int, int, int)); extern char *tic80_trace_shift PARAMS ((int, unsigned32, unsigned32, int, int, int, int, int));
extern void tic80_trace_fpu3 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, extern void tic80_trace_fpu3 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, sim_fpu, sim_fpu, sim_fpu));
sim_fpu, sim_fpu, sim_fpu)); extern void tic80_trace_fpu2 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, sim_fpu, sim_fpu));
extern void tic80_trace_fpu2 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, extern void tic80_trace_fpu1 PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, sim_fpu));
sim_fpu, sim_fpu)); extern void tic80_trace_fpu2i PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int, unsigned32, sim_fpu, sim_fpu));
extern void tic80_trace_fpu2i PARAMS ((SIM_DESC, sim_cpu *, sim_cia, int,
unsigned32, sim_fpu, sim_fpu));
extern char *tic80_trace_nop PARAMS ((int)); extern char *tic80_trace_nop PARAMS ((int));
extern char *tic80_trace_sink1 PARAMS ((int, unsigned32)); extern char *tic80_trace_sink1 PARAMS ((int, unsigned32));
extern char *tic80_trace_sink2 PARAMS ((int, unsigned32, unsigned32)); extern char *tic80_trace_sink2 PARAMS ((int, unsigned32, unsigned32));
@ -217,6 +215,13 @@ do { \
} \ } \
} while (0) } while (0)
#define TRACE_FPU1(indx, result) \
do { \
if (TRACE_FPU_P (CPU)) { \
tic80_trace_fpu1 (SD, CPU, cia, indx, result); \
} \
} while (0)
#define TRACE_FPU2I(indx, result, input1, input2) \ #define TRACE_FPU2I(indx, result, input1, input2) \
do { \ do { \
if (TRACE_FPU_P (CPU)) { \ if (TRACE_FPU_P (CPU)) { \

View file

@ -396,13 +396,10 @@ sim_fpu::function::get_fp_reg:int reg, unsigned32 val, int precision
switch (precision) switch (precision)
{ {
case 0: /* single */ case 0: /* single */
if (reg == 0)
return sim_fpu_32to (0);
else
return sim_fpu_32to (val); return sim_fpu_32to (val);
case 1: /* double */ case 1: /* double */
if (reg < 0) if (reg < 0)
return sim_fpu_32to (val); engine_error (SD, CPU, cia, "DP immediate invalid");
if (reg & 1) if (reg & 1)
engine_error (SD, CPU, cia, "DP FP register must be even"); engine_error (SD, CPU, cia, "DP FP register must be even");
if (reg <= 1) if (reg <= 1)
@ -410,19 +407,13 @@ sim_fpu::function::get_fp_reg:int reg, unsigned32 val, int precision
return sim_fpu_64to (INSERTED64 (GPR(reg + 1), 63, 32) return sim_fpu_64to (INSERTED64 (GPR(reg + 1), 63, 32)
| INSERTED64 (GPR(reg), 31, 0)); | INSERTED64 (GPR(reg), 31, 0));
case 2: /* 32 bit signed integer */ case 2: /* 32 bit signed integer */
if (reg == 0) return sim_fpu_i32to (val);
return sim_fpu_32to (0);
else
return sim_fpu_d2 ((signed32) val);
case 3: /* 32 bit unsigned integer */ case 3: /* 32 bit unsigned integer */
if (reg == 0) return sim_fpu_u32to (val);
return sim_fpu_32to (0);
else
return sim_fpu_d2 ((unsigned32) val);
default: default:
engine_error (SD, CPU, cia, "Unsupported FP precision"); engine_error (SD, CPU, cia, "Unsupported FP precision");
} }
return sim_fpu_32to (0); return sim_fpu_i32to (0);
void::function::set_fp_reg:int Dest, sim_fpu val, int PD void::function::set_fp_reg:int Dest, sim_fpu val, int PD
switch (PD) switch (PD)
{ {
@ -433,13 +424,13 @@ void::function::set_fp_reg:int Dest, sim_fpu val, int PD
} }
case 1: /* double */ case 1: /* double */
{ {
unsigned64 v = *(unsigned64*) &val; unsigned64 v = sim_fpu_to64 (val);
if (Dest & 1) if (Dest & 1)
engine_error (SD, CPU, cia, "DP FP Dest register must be even"); engine_error (SD, CPU, cia, "DP FP Dest register must be even");
if (Dest <= 1) if (Dest <= 1)
engine_error (SD, CPU, cia, "DP FP Dest register must be >= 2"); engine_error (SD, CPU, cia, "DP FP Dest register must be >= 2");
GPR (Dest) = EXTRACTED64 (v, 21, 0); GPR (Dest + 0) = VL4_8 (v);
GPR (Dest + 1) = EXTRACTED64 (v, 63, 32); GPR (Dest + 1) = VH4_8 (v);
break; break;
} }
case 2: /* signed */ case 2: /* signed */
@ -471,36 +462,37 @@ void::function::do_fadd:int Dest, int PD, sim_fpu s1, sim_fpu s2
// fcmp.{s|d}{s|d}{s|d} // fcmp.{s|d}{s|d}{s|d}
void::function::do_fcmp:unsigned32 *rDest, sim_fpu s1, sim_fpu s2 void::function::do_fcmp:int Dest, sim_fpu s1, sim_fpu s2
*rDest = 0; 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))
*rDest |= BIT32 (30); result |= BIT32 (30);
else else
{ {
*rDest |= BIT32 (31); result |= BIT32 (31);
if (sim_fpu_cmp (s1, s2) == 0) *rDest |= BIT32(20); if (sim_fpu_is_eq (s1, s2)) result |= BIT32(20);
if (sim_fpu_cmp (s1, s2) != 0) *rDest |= BIT32(21); if (sim_fpu_is_ne (s1, s2)) result |= BIT32(21);
if (sim_fpu_cmp (s1, s2) > 0) *rDest |= BIT32(22); if (sim_fpu_is_gt (s1, s2)) result |= BIT32(22);
if (sim_fpu_cmp (s1, s2) <= 0) *rDest |= BIT32(23); if (sim_fpu_is_le (s1, s2)) result |= BIT32(23);
if (sim_fpu_cmp (s1, s2) < 0) *rDest |= BIT32(24); if (sim_fpu_is_lt (s1, s2)) result |= BIT32(24);
if (sim_fpu_cmp (s1, s2) >= 0) *rDest |= BIT32(25); if (sim_fpu_is_ge (s1, s2)) result |= BIT32(25);
if (sim_fpu_cmp (s1, sim_fpu_32to (0)) < 0 if (sim_fpu_is_lt (s1, sim_fpu_i32to (0))
|| sim_fpu_cmp (s1, s2) > 0) *rDest |= BIT32(26); || sim_fpu_is_gt (s1, s2)) result |= BIT32(26);
if (sim_fpu_cmp (sim_fpu_32to (0), s1) < 0 if (sim_fpu_is_lt (sim_fpu_i32to (0), s1)
&& sim_fpu_cmp (s1, s2) < 0) *rDest |= BIT32(27); && sim_fpu_is_lt (s1, s2)) result |= BIT32(27);
if (sim_fpu_cmp (sim_fpu_32to (0), s1) <= 0 if (sim_fpu_is_le (sim_fpu_i32to (0), s1)
&& sim_fpu_cmp (s1, s2) <= 0) *rDest |= BIT32(28); && sim_fpu_is_le (s1, s2)) result |= BIT32(28);
if (sim_fpu_cmp (s1, sim_fpu_32to (0)) <= 0 if (sim_fpu_is_le (s1, sim_fpu_i32to (0))
|| sim_fpu_cmp (s1, s2) >= 0) *rDest |= BIT32(29); || sim_fpu_is_ge (s1, s2)) result |= BIT32(29);
} }
TRACE_FPU2I (MY_INDEX, *rDest, s1, s2); GPR (Dest) = result;
TRACE_FPU2I (MY_INDEX, result, s1, s2);
31.Dest,26.Source2,21.0b111110101,12.0,11./,10.0,8.P2,6.P1,4.Source1::f::fcmp r 31.Dest,26.Source2,21.0b111110101,12.0,11./,10.0,8.P2,6.P1,4.Source1::f::fcmp r
do_fcmp (_SD, rDest, do_fcmp (_SD, Dest,
get_fp_reg (_SD, Source1, rSource1, P1), get_fp_reg (_SD, Source1, rSource1, P1),
get_fp_reg (_SD, Source2, rSource2, P2)); get_fp_reg (_SD, Source2, rSource2, P2));
31.Dest,26.Source2,21.0b111110101,12.1,11./,10.0,8.P2,6.P1,4./::f::fcmp l 31.Dest,26.Source2,21.0b111110101,12.1,11./,10.0,8.P2,6.P1,4./::f::fcmp l
long_immediate (SinglePrecisionFloatingPoint); long_immediate (SinglePrecisionFloatingPoint);
do_fcmp (_SD, rDest, do_fcmp (_SD, Dest,
get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1), get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
get_fp_reg (_SD, Source2, rSource2, P2)); get_fp_reg (_SD, Source2, rSource2, P2));
@ -541,6 +533,7 @@ void::function::do_fmpy:int Dest, int PD, sim_fpu s1, sim_fpu s2
// frndm.{s|d|i|u}{s|d|i|u}{s|d|i|u} // frndm.{s|d|i|u}{s|d|i|u}{s|d|i|u}
void::function::do_frnd:int Dest, int PD, sim_fpu s1 void::function::do_frnd:int Dest, int PD, sim_fpu s1
set_fp_reg (_SD, Dest, s1, PD); set_fp_reg (_SD, Dest, s1, PD);
TRACE_FPU1 (MY_INDEX, s1);
31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b11,6.P1,4.Source::f::frndm r 31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b11,6.P1,4.Source::f::frndm r
do_frnd (_SD, Dest, PD, do_frnd (_SD, Dest, PD,
get_fp_reg (_SD, Source, rSource, P1)); get_fp_reg (_SD, Source, rSource, P1));

View file

@ -267,6 +267,26 @@ tic80_trace_fpu2 (SIM_DESC sd,
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 */
void
tic80_trace_fpu1 (SIM_DESC sd,
sim_cpu *cpu,
sim_cia cia,
int indx,
sim_fpu result)
{
if (!tic80_size_name)
tic80_init_trace ();
trace_one_insn (sd, cpu, cia.ip, 1,
itable[indx].file, itable[indx].line_nr, "fpu",
"%-*s %-*s %-*s => %*g",
tic80_size_name, itable[indx].name,
SIZE_HEX + SIZE_DECIMAL + 3, "",
SIZE_HEX + SIZE_DECIMAL + 3, "",
SIZE_HEX + SIZE_DECIMAL, sim_fpu_2d (result));
}
/* Trace the result of an FPU operation with 1 integer input and an integer output */ /* Trace the result of an FPU operation with 1 integer input and an integer output */
void void
tic80_trace_fpu2i (SIM_DESC sd, tic80_trace_fpu2i (SIM_DESC sd,