From 63be8febf762353b62e794963fdc65f1280a7498 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Wed, 5 Nov 1997 08:17:26 +0000 Subject: [PATCH] Rewrite the MIPS simulator's memory model so that it uses the generic common/sim-core. Add support for 3, 5, 6, 7 byte transfers to sim core. --- sim/common/ChangeLog | 25 ++ sim/common/sim-core.c | 29 +- sim/common/sim-n-core.h | 255 ++++++++++++------ sim/mips/ChangeLog | 31 +++ sim/mips/Makefile.in | 1 + sim/mips/interp.c | 699 ++++++++++++------------------------------------ sim/mips/mips.igen | 16 +- sim/mips/sim-main.h | 22 +- 8 files changed, 437 insertions(+), 641 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index d97d81f..a75e522 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,28 @@ +Wed Nov 5 13:40:31 1997 Andrew Cagney + + * sim-core.h (DECLARE_SIM_CORE_WRITE_N. DECLARE_SIM_CORE_READ_N): + Add argument M, size of data type. + (sim_core_read_misaligned_3, sim_core_write_misaligned_3): + Declare, ditto for 5, 6 & 7 byte transfers. + (sim_core_write_unaligned_1, sim_core_write_unaligned_1): Define + as aligned variant. + + * sim-n-core.h (sim_core_trace_M): Rename from + sim_core_trace_N. Add nr_bytes argument. Replace transfer argument + with transfer type. Print transfer direction. Handle 1 and 2 byte + transfers. + (sim_core_read_unaligned_N, sim_core_write_unaligned_N): Trace + unaligned accesses. + (unsigned_M, T2H_M, H2T_M): Rename from unsigned_N, T2H_N, H2T_N. + Update all functions. + + * sim-core.c: Generate functions starting with 16 not 1. + (sim_core_read_unaligned_3): Generate. Ditto for 3 byte write and + all 5, 6 & 7 byte transfers. + + * sim-n-core.h (sim_core_read_misaligned_N, + sim_core_write_misaligned_N): Implement. + Mon Nov 3 15:03:04 1997 Andrew Cagney * sim-endian.h (U16_8): Implement diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c index f79c7c3..1a01359 100644 --- a/sim/common/sim-core.c +++ b/sim/common/sim-core.c @@ -755,24 +755,35 @@ sim_core_xor_write_buffer (SIM_DESC sd, /* define the read/write 1/2/4/8/16/word functions */ -#define N 1 +#define N 16 #include "sim-n-core.h" -#undef N -#define N 2 +#define N 8 +#include "sim-n-core.h" + +#define N 7 +#define M 8 +#include "sim-n-core.h" + +#define N 6 +#define M 8 +#include "sim-n-core.h" + +#define N 5 +#define M 8 #include "sim-n-core.h" -#undef N #define N 4 #include "sim-n-core.h" -#undef N -#define N 8 +#define N 3 +#define M 4 #include "sim-n-core.h" -#undef N -#define N 16 +#define N 2 +#include "sim-n-core.h" + +#define N 1 #include "sim-n-core.h" -#undef N #endif diff --git a/sim/common/sim-n-core.h b/sim/common/sim-n-core.h index b7bc631..2a3cac8 100644 --- a/sim/common/sim-n-core.h +++ b/sim/common/sim-n-core.h @@ -22,74 +22,113 @@ #ifndef N #error "N must be #defined" #endif +#ifndef M +#define M N +#endif #include "sim-xcat.h" /* NOTE: see end of file for #undef of these macros */ -#define unsigned_N XCONCAT2(unsigned_,N) -#define T2H_N XCONCAT2(T2H_,N) -#define H2T_N XCONCAT2(H2T_,N) + +#define unsigned_M XCONCAT2(unsigned_,M) + +#define T2H_M XCONCAT2(T2H_,M) +#define H2T_M XCONCAT2(H2T_,M) +#define SWAP_M XCONCAT2(SWAP_,M) #define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N) -#define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N) #define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N) +#define sim_core_read_misaligned_N XCONCAT2(sim_core_read_misaligned_,N) +#define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N) #define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N) -#define sim_core_trace_N XCONCAT2(sim_core_trace_,N) +#define sim_core_write_misaligned_N XCONCAT2(sim_core_write_misaligned_,N) +#define sim_core_trace_M XCONCAT2(sim_core_trace_,M) /* TAGS: sim_core_trace_1 sim_core_trace_2 */ /* TAGS: sim_core_trace_4 sim_core_trace_8 */ -/* TAGS: sim_core_trace_16 sim_core_trace_word */ +/* TAGS: sim_core_trace_16 */ +#if (M == N) STATIC_SIM_CORE(void) -sim_core_trace_N (sim_cpu *cpu, +sim_core_trace_M (sim_cpu *cpu, sim_cia cia, int line_nr, - char *transfer, + transfer_type type, sim_core_maps map, address_word addr, - unsigned_N val) + unsigned_M val, + int nr_bytes) { -#if (N == 16) + char *transfer = (type == read_transfer ? "read" : "write"); + char *direction = (type == read_transfer ? "->" : "<-"); +#if (M == 16) trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.h:%d: %s-%d %s:0x%08lx -> 0x%08lx%08lx%08lx%08lx\n", + "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx%08lx%08lx%08lx\n", line_nr, - transfer, sizeof (unsigned_N), + transfer, nr_bytes, sim_core_map_to_str (map), (unsigned long) addr, + direction, (unsigned long) V4_16 (val, 0), (unsigned long) V4_16 (val, 1), (unsigned long) V4_16 (val, 2), (unsigned long) V4_16 (val, 3)); #endif -#if (N == 8) +#if (M == 8) trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.h:%d: %s-%d %s:0x%08lx -> 0x%08lx%08lx\n", + "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx%08lx\n", line_nr, - transfer, sizeof (unsigned_N), + transfer, nr_bytes, sim_core_map_to_str (map), (unsigned long) addr, + direction, (unsigned long) V4_8 (val, 0), (unsigned long) V4_8 (val, 1)); #endif -#if (N == 4) +#if (M == 4) + trace_printf (CPU_STATE (cpu), cpu, + "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx\n", + line_nr, + transfer, + nr_bytes, + sim_core_map_to_str (map), + (unsigned long) addr, + direction, + (unsigned long) val); +#endif +#if (M == 2) trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.h:%d: %s-%d %s:0x%08lx -> 0x%0*lx\n", + "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%04lx\n", line_nr, - transfer, sizeof (unsigned_N), + transfer, + nr_bytes, sim_core_map_to_str (map), (unsigned long) addr, - sizeof (unsigned_N) * 2, + direction, + (unsigned long) val); +#endif +#if (M == 1) + trace_printf (CPU_STATE (cpu), cpu, + "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%02lx\n", + line_nr, + transfer, + nr_bytes, + sim_core_map_to_str (map), + (unsigned long) addr, + direction, (unsigned long) val); #endif } +#endif /* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */ /* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */ -/* TAGS: sim_core_read_aligned_16 sim_core_read_aligned_word */ +/* TAGS: sim_core_read_aligned_16 */ -INLINE_SIM_CORE(unsigned_N) +#if (M == N) +INLINE_SIM_CORE(unsigned_M) sim_core_read_aligned_N(sim_cpu *cpu, sim_cia cia, sim_core_maps map, @@ -97,52 +136,46 @@ sim_core_read_aligned_N(sim_cpu *cpu, { sim_cpu_core *cpu_core = CPU_CORE (cpu); sim_core_common *core = &cpu_core->common; - unsigned_N val; + unsigned_M val; sim_core_mapping *mapping; address_word addr; #if WITH_XOR_ENDIAN != 0 if (WITH_XOR_ENDIAN) - addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN]; + addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN]; else #endif addr = xaddr; - mapping = sim_core_find_mapping (core, map, - addr, - sizeof (unsigned_N), - read_transfer, - 1 /*abort*/, cpu, cia); + mapping = sim_core_find_mapping (core, map, addr, N, read_transfer, 1 /*abort*/, cpu, cia); #if (WITH_DEVICES) if (WITH_CALLBACK_MEMORY && mapping->device != NULL) { - unsigned_N data; - if (device_io_read_buffer (mapping->device, - &data, - mapping->space, - addr, - sizeof (unsigned_N)) != sizeof (unsigned_N)) + unsigned_M data; + if (device_io_read_buffer (mapping->device, &data, mapping->space, addr, N) != N) device_error (mapping->device, "internal error - %s - io_read_buffer should not fail", XSTRING (sim_core_read_aligned_N)); - val = T2H_N (data); + val = T2H_M (data); } else #endif - val = T2H_N (*(unsigned_N*) sim_core_translate (mapping, addr)); - PROFILE_COUNT_CORE (cpu, addr, sizeof (unsigned_N), map); + val = T2H_M (*(unsigned_M*) sim_core_translate (mapping, addr)); + PROFILE_COUNT_CORE (cpu, addr, N, map); if (TRACE_P (cpu, TRACE_CORE_IDX)) - sim_core_trace_N (cpu, cia, __LINE__, "read", map, addr, val); + sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N); return val; } +#endif /* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */ /* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */ -/* TAGS: sim_core_read_unaligned_16 sim_core_read_unaligned_word */ +/* TAGS: sim_core_read_unaligned_16 */ -INLINE_SIM_CORE(unsigned_N) +#if (M == N && N > 1) +INLINE_SIM_CORE(unsigned_M) sim_core_read_unaligned_N(sim_cpu *cpu, sim_cia cia, sim_core_maps map, address_word addr) { - int alignment = sizeof (unsigned_N) - 1; + int alignment = N - 1; /* if hardwired to forced alignment just do it */ if (WITH_ALIGNMENT == FORCED_ALIGNMENT) return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment); @@ -152,20 +185,18 @@ sim_core_read_unaligned_N(sim_cpu *cpu, switch (CURRENT_ALIGNMENT) { case STRICT_ALIGNMENT: - SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, - sizeof (unsigned_N), addr, + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, read_transfer, sim_core_unaligned_signal); case NONSTRICT_ALIGNMENT: { - unsigned_N val; - if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, - sizeof(unsigned_N)) - != sizeof(unsigned_N)) - SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, - sizeof (unsigned_N), addr, + unsigned_M val; + if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N) + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, read_transfer, sim_core_unaligned_signal); - val = T2H_N(val); - PROFILE_COUNT_CORE (cpu, addr, sizeof (unsigned_N), map); + val = T2H_M(val); + PROFILE_COUNT_CORE (cpu, addr, N, map); + if (TRACE_P (cpu, TRACE_CORE_IDX)) + sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N); return val; } case FORCED_ALIGNMENT: @@ -180,22 +211,49 @@ sim_core_read_unaligned_N(sim_cpu *cpu, XSTRING (sim_core_read_unaligned_N)); /* to keep some compilers happy, we return a dummy */ { - unsigned_N val[1] = { }; + unsigned_M val[1] = { }; return val[0]; } } } +#endif + +/* TAGS: sim_core_read_misaligned_3 sim_core_read_misaligned_5 */ +/* TAGS: sim_core_read_misaligned_6 sim_core_read_misaligned_7 */ + +#if (M != N) +INLINE_SIM_CORE(unsigned_M) +sim_core_read_misaligned_N(sim_cpu *cpu, + sim_cia cia, + sim_core_maps map, + address_word addr) +{ + unsigned_M val = 0; + if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N) + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, + read_transfer, sim_core_unaligned_signal); + if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER) + val = SWAP_M (val); + if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) + val >>= (M - N) * 8; + PROFILE_COUNT_CORE (cpu, addr, N, map); + if (TRACE_P (cpu, TRACE_CORE_IDX)) + sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N); + return val; +} +#endif /* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */ /* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */ -/* TAGS: sim_core_write_aligned_16 sim_core_write_aligned_word */ +/* TAGS: sim_core_write_aligned_16 */ +#if (M == N) INLINE_SIM_CORE(void) sim_core_write_aligned_N(sim_cpu *cpu, sim_cia cia, sim_core_maps map, address_word xaddr, - unsigned_N val) + unsigned_M val) { sim_cpu_core *cpu_core = CPU_CORE (cpu); sim_core_common *core = &cpu_core->common; @@ -203,48 +261,40 @@ sim_core_write_aligned_N(sim_cpu *cpu, address_word addr; #if WITH_XOR_ENDIAN != 0 if (WITH_XOR_ENDIAN) - addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN]; + addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN]; else #endif addr = xaddr; - mapping = sim_core_find_mapping(core, map, - addr, - sizeof (unsigned_N), - write_transfer, - 1 /*abort*/, cpu, cia); + mapping = sim_core_find_mapping (core, map, addr, N, write_transfer, 1 /*abort*/, cpu, cia); #if (WITH_DEVICES) if (WITH_CALLBACK_MEMORY && mapping->device != NULL) { - unsigned_N data = H2T_N (val); - if (device_io_write_buffer (mapping->device, - &data, - mapping->space, - addr, - sizeof (unsigned_N), /* nr_bytes */ - cpu, - cia) != sizeof (unsigned_N)) + unsigned_M data = H2T_M (val); + if (device_io_write_buffer (mapping->device, &data, mapping->space, addr, N, cpu, cia) != N) device_error (mapping->device, "internal error - %s - io_write_buffer should not fail", XSTRING (sim_core_write_aligned_N)); } else #endif - *(unsigned_N*) sim_core_translate (mapping, addr) = H2T_N (val); - PROFILE_COUNT_CORE (cpu, addr, sizeof (unsigned_N), map); + *(unsigned_M*) sim_core_translate (mapping, addr) = H2T_M (val); + PROFILE_COUNT_CORE (cpu, addr, N, map); if (TRACE_P (cpu, TRACE_CORE_IDX)) - sim_core_trace_N (cpu, cia, __LINE__, "write", map, addr, val); + sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N); } +#endif /* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */ /* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */ -/* TAGS: sim_core_write_unaligned_16 sim_core_write_unaligned_word */ +/* TAGS: sim_core_write_unaligned_16 */ +#if (M == N && N > 1) INLINE_SIM_CORE(void) sim_core_write_unaligned_N(sim_cpu *cpu, sim_cia cia, sim_core_maps map, address_word addr, - unsigned_N val) + unsigned_M val) { - int alignment = sizeof (unsigned_N) - 1; + int alignment = N - 1; /* if hardwired to forced alignment just do it */ if (WITH_ALIGNMENT == FORCED_ALIGNMENT) sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val); @@ -254,20 +304,18 @@ sim_core_write_unaligned_N(sim_cpu *cpu, switch (CURRENT_ALIGNMENT) { case STRICT_ALIGNMENT: - SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, - sizeof (unsigned_N), addr, + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, write_transfer, sim_core_unaligned_signal); break; case NONSTRICT_ALIGNMENT: { - unsigned_N val = H2T_N (val); - if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &val, addr, - sizeof(unsigned_N)) - != sizeof(unsigned_N)) - SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, - sizeof (unsigned_N), addr, + unsigned_M data = H2T_M (val); + if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N) + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, write_transfer, sim_core_unaligned_signal); - PROFILE_COUNT_CORE (cpu, addr, sizeof (unsigned_N), map); + PROFILE_COUNT_CORE (cpu, addr, N, map); + if (TRACE_P (cpu, TRACE_CORE_IDX)) + sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N); break; } case FORCED_ALIGNMENT: @@ -285,14 +333,45 @@ sim_core_write_unaligned_N(sim_cpu *cpu, break; } } +#endif + +/* TAGS: sim_core_write_misaligned_3 sim_core_write_misaligned_5 */ +/* TAGS: sim_core_write_misaligned_6 sim_core_write_misaligned_7 */ + +#if (M != N) +INLINE_SIM_CORE(void) +sim_core_write_misaligned_N(sim_cpu *cpu, + sim_cia cia, + sim_core_maps map, + address_word addr, + unsigned_M val) +{ + unsigned_M data = val; + if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) + data <<= (M - N) * 8; + if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER) + data = SWAP_M (data); + if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N) + SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr, + write_transfer, sim_core_unaligned_signal); + PROFILE_COUNT_CORE (cpu, addr, N, map); + if (TRACE_P (cpu, TRACE_CORE_IDX)) + sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N); +} +#endif /* NOTE: see start of file for #define of these macros */ -#undef unsigned_N -#undef T2H_N -#undef H2T_N +#undef unsigned_M +#undef T2H_M +#undef H2T_M +#undef SWAP_M #undef sim_core_read_aligned_N -#undef sim_core_write_aligned_N #undef sim_core_read_unaligned_N +#undef sim_core_read_misaligned_N +#undef sim_core_write_aligned_N #undef sim_core_write_unaligned_N -#undef sim_core_trace_N +#undef sim_core_write_misaligned_N +#undef sim_core_trace_M +#undef M +#undef N diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index 1d1ef9f..7da3d49 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,34 @@ +Wed Nov 5 12:19:56 1997 Andrew Cagney + + * sim-main.h (MAX_INSNS, INSN_NAME): Define. + + * interp.c (load_memory, store_memory): Delete parameter RAW. + (sim_read, sim_write): Use sim_core_{read,write}_buffer directly + bypassing {load,store}_memory. + + * sim-main.h (ByteSwapMem): Delete definition. + + * Makefile.in (SIM_OBJS): Add sim-memopt module. + + * interp.c (sim_do_command, sim_commands): Delete mips specific + commands. Handled by module sim-options. + + * sim-main.h (SIM_HAVE_FLATMEM): Undefine, use sim-core.o module. + (WITH_MODULO_MEMORY): Define. + + * interp.c (sim_info): Delete code printing memory size. + + * interp.c (mips_size): Nee sim_size, delete function. + (power2): Delete. + (monitor, monitor_base, monitor_size): Delete global variables. + (sim_open, sim_close): Delete code creating monitor and other + memory regions. Use sim-memopts module, via sim_do_commandf, to + manage memory regions. + (load_memory, store_memory): Use sim-core for memory model. + + * interp.c (address_translation): Delete all memory map code + except line forcing 32 bit addresses. + Wed Nov 5 11:21:11 1997 Andrew Cagney * sim-main.h (WITH_TRACE): Delete definition. Enables common diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in index 1b5e503..c8e42c0 100644 --- a/sim/mips/Makefile.in +++ b/sim/mips/Makefile.in @@ -38,6 +38,7 @@ SIM_OBJS = \ sim-config.o \ sim-endian.o \ sim-engine.o \ + sim-memopt.o \ sim-stop.o \ sim-resume.o \ sim-reason.o \ diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 26da8ef..375a45a 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -19,11 +19,6 @@ NOTEs: -We only need to take account of the target endianness when moving data -between the simulator and the host. We do not need to worry about the -endianness of the host, since this sim code and GDB are executing in -the same process. - The IDT monitor (found on the VR4300 board), seems to lie about register contents. It seems to treat the registers as sign-extended 32-bit values. This cause *REAL* problems when single-stepping 64-bit @@ -110,9 +105,6 @@ char* pr_uword64 PARAMS ((uword64 addr)); static void dotrace PARAMS((SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)); static void ColdReset PARAMS((SIM_DESC sd)); -static long getnum PARAMS((SIM_DESC sd, char *value)); -static unsigned int power2 PARAMS((unsigned int value)); -static void mips_size PARAMS((SIM_DESC sd, int n)); /*---------------------------------------------------------------------------*/ @@ -150,11 +142,6 @@ static void mips_size PARAMS((SIM_DESC sd, int n)); #define MONITOR_SIZE (1 << 11) #define MEM_SIZE (2 << 20) -/* Simple run-time monitor support */ -static unsigned char *monitor = NULL; -static ut_reg monitor_base = MONITOR_BASE; -static unsigned monitor_size = MONITOR_SIZE; /* power-of-2 */ - #if defined(TRACE) static char *tracefile = "trace.din"; /* default filename for trace log */ static FILE *tracefh = NULL; @@ -274,17 +261,24 @@ sim_open (kind, cb, abfd, argv) STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event; - /* memory defaults (unless sim_size was here first) */ - if (STATE_MEM_SIZE (sd) == 0) - STATE_MEM_SIZE (sd) = MEM_SIZE; - STATE_MEM_BASE (sd) = K1BASE; - STATE = 0; if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) return 0; sim_add_option_table (sd, mips_options); + /* Allocate core managed memory */ + + /* the monitor */ + sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE); + /* For compatibility with the old code - under this (at level one) + are the kernel spaces K0 & K1. Both of these map to a single + smaller sub region */ + sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x", + K1BASE, K0SIZE, + MEM_SIZE, /* actual size */ + K0BASE); + /* getopt will print the error message so we just have to exit if this fails. FIXME: Hmmm... in the case of gdb we need getopt to call print_filtered. */ @@ -382,24 +376,6 @@ sim_open (kind, cb, abfd, argv) /* end-sanitize-r5900 */ } - - /* FIXME: In the future both of these malloc's can be replaced by - calls to sim-core. */ - - /* If the host has "mmap" available we could use it to provide a - very large virtual address space for the simulator, since memory - would only be allocated within the "mmap" space as it is - accessed. This can also be linked to the architecture specific - support, required to simulate the MMU. */ - mips_size(sd, STATE_MEM_SIZE (sd)); - /* NOTE: The above will also have enabled any profiling state! */ - - /* Create the monitor address space as well */ - monitor = (unsigned char *)calloc(1,monitor_size); - if (!monitor) - fprintf(stderr,"Not enough VM for monitor simulation (%d bytes)\n", - monitor_size); - #if defined(TRACE) if (STATE & simTRACE) open_trace(sd); @@ -505,10 +481,6 @@ sim_close (sd, quitting) STATE &= ~simTRACE; #endif /* TRACE */ - if (STATE_MEMORY (sd) != NULL) - free(STATE_MEMORY (sd)); /* cfree not available on all hosts */ - STATE_MEMORY (sd) = NULL; - return; } @@ -537,7 +509,8 @@ sim_write (sd,addr,buffer,size) int cca; if (!AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW)) break; - StoreMemory (cca, AccessLength_BYTE, buffer[index], 0, paddr, vaddr, isRAW); + if (sim_core_write_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1) + break; } return(index); @@ -561,12 +534,11 @@ sim_read (sd,addr,buffer,size) { address_word vaddr = (address_word)addr + index; address_word paddr; - unsigned64 value; int cca; if (!AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &cca, isTARGET, isRAW)) break; - LoadMemory (&value, NULL, cca, AccessLength_BYTE, paddr, vaddr, isDATA, isRAW); - buffer[index] = (unsigned char)(value&0xFF); + if (sim_core_read_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1) + break; } return(index); @@ -648,10 +620,6 @@ sim_info (sd,verbose) (PROCESSOR_64BIT ? 64 : 32), (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little")); - sim_io_printf (sd, "0x%08X bytes of memory at 0x%s\n", - STATE_MEM_SIZE (sd), - pr_addr (STATE_MEM_BASE (sd))); - #if !defined(FASTSIM) /* It would be a useful feature, if when performing multi-cycle simulations (rather than single-stepping) we keep the start and @@ -712,111 +680,17 @@ sim_create_inferior (sd, abfd, argv,env) return SIM_RC_OK; } -typedef enum {e_terminate,e_help,e_setmemsize,e_reset} e_cmds; - -static struct t_sim_command { - e_cmds id; - const char *name; - const char *help; -} sim_commands[] = { - {e_help, "help", ": Show MIPS simulator private commands"}, - {e_setmemsize,"set-memory-size"," : Specify amount of memory simulated"}, - {e_reset, "reset-system", ": Reset the simulated processor"}, - {e_terminate, NULL} -}; - void sim_do_command (sd,cmd) SIM_DESC sd; char *cmd; { - struct t_sim_command *cptr; - - if (!(cmd && *cmd != '\0')) - cmd = "help"; - - /* NOTE: Accessed from the GDB "sim" commmand: */ - for (cptr = sim_commands; cptr && cptr->name; cptr++) - if (strncmp (cmd, cptr->name, strlen(cptr->name)) == 0) - { - cmd += strlen(cptr->name); - switch (cptr->id) { - case e_help: /* no arguments */ - { /* no arguments */ - struct t_sim_command *lptr; - sim_io_printf(sd,"List of MIPS simulator commands:\n"); - for (lptr = sim_commands; lptr->name; lptr++) - sim_io_printf(sd,"%s %s\n",lptr->name,lptr->help); - sim_args_command (sd, "help"); - } - break; - - case e_setmemsize: /* memory size argument */ - { - unsigned int newsize = (unsigned int)getnum(sd, cmd); - mips_size(sd, newsize); - } - break; - - case e_reset: /* no arguments */ - ColdReset(sd); - /* NOTE: See the comments in sim_open() relating to device - initialisation. */ - break; - - default: - sim_io_printf(sd,"FATAL: Matched \"%s\", but failed to match command id %d.\n",cmd,cptr->id); - break; - } - break; - } - - if (!(cptr->name)) - { - /* try for a common command when the sim specific lookup fails */ - if (sim_args_command (sd, cmd) != SIM_RC_OK) - sim_io_printf(sd,"Error: \"%s\" is not a valid MIPS simulator command.\n",cmd); - } - - return; + if (sim_args_command (sd, cmd) != SIM_RC_OK) + sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n", + cmd); } /*---------------------------------------------------------------------------*/ -/* NOTE: The following routines do not seem to be used by GDB at the - moment. However, they may be useful to the standalone simulator - world. */ - - -static void -mips_size(sd, newsize) - SIM_DESC sd; - int newsize; -{ - char *new; - /* Used by "run", and internally, to set the simulated memory size */ - if (newsize == 0) { - sim_io_printf(sd,"Zero not valid: Memory size still 0x%08X bytes\n",STATE_MEM_SIZE (sd)); - return; - } - newsize = power2(newsize); - if (STATE_MEMORY (sd) == NULL) - new = (char *)calloc(64,(STATE_MEM_SIZE (sd) / 64)); - else - new = (char *)realloc(STATE_MEMORY (sd),newsize); - if (new == NULL) { - if (STATE_MEMORY (sd) == NULL) - sim_io_error(sd,"Not enough VM for simulation memory of 0x%08X bytes",STATE_MEM_SIZE (sd)); - else - sim_io_eprintf(sd,"Failed to resize memory (still 0x%08X bytes)\n",STATE_MEM_SIZE (sd)); - } else { - STATE_MEM_SIZE (sd) = (unsigned)newsize; - STATE_MEMORY (sd) = new; - } - return; -} - - -/*---------------------------------------------------------------------------*/ /*-- Private simulator support interface ------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -1215,48 +1089,6 @@ mips16_entry (sd,insn) } } -static unsigned int -power2(value) - unsigned int value; -{ - int loop,tmp; - - /* Round *UP* to the nearest power-of-2 if not already one */ - if (value != (value & ~(value - 1))) { - for (tmp = value, loop = 0; (tmp != 0); loop++) - tmp >>= 1; - value = (1 << loop); - } - - return(value); -} - -static long -getnum(sd,value) - SIM_DESC sd; - char *value; -{ - long num; - char *end; - - num = strtol(value,&end,10); - if (end == value) - sim_io_printf(sd,"Warning: Invalid number \"%s\" ignored, using zero\n",value); - else { - if (*end && ((tolower(*end) == 'k') || (tolower(*end) == 'm'))) { - if (tolower(*end) == 'k') - num *= (1 << 10); - else - num *= (1 << 20); - end++; - } - if (*end) - sim_io_printf(sd,"Warning: Spurious characters \"%s\" at end of number ignored\n",end); - } - - return(num); -} - /*-- trace support ----------------------------------------------------------*/ /* The TRACE support is provided (if required) in the memory accessing @@ -1408,57 +1240,14 @@ address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,raw) addressess through (mostly) unchanged. */ vAddr &= 0xFFFFFFFF; - /* Treat the kernel memory spaces identically for the moment: */ - if ((STATE_MEM_BASE (sd) == K1BASE) && (vAddr >= K0BASE) && (vAddr < (K0BASE + K0SIZE))) - vAddr += (K1BASE - K0BASE); - - /* Also assume that the K1BASE memory wraps. This is required to - allow the PMON run-time __sizemem() routine to function (without - having to provide exception simulation). NOTE: A kludge to work - around the fact that the monitor memory is currently held in the - K1BASE space. */ - if (((vAddr < monitor_base) || (vAddr >= (monitor_base + monitor_size))) && (vAddr >= K1BASE && vAddr < (K1BASE + K1SIZE))) - vAddr = (K1BASE | (vAddr & (STATE_MEM_SIZE (sd) - 1))); - *pAddr = vAddr; /* default for isTARGET */ *CCA = Uncached; /* not used for isHOST */ - /* NOTE: This is a duplicate of the code that appears in the - LoadMemory and StoreMemory functions. They should be merged into - a single function (that can be in-lined if required). */ - if ((vAddr >= STATE_MEM_BASE (sd)) && (vAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) { - /* do nothing */ - } else if ((vAddr >= monitor_base) && (vAddr < (monitor_base + monitor_size))) { - /* do nothing */ - } else { -#ifdef DEBUG - sim_io_eprintf(sd,"Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC)); -#endif /* DEBUG */ - res = 0; /* AddressTranslation has failed */ - *pAddr = (SIM_ADDR)-1; - if (!raw) /* only generate exceptions on real memory transfers */ - { - if (IorD == isINSTRUCTION) - SignalExceptionInstructionFetch (); - else if (LorS == isSTORE) - SignalExceptionAddressStore (); - else - SignalExceptionAddressLoad (); - } -#ifdef DEBUG - else - /* This is a normal occurance during gdb operation, for instance - trying to print parameters at function start before they have - been setup, and hence we should not print a warning except - when debugging the simulator. */ - sim_io_eprintf(sd,"AddressTranslation for %s %s from 0x%s failed\n",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr)); -#endif - } - return(res); } -/* Description from page A-23 of the "MIPS IV Instruction Set" manual (revision 3.1) */ +/* Description from page A-23 of the "MIPS IV Instruction Set" manual + (revision 3.1) */ /* Prefetch data from memory. Prefetch is an advisory instruction for which an implementation specific action is taken. The action taken may increase performance, but must not change the meaning of the @@ -1481,7 +1270,8 @@ prefetch(sd,CCA,pAddr,vAddr,DATA,hint) return; } -/* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */ +/* Description from page A-22 of the "MIPS IV Instruction Set" manual + (revision 3.1) */ /* Load a value from memory. Use the cache and main memory as specified in the Cache Coherence Algorithm (CCA) and the sort of access (IorD) to find the contents of AccessLength memory bytes @@ -1497,7 +1287,7 @@ prefetch(sd,CCA,pAddr,vAddr,DATA,hint) satisfy a load reference. At a minimum, the block is the entire memory element. */ void -load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) +load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD) SIM_DESC sd; uword64* memvalp; uword64* memval1p; @@ -1506,173 +1296,108 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) address_word pAddr; address_word vAddr; int IorD; - int raw; { uword64 value = 0; uword64 value1 = 0; #ifdef DEBUG - if (STATE_MEMORY (sd) == NULL) - sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(raw ? "isRAW" : "isREAL")); + sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION")); #endif /* DEBUG */ #if defined(WARN_MEM) if (CCA != uncached) - sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA); - - if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) { - /* In reality this should be a Bus Error */ - sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr)); - } + sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA); #endif /* WARN_MEM */ - /* Decide which physical memory locations are being dealt with. At - this point we should be able to split the pAddr bits into the - relevant address map being simulated. */ - /* If the "raw" variable is set, the memory read being performed - should *NOT* update any I/O state or affect the CPU state - (including statistics gathering). The parameter MEMVALP is least - significant byte justified. */ - /* If instruction fetch then we need to check that the two lo-order bits are zero, otherwise raise a InstructionFetch exception: */ if ((IorD == isINSTRUCTION) && ((pAddr & 0x3) != 0) && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0))) - SignalExceptionInstructionFetch (); - else { - unsigned int index = 0; - unsigned char *mem = NULL; + SignalExceptionInstructionFetch (); + + if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) + { + /* In reality this should be a Bus Error */ + sim_io_error (sd, "AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n", + AccessLength, + (LOADDRMASK + 1) << 2, + pr_addr (pAddr)); + } #if defined(TRACE) - if (!raw) - dotrace(sd,tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction")); + dotrace(sd,tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction")); #endif /* TRACE */ + + /* Read the specified number of bytes from memory. Adjust for + host/target byte ordering/ Align the least significant byte + read. */ - /* NOTE: Quicker methods of decoding the address space can be used - when a real memory map is being simulated (i.e. using hi-order - address bits to select device). */ - if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) { - index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1)); - mem = STATE_MEMORY (sd); - } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) { - index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1)); - mem = monitor; - } - if (mem == NULL) - sim_io_error(sd,"Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr)); - else { - /* If we obtained the endianness of the host, and it is the same - as the target memory system we can optimise the memory - accesses. However, without that information we must perform - slow transfer, and hope that the compiler optimisation will - merge successive loads. */ - - /* In reality we should always be loading a doubleword value (or - word value in 32bit memory worlds). The external code then - extracts the required bytes. However, to keep performance - high we only load the required bytes into the relevant - slots. */ - if (BigEndianMem) - switch (AccessLength) { /* big-endian memory */ - case AccessLength_QUADWORD : - value1 |= ((uword64)mem[index++] << 56); - case 14: /* AccessLength is one less than datalen */ - value1 |= ((uword64)mem[index++] << 48); - case 13: - value1 |= ((uword64)mem[index++] << 40); - case 12: - value1 |= ((uword64)mem[index++] << 32); - case 11: - value1 |= ((unsigned int)mem[index++] << 24); - case 10: - value1 |= ((unsigned int)mem[index++] << 16); - case 9: - value1 |= ((unsigned int)mem[index++] << 8); - case 8: - value1 |= mem[index]; - - case AccessLength_DOUBLEWORD : - value |= ((uword64)mem[index++] << 56); - case AccessLength_SEPTIBYTE : - value |= ((uword64)mem[index++] << 48); - case AccessLength_SEXTIBYTE : - value |= ((uword64)mem[index++] << 40); - case AccessLength_QUINTIBYTE : - value |= ((uword64)mem[index++] << 32); - case AccessLength_WORD : - value |= ((unsigned int)mem[index++] << 24); - case AccessLength_TRIPLEBYTE : - value |= ((unsigned int)mem[index++] << 16); - case AccessLength_HALFWORD : - value |= ((unsigned int)mem[index++] << 8); - case AccessLength_BYTE : - value |= mem[index]; - break; - } - else { - index += (AccessLength + 1); - switch (AccessLength) { /* little-endian memory */ - case AccessLength_QUADWORD : - value1 |= ((uword64)mem[--index] << 56); - case 14: /* AccessLength is one less than datalen */ - value1 |= ((uword64)mem[--index] << 48); - case 13: - value1 |= ((uword64)mem[--index] << 40); - case 12: - value1 |= ((uword64)mem[--index] << 32); - case 11: - value1 |= ((uword64)mem[--index] << 24); - case 10: - value1 |= ((uword64)mem[--index] << 16); - case 9: - value1 |= ((uword64)mem[--index] << 8); - case 8: - value1 |= ((uword64)mem[--index] << 0); - - case AccessLength_DOUBLEWORD : - value |= ((uword64)mem[--index] << 56); - case AccessLength_SEPTIBYTE : - value |= ((uword64)mem[--index] << 48); - case AccessLength_SEXTIBYTE : - value |= ((uword64)mem[--index] << 40); - case AccessLength_QUINTIBYTE : - value |= ((uword64)mem[--index] << 32); - case AccessLength_WORD : - value |= ((uword64)mem[--index] << 24); - case AccessLength_TRIPLEBYTE : - value |= ((uword64)mem[--index] << 16); - case AccessLength_HALFWORD : - value |= ((uword64)mem[--index] << 8); - case AccessLength_BYTE : - value |= ((uword64)mem[--index] << 0); - break; - } + switch (AccessLength) + { + case AccessLength_QUADWORD : + { + unsigned_16 val = sim_core_read_aligned_16 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + value1 = VH8_16 (val); + value = VL8_16 (val); + break; } - + case AccessLength_DOUBLEWORD : + value = sim_core_read_aligned_8 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + break; + case AccessLength_SEPTIBYTE : + value = sim_core_read_misaligned_7 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + case AccessLength_SEXTIBYTE : + value = sim_core_read_misaligned_6 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + case AccessLength_QUINTIBYTE : + value = sim_core_read_misaligned_5 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + case AccessLength_WORD : + value = sim_core_read_aligned_4 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + break; + case AccessLength_TRIPLEBYTE : + value = sim_core_read_misaligned_3 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + case AccessLength_HALFWORD : + value = sim_core_read_aligned_2 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + break; + case AccessLength_BYTE : + value = sim_core_read_aligned_1 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_read_map, pAddr); + break; + default: + abort (); + } + #ifdef DEBUG - printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n", - (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value)); + printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n", + (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value)); #endif /* DEBUG */ - - /* When dealing with raw memory accesses there is no need to - deal with shifts. */ - if (AccessLength <= AccessLength_DOUBLEWORD) { - if (!raw) { /* do nothing for raw accessess */ - if (BigEndianMem) - value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8); - else /* little-endian only needs to be shifted up to the correct byte offset */ - value <<= ((pAddr & LOADDRMASK) * 8); - } - } - + + /* See also store_memory. */ + if (AccessLength <= AccessLength_DOUBLEWORD) + { + if (BigEndianMem) + /* for big endian target, byte (pAddr&LOADDRMASK == 0) is + shifted to the most significant byte position. */ + value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8); + else + /* For little endian target, byte (pAddr&LOADDRMASK == 0) + is already in the correct postition. */ + value <<= ((pAddr & LOADDRMASK) * 8); + } + #ifdef DEBUG - printf("DBG: LoadMemory() : shifted value = 0x%s%s\n", - pr_uword64(value1),pr_uword64(value)); + printf("DBG: LoadMemory() : shifted value = 0x%s%s\n", + pr_uword64(value1),pr_uword64(value)); #endif /* DEBUG */ - } - } - + *memvalp = value; if (memval1p) *memval1p = value1; } @@ -1692,7 +1417,7 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) will be changed. */ void -store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) +store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr) SIM_DESC sd; int CCA; int AccessLength; @@ -1700,169 +1425,89 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) uword64 MemElem1; /* High order 64 bits */ address_word pAddr; address_word vAddr; - int raw; { #ifdef DEBUG - sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s,%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr),(raw ? "isRAW" : "isREAL")); + sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr)); #endif /* DEBUG */ - + #if defined(WARN_MEM) if (CCA != uncached) - sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA); - - if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) - sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr)); + sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA); #endif /* WARN_MEM */ - + + if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) + sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr)); + #if defined(TRACE) - if (!raw) - dotrace(sd,tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store"); + dotrace(sd,tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store"); #endif /* TRACE */ - - /* See the comments in the LoadMemory routine about optimising - memory accesses. Also if we wanted to make the simulator smaller, - we could merge a lot of this code with the LoadMemory - routine. However, this would slow the simulator down with - run-time conditionals. */ - - /* If the "raw" variable is set, the memory read being performed - should *NOT* update any I/O state or affect the CPU state - (including statistics gathering). The parameter MEMELEM is least - significant byte justified. */ - { - unsigned int index = 0; - unsigned char *mem = NULL; - - if ((pAddr >= STATE_MEM_BASE (sd)) && (pAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) { - index = ((unsigned int)(pAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1)); - mem = STATE_MEMORY (sd); - } else if ((pAddr >= monitor_base) && (pAddr < (monitor_base + monitor_size))) { - index = ((unsigned int)(pAddr - monitor_base) & (monitor_size - 1)); - mem = monitor; - } - - if (mem == NULL) - sim_io_error(sd,"Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr)); - else { - int shift = 0; - + #ifdef DEBUG - printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem)); + printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem)); #endif /* DEBUG */ - - if (AccessLength <= AccessLength_DOUBLEWORD) { - if (BigEndianMem) { - if (raw) - /* need to shift raw (least significant byte aligned) data - into correct byte slots */ - shift = ((7 - AccessLength) * 8); - else /* real memory access */ - shift = ((pAddr & LOADDRMASK) * 8); - MemElem <<= shift; - } else { - /* no need to shift raw little-endian data */ - if (!raw) - MemElem >>= ((pAddr & LOADDRMASK) * 8); - } - } - + + /* See also load_memory */ + if (AccessLength <= AccessLength_DOUBLEWORD) + { + if (BigEndianMem) + /* for big endian target, byte (pAddr&LOADDRMASK == 0) is + shifted to the most significant byte position. */ + MemElem >>= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8); + else + /* For little endian target, byte (pAddr&LOADDRMASK == 0) + is already in the correct postition. */ + MemElem >>= ((pAddr & LOADDRMASK) * 8); + } + #ifdef DEBUG - printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem)); + printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem)); #endif /* DEBUG */ - - if (BigEndianMem) { - switch (AccessLength) { /* big-endian memory */ - case AccessLength_QUADWORD : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 14 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 13 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 12 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 11 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 10 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 9 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - MemElem1 <<= 8; - case 8 : - mem[index++] = (unsigned char)(MemElem1 >> 56); - - case AccessLength_DOUBLEWORD : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_SEPTIBYTE : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_SEXTIBYTE : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_QUINTIBYTE : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_WORD : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_TRIPLEBYTE : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_HALFWORD : - mem[index++] = (unsigned char)(MemElem >> 56); - MemElem <<= 8; - case AccessLength_BYTE : - mem[index++] = (unsigned char)(MemElem >> 56); - break; - } - } else { - index += (AccessLength + 1); - switch (AccessLength) { /* little-endian memory */ - case AccessLength_QUADWORD : - mem[--index] = (unsigned char)(MemElem1 >> 56); - case 14 : - mem[--index] = (unsigned char)(MemElem1 >> 48); - case 13 : - mem[--index] = (unsigned char)(MemElem1 >> 40); - case 12 : - mem[--index] = (unsigned char)(MemElem1 >> 32); - case 11 : - mem[--index] = (unsigned char)(MemElem1 >> 24); - case 10 : - mem[--index] = (unsigned char)(MemElem1 >> 16); - case 9 : - mem[--index] = (unsigned char)(MemElem1 >> 8); - case 8 : - mem[--index] = (unsigned char)(MemElem1 >> 0); - - case AccessLength_DOUBLEWORD : - mem[--index] = (unsigned char)(MemElem >> 56); - case AccessLength_SEPTIBYTE : - mem[--index] = (unsigned char)(MemElem >> 48); - case AccessLength_SEXTIBYTE : - mem[--index] = (unsigned char)(MemElem >> 40); - case AccessLength_QUINTIBYTE : - mem[--index] = (unsigned char)(MemElem >> 32); - case AccessLength_WORD : - mem[--index] = (unsigned char)(MemElem >> 24); - case AccessLength_TRIPLEBYTE : - mem[--index] = (unsigned char)(MemElem >> 16); - case AccessLength_HALFWORD : - mem[--index] = (unsigned char)(MemElem >> 8); - case AccessLength_BYTE : - mem[--index] = (unsigned char)(MemElem >> 0); - break; - } + + switch (AccessLength) + { + case AccessLength_QUADWORD : + { + unsigned_16 val = U16_8 (MemElem1, MemElem); + sim_core_write_aligned_16 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, val); + break; } - } - } - + case AccessLength_DOUBLEWORD : + sim_core_write_aligned_8 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_SEPTIBYTE : + sim_core_write_misaligned_7 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_SEXTIBYTE : + sim_core_write_misaligned_6 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_QUINTIBYTE : + sim_core_write_misaligned_5 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_WORD : + sim_core_write_aligned_4 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_TRIPLEBYTE : + sim_core_write_misaligned_3 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_HALFWORD : + sim_core_write_aligned_2 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + case AccessLength_BYTE : + sim_core_write_aligned_1 (STATE_CPU (sd, 0), NULL_CIA, + sim_core_write_map, pAddr, MemElem); + break; + default: + abort (); + } + return; } diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index 185d99e..646b78a 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -1466,7 +1466,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL); GPR[destreg] = ((memval << ((7 - byte) * 8)) | (GPR[destreg] & (((unsigned64)1 << ((7 - byte) * 8)) - 1))); @@ -1510,7 +1510,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!ByteSwapMem) + if (BigEndianMem) paddr &= ~mask; LoadMemory(&memval,&memval1,uncached,(7 - byte),paddr,vaddr,isDATA,isREAL); { @@ -1864,7 +1864,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL); if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { @@ -1914,7 +1914,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!ByteSwapMem) + if (BigEndianMem) paddr &= ~mask; LoadMemory(&memval,&memval1,uncached,(3 - byte),paddr,vaddr,isDATA,isREAL); if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { @@ -2497,7 +2497,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; memval = (op2 >> (8 * (7 - byte))); StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL); @@ -2541,7 +2541,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; memval = ((unsigned64) op2 << (byte * 8)); StoreMemory(uncached,(AccessLength_DOUBLEWORD - byte),memval,memval1,paddr,vaddr,isREAL); @@ -2996,7 +2996,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; memval = (op2 >> (8 * (3 - byte))); if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { @@ -3045,7 +3045,7 @@ int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); byte = ((vaddr & mask) ^ bigend); - if (!ByteSwapMem) + if (!BigEndianMem) paddr &= ~mask; memval = ((unsigned64) op2 << (byte * 8)); if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index 5a926e1..fa493de 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -26,16 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc., #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) #define SIM_HAVE_BIENDIAN -#define SIM_HAVE_FLATMEM /* hobble some common features for moment */ #define WITH_WATCHPOINTS 1 +#define WITH_MODULO_MEMORY 1 #include "sim-basics.h" typedef address_word sim_cia; +#if (WITH_IGEN) +/* Get the number of instructions. FIXME: must be a more elegant way + of doing this. */ +#include "itable.h" +#define MAX_INSNS (nr_itable_entries) +#define INSN_NAME(i) itable[(i)].name +#endif + #include "sim-base.h" @@ -579,10 +587,6 @@ struct sim_state { #define BigEndianMem (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) /*(state & simBE) ? 1 : 0)*/ -/* ByteSwapMem */ -/* This is true if the host and target have different endianness. */ -#define ByteSwapMem (CURRENT_TARGET_BYTE_ORDER != CURRENT_HOST_BYTE_ORDER) - /* ReverseEndian */ /* This mode is selected if in User mode with the RE bit being set in SR (Status Register). It reverses the endianness of load and store @@ -691,13 +695,13 @@ int address_translation PARAMS ((SIM_DESC sd, address_word vAddr, int IorD, int #define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \ address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,raw) -void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD, int raw)); +void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD)); #define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \ -load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) +load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD) -void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr, int raw)); +void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr)); #define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \ -store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) +store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr) void cache_op PARAMS ((SIM_DESC sd, int op, address_word pAddr, address_word vAddr, unsigned int instruction)); #define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,op,pAddr,vAddr,instruction) -- 2.7.4