From 4819f490bd2bc88bccf636755abf3d50b7f3850f Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 20 Mar 2015 10:29:46 +0000 Subject: [PATCH] Fixes implementation of hardware multiply/divide peripheral in RL78 G13 cores. * 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. --- sim/rl78/ChangeLog | 9 +++++++++ sim/rl78/load.c | 14 +++++++++++++- sim/rl78/mem.c | 18 +++++++++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/sim/rl78/ChangeLog b/sim/rl78/ChangeLog index 3c92412031a..018b1ff77d0 100644 --- a/sim/rl78/ChangeLog +++ b/sim/rl78/ChangeLog @@ -1,3 +1,12 @@ +2015-03-20 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. + 2015-03-16 Mike Frysinger * aclocal.m4, config.in, configure: Regenerate. diff --git a/sim/rl78/load.c b/sim/rl78/load.c index fcbe1aef85d..8d3a13823e2 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 042c76e131d..8d95199352c 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; -- 2.30.2