This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[applied mips sim patch] Rework FP comparisons, reg moves.


Just applied the following.  Tested by comparing check-gcc test
results for:

	mips-elf (hacked to configure the sim to use a mipsI machine model)
	mips64-elf (hacked to use mipsIII)
	mipsisa32-elf

before and after (and, for good measure to re-verify i'd not broken
anything else recently, from a month ago).

the use of the hacked models was so that i could actually get coverage
on the older-model instruction descriptions.  the compilers for
mips-elf and mips64-elf build binaries for the MIPS I and MIPS III
ISAs, respectively, but by default the sims for those targets are
built for MIPS IV.  There have been significant changes between the
three ISAs tested (well, and others, but using the above three give
good coverage of the affected instructions).

Doing this testing, I find that there are some tests, compiled for
MIPS I, which fail on a sim configured for the mipsI machine but which
pass on the mipsIII machine.  This indicates to me that the simulation
of the older instructions may have problems, or the code generation in
the compiler doesn't adeqately take care to avoid certain hazards
present in the older ISAs.  Something to investigate.  However, the
results before and after were the same, so I know this patch doesn't
break anything.  8-)


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

	* cp1.h: New file.
	* sim-main.h: Include cp1.h.
	(SETFCC, GETFCC, IR, UF, OF, DX, IO, UO, FP_FLAGS, FP_ENABLE)
	(FP_CAUSE, GETFS, FP_RM_NEAREST, FP_RM_TOZERO, FP_RM_TOPINF)
	(FP_RM_TOMINF, GETRM): Remove.  Moved to cp1.h.
	(FP_FS, FP_MASK_RM, FP_SH_RM, Nan, Less, Equal): Remove.
	(value_fcr, store_fcr, test_fcsr, fp_cmp): New prototypes.
	(ValueFCR, StoreFCR, TestFCSR, Compare): New macros.
	* cp1.c: Don't include sim-fpu.h; already included by
	sim-main.h.  Clean up formatting of some comments.
	(NaN, Equal, Less): Remove.
	(test_fcsr, value_fcr, store_fcr, update_fcsr, fp_test)
	(fp_cmp): New functions.
	* mips.igen (do_c_cond_fmt): Remove.
	(C.cond.fmta, C.cond.fmtb): Replace uses of do_c_cond_fmt_a with
	Compare.  Add result tracing.
	(CxC1): Remove, replace with...
	(CFC1a, CFC1b, CFC1c, CTC1a, CTC1b, CTC1c): New instructions.
	(DMxC1): Remove, replace with...
	(DMFC1a, DMFC1b, DMTC1a, DMTC1b): New instructions.
	(MxC1): Remove, replace with... 
	(MFC1a, MFC1b, MTC1a, MTC1b): New instructions.  

Index: cp1.c
===================================================================
RCS file: /cvs/src/src/sim/mips/cp1.c,v
retrieving revision 1.11
diff -u -p -r1.11 cp1.c
--- cp1.c	4 Jun 2002 16:35:24 -0000	1.11
+++ cp1.c	7 Jun 2002 00:12:59 -0000
@@ -40,7 +40,6 @@ with this program; if not, write to the 
 */
 
 #include "sim-main.h"
-#include "sim-fpu.h"
 
 /* Within cp1.c we refer to sim_cpu directly.  */
 #define CPU cpu
@@ -313,77 +312,163 @@ store_fpr (sim_cpu *cpu,
   return;
 }
 
-int
-NaN (op, fmt)
-     uword64 op;
-     FP_formats fmt;
+
+/* CP1 control/status registers */
+
+void
+test_fcsr (sim_cpu *cpu,
+	   address_word cia)
 {
-  int boolean = 0;
-  switch (fmt)
+  unsigned int cause;
+
+  cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
+  if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
+      || (cause & (1 << UO)))
     {
-    case fmt_single:
-    case fmt_word:
-      {
-	sim_fpu wop;
-	sim_fpu_32to (&wop, op);
-	boolean = sim_fpu_is_nan (&wop);
-	break;
-      }
-    case fmt_double:
-    case fmt_long:
-      {
-	sim_fpu wop;
-	sim_fpu_64to (&wop, op);
-	boolean = sim_fpu_is_nan (&wop);
-	break;
-      }
-    default:
-      fprintf (stderr, "Bad switch\n");
-      abort ();
+      SignalExceptionFPE();
     }
