From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 91206 invoked by alias); 19 Mar 2015 15:51:40 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 91151 invoked by uid 89); 19 Mar 2015 15:51:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 19 Mar 2015 15:51:37 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2JFpYJK005540 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 19 Mar 2015 11:51:35 -0400 Received: from littlehelper.redhat.com (vpn1-7-34.ams2.redhat.com [10.36.7.34]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2JFpWjM013830 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 19 Mar 2015 11:51:33 -0400 From: Nick Clifton To: dj@redhat.com Cc: gdb-patches@sourceware.org Subject: RFA: RL78: Fix simulation of G13 multiply/divide peripheral Date: Thu, 19 Mar 2015 15:51:00 -0000 Message-ID: <87fv91nfy3.fsf@redhat.com> MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2015-03/txt/msg00589.txt.bz2 Hi DJ, The patch below fixes a problem with the RL78 simulator simulation of the G13 multiply/divide peripheral. Namely the MDB register is not 32-bit aligned so the mem_put_si and mem_get_si functions cannot be used with it. Instead the value has to be split up into two 16-bit parts and the mem_{get|put}_hi functions used. In addition the patch adds support for the new G13 and G14 flags in RL78 ELF headers. If one of these flag bits is present then the patch selects the appropriate G10/G13/G14 emulation mode. Tested with no regressions on an rl78-elf toolchain. OK to apply ? Cheers Nick sim/rl78/ChangeLog 2015-03-19 Nick Clifton * load.c (rl78_load): If the G10, G13 or G14 flag bits are set in the ELF header use them to select the proper emulation mode. * mem.c (mem_put_byte): Use mem_put_hi to store a value into the MDB register. (mem_get_byte): Use mem_get_hi to extract a value from the MDB register. diff --git a/sim/rl78/load.c b/sim/rl78/load.c index fcbe1ae..8d3a138 100644 --- a/sim/rl78/load.c +++ b/sim/rl78/load.c @@ -27,6 +27,8 @@ #include "libiberty.h" #include "bfd.h" +#include "elf-bfd.h" +#include "elf/rl78.h" #include "libbfd.h" #include "cpu.h" #include "mem.h" @@ -89,7 +91,17 @@ rl78_load (bfd *prog, host_callback *callbacks, const char * const simname) fprintf (stderr, "%s: Failed to read program headers\n", simname); return; } - + + rl78_g10_mode = 0; + switch (elf_elfheader (prog)->e_flags & E_FLAG_RL78_CPU_MASK) + { + case E_FLAG_RL78_G10: rl78_g10_mode = 1; break; + case E_FLAG_RL78_G13: g13_multiply = 1; break; + case E_FLAG_RL78_G14: + default: + break; + } + for (i = 0; i < num_headers; i++) { Elf_Internal_Phdr * p = phdrs + i; diff --git a/sim/rl78/mem.c b/sim/rl78/mem.c index 042c76e..8d95199 100644 --- a/sim/rl78/mem.c +++ b/sim/rl78/mem.c @@ -140,6 +140,10 @@ mem_put_byte (int address, unsigned char value) printf ("Warning: SP value 0x%04x truncated at pc=0x%05x\n", value, pc); value &= ~1; } + + if (! g13_multiply) + return; + if (address == MDUC) { if ((value & 0x81) == 0x81) @@ -166,20 +170,23 @@ mem_put_byte (int address, unsigned char value) ahu = mem_get_hi (MDAH); rvu = alu * ahu; tprintf ("MDUC: %lu * %lu = %lu\n", alu, ahu, rvu); - mem_put_si (MDBL, rvu); + mem_put_hi (MDBL, rvu & 0xffff); + mem_put_hi (MDBH, rvu >> 16); break; case 0x08: als = sign_ext (mem_get_hi (MDAL), 16); ahs = sign_ext (mem_get_hi (MDAH), 16); rvs = als * ahs; tprintf ("MDUC: %ld * %ld = %ld\n", als, ahs, rvs); - mem_put_si (MDBL, rvs); + mem_put_hi (MDBL, rvs & 0xffff); + mem_put_hi (MDBH, rvs >> 16); break; case 0x40: alu = mem_get_hi (MDAL); ahu = mem_get_hi (MDAH); rvu = alu * ahu; - mem_put_si (MDBL, rvu); + mem_put_hi (MDBL, rvu & 0xffff); + mem_put_hi (MDBH, rvu >> 16); mdc = mem_get_si (MDCL); tprintf ("MDUC: %lu * %lu + %lu = ", alu, ahu, mdc); mdc += (long) rvu; @@ -190,7 +197,8 @@ mem_put_byte (int address, unsigned char value) als = sign_ext (mem_get_hi (MDAL), 16); ahs = sign_ext (mem_get_hi (MDAH), 16); rvs = als * ahs; - mem_put_si (MDBL, rvs); + mem_put_hi (MDBL, rvs & 0xffff); + mem_put_hi (MDBH, rvs >> 16); mdc = mem_get_si (MDCL); tprintf ("MDUC: %ld * %ld + %ld = ", als, ahs, mdc); tprintf ("%ld\n", mdc); @@ -228,7 +236,7 @@ mem_get_byte (int address) unsigned long a, b, q, r; memory [MDUC] &= 0xfe; a = mem_get_si (MDAL); - b = mem_get_si (MDAL); + b = mem_get_hi (MDBL) | (mem_get_hi (MDBH) << 16); if (b == 0) { q = ~0;