From 61b62559bab5ab2ce6fbe1c56a6136f4d6f2f3e7 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 5 Feb 1998 21:29:18 +0000 Subject: [PATCH] * cgen-sim.h (EX_FN_NAME): _exc_ -> _ex_. (SEM_INSN): New macro. --- sim/common/ChangeLog | 5 + sim/common/cgen-sim.h | 297 ++++++++++++++++++++++++++++++++---------- 2 files changed, 235 insertions(+), 67 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 765cc69278f..cdddbfa7856 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,8 @@ +Thu Feb 5 13:27:04 1998 Doug Evans + + * cgen-sim.h (EX_FN_NAME): _exc_ -> _ex_. + (SEM_INSN): New macro. + Tue Feb 3 16:31:56 1998 Andrew Cagney * sim-run.c (sim_engine_run): Assume IMEM is 32 bit. diff --git a/sim/common/cgen-sim.h b/sim/common/cgen-sim.h index 7df7d3fddf1..71e41dfa127 100644 --- a/sim/common/cgen-sim.h +++ b/sim/common/cgen-sim.h @@ -1,5 +1,5 @@ /* Simulator header for Cpu tools GENerated simulators. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GDB, the GNU debugger. @@ -21,26 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef CGEN_SIM_H #define CGEN_SIM_H -#define PC (STATE_CPU_CPU (current_state, 0)->pc) - -/* Execution state. */ -enum exec_state { - EXEC_STATE_RUNNING, EXEC_STATE_EXITED, - EXEC_STATE_STOPPED, EXEC_STATE_SIGNALLED -}; - -/* Signals we use. */ -enum sim_signal_type { - SIM_SIGNONE, - SIM_SIGILL, /* illegal insn */ - SIM_SIGTRAP, - SIM_SIGALIGN, /* misaligned memory access */ - SIM_SIGACCESS, /* tried to read/write memory that's not readable/writable */ - SIM_SIGXCPU /* cpu limit exceeded */ -}; - -void engine_halt PARAMS ((struct _sim_cpu *, enum exec_state, int)); -void engine_signal PARAMS ((struct _sim_cpu *, enum sim_signal_type)); +#include "sim-xcat.h" + +#define PC CPU (h_pc) /* Instruction field support macros. */ @@ -56,63 +39,258 @@ void engine_signal PARAMS ((struct _sim_cpu *, enum sim_signal_type)); #define HOST_LONGS_FOR_BITS(n) \ (((n) + sizeof (long) * 8 - 1) / sizeof (long) * 8) -/* Decode,extract,semantics. */ +/* Execution support. */ + +/* Forward decls. Defined in the machine generated arch.h and cpu.h files. */ +typedef struct argbuf ARGBUF; +typedef struct scache SCACHE; +typedef struct parallel_exec PARALLEL_EXEC; -typedef void (EXTRACT_FN) PARAMS ((SIM_CPU *, PCADDR, insn_t, struct argbuf *)); -/*typedef CIA (SEMANTIC_FN) PARAMS ((SEM_ARG));*/ -typedef PCADDR (SEMANTIC_FN) PARAMS ((SIM_CPU *, struct argbuf *)); +/* Types of the machine generated extract and semantic fns. */ +typedef void (EXTRACT_FN) (SIM_CPU *, PCADDR, insn_t, ARGBUF *); +typedef void (READ_FN) (SIM_CPU *, PCADDR, insn_t, PARALLEL_EXEC *); +/*typedef CIA (SEMANTIC_FN) (SEM_ARG);*/ +typedef PCADDR (SEMANTIC_FN) (SIM_CPU *, ARGBUF *); #if 0 /* wip */ -typedef void (EXTRACT_CACHE_FN) PARAMS ((SIM_CPU *, PCADDR, insn_t, struct argbuf *)); +typedef void (EXTRACT_CACHE_FN) (SIM_CPU *, PCADDR, insn_t, ARGBUF *); #endif -typedef PCADDR (SEMANTIC_CACHE_FN) PARAMS ((SIM_CPU *, struct scache *)); +typedef PCADDR (SEMANTIC_CACHE_FN) (SIM_CPU *, SCACHE *); typedef struct { /* Using cgen_insn_type requires -opc.h. */ int /*enum cgen_insn_type*/ insn_type; const struct cgen_insn *opcode; - /* FIXME: Perhaps rename these to normal/fast versions to associate them - with the normal/fast args to genmloop.sh. */ EXTRACT_FN *extract; +#ifdef HAVE_PARALLEL_EXEC +#ifdef USE_READ_SWITCH +#ifdef __GNUC__ + void *read; +#else + int read; +#endif +#else + READ_FN *read; +#endif +#endif SEMANTIC_FN *semantic; #if 0 /* wip */ EXTRACT_CACHE_FN *extract_fast; #endif SEMANTIC_CACHE_FN *semantic_fast; -#if defined (USE_SEM_SWITCH) && defined (__GNUC__) - void *semantic_lab; +#if WITH_SEM_SWITCH_FULL && defined (__GNUC__) + /* Set at runtime. */ + void *sem_full_lab; +#endif +#if WITH_SEM_SWITCH_FAST && defined (__GNUC__) + /* Set at runtime. */ + void *semantic_lab; /* FIXME: Rename to sem_fast_lab. */ #endif } DECODE; -/* FIXME: length parm to decode() is currently unneeded. */ -extern DECODE *decode PARAMS ((insn_t /*, int*/)); +/* Execution support. + + Semantic functions come in two versions. + One that uses the cache, and one that doesn't. + ??? The one that doesn't may eventually be thrown away or replaced with + something else. */ + +#ifdef SCACHE_P + +/* instruction address */ +typedef PCADDR IADDR; +/* current instruction address */ +typedef PCADDR CIA; +/* argument to semantic functions */ +typedef SCACHE *SEM_ARG; + +#else /* ! SCACHE_P */ + +/* instruction address */ +typedef PCADDR IADDR; +/* current instruction address */ +typedef PCADDR CIA; +/* argument to semantic functions */ +typedef ARGBUF *SEM_ARG; + +#endif /* ! SCACHE_P */ + +/* Scache data for each cpu. */ + +typedef struct cpu_scache { + /* Simulator cache size. */ + int size; +#define CPU_SCACHE_SIZE(cpu) ((cpu) -> cgen_cpu.scache.size) + /* Cache. */ + SCACHE *cache; +#define CPU_SCACHE_CACHE(cpu) ((cpu) -> cgen_cpu.scache.cache) +#if 0 /* FIXME: wip */ + /* Free list. */ + SCACHE *free; +#define CPU_SCACHE_FREE(cpu) ((cpu) -> cgen_cpu.scache.free) + /* Hash table. */ + SCACHE **hash_table; +#define CPU_SCACHE_HASH_TABLE(cpu) ((cpu) -> cgen_cpu.scache.hash_table) +#endif + +#if WITH_PROFILE_SCACHE_P + /* Cache hits, misses. */ + unsigned long hits, misses; +#define CPU_SCACHE_HITS(cpu) ((cpu) -> cgen_cpu.scache.hits) +#define CPU_SCACHE_MISSES(cpu) ((cpu) -> cgen_cpu.scache.misses) +#endif +} CPU_SCACHE; + +/* Default number of cached blocks. */ +#ifdef CONFIG_SIM_CACHE_SIZE +#define SCACHE_DEFAULT_CACHE_SIZE CONFIG_SIM_CACHE_SIZE +#else +#define SCACHE_DEFAULT_CACHE_SIZE 1024 +#endif + +/* Hash a PC value. */ +/* FIXME: cpu specific */ +#define SCACHE_HASH_PC(state, pc) \ +(((pc) >> 1) & (STATE_SCACHE_SIZE (sd) - 1)) + +/* Non-zero if cache is in use. */ +#define USING_SCACHE_P(sd) (STATE_SCACHE_SIZE (sd) > 0) + +/* Install the simulator cache into the simulator. */ +MODULE_INSTALL_FN scache_install; + +/* Flush all cpu's caches. */ +void scache_flush (SIM_DESC); -/* Simulator state. */ +/* Scache profiling support. */ -#if WITH_SCACHE -#include "cgen-scache.h" +/* Print summary scache usage information. */ +void scache_print_profile (SIM_CPU *cpu, int verbose); + +#if WITH_PROFILE_SCACHE_P +#define PROFILE_COUNT_SCACHE_HIT(cpu) \ +do { \ + if (CPU_PROFILE_FLAGS (cpu) [PROFILE_SCACHE_IDX]) \ + ++ CPU_SCACHE_HITS (cpu); \ +} while (0) +#define PROFILE_COUNT_SCACHE_MISS(cpu) \ +do { \ + if (CPU_PROFILE_FLAGS (cpu) [PROFILE_SCACHE_IDX]) \ + ++ CPU_SCACHE_MISSES (cpu); \ +} while (0) +#else +#define PROFILE_COUNT_SCACHE_HIT(cpu) +#define PROFILE_COUNT_SCACHE_MISS(cpu) +#endif + +/* Engine support. */ + +/* Values to denote parallel/sequential execution. */ +#define EXEC_SEQUENCE 0 +#define EXEC_PARALLEL 1 + +#ifdef SCACHE_P + +#define CIA_ADDR(cia) (cia) + +/* These are used so that we can compile two copies of the semantic code, + one with scache support and one without. */ +/* FIXME: Do we want _ex_ or _exc_? */ +/*#define EX_FN_NAME(cpu,fn) XCONCAT3 (cpu,_exc_,fn)*/ +#define EX_FN_NAME(cpu,fn) XCONCAT3 (cpu,_ex_,fn) +#define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_semc_,fn) + +/* extract.c support */ +/* scache_unset is a cache entry that is never used. + It's raison d'etre is so BRANCH_VIA_CACHE doesn't have to test for + newval.cache == NULL. */ +extern struct scache scache_unset; +#define RECORD_IADDR(fld, val) \ +do { (fld) = (val); } while (0) + +/* semantics.c support */ +#define SEM_ARGBUF(sem_arg) (&(sem_arg) -> argbuf) +#define SEM_INSN(sem_arg) shouldnt_be_used +#define SEM_NEXT_PC(sc) ((sc) -> next) +#define SEM_BRANCH_VIA_CACHE(sc, newval) (newval) +#define SEM_BRANCH_VIA_ADDR(sc, newval) (newval) +/* Return address a branch insn will branch to. + This is only used during tracing. */ +#define SEM_NEW_PC_ADDR(new_pc) (new_pc) + +#else /* ! SCACHE_P */ + +#define CIA_ADDR(cia) (cia) + +/* These are used so that we can compile two copies of the semantic code, + one with scache support and one without. */ +#define EX_FN_NAME(cpu,fn) XCONCAT3 (cpu,_ex_,fn) +#define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_sem_,fn) + +/* extract.c support */ +#define RECORD_IADDR(fld, val) \ +do { (fld) = (val); } while (0) + +/* semantics.c support */ +#define SEM_ARGBUF(sem_arg) (sem_arg) +#define SEM_INSN(sem_arg) (SEM_ARGBUF (sem_arg) -> insn) +#define SEM_NEXT_PC(abuf) (abuf -> addr + abuf -> length) +#define SEM_BRANCH_VIA_CACHE(abuf, newval) (newval) +#define SEM_BRANCH_VIA_ADDR(abuf, newval) (newval) +#define SEM_NEW_PC_ADDR(new_pc) (new_pc) + +#endif /* ! SCACHE_P */ + +/* GNU C's "computed goto" facility is used to speed things up where + possible. These macros provide a portable way to use them. + Nesting of these switch statements is done by providing an extra argument + that distinguishes them. `N' can be a number or symbol. + Variable `labels_##N' must be initialized with the labels of each case. */ +#ifdef __GNUC__ +#define SWITCH(N, X) goto *X; +#define CASE(N, X) case_##N##_##X +#define BREAK(N) goto end_switch_##N +#define DEFAULT(N) default_##N +#define ENDSWITCH(N) end_switch_##N: +#else +#define SWITCH(N, X) switch (X) +#define CASE(N, X) case X /* FIXME: old sem-switch had (@arch@_,X) here */ +#define BREAK(N) break +#define DEFAULT(N) default +#define ENDSWITCH(N) #endif -/* ??? Do we *need* to pass state to the semantic routines? */ -extern SIM_DESC current_state; +/* Engine control (FIXME). */ +int engine_stop (SIM_DESC); +void engine_run (SIM_DESC, int, int); +/*void engine_resume (SIM_DESC, int, int);*/ + +/* Simulator state. */ -/* FIXME: Until sim_open creates one. */ -extern struct sim_state sim_global_state; +/* Records simulator descriptor so utilities like @cpu@_dump_regs can be + called from gdb. */ +extern SIM_DESC current_state; /* Simulator state. */ -/* Main state struct. - CGEN_STATE contains addition state information not present in +/* CGEN_STATE contains additional state information not present in sim_state_base. */ typedef struct cgen_state { + /* FIXME: Moved to sim_state_base. */ /* argv, env */ char **argv; -#define STATE_ARGV(s) ((s)->cgen_state.argv) +#define STATE_ARGV(s) ((s) -> cgen_state.argv) + /* FIXME: Move to sim_state_base. */ char **envp; -#define STATE_ENVP(s) ((s)->cgen_state.envp) +#define STATE_ENVP(s) ((s) -> cgen_state.envp) + + /* Non-zero if no tracing or profiling is selected. */ + int run_fast_p; +#define STATE_RUN_FAST_P(sd) ((sd) -> cgen_state.run_fast_p) } CGEN_STATE; -/* Additional per-cpu data. */ +/* Additional non-machine generated per-cpu data to go in SIM_CPU. + The member's name must be `cgen_cpu'. */ typedef struct { /* Simulator's execution cache. */ @@ -120,33 +298,18 @@ typedef struct { CPU_SCACHE scache; #endif /* WITH_SCACHE */ - enum exec_state exec_state; -#define CPU_EXEC_STATE(cpu) ((cpu)->cgen_cpu.exec_state) - - int halt_sigrc; -#define CPU_HALT_SIGRC(cpu) ((cpu)->cgen_cpu.halt_sigrc) - - jmp_buf halt_jmp_buf; -#define CPU_HALT_JMP_BUF(cpu) ((cpu)->cgen_cpu.halt_jmp_buf) - - CPU_DATA cpu; -#define CPU_CPU(c) (& (c)->cgen_cpu.cpu) - CPU_PROFILE profile_state; -#define CPU_PROFILE_STATE(cpu) (& (cpu)->cgen_cpu.profile_state) + /* Allow slop in size calcs for case where multiple cpu types are supported + and space for the specified cpu is malloc'd at run time. */ + double slop; } CGEN_CPU; /* Various utilities. */ -int engine_stop (SIM_DESC); -void engine_run (SIM_DESC, int, int); -void engine_resume (SIM_DESC, int, int); -void engine_halt (SIM_CPU *, enum exec_state, int); -void engine_signal (SIM_CPU *, enum sim_signal_type); - -int sim_signal_to_host (int); +/* Called after sim_post_argv_init to do any cgen initialization. */ +void cgen_init (SIM_DESC); void -sim_disassemble_insn (const struct cgen_insn *, const struct argbuf *, - PCADDR, char *); +sim_disassemble_insn (SIM_CPU *, const struct cgen_insn *, + const struct argbuf *, PCADDR, char *); #endif /* CGEN_SIM_H */ -- 2.30.2