+}
 
-#ifdef DEBUG
-  printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
-	  boolean, pr_addr (op), fpu_format_name (fmt));
-#endif /* DEBUG */
+unsigned_word
+value_fcr(sim_cpu *cpu,
+	  address_word cia,
+	  int fcr)
+{
+  unsigned32 value = 0;
+
+  switch (fcr)
+    {
+    case 0:  /* FP Implementation and Revision Register */
+      value = FCR0;
+      break;
+    case 25:  /* FP Condition Codes Register */
+      value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
+      value = (value & 0x1) | (value >> 1);   /* close FCC gap */
+      break;
+    case 26:  /* FP Exceptions Register */
+      value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
+      break;
+    case 28:  /* FP Enables Register */
+      value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
+      if (FCR31 & fcsr_FS)
+	value |= 0x4;                        /* nonstandard FS bit */
+      break;
+    case 31:  /* FP Control/Status Register */
+      value = FCR31 & ~fcsr_ZERO_mask;
+      break;
+    }
 
-  return (boolean);
+  return (EXTEND32 (value));
 }
 
-int
-Less (op1, op2, fmt)
-     uword64 op1;
-     uword64 op2;
-     FP_formats fmt;
+void
+store_fcr(sim_cpu *cpu,
+	  address_word cia,
+	  int fcr,
+	  unsigned_word value)
 {
-  int boolean = 0;
+  unsigned32 v;
 
-  /* Argument checking already performed by the FPCOMPARE code */
+  v = VL4_8(value);
+  switch (fcr)
+    {
+    case 25:  /* FP Condition Codes Register */
+      v = (v << 1) | (v & 0x1);             /* adjust for FCC gap */
+      FCR31 &= ~fcsr_FCC_mask;
+      FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
+      break;
+    case 26:  /* FP Exceptions Register */
+      FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
+      FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
+      test_fcsr(cpu, cia);
+      break;
+    case 28:  /* FP Enables Register */
+      if (v & 0x4)                         /* nonstandard FS bit */
+	v |= fcsr_FS;
+      else
+	v &= ~fcsr_FS;
+      FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
+      FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
+      test_fcsr(cpu, cia);
+      break;
+    case 31:  /* FP Control/Status Register */
+      FCR31 = v & ~fcsr_ZERO_mask;
+      test_fcsr(cpu, cia);
+      break;
+    }
+}
 
