Fix primary reason why the SH simulation hasn't been working on 64 bit hosts.
authorOleg Endo <olegendo@gcc.gnu.org>
Sun, 10 Apr 2016 02:00:01 +0000 (11:00 +0900)
committerOleg Endo <olegendo@gcc.gnu.org>
Sun, 10 Apr 2016 02:02:47 +0000 (11:02 +0900)
sim/sh/
* interp.c (dmul): Split into dmul_s and dmul_u.  Use explicit integer
width types and simplify implementation.
* gencode.c (dmuls.l, dmulu.l): Use new functions dmul_s and dmul_u.

sim/sh/ChangeLog
sim/sh/gencode.c
sim/sh/interp.c

index 432804903e54316e001a0d403625d0f06509b29e..9d3cf44132d6f82eb6b171202be75d10259e1d10 100644 (file)
@@ -1,6 +1,12 @@
+2016-04-10  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       * interp.c (dmul): Split into dmul_s and dmul_u.  Use explicit integer
+       width types and simplify implementation.
+       * gencode.c (dmuls.l, dmulu.l): Use new functions dmul_s and dmul_u.
+
 2016-04-09  Oleg Endo  <olegendo@gcc.gnu.org>
 
-       * sh/interp.c (sim_memory_size): Default init to 30.
+       * interp.c (sim_memory_size): Default init to 30.
        (parse_and_set_memory_size): Adjust upper bound to 31.
 
 2016-01-10  Mike Frysinger  <vapier@gentoo.org>
index e3978eae80a17ac1f137352f4f90bff8a9364a53..2f1a3f5be28d168bab12beeb36f86b962c06a736 100644 (file)
@@ -405,11 +405,11 @@ static op tab[] =
   },
 
   { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
-    "dmul (1/*signed*/, R[n], R[m]);",
+    "dmul_s (R[n], R[m]);",
   },
 
   { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
-    "dmul (0/*unsigned*/, R[n], R[m]);",
+    "dmul_u (R[n], R[m]);",
   },
 
   { "n", "n", "dt <REG_N>", "0100nnnn00010000",
index 46701e210bac4f9561f489f4ac4a68b590e226fd..32618ba4490232f04eb8544c81f7e3eefbce27a9 100644 (file)
@@ -558,7 +558,7 @@ rwat_fast (unsigned char *memory, int x, int maskw, int endianw)
 static INLINE int
 riat_fast (unsigned char *insn_ptr, int endianw)
 {
-  unsigned short *p = (unsigned short *) ((size_t) insn_ptr ^ endianw);
+  unsigned short *p = (unsigned short *) ((uintptr_t) insn_ptr ^ endianw);
 
   return *p;
 }
@@ -1185,41 +1185,19 @@ div1 (int *R, int iRn2, int iRn1/*, int T*/)
 }
 
 static void
-dmul (int sign, unsigned int rm, unsigned int rn)
+dmul_s (uint32_t rm, uint32_t rn)
 {
-  unsigned long RnL, RnH;
-  unsigned long RmL, RmH;
-  unsigned long temp0, temp1, temp2, temp3;
-  unsigned long Res2, Res1, Res0;
-
-  RnL = rn & 0xffff;
-  RnH = (rn >> 16) & 0xffff;
-  RmL = rm & 0xffff;
-  RmH = (rm >> 16) & 0xffff;
-  temp0 = RmL * RnL;
-  temp1 = RmH * RnL;
-  temp2 = RmL * RnH;
-  temp3 = RmH * RnH;
-  Res2 = 0;
-  Res1 = temp1 + temp2;
-  if (Res1 < temp1)
-    Res2 += 0x00010000;
-  temp1 = (Res1 << 16) & 0xffff0000;
-  Res0 = temp0 + temp1;
-  if (Res0 < temp0)
-    Res2 += 1;
-  Res2 += ((Res1 >> 16) & 0xffff) + temp3;
-  
-  if (sign)
-    {
-      if (rn & 0x80000000)
-       Res2 -= rm;
-      if (rm & 0x80000000)
-       Res2 -= rn;
-    }
+  int64_t res = (int64_t)(int32_t)rm * (int64_t)(int32_t)rn;
+  MACH = (uint32_t)((uint64_t)res >> 32);
+  MACL = (uint32_t)res;
+}
 
-  MACH = Res2;
-  MACL = Res0;
+static void
+dmul_u (uint32_t rm, uint32_t rn)
+{
+  uint64_t res = (uint64_t)(uint32_t)rm * (uint64_t)(uint32_t)rn;
+  MACH = (uint32_t)(res >> 32);
+  MACL = (uint32_t)res;
 }
 
 static void