diff options
author | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 07:46:09 +0000 |
---|---|---|
committer | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 07:46:09 +0000 |
commit | 63f36def60e0ebb54113a819db684887d036b387 (patch) | |
tree | 9733144136e5c4f171c1dd6c92c1d1e0f664cfc2 /sim/m68hc11 | |
parent | bed69f0439536ace7602fdfc7a04dde1dc68d31a (diff) | |
download | fsf-binutils-gdb-63f36def60e0ebb54113a819db684887d036b387.zip fsf-binutils-gdb-63f36def60e0ebb54113a819db684887d036b387.tar.gz fsf-binutils-gdb-63f36def60e0ebb54113a819db684887d036b387.tar.bz2 |
* m68hc11_sim.c (cpu_special): Handle call and rtc instructions.
* sim-main.h (M6812_CALL_INDIRECT): Add to enum.
(m6811_regs): Add page register.
(cpu_set_page, cpu_get_page): New macros.
(phys_to_virt): New function.
(cpu_get_indexed_operand_addr, cpu_return): Declare.
* gencode.c: Identify indirect addressing mode for call and fix daa.
(gen_function_entry): New param to tell if src8/dst8 locals are
necessary.
(gen_interpreter): Use it to avoid generation of unused variables.
* interp.c (sim_fetch_register): Allow to read page register; page
register, A, B and CCR are only 1 byte wide.
(sim_store_register): Likewise for writing.
Diffstat (limited to 'sim/m68hc11')
-rw-r--r-- | sim/m68hc11/ChangeLog | 16 | ||||
-rw-r--r-- | sim/m68hc11/gencode.c | 37 | ||||
-rw-r--r-- | sim/m68hc11/interp.c | 23 | ||||
-rw-r--r-- | sim/m68hc11/m68hc11_sim.c | 56 | ||||
-rw-r--r-- | sim/m68hc11/sim-main.h | 28 |
5 files changed, 137 insertions, 23 deletions
diff --git a/sim/m68hc11/ChangeLog b/sim/m68hc11/ChangeLog index 7c08019..95047da 100644 --- a/sim/m68hc11/ChangeLog +++ b/sim/m68hc11/ChangeLog @@ -1,3 +1,19 @@ +2002-08-13 Stephane Carrez <stcarrez@nerim.fr> + + * m68hc11_sim.c (cpu_special): Handle call and rtc instructions. + * sim-main.h (M6812_CALL_INDIRECT): Add to enum. + (m6811_regs): Add page register. + (cpu_set_page, cpu_get_page): New macros. + (phys_to_virt): New function. + (cpu_get_indexed_operand_addr, cpu_return): Declare. + * gencode.c: Identify indirect addressing mode for call and fix daa. + (gen_function_entry): New param to tell if src8/dst8 locals are + necessary. + (gen_interpreter): Use it to avoid generation of unused variables. + * interp.c (sim_fetch_register): Allow to read page register; page + register, A, B and CCR are only 1 byte wide. + (sim_store_register): Likewise for writing. + 2002-06-16 Andrew Cagney <ac131313@redhat.com> * configure: Regenerated to track ../common/aclocal.m4 changes. diff --git a/sim/m68hc11/gencode.c b/sim/m68hc11/gencode.c index 8c32e3e..c602656 100644 --- a/sim/m68hc11/gencode.c +++ b/sim/m68hc11/gencode.c @@ -1,6 +1,6 @@ /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@nerim.fr) This file is part of GDB, GAS, and the GNU binutils. @@ -284,6 +284,7 @@ cpu_set_ccr_Z (proc, dst16 == 0);\n\ /* 68HC12 special instructions. */ { "bgnd", "cpu_special (proc, M6812_BGND)" }, { "call8", "cpu_special (proc, M6812_CALL)" }, + { "call_ind", "cpu_special (proc, M6812_CALL_INDIRECT)" }, { "dbcc8", "cpu_dbcc (proc)" }, { "ediv", "cpu_special (proc, M6812_EDIV)" }, { "emul", "{ uint32 src1 = (uint32) cpu_get_d (proc);\ @@ -384,7 +385,7 @@ struct m6811_opcode_def m6811_page1_opcodes[] = { { "page3", 0, "page3", 1, 0x1a, 0, 0, CHG_NONE }, /* After 'daa', the Z flag is undefined. Mark it as changed. */ - { "daa", "a->a", "daa8", 1, 0x19, 2, 2, CHG_NZVC }, + { "daa", "", "daa8", 1, 0x19, 2, 2, CHG_NZVC }, { "aba", "b,a->a", "add8", 1, 0x1b, 2, 2, CHG_HNZVC}, { "bset", "(x),#->(x)","or8", 3, 0x1c, 7, 7, CLR_V_CHG_NZ }, { "bclr", "(x),#->(x)","bclr8", 3, 0x1d, 7, 7, CLR_V_CHG_NZ }, @@ -821,8 +822,8 @@ struct m6811_opcode_def m6812_page1_opcodes[] = { { "bvc", "r", 0, 2, 0x28, 1, 3, CHG_NONE }, { "bvs", "r", 0, 2, 0x29, 1, 3, CHG_NONE }, - { "call", "()", "call8", 4, 0x4a, 8, 8, CHG_NONE }, - { "call", "[]", "call8", 2, 0x4b, 8, 8, CHG_NONE }, + { "call", "", "call8", 4, 0x4a, 8, 8, CHG_NONE }, + { "call", "", "call_ind",2, 0x4b, 8, 8, CHG_NONE }, { "clr", "->()", "clr8", 3, 0x79, 3, 3, SET_Z_CLR_NVC }, { "clr", "->[]", "clr8", 2, 0x69, 2, 2, SET_Z_CLR_NVC }, @@ -1977,8 +1978,11 @@ gen_cycle_table (FILE *fp, const char *name, print (fp, 0, "};\n\n"); } +#define USE_SRC8 1 +#define USE_DST8 2 + void -gen_function_entry (FILE *fp, const char *name) +gen_function_entry (FILE *fp, const char *name, int locals) { /* Generate interpretor entry point. */ print (fp, 0, "%s (proc)\n", name); @@ -1988,7 +1992,10 @@ gen_function_entry (FILE *fp, const char *name) /* Interpretor local variables. */ print (fp, indent_level, "unsigned char op;"); print (fp, indent_level, "uint16 addr, src16, dst16;"); - print (fp, indent_level, "uint8 src8, dst8;\n"); + if (locals & USE_SRC8) + print (fp, indent_level, "uint8 src8;\n"); + if (locals & USE_DST8) + print (fp, indent_level, "uint8 dst8;\n"); } void @@ -2050,14 +2057,14 @@ gen_interpreter (FILE *fp) gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes, TABLE_SIZE (m6811_page4_opcodes)); - gen_function_entry (fp, "static void\ncpu_page3_interp"); + gen_function_entry (fp, "static void\ncpu_page3_interp", 0); gen_interpreter_for_table (fp, indent_level, m6811_page3_opcodes, TABLE_SIZE(m6811_page3_opcodes), "cycles_page3"); gen_function_close (fp); - gen_function_entry (fp, "static void\ncpu_page4_interp"); + gen_function_entry (fp, "static void\ncpu_page4_interp", 0); gen_interpreter_for_table (fp, indent_level, m6811_page4_opcodes, TABLE_SIZE(m6811_page4_opcodes), @@ -2065,7 +2072,8 @@ gen_interpreter (FILE *fp) gen_function_close (fp); /* Generate the page 2, 3 and 4 handlers. */ - gen_function_entry (fp, "static void\ncpu_page2_interp"); + gen_function_entry (fp, "static void\ncpu_page2_interp", + USE_SRC8 | USE_DST8); gen_interpreter_for_table (fp, indent_level, m6811_page2_opcodes, TABLE_SIZE(m6811_page2_opcodes), @@ -2073,7 +2081,8 @@ gen_interpreter (FILE *fp) gen_function_close (fp); /* Generate the interpretor entry point. */ - gen_function_entry (fp, "void\ncpu_interp_m6811"); + gen_function_entry (fp, "void\ncpu_interp_m6811", + USE_SRC8 | USE_DST8); gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes, TABLE_SIZE(m6811_page1_opcodes), @@ -2087,7 +2096,8 @@ gen_interpreter (FILE *fp) gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes, TABLE_SIZE (m6812_page2_opcodes)); - gen_function_entry (fp, "static void\ncpu_page2_interp"); + gen_function_entry (fp, "static void\ncpu_page2_interp", + USE_SRC8 | USE_DST8); gen_interpreter_for_table (fp, indent_level, m6812_page2_opcodes, TABLE_SIZE(m6812_page2_opcodes), @@ -2095,7 +2105,8 @@ gen_interpreter (FILE *fp) gen_function_close (fp); /* Generate the interpretor entry point. */ - gen_function_entry (fp, "void\ncpu_interp_m6812"); + gen_function_entry (fp, "void\ncpu_interp_m6812", + USE_SRC8 | USE_DST8); gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes, TABLE_SIZE(m6812_page1_opcodes), diff --git a/sim/m68hc11/interp.c b/sim/m68hc11/interp.c index ee2acef..03b6db7 100644 --- a/sim/m68hc11/interp.c +++ b/sim/m68hc11/interp.c @@ -1,6 +1,6 @@ /* interp.c -- Simulator for Motorola 68HC11/68HC12 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Written by Stephane Carrez (stcarrez@nerim.fr) This file is part of GDB, the GNU debugger. @@ -468,16 +468,19 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) { sim_cpu *cpu; uint16 val; + int size = 2; cpu = STATE_CPU (sd, 0); switch (rn) { case A_REGNUM: val = cpu_get_a (cpu); + size = 1; break; case B_REGNUM: val = cpu_get_b (cpu); + size = 1; break; case D_REGNUM: @@ -502,6 +505,12 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case PSW_REGNUM: val = cpu_get_ccr (cpu); + size = 1; + break; + + case PAGE_REGNUM: + val = cpu_get_page (cpu); + size = 1; break; default: @@ -510,7 +519,7 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) } memory[0] = val >> 8; memory[1] = val & 0x0FF; - return 2; + return size; } int @@ -533,11 +542,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case A_REGNUM: cpu_set_a (cpu, val); - break; + return 1; case B_REGNUM: cpu_set_b (cpu, val); - break; + return 1; case X_REGNUM: cpu_set_x (cpu, val); @@ -557,7 +566,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case PSW_REGNUM: cpu_set_ccr (cpu, val); - break; + return 1; + + case PAGE_REGNUM: + cpu_set_page (cpu, val); + return 1; default: break; diff --git a/sim/m68hc11/m68hc11_sim.c b/sim/m68hc11/m68hc11_sim.c index d9fb807..fe5985f 100644 --- a/sim/m68hc11/m68hc11_sim.c +++ b/sim/m68hc11/m68hc11_sim.c @@ -1,6 +1,6 @@ /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Written by Stephane Carrez (stcarrez@nerim.fr) This file is part of GDB, GAS, and the GNU binutils. @@ -907,6 +907,60 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special) } break; + case M6812_CALL: + { + uint8 page; + uint16 addr; + + addr = cpu_fetch16 (cpu); + page = cpu_fetch8 (cpu); + + cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu)); + cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu)); + + cpu_set_page (cpu, page); + cpu_set_pc (cpu, addr); + } + break; + + case M6812_CALL_INDIRECT: + { + uint8 code; + uint16 addr; + uint8 page; + + code = memory_read8 (cpu, cpu_get_pc (cpu)); + /* Indirect addressing call has the page specified in the + memory location pointed to by the address. */ + if ((code & 0xE3) == 0xE3) + { + addr = cpu_get_indexed_operand_addr (cpu, 0); + page = memory_read8 (cpu, addr + 2); + addr = memory_read16 (cpu, addr); + } + else + { + /* Otherwise, page is in the opcode. */ + addr = cpu_get_indexed_operand16 (cpu, 0); + page = cpu_fetch8 (cpu); + } + cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu)); + cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu)); + cpu_set_page (cpu, page); + cpu_set_pc (cpu, addr); + } + break; + + case M6812_RTC: + { + uint8 page = cpu_m68hc12_pop_uint8 (cpu); + uint16 addr = cpu_m68hc12_pop_uint16 (cpu); + + cpu_set_page (cpu, page); + cpu_set_pc (cpu, addr); + } + break; + case M6812_ETBL: default: sim_engine_halt (CPU_STATE (cpu), cpu, NULL, diff --git a/sim/m68hc11/sim-main.h b/sim/m68hc11/sim-main.h index 75c3b5b..c8933a0 100644 --- a/sim/m68hc11/sim-main.h +++ b/sim/m68hc11/sim-main.h @@ -1,6 +1,6 @@ /* sim-main.h -- Simulator for Motorola 68HC11 & 68HC12 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Written by Stephane Carrez (stcarrez@nerim.fr) This file is part of GDB, the GNU debugger. @@ -80,6 +80,7 @@ enum cpu_type #define B_REGNUM 6 #define PSW_REGNUM 7 #define Z_REGNUM 8 +#define PAGE_REGNUM 9 typedef struct m6811_regs { unsigned short d; @@ -88,6 +89,7 @@ typedef struct m6811_regs { unsigned short sp; unsigned short pc; unsigned char ccr; + unsigned short page; } m6811_regs; @@ -126,6 +128,7 @@ enum M6811_Special /* 68HC12 instructions. */ M6812_BGND, M6812_CALL, + M6812_CALL_INDIRECT, M6812_IDIVS, M6812_EDIV, M6812_EDIVS, @@ -232,6 +235,7 @@ struct _sim_cpu { #define cpu_get_sp(PROC) ((PROC)->cpu_regs.sp) #define cpu_get_a(PROC) ((PROC->cpu_regs.d >> 8) & 0x0FF) #define cpu_get_b(PROC) ((PROC->cpu_regs.d) & 0x0FF) +#define cpu_get_page(PROC) (PROC->cpu_regs.page) /* 68HC12 specific and Motorola internal registers. */ #define cpu_get_tmp3(PROC) (0) @@ -240,10 +244,11 @@ struct _sim_cpu { #define cpu_set_d(PROC,VAL) (((PROC)->cpu_regs.d) = (VAL)) #define cpu_set_x(PROC,VAL) (((PROC)->cpu_regs.ix) = (VAL)) #define cpu_set_y(PROC,VAL) (((PROC)->cpu_regs.iy) = (VAL)) +#define cpu_set_page(PROC,VAL) ((PROC->cpu_regs.page) = (VAL)) /* 68HC12 specific and Motorola internal registers. */ #define cpu_set_tmp3(PROC,VAL) (0) -#define cpu_set_tmp2(PROC,VAL) (0) +#define cpu_set_tmp2(PROC,VAL) (void) (0) #if 0 /* This is a function in m68hc11_sim.c to keep track of the frame. */ @@ -287,11 +292,21 @@ extern void cpu_memory_exception (struct _sim_cpu *proc, uint16 addr, const char *message); +inline address_word +phys_to_virt (sim_cpu *cpu, address_word addr) +{ + if (addr >= 0x8000 && addr < 0xc000) + return ((address_word) (addr) - 0x8000) + + (((address_word) cpu->cpu_regs.page) << 14) + 0x01000000; + else + return (address_word) (addr); +} + inline uint8 memory_read8 (sim_cpu *cpu, uint16 addr) { uint8 val; - + if (sim_core_read_buffer (CPU_STATE (cpu), cpu, 0, &val, addr, 1) != 1) { cpu_memory_exception (cpu, SIM_SIGSEGV, addr, @@ -314,7 +329,7 @@ inline uint16 memory_read16 (sim_cpu *cpu, uint16 addr) { uint8 b[2]; - + if (sim_core_read_buffer (CPU_STATE (cpu), cpu, 0, b, addr, 2) != 2) { cpu_memory_exception (cpu, SIM_SIGSEGV, addr, @@ -523,6 +538,11 @@ extern void cpu_info (SIM_DESC sd, sim_cpu *proc); extern int cpu_initialize (SIM_DESC sd, sim_cpu *cpu); +/* Returns the address of a 68HC12 indexed operand. + Pre and post modifications are handled on the source register. */ +extern uint16 cpu_get_indexed_operand_addr (sim_cpu* cpu, int restrict); + +extern void cpu_return (sim_cpu *cpu); extern void cpu_set_sp (sim_cpu *cpu, uint16 val); extern int cpu_reset (sim_cpu *cpu); extern int cpu_restart (sim_cpu *cpu); |