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.
This commit is contained in:
parent
e8ffc436d9
commit
4819f490bd
|
@ -1,3 +1,12 @@
|
||||||
|
2015-03-20 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* 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 <vapier@gentoo.org>
|
2015-03-16 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* aclocal.m4, config.in, configure: Regenerate.
|
* aclocal.m4, config.in, configure: Regenerate.
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
#include "elf-bfd.h"
|
||||||
|
#include "elf/rl78.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
@ -90,6 +92,16 @@ rl78_load (bfd *prog, host_callback *callbacks, const char * const simname)
|
||||||
return;
|
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++)
|
for (i = 0; i < num_headers; i++)
|
||||||
{
|
{
|
||||||
Elf_Internal_Phdr * p = phdrs + i;
|
Elf_Internal_Phdr * p = phdrs + i;
|
||||||
|
|
|
@ -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);
|
printf ("Warning: SP value 0x%04x truncated at pc=0x%05x\n", value, pc);
|
||||||
value &= ~1;
|
value &= ~1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! g13_multiply)
|
||||||
|
return;
|
||||||
|
|
||||||
if (address == MDUC)
|
if (address == MDUC)
|
||||||
{
|
{
|
||||||
if ((value & 0x81) == 0x81)
|
if ((value & 0x81) == 0x81)
|
||||||
|
@ -166,20 +170,23 @@ mem_put_byte (int address, unsigned char value)
|
||||||
ahu = mem_get_hi (MDAH);
|
ahu = mem_get_hi (MDAH);
|
||||||
rvu = alu * ahu;
|
rvu = alu * ahu;
|
||||||
tprintf ("MDUC: %lu * %lu = %lu\n", alu, ahu, rvu);
|
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;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
als = sign_ext (mem_get_hi (MDAL), 16);
|
als = sign_ext (mem_get_hi (MDAL), 16);
|
||||||
ahs = sign_ext (mem_get_hi (MDAH), 16);
|
ahs = sign_ext (mem_get_hi (MDAH), 16);
|
||||||
rvs = als * ahs;
|
rvs = als * ahs;
|
||||||
tprintf ("MDUC: %ld * %ld = %ld\n", als, ahs, rvs);
|
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;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
alu = mem_get_hi (MDAL);
|
alu = mem_get_hi (MDAL);
|
||||||
ahu = mem_get_hi (MDAH);
|
ahu = mem_get_hi (MDAH);
|
||||||
rvu = alu * ahu;
|
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);
|
mdc = mem_get_si (MDCL);
|
||||||
tprintf ("MDUC: %lu * %lu + %lu = ", alu, ahu, mdc);
|
tprintf ("MDUC: %lu * %lu + %lu = ", alu, ahu, mdc);
|
||||||
mdc += (long) rvu;
|
mdc += (long) rvu;
|
||||||
|
@ -190,7 +197,8 @@ mem_put_byte (int address, unsigned char value)
|
||||||
als = sign_ext (mem_get_hi (MDAL), 16);
|
als = sign_ext (mem_get_hi (MDAL), 16);
|
||||||
ahs = sign_ext (mem_get_hi (MDAH), 16);
|
ahs = sign_ext (mem_get_hi (MDAH), 16);
|
||||||
rvs = als * ahs;
|
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);
|
mdc = mem_get_si (MDCL);
|
||||||
tprintf ("MDUC: %ld * %ld + %ld = ", als, ahs, mdc);
|
tprintf ("MDUC: %ld * %ld + %ld = ", als, ahs, mdc);
|
||||||
tprintf ("%ld\n", mdc);
|
tprintf ("%ld\n", mdc);
|
||||||
|
@ -228,7 +236,7 @@ mem_get_byte (int address)
|
||||||
unsigned long a, b, q, r;
|
unsigned long a, b, q, r;
|
||||||
memory [MDUC] &= 0xfe;
|
memory [MDUC] &= 0xfe;
|
||||||
a = mem_get_si (MDAL);
|
a = mem_get_si (MDAL);
|
||||||
b = mem_get_si (MDAL);
|
b = mem_get_hi (MDBL) | (mem_get_hi (MDBH) << 16);
|
||||||
if (b == 0)
|
if (b == 0)
|
||||||
{
|
{
|
||||||
q = ~0;
|
q = ~0;
|
||||||
|
|
Loading…
Reference in New Issue