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.
This commit is contained in:
DJ Delorie 2015-04-30 15:25:49 -04:00
parent b49f93f699
commit 0952813b0b
24 changed files with 706 additions and 467 deletions

View File

@ -1,3 +1,16 @@
2015-04-30 DJ Delorie <dj@redhat.com>
* 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.
2015-04-30 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (i386_target_format): Use "else if" on

View File

@ -47,6 +47,10 @@ extern void rl78_linkrelax_branch (void);
extern int rl78_parse (void);
extern int rl78_wrap (void);
extern int rl78_isa_g10 (void);
extern int rl78_isa_g13 (void);
extern int rl78_isa_g14 (void);
extern char * rl78_lex_start;
extern char * rl78_lex_end;
#endif

View File

@ -105,6 +105,10 @@ static int rl78_bit_insn = 0;
#define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
#define ISA_G10(s) if (!rl78_isa_g10()) rl78_error (s " is only supported on the G10")
#define ISA_G13(s) if (!rl78_isa_g13()) rl78_error (s " is only supported on the G13")
#define ISA_G14(s) if (!rl78_isa_g14()) rl78_error (s " is only supported on the G14")
static void check_expr_is_bit_index (expressionS);
#define Bit(e) check_expr_is_bit_index (e);
@ -500,16 +504,16 @@ statement :
/* ---------------------------------------------------------------------- */
| MULHU
| MULHU { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x01); }
| MULH
| MULH { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x02); }
| MULU X
| MULU X { ISA_G14 ("MULHU"); }
{ B1 (0xd6); }
| DIVHU
| DIVHU { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x03); }
/* Note that the DIVWU encoding was changed from [0xce,0xfb,0x04] to
@ -517,13 +521,13 @@ statement :
with the same version number, but varying encodings. The version
here matches the hardware. */
| DIVWU
| DIVWU { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x0b); }
| MACHU
| MACHU { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x05); }
| MACH
| MACH { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x06); }
/* ---------------------------------------------------------------------- */

View File

@ -339,6 +339,24 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
return 0;
}
int
rl78_isa_g10 (void)
{
return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G10;
}
int
rl78_isa_g13 (void)
{
return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G13;
}
int
rl78_isa_g14 (void)
{
return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G14;
}
void
md_show_usage (FILE * stream)
{

View File

@ -1,3 +1,8 @@
2015-04-30 DJ Delorie <dj@redhat.com>
* rl78-tdep.c (rl78_analyze_prologue): Pass RL78_ISA_DEFAULT to
rl78_decode_opcode
2015-04-29 Doug Evans <dje@google.com>
PR python/18285

View File

@ -921,7 +921,7 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
opcode_handle.pc = pc;
bytes_read = rl78_decode_opcode (pc, &opc, rl78_get_opcode_byte,
&opcode_handle);
&opcode_handle, RL78_ISA_DEFAULT);
next_pc = pc + bytes_read;
if (opc.id == RLO_sel)

View File

@ -1,3 +1,10 @@
2015-04-30 DJ Delorie <dj@redhat.com>
* dis-asm.h (print_insn_rl78_g10): New.
(print_insn_rl78_g13): New.
(print_insn_rl78_g14): New.
(rl78_get_disassembler): New.
2015-04-17 Richard Earnshaw <rearnsha@arm.com>
Merge from gcc:

View File

@ -307,9 +307,13 @@ extern int print_insn_z8001 (bfd_vma, disassemble_info *);
extern int print_insn_z8002 (bfd_vma, disassemble_info *);
extern int print_insn_rx (bfd_vma, disassemble_info *);
extern int print_insn_rl78 (bfd_vma, disassemble_info *);
extern int print_insn_rl78_g10 (bfd_vma, disassemble_info *);
extern int print_insn_rl78_g13 (bfd_vma, disassemble_info *);
extern int print_insn_rl78_g14 (bfd_vma, disassemble_info *);
extern disassembler_ftype arc_get_disassembler (void *);
extern disassembler_ftype cris_get_disassembler (bfd *);
extern disassembler_ftype rl78_get_disassembler (bfd *);
extern void print_aarch64_disassembler_options (FILE *);
extern void print_i386_disassembler_options (FILE *);