-#ifdef DEBUG
-  printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
-	  fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
-#endif /* DEBUG */
+void
+update_fcsr (sim_cpu *cpu,
+	     address_word cia,
+	     sim_fpu_status status)
+{
+  FCSR &= ~fcsr_CAUSE_mask;
+
+  if (status != 0)
+    {
+      unsigned int cause = 0;
+
+      /* map between sim_fpu codes and MIPS FCSR */
+      if (status & (sim_fpu_status_invalid_snan
+		    | sim_fpu_status_invalid_isi
+		    | sim_fpu_status_invalid_idi
+		    | sim_fpu_status_invalid_zdz
+		    | sim_fpu_status_invalid_imz
+		    | sim_fpu_status_invalid_cmp
+		    | sim_fpu_status_invalid_sqrt
+		    | sim_fpu_status_invalid_cvi))
+	cause |= (1 << IO);
+      if (status & sim_fpu_status_invalid_div0)
+	cause |= (1 << DZ);
+      if (status & sim_fpu_status_overflow)
+	cause |= (1 << OF);
+      if (status & sim_fpu_status_underflow)
+	cause |= (1 << UF);
+      if (status & sim_fpu_status_inexact)
+	cause |= (1 << IR);
+#if 0 /* Not yet.  */
+      /* Implicit clearing of other bits by unimplemented done by callers. */
+      if (status & sim_fpu_status_unimplemented)
+	cause |= (1 << UO);
+#endif
+
+      FCSR |= (cause << fcsr_CAUSE_shift);
+      test_fcsr (cpu, cia);
+      FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
+    }
+  return;
+}
+
+
+/* Comparison operations.  */
+
+static sim_fpu_status
+fp_test(unsigned64 op1,
+	unsigned64 op2,
+	FP_formats fmt,
+	int abs,
+	int cond,
+	int *condition)
+{
+  sim_fpu wop1;
+  sim_fpu wop2;
+  sim_fpu_status status = 0;
+  int  less, equal, unordered;
 
-  /* The format type should already have been checked:  */
+  /* The format type has already been checked:  */
   switch (fmt)
     {
     case fmt_single:
       {
-	sim_fpu wop1;
-	sim_fpu wop2;
 	sim_fpu_32to (&wop1, op1);
 	sim_fpu_32to (&wop2, op2);
-	boolean = sim_fpu_is_lt (&wop1, &wop2);
 	break;
       }
     case fmt_double:
       {
-	sim_fpu wop1;
-	sim_fpu wop2;
 	sim_fpu_64to (&wop1, op1);
 	sim_fpu_64to (&wop2, op2);
-	boolean = sim_fpu_is_lt (&wop1, &wop2);
 	break;
       }
     default:
@@ -391,61 +476,60 @@ Less (op1, op2, fmt)
       abort ();
     }
 
-#ifdef DEBUG
-  printf ("DBG: Less: returning %d (format = %s)\n",
-	  boolean, fpu_format_name (fmt));
-#endif /* DEBUG */
-
-  return (boolean);
+  if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
+    {
+      if ((cond & (1 << 3)) ||
+	  sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
+	status = sim_fpu_status_invalid_snan;
+      less = 0;
+      equal = 0;
+      unordered = 1;
+    }
+  else
+    {
+      if (abs)
+	{
+	  status |= sim_fpu_abs (&wop1, &wop1);
+	  status |= sim_fpu_abs (&wop2, &wop2);
+	}
+      equal = sim_fpu_is_eq (&wop1, &wop2);
+      less = !equal && sim_fpu_is_lt (&wop1, &wop2);
+      unordered = 0;
+    }
+  *condition = (((cond & (1 << 2)) && less)
+		|| ((cond & (1 << 1)) && equal)
+		|| ((cond & (1 << 0)) && unordered));
+  return status;
 }
 
-int
-Equal (op1, op2, fmt)
-     uword64 op1;
-     uword64 op2;
-     FP_formats fmt;
+void
+fp_cmp(sim_cpu *cpu,
+       address_word cia,
+       unsigned64 op1,
+       unsigned64 op2,
+       FP_formats fmt,
+       int abs,
+       int cond,
+       int cc)
 {
-  int boolean = 0;
-
-  /* Argument checking already performed by the FPCOMPARE code */
-
-#ifdef DEBUG
-  printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
-	  fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
-#endif /* DEBUG */
+  sim_fpu_status status = 0;
 
-  /* The format type should already have been checked:  */
+  /* The format type should already have been checked: */
   switch (fmt)
     {
     case fmt_single:
-      {
-	sim_fpu wop1;
-	sim_fpu wop2;
-	sim_fpu_32to (&wop1, op1);
-	sim_fpu_32to (&wop2, op2);
-	boolean = sim_fpu_is_eq (&wop1, &wop2);
-	break;
-      }
     case fmt_double:
       {
-	sim_fpu wop1;
-	sim_fpu wop2;
-	sim_fpu_64to (&wop1, op1);
-	sim_fpu_64to (&wop2, op2);
-	boolean = sim_fpu_is_eq (&wop1, &wop2);
+	int result;
+	status = fp_test(op1, op2, fmt, abs, cond, &result);
+	update_fcsr (cpu, cia, status);
+	SETFCC (cc, result);
 	break;
       }
     default:
-      fprintf (stderr, "Bad switch\n");
+      sim_io_eprintf (SD, "Bad switch\n");
       abort ();
     }
-
-#ifdef DEBUG
-  printf ("DBG: Equal: returning %d (format = %s)\n",
-	  boolean, fpu_format_name (fmt));
-#endif /* DEBUG */
-
-  return (boolean);
 }
 
 
@@ -612,6 +696,8 @@ fp_sqrt(sim_cpu *cpu,
   return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
 }
 
+
+/* Conversion operations.  */
 
 uword64
 convert (sim_cpu *cpu,
Index: cp1.h
===================================================================
RCS file: cp1.h
diff -N cp1.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cp1.h	7 Jun 2002 00:12:59 -0000
@@ -0,0 +1,81 @@
+/*> cp1.h <*/
+/* MIPS Simulator FPU (CoProcessor 1) definitions.
+   Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
+   Derived from sim-main.h contributed by Cygnus Solutions,
+   modified substially by Broadcom Corporation (SiByte).
+
+This file is part of GDB, the GNU debugger.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef CP1_H
+#define CP1_H
+
+/* See sim-main.h for allocation of registers FCR0 and FCR31 (FCSR) 
+   in CPU state (struct sim_cpu), and for FPU functions.  */
+
+#define fcsr_FCC_mask      (0xFE800000)
+#define fcsr_FCC_shift     (23)
+#define	fcsr_FCC_bit(cc)   ((cc) == 0 ? 23 : (24 + (cc)))
+#define fcsr_FS            (1 << 24) /* MIPS III onwards : Flush to Zero */
+#define fcsr_ZERO_mask     (0x007C0000)
+#define fcsr_CAUSE_mask    (0x0003F000)
+#define fcsr_CAUSE_shift   (12)
+#define fcsr_ENABLES_mask  (0x00000F80)
+#define fcsr_ENABLES_shift (7)
+#define fcsr_FLAGS_mask    (0x0000007C)
+#define fcsr_FLAGS_shift   (2)
+#define fcsr_RM_mask       (0x00000003)
+#define fcsr_RM_shift      (0)
+
+
+/* Macros to update and retrieve the FCSR condition-code bits.  This
+   is complicated by the fact that there is a hole in the index range
+   of the bits within the FCSR register.  (Note that the number of bits
+   visible depends on the ISA in use, but that is handled elsewhere.)  */
+#define SETFCC(cc,v) \
+  do { \
+    (FCSR = ((FCSR & ~(1 << fcsr_FCC_bit(cc))) | ((v) << fcsr_FCC_bit(cc)))); \
+  } while (0)
+#define GETFCC(cc) ((FCSR & (1 << fcsr_FCC_bit(cc))) != 0 ? 1 : 0)
+
+
+/* Read flush-to-zero bit (not right-justified).  */
+#define GETFS()            ((int)(FCSR & fcsr_FS))
+
+
+/* FCSR flag bits definitions and access macros.  */
+#define IR            0   /* I: Inexact Result */
+#define UF            1   /* U: UnderFlow */
+#define OF            2   /* O: OverFlow */
+#define DZ            3   /* Z: Division by Zero */
+#define IO            4   /* V: Invalid Operation */
+#define UO            5   /* E: Unimplemented Operation (CAUSE field only) */
+
+#define FP_FLAGS(b)   (1 << ((b) + fcsr_FLAGS_shift))
+#define FP_ENABLE(b)  (1 << ((b) + fcsr_ENABLES_shift))
+#define FP_CAUSE(b)   (1 << ((b) + fcsr_CAUSE_shift))
+
+
+/* Rounding mode bit definitions and access macros.  */
+#define FP_RM_NEAREST 0   /* Round to nearest (Round).  */
+#define FP_RM_TOZERO  1   /* Round to zero (Trunc).  */
+#define FP_RM_TOPINF  2   /* Round to Plus infinity (Ceil).  */
+#define FP_RM_TOMINF  3   /* Round to Minus infinity (Floor).  */
+
+#define GETRM()       ((FCSR >> fcsr_RM_shift) & fcsr_RM_mask)
+
+
+#endif /* CP1_H */
Index: mips.igen
===================================================================
RCS file: /cvs/src/src/sim/mips/mips.igen,v
retrieving revision 1.41
diff -u -p -r1.41 mips.igen
--- mips.igen	4 Jun 2002 22:38:41 -0000	1.41
+++ mips.igen	7 Jun 2002 00:12:59 -0000
@@ -3747,45 +3747,6 @@
 }
 
 
-
-
-
-
-// C.EQ.S
-// C.EQ.D
-// ...
-
-:function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
-{
-  int less;
-  int equal;
-  int unordered;
-  int condition;
-  unsigned64 ofs = ValueFPR (fs, fmt);
-  unsigned64 oft = ValueFPR (ft, fmt);
-  if (NaN (ofs, fmt) || NaN (oft, fmt))
-    {
-      if (FCSR & FP_ENABLE (IO))
-	{
-	  FCSR |= FP_CAUSE (IO);
-	  SignalExceptionFPE ();
-	}
-      less = 0;
-      equal = 0;
-      unordered = 1;
-    }
-  else
-    {
-      less = Less (ofs, oft, fmt);
-      equal = Equal (ofs, oft, fmt);
-      unordered = 0;
-    }
-  condition = (((cond & (1 << 2)) && less)
-	       || ((cond & (1 << 1)) && equal)
-	       || ((cond & (1 << 0)) && unordered));
-  SETFCC (cc, condition);
-}
-
 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta
 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
 *mipsI:
@@ -3795,7 +3756,8 @@
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  do_c_cond_fmt (SD_, fmt, FT, FS, 0, COND, instruction_0);
+  Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0);
+  TRACE_ALU_RESULT (ValueFCR (31));
 }
 
 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb
@@ -3812,7 +3774,8 @@
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  do_c_cond_fmt (SD_, fmt, FT, FS, CC, COND, instruction_0);
+  Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, CC);
+  TRACE_ALU_RESULT (ValueFCR (31));
 }
 
 
@@ -3851,80 +3814,92 @@
 }
 
 
-// CFC1
-// CTC1
-010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32,f::CxC1
-"c%s<X>c1 r<RT>, f<FS>"
+010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a
+"cfc1 r<RT>, f<FS>"
 *mipsI:
 *mipsII:
 *mipsIII:
 {
   check_fpu (SD_);
-  if (X)
+  if (FS == 0)
+    PENDING_FILL (RT, EXTEND32 (FCR0));
+  else if (FS == 31)
+    PENDING_FILL (RT, EXTEND32 (FCR31));
+  /* else NOP */
+}
+
+010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b
+"cfc1 r<RT>, f<FS>"
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+  check_fpu (SD_);
+  if (FS == 0 || FS == 31)
     {
-      if (FS == 0)
-	PENDING_FILL(FCR0IDX,VL4_8(GPR[RT]));
-      else if (FS == 31)
-	PENDING_FILL(FCR31IDX,VL4_8(GPR[RT]));
-      /* else NOP */
-      PENDING_SCHED(FCSR, FCR31 & (1<<23), 1, 23);
-    }
-  else
-    { /* control from */
-      if (FS == 0)
- 	PENDING_FILL(RT, EXTEND32 (FCR0));
-      else if (FS == 31)
- 	PENDING_FILL(RT, EXTEND32 (FCR31));
-      /* else NOP */
+      unsigned_word  fcr = ValueFCR (FS);
+      TRACE_ALU_INPUT1 (fcr);
+      GPR[RT] = fcr;
     }
+  /* else NOP */
+  TRACE_ALU_RESULT (GPR[RT]);
 }
-010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32,f::CxC1
-"c%s<X>c1 r<RT>, f<FS>"
-*mipsIV:
+
+010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c
+"cfc1 r<RT>, f<FS>"
 *mipsV:
 *mips32:
 *mips64:
+{
+  check_fpu (SD_);
+  if (FS == 0 || FS == 25 || FS == 26 || FS == 28 || FS == 31)
+    {
+      unsigned_word  fcr = ValueFCR (FS);
+      TRACE_ALU_INPUT1 (fcr);
+      GPR[RT] = fcr;
+    }
+  /* else NOP */
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
+"ctc1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{
+  check_fpu (SD_);
+  if (FS == 31)
+    PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT]));
+  /* else NOP */
+}
+
+010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b
+"ctc1 r<RT>, f<FS>"
+*mipsIV:
 *vr4100:
 *vr5000:
 *r3900:
 {
   check_fpu (SD_);
-  if (X)
-    {
-      /* control to */
-      TRACE_ALU_INPUT1 (GPR[RT]);
-      if (FS == 0)
-	{
-	  FCR0 = VL4_8(GPR[RT]);
-	  TRACE_ALU_RESULT (FCR0);
-	}
-      else if (FS == 31)
-	{
-	  FCR31 = VL4_8(GPR[RT]);
-	  SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
-	  TRACE_ALU_RESULT (FCR31);
-	}
-      else
-	{
-	  TRACE_ALU_RESULT0 ();
-	}
-      /* else NOP */
-    }
-  else
-    { /* control from */
-      if (FS == 0)
-	{
-	  TRACE_ALU_INPUT1 (FCR0);
-	  GPR[RT] = EXTEND32 (FCR0);
-	}
-      else if (FS == 31)
-	{
-	  TRACE_ALU_INPUT1 (FCR31);
-	  GPR[RT] = EXTEND32 (FCR31);
-	}
-      TRACE_ALU_RESULT (GPR[RT]);
-      /* else NOP */
-    }
+  TRACE_ALU_INPUT1 (GPR[RT]);
+  if (FS == 31)
+    StoreFCR (FS, GPR[RT]);
+  /* else NOP */
+}
+
+010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c
+"ctc1 r<RT>, f<FS>"
+*mipsV:
+*mips32:
+*mips64:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT1 (GPR[RT]);
+  if (FS == 25 || FS == 26 || FS == 28 || FS == 31)
+      StoreFCR (FS, GPR[RT]);
+  /* else NOP */
 }
 
 
@@ -4047,42 +4022,25 @@
 }
 
 
-// DMFC1
-// DMTC1
-010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64,f::DMxC1
-"dm%s<X>c1 r<RT>, f<FS>"
+010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a
+"dmfc1 r<RT>, f<FS>"
 *mipsIII:
 {
+  unsigned64 v;
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (X)
-    {
-      if (SizeFGR() == 64)
-	PENDING_FILL((FS + FGR_BASE),GPR[RT]);
-      else if ((FS & 0x1) == 0)
-	{
-	  PENDING_FILL(((FS + 1) + FGR_BASE),VH4_8(GPR[RT]));
-	  PENDING_FILL((FS + FGR_BASE),VL4_8(GPR[RT]));
-	}
-    }
+  if (SizeFGR () == 64)
+    v = FGR[FS];
+  else if ((FS & 0x1) == 0)
+    v = SET64HI (FGR[FS+1]) | FGR[FS];
   else
-    {
-      if (SizeFGR() == 64)
-	PENDING_FILL(RT,FGR[FS]);
-      else if ((FS & 0x1) == 0)
-	PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
-      else
-	{
-	  if (STATE_VERBOSE_P(SD))
-	    sim_io_eprintf (SD,
-	      "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n",
-	      (long) CIA);
-	  PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
-	}
-    }
+    v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+  PENDING_FILL (RT, v);
+  TRACE_ALU_RESULT (v);
 }
-010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64,f::DMxC1
-"dm%s<X>c1 r<RT>, f<FS>"
+
+010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b
+"dmfc1 r<RT>, f<FS>"
 *mipsIV:
 *mipsV:
 *mips64:
@@ -4092,28 +4050,52 @@
 {
   check_fpu (SD_);
   check_u64 (SD_, instruction_0);
-  if (X)
-    {
-      if (SizeFGR() == 64)
-	StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
-      else if ((FS & 0x1) == 0)
-	StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
-    }
+  if (SizeFGR () == 64)
+    GPR[RT] = FGR[FS];
+  else if ((FS & 0x1) == 0)
+    GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
   else
+    GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+
+010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a
+"dmtc1 r<RT>, f<FS>"
+*mipsIII:
+{
+  unsigned64 v;
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  if (SizeFGR () == 64)
+    PENDING_FILL ((FS + FGR_BASE), GPR[RT]);
+  else if ((FS & 0x1) == 0)
     {
-      if (SizeFGR() == 64)
-	GPR[RT] = FGR[FS];
-      else if ((FS & 0x1) == 0)
-	GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
-      else
-	{
-	  if (STATE_VERBOSE_P(SD))
-	    sim_io_eprintf (SD,
-	      "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n",
-			    (long) CIA);
-	  GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
-	}
+      PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT]));
+      PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
     }
+  else
+    Unpredictable ();
+  TRACE_FP_RESULT (GPR[RT]);
+}
+
+010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b
+"dmtc1 r<RT>, f<FS>"
+*mipsIV:
+*mipsV:
+*mips64:
+*vr4100:
+*vr5000:
+*r3900:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  if (SizeFGR () == 64)
+    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
+  else if ((FS & 0x1) == 0)
+    StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
+  else
+    Unpredictable ();
 }
 
 
@@ -4247,33 +4229,21 @@
 }
 
 
-// MFC1
-// MTC1
-010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32,f::MxC1
-"m%s<X>c1 r<RT>, f<FS>"
+010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a
+"mfc1 r<RT>, f<FS>"
 *mipsI:
 *mipsII:
 *mipsIII:
 {
+  unsigned64 v;
   check_fpu (SD_);
-  if (X)
-    { /*MTC1*/
-      if (SizeFGR() == 64)
-	{
-	  if (STATE_VERBOSE_P(SD))
-	    sim_io_eprintf (SD,
-			    "Warning:  PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n",
-			    (long) CIA);
-	  PENDING_FILL ((FS + FGR_BASE), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
-	}
-      else
-	PENDING_FILL ((FS + FGR_BASE), VL4_8(GPR[RT]));
-    }
-  else /*MFC1*/
-    PENDING_FILL (RT, EXTEND32 (FGR[FS]));
+  v = EXTEND32 (FGR[FS]);
+  PENDING_FILL (RT, v);
+  TRACE_ALU_RESULT (v);
 }
-010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32,f::MxC1
-"m%s<X>c1 r<RT>, f<FS>"
+  
+010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b
+"mfc1 r<RT>, f<FS>"
 *mipsIV:
 *mipsV:
 *mips32:
@@ -4281,14 +4251,10 @@
 *vr4100:
 *vr5000:
 *r3900:
-{
-  int fs = FS;
+{ 
   check_fpu (SD_);
-  if (X)
-    /*MTC1*/
-    StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
-  else /*MFC1*/
-    GPR[RT] = EXTEND32 (FGR[FS]);
+  GPR[RT] = EXTEND32 (FGR[FS]);
+  TRACE_ALU_RESULT (GPR[RT]);
 }
 
 
@@ -4414,7 +4380,33 @@
 }
 
 
-// MTC1 see MxC1
+010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a
+"mtc1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{ 
+  check_fpu (SD_);
+  if (SizeFGR () == 64)
+    PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT])));
+  else
+    PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
+  TRACE_FP_RESULT (GPR[RT]);
+} 
+
+010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b
+"mtc1 r<RT>, f<FS>"
+*mipsIV:
+*mipsV:
+*mips32:
+*mips64:
+*vr4100:
+*vr5000:
+*r3900:
+{
+  check_fpu (SD_); 
+  StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
+}
 
 
 010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
Index: sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/mips/sim-main.h,v
retrieving revision 1.19
diff -u -p -r1.19 sim-main.h
--- sim-main.h	4 Jun 2002 22:38:41 -0000	1.19
+++ sim-main.h	7 Jun 2002 00:12:59 -0000
@@ -64,6 +64,7 @@ typedef unsigned64 uword64;
 /* Floating-point operations: */
 
 #include "sim-fpu.h"
+#include "cp1.h"
 
 /* FPU registers must be one of the following types. All other values
    are reserved (and undefined). */
@@ -80,17 +81,6 @@ typedef enum {
  fmt_uninterpreted_64 = 0x80000000U,
 } FP_formats;
 
-/* Macro to update FPSR condition-code field. This is complicated by
-   the fact that there is a hole in the index range of the bits within
-   the FCSR register. Also, the number of bits visible depends on the
-   MIPS ISA version being supported. */
-
-#define SETFCC(cc,v) {\
-  int bit = ((cc == 0) ? 23 : (24 + (cc)));\
-  FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
-}
-#define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1U : 0)
-
 /* This should be the COC1 value at the start of the preceding
    instruction: */
 #define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
@@ -104,36 +94,6 @@ typedef enum {
 #define SizeFGR() (WITH_TARGET_FLOATING_POINT_BITSIZE)
 #endif
 
-/* Standard FCRS bits: */
-#define IR (0) /* Inexact Result */
-#define UF (1) /* UnderFlow */
-#define OF (2) /* OverFlow */
-#define DZ (3) /* Division by Zero */
-#define IO (4) /* Invalid Operation */
-#define UO (5) /* Unimplemented Operation */
-
-/* Get masks for individual flags: */
-#if 1 /* SAFE version */
-#define FP_FLAGS(b)  (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
-#define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
-#define FP_CAUSE(b)  (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
-#else
-#define FP_FLAGS(b)  (1 << ((b) + 2))
-#define FP_ENABLE(b) (1 << ((b) + 7))
-#define FP_CAUSE(b)  (1 << ((b) + 12))
-#endif
-
-#define FP_FS         (1 << 24) /* MIPS III onwards : Flush to Zero */
-
-#define FP_MASK_RM    (0x3)
-#define FP_SH_RM      (0)
-#define FP_RM_NEAREST (0) /* Round to nearest        (Round) */
-#define FP_RM_TOZERO  (1) /* Round to zero           (Trunc) */
-#define FP_RM_TOPINF  (2) /* Round to Plus infinity  (Ceil) */
-#define FP_RM_TOMINF  (3) /* Round to Minus infinity (Floor) */
-#define GETRM()       (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
-
-
 
 
 
@@ -716,10 +676,18 @@ void store_fpr (SIM_STATE, int fpr, FP_f
 #define StoreFPR(FPR,FMT,VALUE) store_fpr (SIM_ARGS, (FPR), (FMT), (VALUE))
 
 
+/* FCR access.  */
+unsigned_word value_fcr (SIM_STATE, int fcr);
+#define ValueFCR(FCR) value_fcr (SIM_ARGS, (FCR))
+void store_fcr (SIM_STATE, int fcr, unsigned_word value);
+#define StoreFCR(FCR,VALUE) store_fcr (SIM_ARGS, (FCR), (VALUE))
+void test_fcsr (SIM_STATE);
+#define TestFCSR() test_fcsr (SIM_ARGS)
+
+
 /* FPU operations.  */
-int NaN (unsigned64 op, FP_formats fmt);
-int Less (unsigned64 op1, unsigned64 op2, FP_formats fmt);
-int Equal (unsigned64 op1, unsigned64 op2, FP_formats fmt);
+void fp_cmp (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt, int abs, int cond, int cc);
+#define Compare(op1,op2,fmt,cond,cc) fp_cmp(SIM_ARGS, op1, op2, fmt, 0, cond, cc)
 unsigned64 fp_abs (SIM_STATE, unsigned64 op, FP_formats fmt);
 #define AbsoluteValue(op,fmt) fp_abs(SIM_ARGS, op, fmt)
 unsigned64 fp_neg (SIM_STATE, unsigned64 op, FP_formats fmt);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]