c80 simulator fixes.

This commit is contained in:
Andrew Cagney 1997-05-12 04:57:49 +00:00
parent e05e76e8a4
commit c445af5a2b
10 changed files with 242 additions and 70 deletions

View File

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

View File

@ -42,14 +42,11 @@
#endif
/* 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_ */

View File

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

View File

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

View File

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

View File

@ -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:
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);
{
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;
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:
if (Source & 0x1)
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);
{
signed64 val;
if (Source & 0x1)
engine_error (SD, CPU, cia,
"0x%lx: st.d with odd source register %d",
cia.ip, Source);
addr = Base + (S ? (Offset << 3) : Offset);
val = (V4_H8 (GPR(Source + 1)) | V4_L8 (GPR(Source)));
STORE (addr, 8, val);
}
break;
default:
addr = -1;

View File

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

View File

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

View File

@ -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)
@ -233,9 +233,17 @@ volatile int keep_running = 1;
void
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
{
*reason = simulation.reason;
*sigrc = simulation.siggnal;
keep_running = 1; /* ready for next run */
if (!keep_running)
{
*reason = sim_stopped;
*sigrc = SIGINT;
keep_running = 0;
}
else
{
*reason = simulation.reason;
*sigrc = simulation.siggnal;
}
}
@ -251,8 +259,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
{
/* keep_running = 1 - in sim_stop_reason */
if (step)
keep_running = 0;
engine_run_until_stop(sd, &keep_running);
engine_step (sd);
else
engine_run_until_stop (sd, &keep_running);
}
void

View File

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