* cp1.c (value_fpr): Don't inherit existing FPR_STATE for
authorThiemo Seufer <ths@networkno.de>
Mon, 19 Feb 2007 17:31:08 +0000 (17:31 +0000)
committerThiemo Seufer <ths@networkno.de>
Mon, 19 Feb 2007 17:31:08 +0000 (17:31 +0000)
uninterpreted formats. If fmt is one of the uninterpreted types
don't update the FPR_STATE. Handle fmt_uninterpreted_32 like
fmt_word, and fmt_uninterpreted_64 like fmt_long.
(store_fpr): When writing an invalid odd register, set the
matching even register to fmt_unknown, not the following register.
* interp.c (sim_open): If STATE_MEM_SIZE isn't set then set it to
the the memory window at offset 0 set by --memory-size command
line option.
(sim_store_register): Handle storing 4 bytes to an 8 byte floating
point register.
(sim_fetch_register): Likewise for reading 4 bytes from an 8 byte
register.
(sim_monitor): When returning the memory size to the MIPS
application, use the value in STATE_MEM_SIZE, not an arbitrary
hardcoded value.
(cop_lw): Don' mess around with FPR_STATE, just pass
fmt_uninterpreted_32 to StoreFPR.
(cop_sw): Similarly.
(cop_ld): Pass fmt_uninterpreted_64 not fmt_uninterpreted.
(cop_sd): Similarly.
* mips.igen (not_word_value): Single version for mips32, mips64
and mips16.

sim/mips/ChangeLog
sim/mips/cp1.c
sim/mips/interp.c
sim/mips/mips.igen

index 44fd87f3f0525c0a2439e01317c2e4716eb10202..b6e956eac672e0e7abe164006c1dded35437f6ab 100644 (file)
@@ -1,3 +1,31 @@
+2007-02-19  Thiemo Seufer  <ths@mips.com>
+            Nigel Stephens  <nigel@mips.com>
+            David Ung  <davidu@mips.com>
+
+       * cp1.c (value_fpr): Don't inherit existing FPR_STATE for
+       uninterpreted formats. If fmt is one of the uninterpreted types
+       don't update the FPR_STATE. Handle fmt_uninterpreted_32 like
+       fmt_word, and fmt_uninterpreted_64 like fmt_long.
+       (store_fpr): When writing an invalid odd register, set the
+       matching even register to fmt_unknown, not the following register.
+       * interp.c (sim_open): If STATE_MEM_SIZE isn't set then set it to
+       the the memory window at offset 0 set by --memory-size command
+       line option.
+       (sim_store_register): Handle storing 4 bytes to an 8 byte floating
+       point register.
+       (sim_fetch_register): Likewise for reading 4 bytes from an 8 byte
+       register.
+       (sim_monitor): When returning the memory size to the MIPS
+       application, use the value in STATE_MEM_SIZE, not an arbitrary
+       hardcoded value.
+       (cop_lw): Don' mess around with FPR_STATE, just pass
+       fmt_uninterpreted_32 to StoreFPR.
+       (cop_sw): Similarly.
+       (cop_ld): Pass fmt_uninterpreted_64 not fmt_uninterpreted.
+       (cop_sd): Similarly.
+       * mips.igen (not_word_value): Single version for mips32, mips64
+       and mips16.
+
 2007-02-19  Thiemo Seufer <ths@mips.com>
             Nigel Stephens  <nigel@mips.com>
 
index 5e569ef3ee43ea16bea3ac66562d7b040baa8e88..d8ee00e160be834adb00fabc0cd63b65d99ee505 100644 (file)
@@ -111,10 +111,10 @@ value_fpr (sim_cpu *cpu,
   int err = 0;
 
   /* Treat unused register values, as fixed-point 64bit values.  */
-  if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
+  if (fmt == fmt_unknown)
     {
 #if 1
-      /* If request to read data as "uninterpreted", then use the current
+      /* If request to read data as "unknown", then use the current
         encoding:  */
       fmt = FPR_STATE[fpr];
 #else
@@ -123,20 +123,23 @@ value_fpr (sim_cpu *cpu,
     }
 
   /* For values not yet accessed, set to the desired format.  */
-  if (FPR_STATE[fpr] == fmt_uninterpreted)
+  if (fmt < fmt_uninterpreted) 
     {
-      FPR_STATE[fpr] = fmt;
+      if (FPR_STATE[fpr] == fmt_uninterpreted)
+       {
+         FPR_STATE[fpr] = fmt;
 #ifdef DEBUG
-      printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
-             fpu_format_name (fmt));
+         printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
+                 fpu_format_name (fmt));
 #endif /* DEBUG */
-    }
-  if (fmt != FPR_STATE[fpr])
-    {
-      sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
-                     fpr, fpu_format_name (FPR_STATE[fpr]),
-                     fpu_format_name (fmt), pr_addr (cia));
-      FPR_STATE[fpr] = fmt_unknown;
+       }
+      else if (fmt != FPR_STATE[fpr])
+       {
+         sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
+                         fpr, fpu_format_name (FPR_STATE[fpr]),
+                         fpu_format_name (fmt), pr_addr (cia));
+         FPR_STATE[fpr] = fmt_unknown;
+       }
     }
 
   if (FPR_STATE[fpr] == fmt_unknown)
@@ -156,11 +159,13 @@ value_fpr (sim_cpu *cpu,
     {
       switch (fmt)
        {
+       case fmt_uninterpreted_32:
        case fmt_single:
        case fmt_word:
          value = (FGR[fpr] & 0xFFFFFFFF);
          break;
 
+       case fmt_uninterpreted_64:
        case fmt_uninterpreted:
        case fmt_double:
        case fmt_long:
@@ -177,11 +182,13 @@ value_fpr (sim_cpu *cpu,
     {
       switch (fmt)
        {
+       case fmt_uninterpreted_32:
        case fmt_single:
        case fmt_word:
          value = (FGR[fpr] & 0xFFFFFFFF);
          break;
 
+       case fmt_uninterpreted_64:
        case fmt_uninterpreted:
        case fmt_double:
        case fmt_long:
@@ -299,7 +306,7 @@ store_fpr (sim_cpu *cpu,
          else
            {
              FPR_STATE[fpr] = fmt_unknown;
-             FPR_STATE[fpr + 1] = fmt_unknown;
+             FPR_STATE[fpr ^ 1] = fmt_unknown;
              SignalException (ReservedInstruction, 0);
            }
          break;
index a8921f9de5fc09b3ea7db7eb0c7b3e2264a720cd..9bef8908c1dc11287ee0a03ee59bdfd4b18d34eb 100644 (file)
@@ -131,6 +131,9 @@ static void ColdReset PARAMS((SIM_DESC sd));
 
 /* Note that the monitor code essentially assumes this layout of memory.
    If you change these, change the monitor code, too.  */
+/* FIXME Currently addresses are truncated to 32-bits, see
+   mips/sim-main.c:address_translation(). If that changes, then these
+   values will need to be extended, and tested for more carefully. */
 #define K0BASE  (0x80000000)
 #define K0SIZE  (0x20000000)
 #define K1BASE  (0xA0000000)
@@ -365,17 +368,67 @@ sim_open (kind, cb, abfd, argv)
   if (board == NULL)
     {
       /* Allocate core managed memory */
-      
+      sim_memopt *entry, *match = NULL;
+      address_word mem_size = 0;
+      int mapped = 0;
 
       /* For compatibility with the old code - under this (at level one)
         are the kernel spaces K0 & K1.  Both of these map to a single
         smaller sub region */
       sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
-                      K1BASE, K0SIZE,
-                      MEM_SIZE, /* actual size */
-                      K0BASE);
-      
+
+      /* Look for largest memory region defined on command-line at
+        phys address 0. */
+#ifdef SIM_HAVE_FLATMEM
+      mem_size = STATE_MEM_SIZE (sd);
+#endif
+      for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
+       {
+         /* If we find an entry at address 0, then we will end up
+            allocating a new buffer in the "memory alias" command
+            below. The region at address 0 will be deleted. */
+         address_word size = (entry->modulo != 0
+                              ? entry->modulo : entry->nr_bytes);
+         if (entry->addr == 0
+             && (!match || entry->level < match->level))
+           match = entry;
+         else if (entry->addr == K0BASE || entry->addr == K1BASE)
+           mapped = 1;
+         else
+           {
+             sim_memopt *alias;
+             for (alias = entry->alias; alias != NULL; alias = alias->next)
+               {
+                 if (alias->addr == 0
+                     && (!match || entry->level < match->level))
+                   match = entry;
+                 else if (alias->addr == K0BASE || alias->addr == K1BASE)
+                   mapped = 1;
+               }
+           }
+       }
+
+      if (!mapped)
+       {
+         if (match)
+           {
+             /* Get existing memory region size. */
+             mem_size = (match->modulo != 0
+                         ? match->modulo : match->nr_bytes);
+             /* Delete old region. */
+             sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
+                              match->space, match->addr, match->level);
+           }         
+         else if (mem_size == 0)
+           mem_size = MEM_SIZE;
+         /* Limit to KSEG1 size (512MB) */
+         if (mem_size > K1SIZE)
+           mem_size = K1SIZE;
+         /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
+         sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
+                          K1BASE, K1SIZE, (long)mem_size, K0BASE);
+       }
+
       device_init(sd);
     }
   else if (board != NULL
@@ -868,8 +921,16 @@ sim_store_register (sd,rn,memory,length)
        }
       else
        {
-         cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
-         return 8;
+          if (length == 8)
+           {
+             cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
+             return 8;
+           }
+         else
+           {
+             cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
+             return 4;
+           }
        }
     }
 
@@ -889,8 +950,16 @@ sim_store_register (sd,rn,memory,length)
     }
   else
     {
-      cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
-      return 8;
+      if (length == 8)
+       {
+         cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
+         return 8;
+       }
+      else
+       {
+         cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
+         return 4;
+       }
     }
 
   return 0;
@@ -939,8 +1008,16 @@ sim_fetch_register (sd,rn,memory,length)
        }
       else
        {
-         *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
-         return 8;
+         if (length == 8)
+           {
+             *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
+             return 8;
+           }
+         else
+           {
+             *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
+             return 4;
+           }
        }
     }
 
@@ -960,8 +1037,17 @@ sim_fetch_register (sd,rn,memory,length)
     }
   else
     {
-      *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
-      return 8;
+      if (length == 8)
+       {
+         *(unsigned64*)memory =
+           H2T_8 ((unsigned64) (cpu->registers[rn]));
+         return 8;
+       }
+      else
+       {
+         *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
+         return 4;
+       }
     }
 
   return 0;
@@ -1235,8 +1321,39 @@ sim_monitor (SIM_DESC sd,
       /*      [A0 + 4] = instruction cache size */
       /*      [A0 + 8] = data cache size */
       {
-       unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
+       unsigned_4 value;
        unsigned_4 zero = 0;
+       address_word mem_size;
+       sim_memopt *entry, *match = NULL;
+
+       /* Search for memory region mapped to KSEG0 or KSEG1. */
+       for (entry = STATE_MEMOPT (sd); 
+            entry != NULL;
+            entry = entry->next)
+         {
+           if ((entry->addr == K0BASE || entry->addr == K1BASE)
+               && (!match || entry->level < match->level))
+             match = entry;
+           else
+             {
+               sim_memopt *alias;
+               for (alias = entry->alias; 
+                    alias != NULL;
+                    alias = alias->next)
+                 if ((alias->addr == K0BASE || alias->addr == K1BASE)
+                     && (!match || entry->level < match->level))
+                   match = entry;
+             }
+         }
+
+       /* Get region size, limit to KSEG1 size (512MB). */
+       SIM_ASSERT (match != NULL);
+       mem_size = (match->modulo != 0
+                   ? match->modulo : match->nr_bytes);
+       if (mem_size > K1SIZE)
+         mem_size = K1SIZE;
+
+       value = mem_size;
        H2T (value);
        sim_write (sd, A0 + 0, (char *)&value, 4);
        sim_write (sd, A0 + 4, (char *)&zero, 4);
@@ -1924,8 +2041,7 @@ cop_lw (SIM_DESC sd,
 #ifdef DEBUG
          printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
 #endif
-         StoreFPR(coproc_reg,fmt_word,(uword64)memword);
-         FPR_STATE[coproc_reg] = fmt_uninterpreted;
+         StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
          break;
        }
 
@@ -1956,7 +2072,7 @@ cop_ld (SIM_DESC sd,
     case 1:
       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
        {
-         StoreFPR(coproc_reg,fmt_uninterpreted,memword);
+         StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
          break;
        }
 
@@ -1987,11 +2103,7 @@ cop_sw (SIM_DESC sd,
     case 1:
       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
        {
-         FP_formats hold;
-         hold = FPR_STATE[coproc_reg];
-         FPR_STATE[coproc_reg] = fmt_word;
-         value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
-         FPR_STATE[coproc_reg] = hold;
+         value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
          break;
        }
 
@@ -2018,7 +2130,7 @@ cop_sd (SIM_DESC sd,
     case 1:
       if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
        {
-         value = ValueFPR(coproc_reg,fmt_uninterpreted);
+         value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
          break;
        }
 
index 85d08ea632826f8a3bffa1f3260f1d2aff200f4a..610958953943fd75247bc26fb64201b5dae218d4 100644 (file)
 *vr4100:
 *vr5000:
 *r3900:
-{
-  /* For historical simulator compatibility (until documentation is
-     found that makes these operations unpredictable on some of these
-     architectures), this check never returns true.  */
-  return 0;
-}
-
-:function:::int:not_word_value:unsigned_word value
 *mips32:
 *mips32r2:
-{
-  /* On MIPS32, since registers are 32-bits, there's no check to be done.  */
-  return 0;
-}
-
-:function:::int:not_word_value:unsigned_word value
 *mips64:
 *mips64r2:
 {
-  return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0));
+#if WITH_TARGET_WORD_BITSIZE == 64
+  return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+#else
+  return 0;
+#endif
 }
 
-
 // Helper:
 //
 // Handle UNPREDICTABLE operation behaviour.  The goal here is to prevent