View File

@ -1,3 +1,8 @@
2015-04-30 DJ Delorie <dj@redhat.com>
* rl78.h (RL78_Dis_Isa): New.
(rl78_decode_opcode): Add ISA parameter.
2015-03-24 Terry Guo <terry.guo@arm.com>
* arm.h (arm_feature_set): Extended to provide more available bits.

View File

@ -30,6 +30,13 @@
extern "C" {
#endif
typedef enum {
RL78_ISA_DEFAULT,
RL78_ISA_G10,
RL78_ISA_G13,
RL78_ISA_G14,
} RL78_Dis_Isa;
/* For the purposes of these structures, the RL78 registers are as
follows, despite most of these being memory-mapped and
bank-switched: */
@ -166,7 +173,7 @@ typedef struct
RL78_Opcode_Operand op[2];
} RL78_Opcode_Decoded;
int rl78_decode_opcode (unsigned long, RL78_Opcode_Decoded *, int (*)(void *), void *);
int rl78_decode_opcode (unsigned long, RL78_Opcode_Decoded *, int (*)(void *), void *, RL78_Dis_Isa);
#ifdef __cplusplus
}

View File

@ -1,3 +1,18 @@
2015-04-30 DJ Delorie <dj@redhat.com>
* 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.
2015-04-29 Nick Clifton <nickc@redhat.com>
* po/fr.po: Updated French translation.

View File

@ -385,7 +385,7 @@ disassembler (abfd)
#endif
#ifdef ARCH_rl78
case bfd_arch_rl78:
disassemble = print_insn_rl78;
disassemble = rl78_get_disassembler (abfd);
break;
#endif
#ifdef ARCH_rx

File diff suppressed because it is too large Load Diff

View File

@ -164,7 +164,8 @@ int
rl78_decode_opcode (unsigned long pc AU,
RL78_Opcode_Decoded * rl78,
int (* getbyte)(void *),
void * ptr)
void * ptr,
RL78_Dis_Isa isa)
{
LocalData lds, * ld = &lds;
unsigned char op_buf[20] = {0};
@ -749,7 +750,7 @@ rl78_decode_opcode (unsigned long pc AU,
op0 = SFR;
op1 = IMMU(1);
ID(mov); DM(None, op0); SC(op1);
if (op0 == 0xffffb)
if (op0 == 0xffffb && isa == RL78_ISA_G14)
switch (op1)
{
case 0x01:
@ -902,6 +903,7 @@ rl78_decode_opcode (unsigned long pc AU,
/*----------------------------------------------------------------------*/
/** 1101 0110 mulu x */
if (isa == RL78_ISA_G14)
ID(mulu);
/*----------------------------------------------------------------------*/

View File

@ -24,8 +24,10 @@
#include <stdio.h>
#include "bfd.h"
#include "elf-bfd.h"
#include "dis-asm.h"
#include "opcode/rl78.h"
#include "elf/rl78.h"
#define DEBUG_SEMANTICS 0
@ -80,8 +82,8 @@ indirect_type (int t)
}
}
int
print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
static int
print_insn_rl78_common (bfd_vma addr, disassemble_info * dis, RL78_Dis_Isa isa)
{
int rv;
RL78_Data rl78_data;
@ -94,7 +96,7 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
rl78_data.pc = addr;
rl78_data.dis = dis;
rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data);
rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data, isa);
dis->bytes_per_line = 10;
@ -327,3 +329,44 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
return rv;
}
int
print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_DEFAULT);
}
int
print_insn_rl78_g10 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G10);
}
int
print_insn_rl78_g13 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G13);
}
int
print_insn_rl78_g14 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G14);
}
disassembler_ftype
rl78_get_disassembler (bfd *abfd)
{
int cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK;
switch (cpu)
{
case E_FLAG_RL78_G10:
return print_insn_rl78_g10;
case E_FLAG_RL78_G13:
return print_insn_rl78_g13;
case E_FLAG_RL78_G14:
return print_insn_rl78_g14;
default:
return print_insn_rl78;
}
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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));