From 0952813b0b27abe7f53a8048c0218883412e54cd Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Thu, 30 Apr 2015 15:25:49 -0400 Subject: 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. --- sim/rl78/ChangeLog | 11 +++++++++++ sim/rl78/cpu.c | 1 + sim/rl78/cpu.h | 1 + sim/rl78/gdb-if.c | 31 +++++++++++++++++++++++++++++++ sim/rl78/load.c | 19 ++++++++++++++++--- sim/rl78/main.c | 24 +++++++++++++++++++++++- sim/rl78/mem.c | 18 ++++++++++++++---- sim/rl78/rl78.c | 10 ++++++++-- sim/rl78/trace.c | 17 ++++++++++++++++- 9 files changed, 121 insertions(+), 11 deletions(-) (limited to 'sim/rl78') 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 + + * 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 * 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 \t- ram size.\n" + "\t-M \t- mcu type, default none, allowed: g10,g13,g14\n" "\t-D \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)); -- cgit v1.1