From c445af5a2b1fd76533a6ce709677e779f215721f Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Mon, 12 May 1997 04:57:49 +0000 Subject: [PATCH] c80 simulator fixes. --- sim/common/ChangeLog | 13 ++++ sim/common/sim-basics.h | 19 +++--- sim/common/sim-core.c | 2 +- sim/common/sim-events.h | 160 ++++++++++++++++++++++++++++++++++++++---------- sim/tic80/ChangeLog | 24 ++++++++ sim/tic80/insns | 40 ++++++------ sim/tic80/interp.c | 27 ++++++++ sim/tic80/misc.c | 2 +- sim/tic80/sim-calls.c | 23 ++++--- sim/tic80/sim-main.h | 2 + 10 files changed, 242 insertions(+), 70 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 54a4c6b..e859b9a 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,16 @@ +Mon May 12 14:49:05 1997 Andrew Cagney + + * 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 + + * 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 * sim-options.h (struct OPTION): Add doc_opt as the documenting diff --git a/sim/common/sim-basics.h b/sim/common/sim-basics.h index d33a0d5..149e6a0 100644 --- a/sim/common/sim-basics.h +++ b/sim/common/sim-basics.h @@ -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_ */ diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c index 01ff5d7..e9102cf 100644 --- a/sim/common/sim-core.c +++ b/sim/common/sim-core.c @@ -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); } diff --git a/sim/common/sim-events.h b/sim/common/sim-events.h index eb52690..05b28b5 100644 --- a/sim/common/sim-events.h +++ b/sim/common/sim-events.h @@ -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) 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) event_queue_deschedule -(engine *system, - event_entry_tag event_to_remove); +(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 diff --git a/sim/tic80/ChangeLog b/sim/tic80/ChangeLog index ac4ffa5..8df333e 100644 --- a/sim/tic80/ChangeLog +++ b/sim/tic80/ChangeLog @@ -1,3 +1,27 @@ +Mon May 12 11:12:24 1997 Andrew Cagney + + * insns (do_ld): For 64bit loads, always store LSW in rDest, MSW in + rDest + 1. Also done by Michael Meissner + (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 + + * 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 + + * sim-calls.c (sim_fetch_register): Use correct reg base. + (sim_store_register): Ditto. + Sun May 11 10:25:14 1997 Michael Meissner * cpu.h (tic80_trace_shift): Add declaration. diff --git a/sim/tic80/insns b/sim/tic80/insns index 5a4110b..d924005 100644 --- a/sim/tic80/insns +++ b/sim/tic80/insns @@ -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; diff --git a/sim/tic80/interp.c b/sim/tic80/interp.c index b8ba567..8fda287 100644 --- a/sim/tic80/interp.c +++ b/sim/tic80/interp.c @@ -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); + } +} diff --git a/sim/tic80/misc.c b/sim/tic80/misc.c index b9af1b8..e24efd3 100644 --- a/sim/tic80/misc.c +++ b/sim/tic80/misc.c @@ -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), diff --git a/sim/tic80/sim-calls.c b/sim/tic80/sim-calls.c index 23b3860..ae3f2ab 100644 --- a/sim/tic80/sim-calls.c +++ b/sim/tic80/sim-calls.c @@ -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 diff --git a/sim/tic80/sim-main.h b/sim/tic80/sim-main.h index 1992f29..be4e88d 100644 --- a/sim/tic80/sim-main.h +++ b/sim/tic80/sim-main.h @@ -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 -- 2.7.4