aboutsummaryrefslogtreecommitdiff
path: root/sim/sh/interp.c
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2016-04-10 11:00:01 +0900
committerOleg Endo <olegendo@gcc.gnu.org>2016-04-10 11:02:47 +0900
commit93e6fe04ccb4008f14e3584bb1e86b2d04c9234c (patch)
tree6434e6b44038c517764a4c7005cc7c87cd8320a9 /sim/sh/interp.c
parentba442f0f41a57ee9a3f0c7f574500f2bda896d08 (diff)
downloadfsf-binutils-gdb-93e6fe04ccb4008f14e3584bb1e86b2d04c9234c.zip
fsf-binutils-gdb-93e6fe04ccb4008f14e3584bb1e86b2d04c9234c.tar.gz
fsf-binutils-gdb-93e6fe04ccb4008f14e3584bb1e86b2d04c9234c.tar.bz2
Fix primary reason why the SH simulation hasn't been working on 64 bit hosts.
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.
Diffstat (limited to 'sim/sh/interp.c')
-rw-r--r--sim/sh/interp.c46
1 files changed, 12 insertions, 34 deletions
diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index 46701e2..32618ba 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -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