mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-24 18:35:28 +00:00
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.
This commit is contained in:
parent
22de994d0e
commit
63be8febf7
@ -1,3 +1,28 @@
|
||||
Wed Nov 5 13:40:31 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* 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 <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-endian.h (U16_8): Implement
|
||||
|
@ -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
|
||||
#include "sim-n-core.h"
|
||||
#undef N
|
||||
|
||||
#define N 4
|
||||
#include "sim-n-core.h"
|
||||
#undef N
|
||||
|
||||
#define N 8
|
||||
#include "sim-n-core.h"
|
||||
#undef N
|
||||
|
||||
#define N 16
|
||||
#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"
|
||||
|
||||
#define N 4
|
||||
#include "sim-n-core.h"
|
||||
|
||||
#define N 3
|
||||
#define M 4
|
||||
#include "sim-n-core.h"
|
||||
|
||||
#define N 2
|
||||
#include "sim-n-core.h"
|
||||
|
||||
#define N 1
|
||||
#include "sim-n-core.h"
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
|
@ -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 -> 0x%0*lx\n",
|
||||
"sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx\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 == 2)
|
||||
trace_printf (CPU_STATE (cpu), cpu,
|
||||
"sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%04lx\n",
|
||||
line_nr,
|
||||
transfer,
|
||||
nr_bytes,
|
||||
sim_core_map_to_str (map),
|
||||
(unsigned long) addr,
|
||||
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
|
||||
|
@ -1,3 +1,34 @@
|
||||
Wed Nov 5 12:19:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* 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 <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-main.h (WITH_TRACE): Delete definition. Enables common
|
||||
|
@ -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 \
|
||||
|
@ -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,110 +680,16 @@ 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","<n> : 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;
|
||||
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 ();
|
||||
}
|
||||
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. */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
|
||||
(int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* See also store_memory. */
|
||||
if (AccessLength <= AccessLength_DOUBLEWORD)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
|
||||
pr_uword64(value1),pr_uword64(value));
|
||||
#endif /* DEBUG */
|
||||
/* 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));
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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));
|
||||
#endif /* DEBUG */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user