Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [applied mips sim patch] better implementations of mul-acc ops.
@ 2002-06-07 20:07 cgd
       [not found] ` <mailpost.1023505630.3068@news-sj1-1>
  0 siblings, 1 reply; 3+ messages in thread
From: cgd @ 2002-06-07 20:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: cgd

[ tested in the same way as described in 
  http://sources.redhat.com/ml/gdb-patches/2002-06/msg00103.html, but
  with a mipsisa64-elf target hacked to use the -mips64 multilib. ]

2002-06-07  Chris Demetriou  <cgd@broadcom.com>
            Ed Satterthwaite  <ehs@broadcom.com>

	* cp1.c (inner_mac, fp_mac, inner_rsqrt, fp_inv_sqrt)
	(fp_rsqrt, fp_madd, fp_msub, fp_nmadd, fp_nmsub): New functions.
	* sim-main.h (fp_rsqrt, fp_madd, fp_msub, fp_nmadd)
	(fp_nmsub): New prototypes.
	(RSquareRoot, MultiplyAdd, MultiplySub, NegMultiplyAdd)
	(NegMultiplySub): New defines.
	* mips.igen (RSQRT.fmt): Use RSquareRoot().
	(MADD.D, MADD.S): Replace with...
	(MADD.fmt): New instruction.
	(MSUB.D, MSUB.S): Replace with...
	(MSUB.fmt): New instruction.
	(NMADD.D, NMADD.S): Replace with...
	(NMADD.fmt): New instruction.
	(NMSUB.D, MSUB.S): Replace with...
	(NMSUB.fmt): New instruction.

Index: cp1.c
===================================================================
RCS file: /cvs/src/src/sim/mips/cp1.c,v
retrieving revision 1.15
diff -u -p -r1.15 cp1.c
--- cp1.c	7 Jun 2002 22:55:49 -0000	1.15
+++ cp1.c	7 Jun 2002 23:12:24 -0000
@@ -672,6 +672,206 @@ fp_binary(sim_cpu *cpu,
   return result;
 }
 
+/* Common MAC code for single operands (.s or .d), defers setting FCSR.  */
+static sim_fpu_status
+inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
+	  unsigned64 op1,
+	  unsigned64 op2,
+	  unsigned64 op3,
+	  int scale,
+	  int negate,
+	  FP_formats fmt,
+	  sim_fpu_round round,
+	  sim_fpu_denorm denorm,
+	  unsigned64 *result)
+{
+  sim_fpu wop1;
+  sim_fpu wop2;
+  sim_fpu ans;
+  sim_fpu_status status = 0;
+  sim_fpu_status op_status;
+  unsigned64 temp = 0;
+
+  switch (fmt)
+    {
+    case fmt_single:
+      {
+	unsigned32 res;
+	sim_fpu_32to (&wop1, op1);
+	sim_fpu_32to (&wop2, op2);
+	status |= sim_fpu_mul (&ans, &wop1, &wop2);
+	if (scale != 0 && sim_fpu_is_number (&ans))  /* number or denorm */
+	  ans.normal_exp += scale;
+	status |= sim_fpu_round_32 (&ans, round, denorm);
+	wop1 = ans;
+        op_status = 0;
+	sim_fpu_32to (&wop2, op3);
+	op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
+	op_status |= sim_fpu_round_32 (&ans, round, denorm);
+	status |= op_status;
+	if (negate)
+	  {
+	    wop1 = ans;
+	    op_status = sim_fpu_neg (&ans, &wop1);
+	    op_status |= sim_fpu_round_32 (&ans, round, denorm);
+	    status |= op_status;
+	  }
+	sim_fpu_to32 (&res, &ans);
+	temp = res;
+	break;
+      }
+    case fmt_double:
+      {
+	unsigned64 res;
+	sim_fpu_64to (&wop1, op1);
+	sim_fpu_64to (&wop2, op2);
+	status |= sim_fpu_mul (&ans, &wop1, &wop2);
+	if (scale != 0 && sim_fpu_is_number (&ans))  /* number or denorm */
+	  ans.normal_exp += scale;
+	status |= sim_fpu_round_64 (&ans, round, denorm);
+	wop1 = ans;
+        op_status = 0;
+	sim_fpu_64to (&wop2, op3);
+	op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
+	op_status |= sim_fpu_round_64 (&ans, round, denorm);
+	status |= op_status;
+	if (negate)
+	  {
+	    wop1 = ans;
+	    op_status = sim_fpu_neg (&ans, &wop1);
+	    op_status |= sim_fpu_round_64 (&ans, round, denorm);
+	    status |= op_status;
+	  }
+	sim_fpu_to64 (&res, &ans);
+	temp = res;
+	break;
+      }
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+  *result = temp;
+  return status;
+}
+
+/* Common implementation of madd, nmadd, msub, nmsub that does
+   intermediate rounding per spec.  Also used for recip2 and rsqrt2,
+   which are transformed into equivalent nmsub operations.  The scale
+   argument is an adjustment to the exponent of the intermediate
+   product op1*op2.  It is currently non-zero for rsqrt2 (-1), which
+   requires an effective division by 2. */
+static unsigned64
+fp_mac(sim_cpu *cpu,
+       address_word cia,
+       int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
+       unsigned64 op1,
+       unsigned64 op2,
+       unsigned64 op3,
+       int scale,
+       int negate,
+       FP_formats fmt)
+{
+  sim_fpu_round round = rounding_mode (GETRM());
+  sim_fpu_denorm denorm = denorm_mode (cpu);
+  sim_fpu_status status = 0;
+  unsigned64 result = 0;
+
+  /* The format type has already been checked: */
+  switch (fmt)
+    {
+    case fmt_single:
+    case fmt_double:
+      status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
+			 negate, fmt, round, denorm, &result);
+      break;
+    default:
+      sim_io_eprintf (SD, "Bad switch\n");
+      abort ();
+    }
+
+  update_fcsr (cpu, cia, status);
+  return result;
+}
+
+/* Common rsqrt code for single operands (.s or .d), intermediate rounding.  */
+static sim_fpu_status
+inner_rsqrt(unsigned64 op1,
+	    FP_formats fmt,
+	    sim_fpu_round round,
+	    sim_fpu_denorm denorm,
+	    unsigned64 *result)
+{
+  sim_fpu wop1;
+  sim_fpu ans;
+  sim_fpu_status status = 0;
+  sim_fpu_status op_status;
+  unsigned64 temp = 0;
+
+  switch (fmt)
+    {
+    case fmt_single:
+      {
+	unsigned32 res;
+	sim_fpu_32to (&wop1, op1);
+	status |= sim_fpu_sqrt (&ans, &wop1);
+	status |= sim_fpu_round_32 (&ans, status, round);
+	wop1 = ans;
+	op_status = sim_fpu_inv (&ans, &wop1);
+	op_status |= sim_fpu_round_32 (&ans, round, denorm);
+	sim_fpu_to32 (&res, &ans);
+	temp = res;
+	status |= op_status;
+	break;
+      }
+    case fmt_double:
+      {
+	unsigned64 res;
+	sim_fpu_64to (&wop1, op1);
+	status |= sim_fpu_sqrt (&ans, &wop1);
+	status |= sim_fpu_round_64 (&ans, round, denorm);
+	wop1 = ans;
+	op_status = sim_fpu_inv (&ans, &wop1);
+	op_status |= sim_fpu_round_64 (&ans, round, denorm);
+	sim_fpu_to64 (&res, &ans);
+	temp = res;
+	status |= op_status;
+	break;
+      }
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+  *result = temp;
+  return status;
+}
+
+static unsigned64
+fp_inv_sqrt(sim_cpu *cpu,
+	    address_word cia,
+	    unsigned64 op1,
+	    FP_formats fmt)
+{
+  sim_fpu_round round = rounding_mode (GETRM());
+  sim_fpu_round denorm = denorm_mode (cpu);
+  sim_fpu_status status = 0;
+  unsigned64 result = 0;
+
+  /* The format type has already been checked: */
+  switch (fmt)
+    {
+    case fmt_single:
+    case fmt_double:
+      status = inner_rsqrt (op1, fmt, round, denorm, &result);
+      break;
+    default:
+      sim_io_eprintf (SD, "Bad switch\n");
+      abort ();
+    }
+
+  update_fcsr (cpu, cia, status);
+  return result;
+}
+
 
 unsigned64
 fp_abs(sim_cpu *cpu,
@@ -747,6 +947,59 @@ fp_sqrt(sim_cpu *cpu,
         FP_formats fmt)
 {
   return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
+}
+
+unsigned64
+fp_rsqrt(sim_cpu *cpu,
+         address_word cia,
+         unsigned64 op,
+         FP_formats fmt)
+{
+  return fp_inv_sqrt(cpu, cia, op, fmt);
+}
+
+unsigned64
+fp_madd(sim_cpu *cpu,
+        address_word cia,
+        unsigned64 op1,
+        unsigned64 op2,
+        unsigned64 op3,
+        FP_formats fmt)
+{
+  return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
+}
+
+unsigned64
+fp_msub(sim_cpu *cpu,
+        address_word cia,
+        unsigned64 op1,
+        unsigned64 op2,
+        unsigned64 op3,
+        FP_formats fmt)
+{
+  return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
+}
+
+unsigned64
+fp_nmadd(sim_cpu *cpu,
+         address_word cia,
+         unsigned64 op1,
+         unsigned64 op2,
+         unsigned64 op3,
+         FP_formats fmt)
+{
+  return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
+}
+
+unsigned64
+fp_nmsub(sim_cpu *cpu,
+         address_word cia,
+         unsigned64 op1,
+         unsigned64 op2,
+         unsigned64 op3,
+         FP_formats fmt)
+{
+  return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
 }
 
 
Index: mips.igen
===================================================================
RCS file: /cvs/src/src/sim/mips/mips.igen,v
retrieving revision 1.42
diff -u -p -r1.42 mips.igen
--- mips.igen	7 Jun 2002 00:13:24 -0000	1.42
+++ mips.igen	7 Jun 2002 23:12:24 -0000
@@ -4198,34 +4198,19 @@
 
 
 
-//
-// FIXME: Not correct for mips*
-//
-010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D
-"madd.d f<FD>, f<FR>, f<FS>, f<FT>"
-*mipsIV:
-*mipsV:
-*mips64:
-*vr5000:
-{
-  check_fpu (SD_);
-  {
-    StoreFPR(FD,fmt_double,Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double));
-  }
-}
-
-
-010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S
-"madd.s f<FD>, f<FR>, f<FS>, f<FT>"
+010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT:COP1X:64,f::MADD.fmt
+"madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
 *mipsIV:
 *mipsV:
 *mips64:
 *vr5000:
 {
+  int fmt = FMT;
   check_fpu (SD_);
-  {
-    StoreFPR(FD,fmt_single,Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single));
-  }
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0); 
+  StoreFPR (FD, fmt, MultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
+				  ValueFPR (FR, fmt), fmt));
 }
 
 
@@ -4354,29 +4339,19 @@
 }
 
 
-// MSUB.fmt
-010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32,f::MSUB.D
-"msub.d f<FD>, f<FR>, f<FS>, f<FT>"
-*mipsIV:
-*mipsV:
-*mips64:
-*vr5000:
-{
-  check_fpu (SD_);
-  StoreFPR(FD,fmt_double,Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double));
-}
-
-
-// MSUB.fmt
-010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32,f::MSUB.S
-"msub.s f<FD>, f<FR>, f<FS>, f<FT>"
+010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT:COP1X:64,f::MSUB.fmt
+"msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
 *mipsIV:
 *mipsV:
 *mips64:
 *vr5000:
 {
+  int fmt = FMT;
   check_fpu (SD_);
-  StoreFPR(FD,fmt_single,Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single));
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (FD, fmt, MultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
+				  ValueFPR (FR, fmt), fmt));
 }
 
 
@@ -4449,55 +4424,35 @@
 }
 
 
-// NMADD.fmt
-010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32,f::NMADD.D
-"nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
-*mipsIV:
-*mipsV:
-*mips64:
-*vr5000:
-{
-  check_fpu (SD_);
-  StoreFPR(FD,fmt_double,Negate(Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double));
-}
-
-
-// NMADD.fmt
-010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32,f::NMADD.S
-"nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
-*mipsIV:
-*mipsV:
-*mips64:
-*vr5000:
-{
-  check_fpu (SD_);
-  StoreFPR(FD,fmt_single,Negate(Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single));
-}
-
-
-// NMSUB.fmt
-010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32,f::NMSUB.D
-"nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
+010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT:COP1X:64,f::NMADD.fmt
+"nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
 *mipsIV:
 *mipsV:
 *mips64:
 *vr5000:
 {
+  int fmt = FMT;
   check_fpu (SD_);
-  StoreFPR(FD,fmt_double,Negate(Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double));
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (FD, fmt, NegMultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
+				     ValueFPR (FR, fmt), fmt));
 }
 
 
-// NMSUB.fmt
-010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32,f::NMSUB.S
-"nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
+010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT:COP1X:64,f::NMSUB.fmt
+"nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
 *mipsIV:
 *mipsV:
 *mips64:
 *vr5000:
 {
+  int fmt = FMT;
   check_fpu (SD_);
-  StoreFPR(FD,fmt_single,Negate(Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single));
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (FD, fmt, NegMultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt),
+				     ValueFPR (FR, fmt), fmt));
 }
 
 
@@ -4579,7 +4534,7 @@
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Recip(SquareRoot(ValueFPR(FS,fmt),fmt),fmt));
+  StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt));
 }
 
 
Index: sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/mips/sim-main.h,v
retrieving revision 1.20
diff -u -p -r1.20 sim-main.h
--- sim-main.h	7 Jun 2002 00:13:24 -0000	1.20
+++ sim-main.h	7 Jun 2002 23:12:24 -0000
@@ -704,6 +704,20 @@ unsigned64 fp_recip (SIM_STATE, unsigned
 #define Recip(op,fmt) fp_recip(SIM_ARGS, op, fmt)
 unsigned64 fp_sqrt (SIM_STATE, unsigned64 op, FP_formats fmt);
 #define SquareRoot(op,fmt) fp_sqrt(SIM_ARGS, op, fmt)
+unsigned64 fp_rsqrt (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define RSquareRoot(op,fmt) fp_rsqrt(SIM_ARGS, op, fmt)
+unsigned64 fp_madd (SIM_STATE, unsigned64 op1, unsigned64 op2,
+		    unsigned64 op3, FP_formats fmt);
+#define MultiplyAdd(op1,op2,op3,fmt) fp_madd(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_msub (SIM_STATE, unsigned64 op1, unsigned64 op2,
+		    unsigned64 op3, FP_formats fmt);
+#define MultiplySub(op1,op2,op3,fmt) fp_msub(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_nmadd (SIM_STATE, unsigned64 op1, unsigned64 op2,
+		     unsigned64 op3, FP_formats fmt);
+#define NegMultiplyAdd(op1,op2,op3,fmt) fp_nmadd(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_nmsub (SIM_STATE, unsigned64 op1, unsigned64 op2,
+		     unsigned64 op3, FP_formats fmt);
+#define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt)
 unsigned64 convert (SIM_STATE, int rm, unsigned64 op, FP_formats from, FP_formats to);
 #define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to)
 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [applied mips sim patch] better implementations of mul-acc ops.
       [not found] ` <mailpost.1023505630.3068@news-sj1-1>
