c80 simulator fixes.
This commit is contained in:
parent
e05e76e8a4
commit
c445af5a2b
10 changed files with 242 additions and 70 deletions
|
@ -1,3 +1,16 @@
|
|||
Mon May 12 14:49:05 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-core.c (sim_core_find_mapping): Call engine_error not
|
||||
sim_io_error when possible.
|
||||
|
||||
Mon May 12 08:55:07 1997 Andrew Cagney <cagney@b2.cygnus.com>
|
||||
|
||||
* sim-endian.h (V1_H2): Add macro's to insert a word into a
|
||||
high/low double word.
|
||||
|
||||
* sim-trace.h: Remove definition of attribute - defined in
|
||||
sim_basics.h.
|
||||
|
||||
Mon May 12 08:55:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-options.h (struct OPTION): Add doc_opt as the documenting
|
||||
|
|
|
@ -43,13 +43,10 @@
|
|||
|
||||
|
||||
|
||||
|
||||
/* Some versions of GCC include an attribute operator, define it */
|
||||
|
||||
#if !defined (__attribute__)
|
||||
#if (!defined(__GNUC__) \
|
||||
|| (__GNUC__ < 2) \
|
||||
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 6))
|
||||
#if (!defined(__GNUC__) || (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 6))
|
||||
#define __attribute__(arg)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -64,15 +61,19 @@ void *zalloc (unsigned long size);
|
|||
|
||||
void zfree(void*);
|
||||
|
||||
|
||||
/* Turn VALUE into a string with commas. */
|
||||
char *sim_add_commas (char *, int, unsigned long);
|
||||
|
||||
|
||||
/* Utilities for elapsed time reporting. */
|
||||
|
||||
/* Opaque type, known only inside sim_elapsed_time_foo fns. */
|
||||
typedef unsigned long SIM_ELAPSED_TIME;
|
||||
|
||||
/* Get reference point for future call to sim_time_elapsed. */
|
||||
SIM_ELAPSED_TIME sim_elapsed_time_get (void);
|
||||
|
||||
/* Elapsed time in milliseconds since START. */
|
||||
unsigned long sim_elapsed_time_since (SIM_ELAPSED_TIME start);
|
||||
|
||||
|
@ -117,16 +118,14 @@ typedef enum _attach_type {
|
|||
|
||||
#include "sim-config.h"
|
||||
|
||||
#include "sim-module.h"
|
||||
#include "sim-trace.h"
|
||||
#include "sim-profile.h"
|
||||
#include "sim-model.h"
|
||||
#include "sim-base.h"
|
||||
|
||||
#include "sim-inline.h"
|
||||
|
||||
#include "sim-types.h"
|
||||
#include "sim-bits.h"
|
||||
#include "sim-endian.h"
|
||||
|
||||
/* Note: Only the simpler interfaces are defined here. More heavy
|
||||
weight objects, such as core and events, are defined in the more
|
||||
serious sim-base.h header. */
|
||||
|
||||
#endif /* _SIM_BASICS_H_ */
|
||||
|
|
|
@ -312,7 +312,7 @@ sim_core_find_mapping(sim_core *core,
|
|||
if (cpu == NULL)
|
||||
sim_io_error (NULL, "sim_core_find_map - internal error - can not abort without a processor");
|
||||
else
|
||||
sim_io_error (CPU_STATE (cpu),
|
||||
engine_error (CPU_STATE (cpu), cpu, cia,
|
||||
"access to unmaped address 0x%lx (%d bytes)\n",
|
||||
(unsigned long) addr, nr_bytes);
|
||||
}
|
||||
|
|
|
@ -23,84 +23,178 @@
|
|||
#define _SIM_EVENTS_H_
|
||||
|
||||
|
||||
typedef void event_handler(void *data);
|
||||
/* Notes:
|
||||
|
||||
typedef struct _event_entry event_entry;
|
||||
struct _event_entry {
|
||||
When scheduling an event, the a delta of zero/one refers to the
|
||||
timeline as follows:
|
||||
|
||||
epoch 0|1 1|2 2|3 3|
|
||||
**queue**|--insn--|*queue*|--insn--|*queue*|--insn--|*queue*|
|
||||
| ^ ^ | ^ ^
|
||||
`- +0 ------------ +1 --.. `----- +0 ------------- +1 --..
|
||||
|
||||
When the queue is initialized, the time is set to zero with a
|
||||
number of initialization events scheduled. Consequently, as also
|
||||
illustrated above, the event queue should be processed before the
|
||||
first instruction. That instruction being executed during tick 1.
|
||||
|
||||
The event queue is processed using:
|
||||
|
||||
if (sim_events_tick (sd)) {
|
||||
sim_events_process (sd);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
typedef void sim_event_handler(void *data);
|
||||
|
||||
typedef struct _sim_event sim_event;
|
||||
struct _sim_event {
|
||||
void *data;
|
||||
event_handler *handler;
|
||||
sim_event_handler *handler;
|
||||
signed64 time_of_event;
|
||||
event_entry *next;
|
||||
sim_event *next;
|
||||
};
|
||||
|
||||
typedef struct _event_queue event_queue;
|
||||
struct _event_queue {
|
||||
typedef struct _sim_events sim_events;
|
||||
struct _sim_events {
|
||||
int processing;
|
||||
event_entry *queue;
|
||||
event_entry *volatile held;
|
||||
event_entry *volatile *volatile held_end;
|
||||
sim_event *queue;
|
||||
sim_event *volatile held;
|
||||
sim_event *volatile *volatile held_end;
|
||||
signed64 time_of_event;
|
||||
signed64 time_from_event;
|
||||
int time_from_event;
|
||||
void *path_to_halt_or_restart;
|
||||
int trace;
|
||||
};
|
||||
|
||||
typedef struct event_entry *event_entry_tag;
|
||||
|
||||
|
||||
/* Initialization */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) event_queue_init
|
||||
(engine *system);
|
||||
(void) sim_events_init
|
||||
(SIM_DESC sd);
|
||||
|
||||
|
||||
/* Tracing level */
|
||||
/* Set Tracing Level */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) event_queue_trace
|
||||
(engine *system,
|
||||
(void) sim_events_set_trace
|
||||
(SIM_DESC sd,
|
||||
int level);
|
||||
|
||||
|
||||
/* (de)Schedule things to happen in the future. */
|
||||
/* Schedule an event DELTA_TIME ticks into the future */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(event_entry_tag) event_queue_schedule
|
||||
(engine *system,
|
||||
(sim_event *) sim_events_schedule
|
||||
(SIM_DESC sd,
|
||||
signed64 delta_time,
|
||||
event_handler *handler,
|
||||
sim_event_handler *handler,
|
||||
void *data);
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(event_entry_tag) event_queue_schedule_after_signal
|
||||
(engine *system,
|
||||
(sim_event *) sim_events_schedule_after_signal
|
||||
(SIM_DESC sd,
|
||||
signed64 delta_time,
|
||||
event_handler *handler,
|
||||
sim_event_handler *handler,
|
||||
void *data);
|
||||
|
||||
|
||||
/* Schedule an event WALLCLOCK milli-seconds from the start of the
|
||||
simulation. The exact interpretation of wallclock is host
|
||||
dependant. */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) event_queue_deschedule
|
||||
(engine *system,
|
||||
event_entry_tag event_to_remove);
|
||||
(void) sim_events_wallclock_schedule
|
||||
(SIM_DESC sd,
|
||||
signed64 wallclock_ms_time,
|
||||
sim_event_handler *handler,
|
||||
void *data);
|
||||
|
||||
|
||||
#if 0
|
||||
/* Schedule an event when the value at ADDR lies between LB..UB */
|
||||
|
||||
typedef enum {
|
||||
/* value host byte ordered */
|
||||
watch_host_1,
|
||||
watch_host_2,
|
||||
watch_host_4,
|
||||
watch_host_8,
|
||||
/* value target byte ordered */
|
||||
watch_targ_1,
|
||||
watch_targ_2,
|
||||
watch_targ_4,
|
||||
watch_targ_8,
|
||||
/* value big-endian */
|
||||
watch_bend_1,
|
||||
watch_bend_2,
|
||||
watch_bend_4,
|
||||
watch_bend_8,
|
||||
/* value little-endian */
|
||||
watch_lend_1,
|
||||
watch_lend_2,
|
||||
watch_lend_4,
|
||||
watch_lend_8,
|
||||
} sim_watchpoint;
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) sim_events_watchpoint_schedule
|
||||
(SIM_DESC sd,
|
||||
sim_watchpoint type,
|
||||
void *addr,
|
||||
unsigned64 lb,
|
||||
unsigned64 ub,
|
||||
sim_event_handler *handler,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Schedule an event when the value in CORE lies between LB..UB */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) sim_events_watchcore_schedule
|
||||
(SIM_DESC sd,
|
||||
sim_watchpoint type,
|
||||
address_word addr,
|
||||
sim_core_maps map,
|
||||
unsigned64 lb,
|
||||
unsigned64 ub,
|
||||
sim_event_handler *handler,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
|
||||
/* Deschedule the specified event */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) sim_events_deschedule
|
||||
(SIM_DESC sd,
|
||||
sim_event *event_to_remove);
|
||||
|
||||
|
||||
|
||||
/* progress time. Broken into two parts so that if something is
|
||||
pending, the caller has a chance to save any cached state */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(int) event_queue_tick
|
||||
(engine *system);
|
||||
(int) sim_events_tick
|
||||
(SIM_DESC sd);
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(void) event_queue_process
|
||||
(engine *system);
|
||||
(void) sim_events_process
|
||||
(SIM_DESC sd);
|
||||
|
||||
|
||||
/* local concept of time */
|
||||
|
||||
INLINE_SIM_EVENTS\
|
||||
(signed64) event_queue_time
|
||||
(engine *system);
|
||||
(signed64) sim_events_time
|
||||
(SIM_DESC sd);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
Mon May 12 11:12:24 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* insns (do_ld): For 64bit loads, always store LSW in rDest, MSW in
|
||||
rDest + 1. Also done by Michael Meissner <meissner@cygnus.com>
|
||||
(do_st): Converse for store.
|
||||
|
||||
* misc.c (tic80_trace_fpu2i): Correct printf format for int type.
|
||||
|
||||
Sun May 11 11:02:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-calls.c (sim_stop_reason): Return a SIGINT if keep_running
|
||||
was cleared.
|
||||
|
||||
* interp.c (engine_step): New function. Single step the simulator
|
||||
taking care of cntrl-c during a step.
|
||||
|
||||
* sim-calls.c (sim_resume): Differentiate between stepping and
|
||||
running so that a cntrl-c during a step is reported.
|
||||
|
||||
Sun May 11 10:54:31 1997 Mark Alexander <marka@cygnus.com>
|
||||
|
||||
* sim-calls.c (sim_fetch_register): Use correct reg base.
|
||||
(sim_store_register): Ditto.
|
||||
|
||||
Sun May 11 10:25:14 1997 Michael Meissner <meissner@cygnus.com>
|
||||
|
||||
* cpu.h (tic80_trace_shift): Add declaration.
|
||||
|
|
|
@ -633,7 +633,6 @@ instruction_address::function::do_jsr:instruction_address nia, signed32 *rLink,
|
|||
// ld[{.b.h.d}]
|
||||
void::function::do_ld:int Dest, unsigned32 Base, unsigned32 *rBase, int m , int sz, int S, unsigned32 Offset
|
||||
unsigned32 addr;
|
||||
unsigned64 u64;
|
||||
switch (sz)
|
||||
{
|
||||
case 0:
|
||||
|
@ -655,15 +654,18 @@ void::function::do_ld:int Dest, unsigned32 Base, unsigned32 *rBase, int m , int
|
|||
GPR(Dest) = MEM (signed, addr, 4);
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
signed64 val;
|
||||
if (Dest & 0x1)
|
||||
engine_error (SD, CPU, cia, "0x%lx: ld.d to odd register %d",
|
||||
cia.ip, Dest);
|
||||
addr = Base + (S ? (Offset << 3) : Offset);
|
||||
if (m)
|
||||
*rBase = addr;
|
||||
u64 = MEM (signed, addr, 8);
|
||||
GPR(Dest) = (unsigned32) u64;
|
||||
GPR(Dest+1) = (unsigned32) (u64 >> 32);
|
||||
val = MEM (signed, addr, 8);
|
||||
GPR(Dest + 1) = VH4_8 (val);
|
||||
GPR(Dest + 0) = VL4_8 (val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
addr = -1;
|
||||
|
@ -898,7 +900,6 @@ void::function::do_shift:int Dest, int Source, int Merge, int i, int n, int EndM
|
|||
// st[{.b|.h|.d}]
|
||||
void::function::do_st:int Source, unsigned32 Base, unsigned32 *rBase, int m , int sz, int S, unsigned32 Offset
|
||||
unsigned32 addr;
|
||||
unsigned64 u64;
|
||||
switch (sz)
|
||||
{
|
||||
case 0:
|
||||
|
@ -914,13 +915,16 @@ void::function::do_st:int Source, unsigned32 Base, unsigned32 *rBase, int m , in
|
|||
STORE (addr, 4, GPR(Source));
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
signed64 val;
|
||||
if (Source & 0x1)
|
||||
engine_error (SD, CPU, cia, "0x%lx: st.d with odd source register %d",
|
||||
engine_error (SD, CPU, cia,
|
||||
"0x%lx: st.d with odd source register %d",
|
||||
cia.ip, Source);
|
||||
addr = Base + (S ? (Offset << 3) : Offset);
|
||||
u64 = GPR (Source);
|
||||
u64 |= (((unsigned64) GPR (Source+1)) << 32);
|
||||
STORE (addr, 8, u64);
|
||||
val = (V4_H8 (GPR(Source + 1)) | V4_L8 (GPR(Source)));
|
||||
STORE (addr, 8, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
addr = -1;
|
||||
|
|
|
@ -129,3 +129,30 @@ engine_run_until_stop (SIM_DESC sd,
|
|||
engine_halt (sd, cpu, cia, sim_stopped, SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
engine_step (SIM_DESC sd)
|
||||
{
|
||||
if (!setjmp (sd->path_to_halt))
|
||||
{
|
||||
instruction_address cia;
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
sd->halt_ok = 1;
|
||||
setjmp (sd->path_to_restart);
|
||||
sd->restart_ok = 1;
|
||||
cia = cpu->cia;
|
||||
if (cia.ip == -1)
|
||||
{
|
||||
/* anulled instruction */
|
||||
cia.ip = cia.dp;
|
||||
cia.dp = cia.dp + sizeof (instruction_word);
|
||||
}
|
||||
else
|
||||
{
|
||||
instruction_word insn = IMEM (cia.ip);
|
||||
cia = idecode_issue (sd, insn, cia);
|
||||
}
|
||||
engine_halt (sd, cpu, cia, sim_stopped, SIGTRAP);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,7 +282,7 @@ tic80_trace_fpu2i (SIM_DESC sd,
|
|||
|
||||
trace_one_insn (sd, cpu, cia.ip, 1,
|
||||
itable[indx].file, itable[indx].line_nr, "fpu",
|
||||
"%-*s %*f %*f => 0x%.*lx %-*s",
|
||||
"%-*s %*f %*f => 0x%.*lx %-*ld",
|
||||
tic80_size_name, itable[indx].name,
|
||||
SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input1),
|
||||
SIZE_HEX + SIZE_DECIMAL + 3, sim_fpu_2d (input2),
|
||||
|
|
|
@ -178,7 +178,7 @@ void
|
|||
sim_fetch_register (SIM_DESC sd, int regnr, unsigned char *buf)
|
||||
{
|
||||
if (regnr >= R0_REGNUM && regnr <= Rn_REGNUM)
|
||||
*(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->reg[regnr - A0_REGNUM]);
|
||||
*(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->reg[regnr - R0_REGNUM]);
|
||||
else if (regnr == PC_REGNUM)
|
||||
*(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->cia.ip);
|
||||
else if (regnr == NPC_REGNUM)
|
||||
|
@ -195,7 +195,7 @@ void
|
|||
sim_store_register (SIM_DESC sd, int regnr, unsigned char *buf)
|
||||
{
|
||||
if (regnr >= R0_REGNUM && regnr <= Rn_REGNUM)
|
||||
STATE_CPU (sd, 0)->reg[regnr - A0_REGNUM] = T2H_4 (*(unsigned32*)buf);
|
||||
STATE_CPU (sd, 0)->reg[regnr - R0_REGNUM] = T2H_4 (*(unsigned32*)buf);
|
||||
else if (regnr == PC_REGNUM)
|
||||
STATE_CPU (sd, 0)->cia.ip = T2H_4 (*(unsigned32*)buf);
|
||||
else if (regnr == NPC_REGNUM)
|
||||
|
@ -232,10 +232,18 @@ volatile int keep_running = 1;
|
|||
|
||||
void
|
||||
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
|
||||
{
|
||||
if (!keep_running)
|
||||
{
|
||||
*reason = sim_stopped;
|
||||
*sigrc = SIGINT;
|
||||
keep_running = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*reason = simulation.reason;
|
||||
*sigrc = simulation.siggnal;
|
||||
keep_running = 1; /* ready for next run */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -251,7 +259,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
|
|||
{
|
||||
/* keep_running = 1 - in sim_stop_reason */
|
||||
if (step)
|
||||
keep_running = 0;
|
||||
engine_step (sd);
|
||||
else
|
||||
engine_run_until_stop (sd, &keep_running);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,5 +101,7 @@ extern void engine_run_until_stop
|
|||
(SIM_DESC sd,
|
||||
volatile int *keep_running);
|
||||
|
||||
extern void engine_step
|
||||
(SIM_DESC sd);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue