aboutsummaryrefslogtreecommitdiff
path: root/sim/rl78
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2015-04-30 15:25:49 -0400
committerDJ Delorie <dj@redhat.com>2015-04-30 15:25:49 -0400
commit0952813b0b27abe7f53a8048c0218883412e54cd (patch)
tree5407096ab234c7abec96a530789cd5bdb7069077 /sim/rl78
parentb49f93f6995a5d23c752db103902314d4e23f761 (diff)
downloadgdb-0952813b0b27abe7f53a8048c0218883412e54cd.zip
gdb-0952813b0b27abe7f53a8048c0218883412e54cd.tar.gz
gdb-0952813b0b27abe7f53a8048c0218883412e54cd.tar.bz2
Make RL78 disassembler and simulator respect ISA for mul/div
[gas] * config/rl78-defs.h (rl78_isa_g10): New. (rl78_isa_g13): New. (rl78_isa_g14): New. * config/rl78-parse.y (ISA_G10): New. (ISA_G13): New. (ISA_G14): New. (MULHU, MULH, MULU, DIVHU, DIVWU, MACHU, MACH): Use them. * config/tc-rl78.c (rl78_isa_g10): New. (rl78_isa_g13): New. (rl78_isa_g14): New. [gdb] * rl78-tdep.c (rl78_analyze_prologue): Pass RL78_ISA_DEFAULT to rl78_decode_opcode [include] * dis-asm.h (print_insn_rl78_g10): New. (print_insn_rl78_g13): New. (print_insn_rl78_g14): New. (rl78_get_disassembler): New. * opcode/rl78.h (RL78_Dis_Isa): New. (rl78_decode_opcode): Add ISA parameter. [opcodes] * disassemble.c (disassembler): Choose suitable disassembler based on E_ABI. * rl78-decode.opc (rl78_decode_opcode): Take ISA parameter. Use it to decode mul/div insns. * rl78-decode.c: Regenerate. * rl78-dis.c (print_insn_rl78): Rename to... (print_insn_rl78_common): ...this, take ISA parameter. (print_insn_rl78): New. (print_insn_rl78_g10): New. (print_insn_rl78_g13): New. (print_insn_rl78_g14): New. (rl78_get_disassembler): New. [sim] * rl78/cpu.c (g14_multiply): New. * rl78/cpu.h (g14_multiply): New. * rl78/load.c (rl78_load): Decode ISA completely. * rl78/main.c (main): Expand -M to include other ISAs. * rl78/rl78.c (decode_opcode): Decode based on ISA. * rl78/trace.c (rl78_disasm_fn): New. (sim_disasm_init): Reset it. (sim_disasm_one): Get correct disassembler for ISA.
Diffstat (limited to 'sim/rl78')
-rw-r--r--sim/rl78/ChangeLog11
-rw-r--r--sim/rl78/cpu.c1
-rw-r--r--sim/rl78/cpu.h1
-rw-r--r--sim/rl78/gdb-if.c31
-rw-r--r--sim/rl78/load.c19
-rw-r--r--sim/rl78/main.c24
-rw-r--r--sim/rl78/mem.c18
-rw-r--r--sim/rl78/rl78.c10
-rw-r--r--sim/rl78/trace.c17
9 files changed, 121 insertions, 11 deletions
diff --git a/sim/rl78/ChangeLog b/sim/rl78/ChangeLog
index d515328..c3eec85 100644
--- a/sim/rl78/ChangeLog
+++ b/sim/rl78/ChangeLog
@@ -1,3 +1,14 @@
+2015-04-30 DJ Delorie <dj@redhat.com>
+
+ * cpu.c (g14_multiply): New.
+ * cpu.h (g14_multiply): New.
+ * load.c (rl78_load): Decode ISA completely.
+ * main.c (main): Expand -M to include other ISAs.
+ * rl78.c (decode_opcode): Decode based on ISA.
+ * trace.c (rl78_disasm_fn): New.
+ (sim_disasm_init): Reset it.
+ (sim_disasm_one): Get correct disassembler for ISA.
+
2015-04-13 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.
diff --git a/sim/rl78/cpu.c b/sim/rl78/cpu.c
index 32b1399..ed5f118 100644
--- a/sim/rl78/cpu.c
+++ b/sim/rl78/cpu.c
@@ -34,6 +34,7 @@ int rl78_in_gdb = 1;
int timer_enabled = 2;
int rl78_g10_mode = 0;
int g13_multiply = 0;
+int g14_multiply = 0;
#define REGISTER_ADDRESS 0xffee0
diff --git a/sim/rl78/cpu.h b/sim/rl78/cpu.h
index 0e10db9..85c03ae 100644
--- a/sim/rl78/cpu.h
+++ b/sim/rl78/cpu.h
@@ -99,5 +99,6 @@ extern unsigned int counts_per_insn[0x100000];
extern int rl78_g10_mode;
extern int g13_multiply;
+extern int g14_multiply;
#endif
diff --git a/sim/rl78/gdb-if.c b/sim/rl78/gdb-if.c
index 6317a73..cb64b7a 100644
--- a/sim/rl78/gdb-if.c
+++ b/sim/rl78/gdb-if.c
@@ -86,6 +86,37 @@ sim_open (SIM_OPEN_KIND kind,
sim_disasm_init (abfd);
open = 1;
+
+ while (argv != NULL && *argv != NULL)
+ {
+ if (strcmp (*argv, "g10") == 0 || strcmp (*argv, "-Mg10") == 0)
+ {
+ fprintf (stderr, "rl78 g10 support enabled.\n");
+ rl78_g10_mode = 1;
+ g13_multiply = 0;
+ g14_multiply = 0;
+ mem_set_mirror (0, 0xf8000, 4096);
+ break;
+ }
+ if (strcmp (*argv, "g13") == 0 || strcmp (*argv, "-Mg13") == 0)
+ {
+ fprintf (stderr, "rl78 g13 support enabled.\n");
+ rl78_g10_mode = 0;
+ g13_multiply = 1;
+ g14_multiply = 0;
+ break;
+ }
+ if (strcmp (*argv, "g14") == 0 || strcmp (*argv, "-Mg14") == 0)
+ {
+ fprintf (stderr, "rl78 g14 support enabled.\n");
+ rl78_g10_mode = 0;
+ g13_multiply = 0;
+ g14_multiply = 1;
+ break;
+ }
+ argv++;
+ }
+
return &the_minisim;
}
diff --git a/sim/rl78/load.c b/sim/rl78/load.c
index 66d00d3..ef559a5 100644
--- a/sim/rl78/load.c
+++ b/sim/rl78/load.c
@@ -92,13 +92,26 @@ rl78_load (bfd *prog, host_callback *callbacks, const char * const 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_G10:
+ rl78_g10_mode = 1;
+ g13_multiply = 0;
+ g14_multiply = 0;
+ mem_set_mirror (0, 0xf8000, 4096);
+ break;
+ case E_FLAG_RL78_G13:
+ rl78_g10_mode = 0;
+ g13_multiply = 1;
+ g14_multiply = 0;
+ break;
case E_FLAG_RL78_G14:
+ rl78_g10_mode = 0;
+ g13_multiply = 0;
+ g14_multiply = 1;
+ break;
default:
+ /* Keep whatever was manually specified. */
break;
}
diff --git a/sim/rl78/main.c b/sim/rl78/main.c
index 0ae50fd..acdc20b 100644
--- a/sim/rl78/main.c
+++ b/sim/rl78/main.c
@@ -68,7 +68,7 @@ main (int argc, char **argv)
xmalloc_set_program_name (argv[0]);
- while ((o = getopt (argc, argv, "tvdr:D:")) != -1)
+ while ((o = getopt (argc, argv, "tvdr:D:M:")) != -1)
{
switch (o)
{
@@ -87,6 +87,27 @@ main (int argc, char **argv)
case 'D':
dump_counts_filename = optarg;
break;
+ case 'M':
+ if (strcmp (optarg, "g10") == 0)
+ {
+ rl78_g10_mode = 1;
+ g13_multiply = 0;
+ g14_multiply = 0;
+ mem_set_mirror (0, 0xf8000, 4096);
+ }
+ if (strcmp (optarg, "g13") == 0)
+ {
+ rl78_g10_mode = 0;
+ g13_multiply = 1;
+ g14_multiply = 0;
+ }
+ if (strcmp (optarg, "g14") == 0)
+ {
+ rl78_g10_mode = 0;
+ g13_multiply = 0;
+ g14_multiply = 1;
+ }
+ break;
case '?':
{
fprintf (stderr,
@@ -96,6 +117,7 @@ main (int argc, char **argv)
"\t-t\t\t- trace.\n"
"\t-d\t\t- disassemble.\n"
"\t-r <bytes>\t- ram size.\n"
+ "\t-M <mcu>\t- mcu type, default none, allowed: g10,g13,g14\n"
"\t-D <filename>\t- dump cycle count histogram\n");
exit (1);
}
diff --git a/sim/rl78/mem.c b/sim/rl78/mem.c
index 8d95199..f40d2c1 100644
--- a/sim/rl78/mem.c
+++ b/sim/rl78/mem.c
@@ -63,6 +63,18 @@ mem_rom_size (int rom_bytes)
rom_limit = rom_bytes;
}
+int mirror_rom_base = 0x01000;
+int mirror_ram_base = 0xf1000;
+int mirror_length = 0x7000;
+
+void
+mem_set_mirror (int rom_base, int ram_base, int length)
+{
+ mirror_rom_base = rom_base;
+ mirror_ram_base = ram_base;
+ mirror_length = length;
+}
+
/* ---------------------------------------------------------------------- */
/* Note: the RL78 memory map has a few surprises. For starters, part
of the first 64k is mapped to the last 64k, depending on an SFR bit
@@ -92,13 +104,11 @@ static int
address_mapping (int address)
{
address &= MASK;
- if (address >= 0xf1000 && address < ram_base)
+ if (address >= mirror_ram_base && address < mirror_ram_base + mirror_length)
{
- address &= 0xffff;
- tprintf ("&");
+ address = address - mirror_ram_base + mirror_rom_base;
if (memory[RL78_SFR_PMC] & 1)
{
- tprintf ("|");
address |= 0x10000;
}
last_addr_was_mirror = 1;
diff --git a/sim/rl78/rl78.c b/sim/rl78/rl78.c
index aca6762..c8d1442 100644
--- a/sim/rl78/rl78.c
+++ b/sim/rl78/rl78.c
@@ -421,10 +421,16 @@ decode_opcode (void)
int a, b, v, v2;
unsigned int u, u2;
int obits;
+ RL78_Dis_Isa isa;
+
+ isa = (rl78_g10_mode ? RL78_ISA_G10
+ : g14_multiply ? RL78_ISA_G14
+ : g13_multiply ? RL78_ISA_G13
+ : RL78_ISA_DEFAULT);
rl78_data.dpc = pc;
opcode_size = rl78_decode_opcode (pc, &opcode,
- rl78_get_byte, &rl78_data);
+ rl78_get_byte, &rl78_data, isa);
opcode_pc = pc;
pc += opcode_size;
@@ -851,7 +857,7 @@ decode_opcode (void)
rl78_data.dpc = pc;
opcode_size = rl78_decode_opcode (pc, &opcode,
- rl78_get_byte, &rl78_data);
+ rl78_get_byte, &rl78_data, isa);
pc += opcode_size;
tprintf (" skipped: %s\n", opcode.syntax);
break;
diff --git a/sim/rl78/trace.c b/sim/rl78/trace.c
index 764c85e..b8dfb34 100644
--- a/sim/rl78/trace.c
+++ b/sim/rl78/trace.c
@@ -37,6 +37,8 @@
#include "mem.h"
#include "load.h"
+static disassembler_ftype rl78_disasm_fn = NULL;
+
static int
sim_dis_read (bfd_vma memaddr, bfd_byte * ptr, unsigned int length,
struct disassemble_info *info)
@@ -111,6 +113,7 @@ void
sim_disasm_init (bfd *prog)
{
current_bfd = prog;
+ rl78_disasm_fn = NULL;
}
typedef struct Files
@@ -256,6 +259,18 @@ sim_disasm_one (void)
trace = 0;
+ if (!rl78_disasm_fn)
+ {
+ if (rl78_g10_mode)
+ rl78_disasm_fn = print_insn_rl78_g10;
+ else if (g14_multiply)
+ rl78_disasm_fn = print_insn_rl78_g14;
+ else if (g13_multiply)
+ rl78_disasm_fn = print_insn_rl78_g13;
+ else
+ rl78_disasm_fn = print_insn_rl78;
+ }
+
if (filename && functionname && lineno)
{
if (lineno != prev_lineno || strcmp (prev_filename, filename))
@@ -323,7 +338,7 @@ sim_disasm_one (void)
printf ("\033[33m %08llx %06x: ", total_clocks, mypc);
#endif
- max = print_insn_rl78 (mypc, & info);
+ max = rl78_disasm_fn (mypc, & info);
for (i = 0; i < max; i ++)
printf ("%02x", mem_get_qi (mypc + i));