@ 2002-06-08  0:18   ` cgd
  2002-06-08 23:22     ` cgd
  0 siblings, 1 reply; 3+ messages in thread
From: cgd @ 2002-06-08  0:18 UTC (permalink / raw)
  To: gdb-patches

At Sat, 8 Jun 2002 03:07:10 +0000 (UTC), cgd@broadcom.com wrote:
> [ tested in the same way as described in 
>   http://sources.redhat.com/ml/gdb-patches/2002-06/msg00103.html, but
>   with a mipsisa64-elf target hacked to use the -mips64 multilib. ]

After checking it in (of course!), I looked at the test results some
more, and found that, before and after, none of the tests which use
the {,n}m{add,sub}.fmt instructions actually passed either before or
after.

Running with a simulator from a month ago but sources otherwise the
same, they seem to work...

So, i've got some bug-hunting to do.


Not worried about it screwing people up, because mipsisa64-elf isn't
even a supported in gcc right now.  8-)


chris


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [applied mips sim patch] better implementations of mul-acc ops.
  2002-06-08  0:18   ` cgd
@ 2002-06-08 23:22     ` cgd
  0 siblings, 0 replies; 3+ messages in thread
From: cgd @ 2002-06-08 23:22 UTC (permalink / raw)
  To: gdb-patches

At 08 Jun 2002 00:18:28 -0700, Chris G. Demetriou wrote:
> After checking it in (of course!), I looked at the test results some
> more, and found that, before and after, none of the tests which use
> the {,n}m{add,sub}.fmt instructions actually passed either before or
> after.
> 
> Running with a simulator from a month ago but sources otherwise the
> same, they seem to work...

That wasn't actually true.  Different tests passed, but not the ones
in question AFAICT.  (The different tests that passed now fail due to
the unpredictable checking added to the MIPS32 & MIPS64 simulators.)

The cause of the problem with FP is discussed in:

	http://gcc.gnu.org/ml/gcc/2002-06/msg00601.html



chris


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-06-09  6:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-07 20:07 [applied mips sim patch] better implementations of mul-acc ops cgd
     [not found] ` <mailpost.1023505630.3068@news-sj1-1>
2002-06-08  0:18   ` cgd
2002-06-08 23:22     ` cgd

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox