The r5900 doesn't have HI/LO DIV/MUL register problems. Hobble
authorAndrew Cagney <cagney@redhat.com>
Thu, 4 Jun 1998 08:46:56 +0000 (08:46 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 4 Jun 1998 08:46:56 +0000 (08:46 +0000)
checks on hi/lo usage but retain functions so that they can be used
for HI/LO stall counting code.

sim/mips/ChangeLog
sim/mips/mips.igen

index c90e1c0..9a16c1d 100644 (file)
@@ -1,3 +1,15 @@
+start-sanitize-r5900
+Thu Jun  4 16:47:27 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mips.igen (check_mt_hilo): 2.1 of r5900 spec stalls for HILO.
+       Select corresponding check_mt_hilo function.
+       (check_mult_hilo, check_div_hilo, check_mf_hilo, check_mt_hilo):
+       Ditto.
+       
+       * r5900.igen (check_mult_hilo_hi1lo1, check_div_hilo_hi1lo1): Mark
+       as r5900 specific.
+
+end-sanitize-r5900
 Tue Jun  2 15:48:02 1998  Ian Carmichael  <iancarm@cygnus.com>
 
        * interp.c (signal_exception): SystemCall exception now uses
index df89140..48c6216 100644 (file)
 // start-sanitize-vr5400
 *vr5400:
 // end-sanitize-vr5400
-// start-sanitize-r5900
-*r5900:
-// end-sanitize-r5900
 {
   signed64 time = sim_events_time (SD);
   int ok = check_mf_cycles (SD_, history, time, "MT");
 // start-sanitize-tx19
 *tx19:
 // end-sanitize-tx19
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
 {
   signed64 time = sim_events_time (SD);
   history->mt.timestamp = time;
   return 1;
 }
 
+
 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr4320
+*vr4320:
+// end-sanitize-vr4320
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
 {
   signed64 time = sim_events_time (SD);
   int ok = 1;
   return ok;
 }
 
+// start-sanitize-r5900
+// The r5900 mfhi et.al insns _can_ be exectuted immediatly after a div
+:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
+// end-sanitize-r5900
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+// start-sanitize-r5900
+{
+  /* FIXME: could record the fact that a stall occured if we want */
+  signed64 time = sim_events_time (SD);
+  history->mf.timestamp = time;
+  history->mf.cia = CIA;
+  return 1;
+}
+// end-sanitize-r5900
+
+
 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
 *mipsI,mipsII,mipsIII,mipsIV:
 *vr5000:
 // start-sanitize-vr5400
 *vr5400:
 // end-sanitize-vr5400
-// start-sanitize-r5900
-*r5900:
-// end-sanitize-r5900
 {
   signed64 time = sim_events_time (SD);
   int ok = (check_mf_cycles (SD_, hi, time, "OP")
   return ok;
 }
 
-
 // The r3900 mult and multu insns _can_ be exectuted immediatly after
 // a mf{hi,lo}
 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
 // start-sanitize-tx19
 *tx19:
 // end-sanitize-tx19
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
 {
+  /* FIXME: could record the fact that a stall occured if we want */
   signed64 time = sim_events_time (SD);
   hi->op.timestamp = time;
   lo->op.timestamp = time;
   return 1;
 }
 
+
 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
 *mipsI,mipsII,mipsIII,mipsIV:
 *vr5000:
 // start-sanitize-tx19
 *tx19:
 // end-sanitize-tx19
-// start-sanitize-r5900
-*r5900:
-// end-sanitize-r5900
 {
   signed64 time = sim_events_time (SD);
   int ok = (check_mf_cycles (SD_, hi, time, "OP")
 }
 
 
+// start-sanitize-r5900
+// The r5900 div et.al insns _can_ be exectuted immediatly after
+// a mf{hi,lo}
+:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
+// end-sanitize-r5900
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+// start-sanitize-r5900
+{
+  /* FIXME: could record the fact that a stall occured if we want */
+  signed64 time = sim_events_time (SD);
+  hi->op.timestamp = time;
+  lo->op.timestamp = time;
+  hi->op.cia = CIA;
+  lo->op.cia = CIA;
+  return 1;
+}
+// end-sanitize-r5900
+
+
 
 //
 // Mips Architecture:
   address_word reverseendian = (ReverseEndian ? -1 : 0);
   address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
   unsigned int byte;
+  unsigned int word;
   address_word paddr;
   int uncached;
   unsigned64 memval;
   address_word vaddr;
+  int nr_lhs_bits;
+  int nr_rhs_bits;
+  unsigned_word lhs_mask;
+  unsigned_word temp;
 
   vaddr = base + offset;
   AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem == 0)
     paddr = paddr & ~access;
-  byte = ((vaddr & mask) ^ (bigendiancpu & mask));
-  LoadMemory (&memval, NULL, uncached, byte & access, paddr, vaddr, isDATA, isREAL);
-  /* printf ("ll: 0x%08lx %d@0x%08lx 0x%08lx\n",
-     (long) vaddr, byte, (long) paddr, (long) memval); */
-  if ((byte & ~access) == 0)
+
+  /* compute where within the word/mem we are */
+  byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
+  word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
+  nr_lhs_bits = 8 * byte + 8;
+  nr_rhs_bits = 8 * access - 8 * byte;
+  /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
+
+  /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
+          (long) ((unsigned64) vaddr >> 32), (long) vaddr,
+          (long) ((unsigned64) paddr >> 32), (long) paddr,
+          word, byte, nr_lhs_bits, nr_rhs_bits); */
+
+  LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
+  if (word == 0)
     {
-      int bits = 8 * (access - byte);
-      unsigned_word screen = LSMASK (bits - 1, 0);
-      rt &= screen;
-      rt |= ((memval << bits) & ~screen);
+      /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
+      temp = (memval << nr_rhs_bits);
     }
   else
     {
-      unsigned_word screen = LSMASK (8 * (access - (byte & access)) - 1, 0);
-      rt &= screen;
-      rt |= ((memval >> (8 * (mask - byte))) & ~screen);
+      /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
+      temp = (memval >> nr_lhs_bits);
     }
+  lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
+  rt = (rt & ~lhs_mask) | (temp & lhs_mask);
+
+  /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
+          (long) ((unsigned64) memval >> 32), (long) memval,
+          (long) ((unsigned64) temp >> 32), (long) temp,
+          (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
+          (long) (rt >> 32), (long) rt); */
   return rt;
 }
 
   address_word reverseendian = (ReverseEndian ? -1 : 0);
   address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
   unsigned int byte;
+  unsigned int word;
   address_word paddr;
   int uncached;
   unsigned64 memval;
   address_word vaddr;
+  int nr_lhs_bits;
+  int nr_rhs_bits;
 
   vaddr = base + offset;
   AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem == 0)
     paddr = paddr & ~access;
-  byte = ((vaddr & mask) ^ (bigendiancpu & mask));
-  if ((byte & ~access) == 0)
-    memval = (rt >> (8 * (access - byte)));
+
+  /* compute where within the word/mem we are */
+  byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
+  word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
+  nr_lhs_bits = 8 * byte + 8;
+  nr_rhs_bits = 8 * access - 8 * byte;
+  /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
+  /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
+          (long) ((unsigned64) vaddr >> 32), (long) vaddr,
+          (long) ((unsigned64) paddr >> 32), (long) paddr,
+          word, byte, nr_lhs_bits, nr_rhs_bits); */
+
+  if (word == 0)
+    {
+      memval = (rt >> nr_rhs_bits);
+    }
   else
-    memval = (rt << (8 * (mask - byte)));
-  StoreMemory (uncached, byte & access, memval, 0, paddr, vaddr, isREAL);
+    {
+      memval = (rt << nr_lhs_bits);
+    }
+  /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
+          (long) ((unsigned64) rt >> 32), (long) rt,
+          (long) ((unsigned64) memval >> 32), (long) memval); */
+  StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
 }