From patchwork Sat Apr 9 19:24:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Endo X-Patchwork-Id: 11682 Received: (qmail 26591 invoked by alias); 9 Apr 2016 19:25:14 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 26580 invoked by uid 89); 9 Apr 2016 19:25:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=rnl, rnh, H*r:sk:mailout X-HELO: mailout05.t-online.de Received: from mailout05.t-online.de (HELO mailout05.t-online.de) (194.25.134.82) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sat, 09 Apr 2016 19:25:07 +0000 Received: from fwd34.aul.t-online.de (fwd34.aul.t-online.de [172.20.26.145]) by mailout05.t-online.de (Postfix) with SMTP id DED25592532 for ; Sat, 9 Apr 2016 21:25:02 +0200 (CEST) Received: from [192.168.0.16] (ZB9eXvZYrhddx23LycLa-YOE+juD7GdPV3kDdMfbcCFf4epUOz6rKMxPg+6wBXygtW@[115.165.93.200]) by fwd34.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1aoyVB-2FyRW40; Sat, 9 Apr 2016 21:25:01 +0200 Message-ID: <1460229897.2115.24.camel@t-online.de> Subject: [SH] Fix simulator on 64 bit hosts From: Oleg Endo To: gdb-patches@sourceware.org Date: Sun, 10 Apr 2016 04:24:57 +0900 Mime-Version: 1.0 Hi, The attached patch fixes the SH simulator when ran on 64 bit hosts. It seems there are quite a few adventurous or at least confusing integer type casts, but the main problem was the widening 32 x 32 -> 64 bit multiplication. Tested by running the GCC testsuite and checking that 32 bit sim and 64 bit sim produce the same test results. Cheers, Oleg sim/sh/ChangeLog: * 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. diff --git a/sim/sh/gencode.c b/sim/sh/gencode.c index aa26e6c..f8f7074 100644 --- a/sim/sh/gencode.c +++ b/sim/sh/gencode.c @@ -405,11 +405,11 @@ static op tab[] = }, { "", "nm", "dmuls.l ,", "0011nnnnmmmm1101", - "dmul (1/*signed*/, R[n], R[m]);", + "dmul_s (R[n], R[m]);", }, { "", "nm", "dmulu.l ,", "0011nnnnmmmm0101", - "dmul (0/*unsigned*/, R[n], R[m]);", + "dmul_u (R[n], R[m]);", }, { "n", "n", "dt ", "0100nnnn00010000", diff --git a/sim/sh/interp.c b/sim/sh/interp.c index 072f71d..b4914d1 100644 --- a/sim/sh/interp.c +++ b/sim/sh/interp.c @@ -577,7 +577,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; } @@ -1201,41 +1201,19 @@ div1 (int *R, int iRn2, int iRn1/*, int T*/) } static void -dmul (int sign, unsigned int rm, unsigned int 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; - } +dmul_s (uint32_t rm, uint32_t 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