diff options
author | David Edelsohn <dje.gcc@gmail.com> | 1997-05-01 01:48:27 +0000 |
---|---|---|
committer | David Edelsohn <dje.gcc@gmail.com> | 1997-05-01 01:48:27 +0000 |
commit | b9c8cd102327327d3367feb770f41e051243f7de (patch) | |
tree | c151d6c7f179f0986f005a35070a81324f7b9db8 /sim/common | |
parent | 070573509fc9cd4a23e72675df94e6dea592853f (diff) | |
download | gdb-b9c8cd102327327d3367feb770f41e051243f7de.zip gdb-b9c8cd102327327d3367feb770f41e051243f7de.tar.gz gdb-b9c8cd102327327d3367feb770f41e051243f7de.tar.bz2 |
* cgen-mem.h, cgen-scache.[ch], cgen-sem.h, cgen-sim.h: New files.
* cgen-trace.[ch], cgen-types.h, cgen-utils.c, genmloop.sh: New files.
* sim-model.c: New file.
Diffstat (limited to 'sim/common')
-rw-r--r-- | sim/common/.Sanitize | 11 | ||||
-rw-r--r-- | sim/common/ChangeLog | 4 | ||||
-rw-r--r-- | sim/common/cgen-mem.h | 503 | ||||
-rw-r--r-- | sim/common/cgen-scache.c | 194 | ||||
-rw-r--r-- | sim/common/cgen-scache.h | 108 | ||||
-rw-r--r-- | sim/common/cgen-sem.h | 978 | ||||
-rw-r--r-- | sim/common/cgen-sim.h | 138 | ||||
-rw-r--r-- | sim/common/cgen-trace.c | 251 | ||||
-rw-r--r-- | sim/common/cgen-types.h | 176 | ||||
-rw-r--r-- | sim/common/cgen-utils.c | 406 | ||||
-rw-r--r-- | sim/common/genmloop.sh | 184 |
11 files changed, 2953 insertions, 0 deletions
diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize index 0f892b9..c08bddc 100644 --- a/sim/common/.Sanitize +++ b/sim/common/.Sanitize @@ -28,9 +28,19 @@ Make-common.in Makefile.in aclocal.m4 callback.c +cgen-mem.h +cgen-scache.c +cgen-scache.h +cgen-sem.h +cgen-sim.h +cgen-trace.c +cgen-trace.h +cgen-types.h +cgen-utils.c config.in configure.in configure +genmloop.sh gentmap.c gentvals.sh nltvals.def @@ -55,6 +65,7 @@ sim-inline.h sim-io.c sim-io.h sim-load.c +sim-model.c sim-model.h sim-module.c sim-module.h diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index e42de0a..4f29d2c 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,5 +1,9 @@ Wed Apr 30 11:34:14 1997 Doug Evans <dje@canuck.cygnus.com> + * cgen-mem.h, cgen-scache.[ch], cgen-sem.h, cgen-sim.h: New files. + * cgen-trace.[ch], cgen-types.h, cgen-utils.c, genmloop.sh: New files. + * sim-model.c: New file. + * Make-common.in (clean targets): Undo patch of Apr. 22. Fri Apr 25 15:28:32 1997 Mike Meissner <meissner@cygnus.com> diff --git a/sim/common/cgen-mem.h b/sim/common/cgen-mem.h new file mode 100644 index 0000000..9be66d0 --- /dev/null +++ b/sim/common/cgen-mem.h @@ -0,0 +1,503 @@ +/* Memory ops header for CGEN-based simlators. + +This file is machine generated. + +Copyright (C) 1996, 1997 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef CGEN_MEM_H +#define CGEN_MEM_H + +#ifdef MEMOPS_DEFINE_INLINE +#define MEMOPS_INLINE +#else +#define MEMOPS_INLINE extern inline +#endif + +/* Only used in this file. */ +typedef unsigned char *ptr; + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE QI +GETTQI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return p[0]; + else + return p[0]; +} +#else +extern QI GETTQI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE HI +GETTHI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return ((p[0] << 8) | p[1]); + else + return ((p[1] << 8) | p[0]); +} +#else +extern HI GETTHI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE SI +GETTSI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + else + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} +#else +extern SI GETTSI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE DI +GETTDI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return MAKEDI ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]); + else + return MAKEDI ((p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4], (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} +#else +extern DI GETTDI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UQI +GETTUQI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return p[0]; + else + return p[0]; +} +#else +extern UQI GETTUQI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UHI +GETTUHI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return ((p[0] << 8) | p[1]); + else + return ((p[1] << 8) | p[0]); +} +#else +extern UHI GETTUHI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE USI +GETTUSI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + else + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} +#else +extern USI GETTUSI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UDI +GETTUDI (ptr p) +{ + if (TARGET_BIG_ENDIAN) + return MAKEDI ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]); + else + return MAKEDI ((p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4], (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} +#else +extern UDI GETTUDI (ptr); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTQI (ptr p, QI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val; } while (0); +else + do { p[0] = val; } while (0); +} +#else +extern void SETTQI (ptr, QI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTHI (ptr p, HI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val >> 8; p[1] = val; } while (0); +else + do { p[1] = val >> 8; p[0] = val; } while (0); +} +#else +extern void SETTHI (ptr, HI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTSI (ptr p, SI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val >> 24; p[1] = val >> 16; p[2] = val >> 8; p[3] = val; } while (0); +else + do { p[3] = val >> 24; p[2] = val >> 16; p[1] = val >> 8; p[0] = val; } while (0); +} +#else +extern void SETTSI (ptr, SI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTDI (ptr p, DI val) +{ + if (TARGET_BIG_ENDIAN) + do { SI t = GETHIDI (val); p[0] = t >> 24; p[1] = t >> 16; p[2] = t >> 8; p[3] = t; t = GETLODI (val); p[4] = t >> 24; p[5] = t >> 16; p[6] = t >> 8; p[7] = t; } while (0); +else + do { SI t = GETHIDI (val); p[7] = t >> 24; p[6] = t >> 16; p[5] = t >> 8; p[4] = t; t = GETLODI (val); p[3] = t >> 24; p[2] = t >> 16; p[1] = t >> 8; p[0] = t; } while (0); +} +#else +extern void SETTDI (ptr, DI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTUQI (ptr p, UQI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val; } while (0); +else + do { p[0] = val; } while (0); +} +#else +extern void SETTUQI (ptr, UQI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTUHI (ptr p, UHI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val >> 8; p[1] = val; } while (0); +else + do { p[1] = val >> 8; p[0] = val; } while (0); +} +#else +extern void SETTUHI (ptr, UHI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTUSI (ptr p, USI val) +{ + if (TARGET_BIG_ENDIAN) + do { p[0] = val >> 24; p[1] = val >> 16; p[2] = val >> 8; p[3] = val; } while (0); +else + do { p[3] = val >> 24; p[2] = val >> 16; p[1] = val >> 8; p[0] = val; } while (0); +} +#else +extern void SETTUSI (ptr, USI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETTUDI (ptr p, UDI val) +{ + if (TARGET_BIG_ENDIAN) + do { SI t = GETHIDI (val); p[0] = t >> 24; p[1] = t >> 16; p[2] = t >> 8; p[3] = t; t = GETLODI (val); p[4] = t >> 24; p[5] = t >> 16; p[6] = t >> 8; p[7] = t; } while (0); +else + do { SI t = GETHIDI (val); p[7] = t >> 24; p[6] = t >> 16; p[5] = t >> 8; p[4] = t; t = GETLODI (val); p[3] = t >> 24; p[2] = t >> 16; p[1] = t >> 8; p[0] = t; } while (0); +} +#else +extern void SETTUDI (ptr, UDI); +#endif + + +/* FIXME: Need to merge with sim-core. */ +/* FIXME: Don't perform >= 4, text section checks if OEA. */ +#ifndef MEM_CHECK_READ +#define MEM_CHECK_READ(addr, type) \ + ((addr) >= 4 /*&& (addr) < STATE_MEM_SIZE (current_state)*/) +#endif +#ifndef MEM_CHECK_WRITE +#define MEM_CHECK_WRITE(addr, type) \ + ((addr) >= 4 /*&& (addr) < STATE_MEM_SIZE (current_state)*/ \ + && ((addr) >= STATE_TEXT_END (current_state) \ + || (addr) < STATE_TEXT_START (current_state))) +#endif +#ifndef MEM_CHECK_ALIGNMENT +#define MEM_CHECK_ALIGNMENT(addr, type) \ + (((addr) & (sizeof (type) - 1)) == 0) +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE QI +GETMEMQI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, QI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, QI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_QI); + return sim_core_read_1 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern QI GETMEMQI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE HI +GETMEMHI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, HI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, HI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_HI); + return sim_core_read_2 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern HI GETMEMHI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE SI +GETMEMSI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, SI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, SI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_SI); + return sim_core_read_4 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern SI GETMEMSI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE DI +GETMEMDI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, DI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, DI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_DI); + return sim_core_read_8 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern DI GETMEMDI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UQI +GETMEMUQI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, UQI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, UQI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_UQI); + return sim_core_read_1 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern UQI GETMEMUQI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UHI +GETMEMUHI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, UHI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, UHI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_UHI); + return sim_core_read_2 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern UHI GETMEMUHI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE USI +GETMEMUSI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, USI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, USI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_USI); + return sim_core_read_4 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern USI GETMEMUSI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE UDI +GETMEMUDI (SIM_CPU *cpu, ADDR a) +{ + if (! MEM_CHECK_READ (a, UDI)) + { engine_signal (cpu, SIM_SIGACCESS); } + if (! MEM_CHECK_ALIGNMENT (a, UDI)) + { engine_signal (cpu, SIM_SIGALIGN); } + PROFILE_COUNT_READ (cpu, a, MODE_UDI); + return sim_core_read_8 (CPU_STATE (cpu), sim_core_read_map, a); +} +#else +extern UDI GETMEMUDI (SIM_CPU *, ADDR); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMQI (SIM_CPU *cpu, ADDR a, QI val) +{ + if (! MEM_CHECK_WRITE (a, QI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, QI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_QI); + sim_core_write_1 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMQI (SIM_CPU *, ADDR, QI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMHI (SIM_CPU *cpu, ADDR a, HI val) +{ + if (! MEM_CHECK_WRITE (a, HI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, HI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_HI); + sim_core_write_2 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMHI (SIM_CPU *, ADDR, HI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMSI (SIM_CPU *cpu, ADDR a, SI val) +{ + if (! MEM_CHECK_WRITE (a, SI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, SI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_SI); + sim_core_write_4 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMSI (SIM_CPU *, ADDR, SI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMDI (SIM_CPU *cpu, ADDR a, DI val) +{ + if (! MEM_CHECK_WRITE (a, DI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, DI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_DI); + sim_core_write_8 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMDI (SIM_CPU *, ADDR, DI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMUQI (SIM_CPU *cpu, ADDR a, UQI val) +{ + if (! MEM_CHECK_WRITE (a, UQI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, UQI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_UQI); + sim_core_write_1 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMUQI (SIM_CPU *, ADDR, UQI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMUHI (SIM_CPU *cpu, ADDR a, UHI val) +{ + if (! MEM_CHECK_WRITE (a, UHI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, UHI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_UHI); + sim_core_write_2 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMUHI (SIM_CPU *, ADDR, UHI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMUSI (SIM_CPU *cpu, ADDR a, USI val) +{ + if (! MEM_CHECK_WRITE (a, USI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, USI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_USI); + sim_core_write_4 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMUSI (SIM_CPU *, ADDR, USI); +#endif + +#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) +MEMOPS_INLINE void +SETMEMUDI (SIM_CPU *cpu, ADDR a, UDI val) +{ + if (! MEM_CHECK_WRITE (a, UDI)) + { engine_signal (cpu, SIM_SIGACCESS); return; } + if (! MEM_CHECK_ALIGNMENT (a, UDI)) + { engine_signal (cpu, SIM_SIGALIGN); return; } + PROFILE_COUNT_WRITE (cpu, a, MODE_UDI); + sim_core_write_8 (CPU_STATE (cpu), sim_core_read_map, a, val); +} +#else +extern void SETMEMUDI (SIM_CPU *, ADDR, UDI); +#endif + +#endif /* CGEN_MEMS_H */ diff --git a/sim/common/cgen-scache.c b/sim/common/cgen-scache.c new file mode 100644 index 0000000..ecebff5 --- /dev/null +++ b/sim/common/cgen-scache.c @@ -0,0 +1,194 @@ +/* Simulator cache routines for CGEN simulators (and maybe others). + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#define SCACHE_P +#define SCACHE_DEFINE_INLINE + +#include "sim-main.h" +#include "libiberty.h" +#include "cgen-scache.h" +#include "sim-options.h" +#include "sim-io.h" + +/* Unused address. */ +#define UNUSED_ADDR 0xffffffff + +static MODULE_INIT_FN scache_init; +static MODULE_UNINSTALL_FN scache_uninstall; + +static DECLARE_OPTION_HANDLER (scache_option_handler); + +#define OPTION_PROFILE_SCACHE (OPTION_START + 0) + +static const OPTION scache_options[] = { + { {"scache-size", optional_argument, NULL, 'c'}, + 'c', "[SIZE]", "Specify size of simulator execution cache", + scache_option_handler }, + { {"profile-scache", no_argument, NULL, OPTION_PROFILE_SCACHE}, + '\0', NULL, "Perform simulator execution cache profiling", + scache_option_handler }, + { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } +}; + +static SIM_RC +scache_option_handler (sd, opt, arg) + SIM_DESC sd; + int opt; + char *arg; +{ + int n; + + switch (opt) + { + case 'c' : + if (WITH_SCACHE) + { + if (arg != NULL) + { + int n = strtol (arg, NULL, 0); + /* The m32r port assumes a cache size of at least 2 so it + can decode both 16 bit insns. */ + if (n < 2) + { + sim_io_eprintf (sd, "invalid scache size `%d'", n); + return SIM_RC_FAIL; + } + /* Ensure it's a multiple of 2. */ + if ((n & (n - 1)) != 0) + { + sim_io_eprintf (sd, "scache size `%d' not a multiple of 2\n", n); + { + /* round up to nearest multiple of 2 */ + int i; + for (i = 1; i < n; i <<= 1) + continue; + n = i; + + } + sim_io_eprintf (sd, "rounding scache size up to %d\n", n); + } + STATE_SCACHE_SIZE (sd) = n; + } + else + STATE_SCACHE_SIZE (sd) = SCACHE_DEFAULT_CACHE_SIZE; + } + else + sim_io_eprintf (sd, "Simulator execution cache not enabled, `--scache-size' ignored\n"); + break; + + case OPTION_PROFILE_SCACHE : + if (WITH_SCACHE && WITH_PROFILE_SCACHE_P) + for (n = 0; n < MAX_NR_PROCESSORS; ++n) + CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_SCACHE_IDX] = 1; + else + sim_io_eprintf (sd, "Simulator cache profiling not compiled in, `--profile-scache' ignored\n"); + break; + + } + + return SIM_RC_OK; +} + +SIM_RC +scache_install (SIM_DESC sd) +{ + sim_add_option_table (sd, scache_options); + sim_module_add_init_fn (sd, scache_init); + sim_module_add_uninstall_fn (sd, scache_uninstall); + + /* This is the default, it may be overridden on the command line. */ + STATE_SCACHE_SIZE (sd) = WITH_SCACHE; + + return SIM_RC_OK; +} + +static SIM_RC +scache_init (SIM_DESC sd) +{ + int c; + + for (c = 0; c < MAX_NR_PROCESSORS; ++c) + { + SIM_CPU *cpu = STATE_CPU (sd, c); + + CPU_SCACHE_SIZE (cpu) = STATE_SCACHE_SIZE (sd); + CPU_SCACHE_CACHE (cpu) = (SCACHE *) + xmalloc (CPU_SCACHE_SIZE (cpu) * sizeof (SCACHE)); + } + + scache_flush (sd); + + return SIM_RC_OK; +} + +static void +scache_uninstall (SIM_DESC sd) +{ + int c; + + for (c = 0; c < MAX_NR_PROCESSORS; ++c) + { + SIM_CPU *cpu = STATE_CPU (sd, c); + + if (CPU_SCACHE_CACHE (cpu) != NULL) + free (CPU_SCACHE_CACHE (cpu)); + } +} + +void +scache_flush (SIM_DESC sd) +{ + int i,c; + SCACHE *sc; + + for (c = 0; c < MAX_NR_PROCESSORS; ++c) + { + SIM_CPU *cpu = STATE_CPU (sd, c); + + /* Technically, this may not be necessary, but it helps debugging. */ + memset (CPU_SCACHE_CACHE (cpu), 0, + CPU_SCACHE_SIZE (cpu) * sizeof (SCACHE)); + + for (i = 0, sc = CPU_SCACHE_CACHE (cpu); i < CPU_SCACHE_SIZE (cpu); + ++i, ++sc) + { + sc->argbuf.addr = UNUSED_ADDR; + } + } +} + +void +scache_print_profile (SIM_DESC sd, int verbose) +{ + /* FIXME: Need to add smp support. */ + SIM_CPU *cpu = STATE_CPU (sd, 0); + unsigned long hits = CPU_SCACHE_HITS (cpu); + unsigned long misses = CPU_SCACHE_MISSES (cpu); + + sim_io_printf (sd, "Simulator Cache Statistics\n\n"); + + sim_io_printf (sd, "Cache size: %d\n", CPU_SCACHE_SIZE (cpu)); + sim_io_printf (sd, "Hits: %d\n", hits); + sim_io_printf (sd, "Misses: %d\n", misses); + if (hits + misses != 0) + sim_io_printf (sd, "Hit rate: %.2f%%\n", + ((double) hits / ((double) hits + (double) misses)) * 100); + sim_io_printf (sd, "\n"); +} diff --git a/sim/common/cgen-scache.h b/sim/common/cgen-scache.h new file mode 100644 index 0000000..9cb2a5f --- /dev/null +++ b/sim/common/cgen-scache.h @@ -0,0 +1,108 @@ +/* Simulator cache definitions for CGEN simulators (and maybe others). + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SCACHE_H +#define SCACHE_H + +/* A cached insn. */ +typedef struct scache { + IADDR next; + union { +#ifdef USE_SEM_SWITCH +#ifdef __GNUC__ + void *sem_case; +#else + int sem_case; +#endif +#endif + SEMANTIC_CACHE_FN *sem_fn; + } semantic; + ARGBUF argbuf; +} SCACHE; + +/* 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); + +/* Profiling support. */ + +/* Print summary scache usage information. */ +void scache_print_profile (SIM_DESC sd, 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 + +#endif /* SCACHE_H */ diff --git a/sim/common/cgen-sem.h b/sim/common/cgen-sem.h new file mode 100644 index 0000000..18b8f98 --- /dev/null +++ b/sim/common/cgen-sem.h @@ -0,0 +1,978 @@ +/* Semantics ops support for CGEN-based simulators. + +This file is machine generated. + +Copyright (C) 1996, 1997 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef CGEN_SEMOPS_H +#define CGEN_SEMOPS_H + +/* Semantic operations. */ + +#define ADDBI(x, y) ((x) + (y)) +#define SUBBI(x, y) ((x) - (y)) +#define MULBI(x, y) ((x) * (y)) +#define DIVBI(x, y) ((BI) (x) / (BI) (y)) +#define UDIVBI(x, y) ((BI) (x) / (BI) (y)) +#define MODBI(x, y) ((BI) (x) % (BI) (y)) +#define UMODBI(x, y) ((BI) (x) % (BI) (y)) +#define SRABI(x, y) ((BI) (x) >> (y)) +#define SRLBI(x, y) ((UBI) (x) >> (y)) +#define SHLBI(x, y) ((BI) (x) << (y)) +extern BI RORBI PARAMS ((BI, int)); +extern BI ROLBI PARAMS ((BI, int)); +#define ANDBI(x, y) ((x) & (y)) +#define ORBI(x, y) ((x) | (y)) +#define XORBI(x, y) ((x) ^ (y)) +#define ANDIFBI(x, y) ((BI) (x) && (BI) (y)) +#define ORIFBI(x, y) ((BI) (x) || (BI) (y)) +#define NEGBI(x) (- (x)) +#define NOTBI(x) (! (BI) (x)) +#define INVBI(x) (~ (x)) +#define EQBI(x, y) ((BI) (x) == (BI) (y)) +#define NEBI(x, y) ((BI) (x) != (BI) (y)) +#define LTBI(x, y) ((BI) (x) < (BI) (y)) +#define LEBI(x, y) ((BI) (x) <= (BI) (y)) +#define GTBI(x, y) ((BI) (x) > (BI) (y)) +#define GEBI(x, y) ((BI) (x) >= (BI) (y)) +#define LTUBI(x, y) ((BI) (x) < (BI) (y)) +#define LEUBI(x, y) ((BI) (x) <= (BI) (y)) +#define GTUBI(x, y) ((BI) (x) > (BI) (y)) +#define GEUBI(x, y) ((BI) (x) >= (BI) (y)) + +#define ADDQI(x, y) ((x) + (y)) +#define SUBQI(x, y) ((x) - (y)) +#define MULQI(x, y) ((x) * (y)) +#define DIVQI(x, y) ((QI) (x) / (QI) (y)) +#define UDIVQI(x, y) ((QI) (x) / (QI) (y)) +#define MODQI(x, y) ((QI) (x) % (QI) (y)) +#define UMODQI(x, y) ((QI) (x) % (QI) (y)) +#define SRAQI(x, y) ((QI) (x) >> (y)) +#define SRLQI(x, y) ((UQI) (x) >> (y)) +#define SHLQI(x, y) ((QI) (x) << (y)) +extern QI RORQI PARAMS ((QI, int)); +extern QI ROLQI PARAMS ((QI, int)); +#define ANDQI(x, y) ((x) & (y)) +#define ORQI(x, y) ((x) | (y)) +#define XORQI(x, y) ((x) ^ (y)) +#define ANDIFQI(x, y) ((QI) (x) && (QI) (y)) +#define ORIFQI(x, y) ((QI) (x) || (QI) (y)) +#define NEGQI(x) (- (x)) +#define NOTQI(x) (! (QI) (x)) +#define INVQI(x) (~ (x)) +#define EQQI(x, y) ((QI) (x) == (QI) (y)) +#define NEQI(x, y) ((QI) (x) != (QI) (y)) +#define LTQI(x, y) ((QI) (x) < (QI) (y)) +#define LEQI(x, y) ((QI) (x) <= (QI) (y)) +#define GTQI(x, y) ((QI) (x) > (QI) (y)) +#define GEQI(x, y) ((QI) (x) >= (QI) (y)) +#define LTUQI(x, y) ((QI) (x) < (QI) (y)) +#define LEUQI(x, y) ((QI) (x) <= (QI) (y)) +#define GTUQI(x, y) ((QI) (x) > (QI) (y)) +#define GEUQI(x, y) ((QI) (x) >= (QI) (y)) + +#define ADDHI(x, y) ((x) + (y)) +#define SUBHI(x, y) ((x) - (y)) +#define MULHI(x, y) ((x) * (y)) +#define DIVHI(x, y) ((HI) (x) / (HI) (y)) +#define UDIVHI(x, y) ((HI) (x) / (HI) (y)) +#define MODHI(x, y) ((HI) (x) % (HI) (y)) +#define UMODHI(x, y) ((HI) (x) % (HI) (y)) +#define SRAHI(x, y) ((HI) (x) >> (y)) +#define SRLHI(x, y) ((UHI) (x) >> (y)) +#define SHLHI(x, y) ((HI) (x) << (y)) +extern HI RORHI PARAMS ((HI, int)); +extern HI ROLHI PARAMS ((HI, int)); +#define ANDHI(x, y) ((x) & (y)) +#define ORHI(x, y) ((x) | (y)) +#define XORHI(x, y) ((x) ^ (y)) +#define ANDIFHI(x, y) ((HI) (x) && (HI) (y)) +#define ORIFHI(x, y) ((HI) (x) || (HI) (y)) +#define NEGHI(x) (- (x)) +#define NOTHI(x) (! (HI) (x)) +#define INVHI(x) (~ (x)) +#define EQHI(x, y) ((HI) (x) == (HI) (y)) +#define NEHI(x, y) ((HI) (x) != (HI) (y)) +#define LTHI(x, y) ((HI) (x) < (HI) (y)) +#define LEHI(x, y) ((HI) (x) <= (HI) (y)) +#define GTHI(x, y) ((HI) (x) > (HI) (y)) +#define GEHI(x, y) ((HI) (x) >= (HI) (y)) +#define LTUHI(x, y) ((HI) (x) < (HI) (y)) +#define LEUHI(x, y) ((HI) (x) <= (HI) (y)) +#define GTUHI(x, y) ((HI) (x) > (HI) (y)) +#define GEUHI(x, y) ((HI) (x) >= (HI) (y)) + +#define ADDSI(x, y) ((x) + (y)) +#define SUBSI(x, y) ((x) - (y)) +#define MULSI(x, y) ((x) * (y)) +#define DIVSI(x, y) ((SI) (x) / (SI) (y)) +#define UDIVSI(x, y) ((SI) (x) / (SI) (y)) +#define MODSI(x, y) ((SI) (x) % (SI) (y)) +#define UMODSI(x, y) ((SI) (x) % (SI) (y)) +#define SRASI(x, y) ((SI) (x) >> (y)) +#define SRLSI(x, y) ((USI) (x) >> (y)) +#define SHLSI(x, y) ((SI) (x) << (y)) +extern SI RORSI PARAMS ((SI, int)); +extern SI ROLSI PARAMS ((SI, int)); +#define ANDSI(x, y) ((x) & (y)) +#define ORSI(x, y) ((x) | (y)) +#define XORSI(x, y) ((x) ^ (y)) +#define ANDIFSI(x, y) ((SI) (x) && (SI) (y)) +#define ORIFSI(x, y) ((SI) (x) || (SI) (y)) +#define NEGSI(x) (- (x)) +#define NOTSI(x) (! (SI) (x)) +#define INVSI(x) (~ (x)) +#define EQSI(x, y) ((SI) (x) == (SI) (y)) +#define NESI(x, y) ((SI) (x) != (SI) (y)) +#define LTSI(x, y) ((SI) (x) < (SI) (y)) +#define LESI(x, y) ((SI) (x) <= (SI) (y)) +#define GTSI(x, y) ((SI) (x) > (SI) (y)) +#define GESI(x, y) ((SI) (x) >= (SI) (y)) +#define LTUSI(x, y) ((SI) (x) < (SI) (y)) +#define LEUSI(x, y) ((SI) (x) <= (SI) (y)) +#define GTUSI(x, y) ((SI) (x) > (SI) (y)) +#define GEUSI(x, y) ((SI) (x) >= (SI) (y)) + +#ifdef DI_FN_SUPPORT +#define ADDDI(x, y) ((x) + (y)) +#define SUBDI(x, y) ((x) - (y)) +#define MULDI(x, y) ((x) * (y)) +#define DIVDI(x, y) ((DI) (x) / (DI) (y)) +#define UDIVDI(x, y) ((DI) (x) / (DI) (y)) +#define MODDI(x, y) ((DI) (x) % (DI) (y)) +#define UMODDI(x, y) ((DI) (x) % (DI) (y)) +#define SRADI(x, y) ((DI) (x) >> (y)) +#define SRLDI(x, y) ((UDI) (x) >> (y)) +#define SHLDI(x, y) ((DI) (x) << (y)) +extern DI RORDI PARAMS ((DI, int)); +extern DI ROLDI PARAMS ((DI, int)); +#define ANDDI(x, y) ((x) & (y)) +#define ORDI(x, y) ((x) | (y)) +#define XORDI(x, y) ((x) ^ (y)) +#define ANDIFDI(x, y) ((DI) (x) && (DI) (y)) +#define ORIFDI(x, y) ((DI) (x) || (DI) (y)) +#define NEGDI(x) (- (x)) +#define NOTDI(x) (! (DI) (x)) +#define INVDI(x) (~ (x)) +#define EQDI(x, y) ((DI) (x) == (DI) (y)) +#define NEDI(x, y) ((DI) (x) != (DI) (y)) +#define LTDI(x, y) ((DI) (x) < (DI) (y)) +#define LEDI(x, y) ((DI) (x) <= (DI) (y)) +#define GTDI(x, y) ((DI) (x) > (DI) (y)) +#define GEDI(x, y) ((DI) (x) >= (DI) (y)) +#define LTUDI(x, y) ((DI) (x) < (DI) (y)) +#define LEUDI(x, y) ((DI) (x) <= (DI) (y)) +#define GTUDI(x, y) ((DI) (x) > (DI) (y)) +#define GEUDI(x, y) ((DI) (x) >= (DI) (y)) +#else /* ! DI_FN_SUPPORT */ +#define ADDDI(x, y) ((x) + (y)) +#define SUBDI(x, y) ((x) - (y)) +#define MULDI(x, y) ((x) * (y)) +#define DIVDI(x, y) ((DI) (x) / (DI) (y)) +#define UDIVDI(x, y) ((DI) (x) / (DI) (y)) +#define MODDI(x, y) ((DI) (x) % (DI) (y)) +#define UMODDI(x, y) ((DI) (x) % (DI) (y)) +#define SRADI(x, y) ((DI) (x) >> (y)) +#define SRLDI(x, y) ((UDI) (x) >> (y)) +#define SHLDI(x, y) ((DI) (x) << (y)) +extern DI RORDI PARAMS ((DI, int)); +extern DI ROLDI PARAMS ((DI, int)); +#define ANDDI(x, y) ((x) & (y)) +#define ORDI(x, y) ((x) | (y)) +#define XORDI(x, y) ((x) ^ (y)) +#define ANDIFDI(x, y) ((DI) (x) && (DI) (y)) +#define ORIFDI(x, y) ((DI) (x) || (DI) (y)) +#define NEGDI(x) (- (x)) +#define NOTDI(x) (! (DI) (x)) +#define INVDI(x) (~ (x)) +#define EQDI(x, y) ((DI) (x) == (DI) (y)) +#define NEDI(x, y) ((DI) (x) != (DI) (y)) +#define LTDI(x, y) ((DI) (x) < (DI) (y)) +#define LEDI(x, y) ((DI) (x) <= (DI) (y)) +#define GTDI(x, y) ((DI) (x) > (DI) (y)) +#define GEDI(x, y) ((DI) (x) >= (DI) (y)) +#define LTUDI(x, y) ((DI) (x) < (DI) (y)) +#define LEUDI(x, y) ((DI) (x) <= (DI) (y)) +#define GTUDI(x, y) ((DI) (x) > (DI) (y)) +#define GEUDI(x, y) ((DI) (x) >= (DI) (y)) +#endif /* DI_FN_SUPPORT */ + +#ifdef SF_FN_SUPPORT +#define ADDSF(x, y) ((x) + (y)) +#define SUBSF(x, y) ((x) - (y)) +#define NEGSF(x) (- (x)) +#define MULSF(x, y) ((x) * (y)) +#define DIVSF(x, y) ((x) / (y)) +#define EQSF(x, y) ((SF) (x) == (SF) (y)) +#define NESF(x, y) ((SF) (x) != (SF) (y)) +#define LTSF(x, y) ((SF) (x) < (SF) (y)) +#define LESF(x, y) ((SF) (x) <= (SF) (y)) +#define GTSF(x, y) ((SF) (x) > (SF) (y)) +#define GESF(x, y) ((SF) (x) >= (SF) (y)) +extern SF ABSSF PARAMS ((SF)); +extern SF SQRTSF PARAMS ((SF)); +extern SF COSSF PARAMS ((SF)); +extern SF SINSF PARAMS ((SF)); +#else /* ! SF_FN_SUPPORT */ +#define ADDSF(x, y) ((x) + (y)) +#define SUBSF(x, y) ((x) - (y)) +#define NEGSF(x) (- (x)) +#define MULSF(x, y) ((x) * (y)) +#define DIVSF(x, y) ((x) / (y)) +#define EQSF(x, y) ((SF) (x) == (SF) (y)) +#define NESF(x, y) ((SF) (x) != (SF) (y)) +#define LTSF(x, y) ((SF) (x) < (SF) (y)) +#define LESF(x, y) ((SF) (x) <= (SF) (y)) +#define GTSF(x, y) ((SF) (x) > (SF) (y)) +#define GESF(x, y) ((SF) (x) >= (SF) (y)) +extern SF ABSSF PARAMS ((SF)); +extern SF SQRTSF PARAMS ((SF)); +extern SF COSSF PARAMS ((SF)); +extern SF SINSF PARAMS ((SF)); +#endif /* SF_FN_SUPPORT */ + +#ifdef DF_FN_SUPPORT +#define ADDDF(x, y) ((x) + (y)) +#define SUBDF(x, y) ((x) - (y)) +#define NEGDF(x) (- (x)) +#define MULDF(x, y) ((x) * (y)) +#define DIVDF(x, y) ((x) / (y)) +#define EQDF(x, y) ((DF) (x) == (DF) (y)) +#define NEDF(x, y) ((DF) (x) != (DF) (y)) +#define LTDF(x, y) ((DF) (x) < (DF) (y)) +#define LEDF(x, y) ((DF) (x) <= (DF) (y)) +#define GTDF(x, y) ((DF) (x) > (DF) (y)) +#define GEDF(x, y) ((DF) (x) >= (DF) (y)) +extern DF ABSDF PARAMS ((DF)); +extern DF SQRTDF PARAMS ((DF)); +extern DF COSDF PARAMS ((DF)); +extern DF SINDF PARAMS ((DF)); +#else /* ! DF_FN_SUPPORT */ +#define ADDDF(x, y) ((x) + (y)) +#define SUBDF(x, y) ((x) - (y)) +#define NEGDF(x) (- (x)) +#define MULDF(x, y) ((x) * (y)) +#define DIVDF(x, y) ((x) / (y)) +#define EQDF(x, y) ((DF) (x) == (DF) (y)) +#define NEDF(x, y) ((DF) (x) != (DF) (y)) +#define LTDF(x, y) ((DF) (x) < (DF) (y)) +#define LEDF(x, y) ((DF) (x) <= (DF) (y)) +#define GTDF(x, y) ((DF) (x) > (DF) (y)) +#define GEDF(x, y) ((DF) (x) >= (DF) (y)) +extern DF ABSDF PARAMS ((DF)); +extern DF SQRTDF PARAMS ((DF)); +extern DF COSDF PARAMS ((DF)); +extern DF SINDF PARAMS ((DF)); +#endif /* DF_FN_SUPPORT */ + +#ifdef XF_FN_SUPPORT +#define ADDXF(x, y) ((x) + (y)) +#define SUBXF(x, y) ((x) - (y)) +#define NEGXF(x) (- (x)) +#define MULXF(x, y) ((x) * (y)) +#define DIVXF(x, y) ((x) / (y)) +#define EQXF(x, y) ((XF) (x) == (XF) (y)) +#define NEXF(x, y) ((XF) (x) != (XF) (y)) +#define LTXF(x, y) ((XF) (x) < (XF) (y)) +#define LEXF(x, y) ((XF) (x) <= (XF) (y)) +#define GTXF(x, y) ((XF) (x) > (XF) (y)) +#define GEXF(x, y) ((XF) (x) >= (XF) (y)) +extern XF ABSXF PARAMS ((XF)); +extern XF SQRTXF PARAMS ((XF)); +extern XF COSXF PARAMS ((XF)); +extern XF SINXF PARAMS ((XF)); +#else /* ! XF_FN_SUPPORT */ +#define ADDXF(x, y) ((x) + (y)) +#define SUBXF(x, y) ((x) - (y)) +#define NEGXF(x) (- (x)) +#define MULXF(x, y) ((x) * (y)) +#define DIVXF(x, y) ((x) / (y)) +#define EQXF(x, y) ((XF) (x) == (XF) (y)) +#define NEXF(x, y) ((XF) (x) != (XF) (y)) +#define LTXF(x, y) ((XF) (x) < (XF) (y)) +#define LEXF(x, y) ((XF) (x) <= (XF) (y)) +#define GTXF(x, y) ((XF) (x) > (XF) (y)) +#define GEXF(x, y) ((XF) (x) >= (XF) (y)) +extern XF ABSXF PARAMS ((XF)); +extern XF SQRTXF PARAMS ((XF)); +extern XF COSXF PARAMS ((XF)); +extern XF SINXF PARAMS ((XF)); +#endif /* XF_FN_SUPPORT */ + +#ifdef TF_FN_SUPPORT +#define ADDTF(x, y) ((x) + (y)) +#define SUBTF(x, y) ((x) - (y)) +#define NEGTF(x) (- (x)) +#define MULTF(x, y) ((x) * (y)) +#define DIVTF(x, y) ((x) / (y)) +#define EQTF(x, y) ((TF) (x) == (TF) (y)) +#define NETF(x, y) ((TF) (x) != (TF) (y)) +#define LTTF(x, y) ((TF) (x) < (TF) (y)) +#define LETF(x, y) ((TF) (x) <= (TF) (y)) +#define GTTF(x, y) ((TF) (x) > (TF) (y)) +#define GETF(x, y) ((TF) (x) >= (TF) (y)) +extern TF ABSTF PARAMS ((TF)); +extern TF SQRTTF PARAMS ((TF)); +extern TF COSTF PARAMS ((TF)); +extern TF SINTF PARAMS ((TF)); +#else /* ! TF_FN_SUPPORT */ +#define ADDTF(x, y) ((x) + (y)) +#define SUBTF(x, y) ((x) - (y)) +#define NEGTF(x) (- (x)) +#define MULTF(x, y) ((x) * (y)) +#define DIVTF(x, y) ((x) / (y)) +#define EQTF(x, y) ((TF) (x) == (TF) (y)) +#define NETF(x, y) ((TF) (x) != (TF) (y)) +#define LTTF(x, y) ((TF) (x) < (TF) (y)) +#define LETF(x, y) ((TF) (x) <= (TF) (y)) +#define GTTF(x, y) ((TF) (x) > (TF) (y)) +#define GETF(x, y) ((TF) (x) >= (TF) (y)) +extern TF ABSTF PARAMS ((TF)); +extern TF SQRTTF PARAMS ((TF)); +extern TF COSTF PARAMS ((TF)); +extern TF SINTF PARAMS ((TF)); +#endif /* TF_FN_SUPPORT */ + + +#define EXTBIQI(x) ((QI) (BI) (x)) +#define EXTBIHI(x) ((HI) (BI) (x)) +#define EXTBISI(x) ((SI) (BI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI EXTBIDI PARAMS ((BI)); +#else +#define EXTBIDI(x) ((DI) (BI) (x)) +#endif +#define EXTQIHI(x) ((HI) (QI) (x)) +#define EXTQISI(x) ((SI) (QI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI EXTQIDI PARAMS ((QI)); +#else +#define EXTQIDI(x) ((DI) (QI) (x)) +#endif +#define EXTHISI(x) ((SI) (HI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI EXTHIDI PARAMS ((HI)); +#else +#define EXTHIDI(x) ((DI) (HI) (x)) +#endif +#if defined (DI_FN_SUPPORT) +extern DI EXTSIDI PARAMS ((SI)); +#else +#define EXTSIDI(x) ((DI) (SI) (x)) +#endif +#if defined (SF_FN_SUPPORT) || defined (DF_FN_SUPPORT) +extern DF EXTSFDF PARAMS ((SF)); +#else +#define EXTSFDF(x) ((DF) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) || defined (XF_FN_SUPPORT) +extern XF EXTSFXF PARAMS ((SF)); +#else +#define EXTSFXF(x) ((XF) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) || defined (TF_FN_SUPPORT) +extern TF EXTSFTF PARAMS ((SF)); +#else +#define EXTSFTF(x) ((TF) (SF) (x)) +#endif +#if defined (DF_FN_SUPPORT) || defined (XF_FN_SUPPORT) +extern XF EXTDFXF PARAMS ((DF)); +#else +#define EXTDFXF(x) ((XF) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) || defined (TF_FN_SUPPORT) +extern TF EXTDFTF PARAMS ((DF)); +#else +#define EXTDFTF(x) ((TF) (DF) (x)) +#endif +#if defined (XF_FN_SUPPORT) || defined (TF_FN_SUPPORT) +extern TF EXTXFTF PARAMS ((XF)); +#else +#define EXTXFTF(x) ((TF) (XF) (x)) +#endif +#define ZEXTBIQI(x) ((QI) (UBI) (x)) +#define ZEXTBIHI(x) ((HI) (UBI) (x)) +#define ZEXTBISI(x) ((SI) (UBI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI ZEXTBIDI PARAMS ((BI)); +#else +#define ZEXTBIDI(x) ((DI) (UBI) (x)) +#endif +#define ZEXTQIHI(x) ((HI) (UQI) (x)) +#define ZEXTQISI(x) ((SI) (UQI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI ZEXTQIDI PARAMS ((QI)); +#else +#define ZEXTQIDI(x) ((DI) (UQI) (x)) +#endif +#define ZEXTHISI(x) ((SI) (UHI) (x)) +#if defined (DI_FN_SUPPORT) +extern DI ZEXTHIDI PARAMS ((HI)); +#else +#define ZEXTHIDI(x) ((DI) (UHI) (x)) +#endif +#if defined (DI_FN_SUPPORT) +extern DI ZEXTSIDI PARAMS ((SI)); +#else +#define ZEXTSIDI(x) ((DI) (USI) (x)) +#endif +#define TRUNCQIBI(x) ((BI) (QI) (x)) +#define TRUNCHIBI(x) ((BI) (HI) (x)) +#define TRUNCHIQI(x) ((QI) (HI) (x)) +#define TRUNCSIBI(x) ((BI) (SI) (x)) +#define TRUNCSIQI(x) ((QI) (SI) (x)) +#define TRUNCSIHI(x) ((HI) (SI) (x)) +#if defined (DI_FN_SUPPORT) +extern BI TRUNCDIBI PARAMS ((DI)); +#else +#define TRUNCDIBI(x) ((BI) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) +extern QI TRUNCDIQI PARAMS ((DI)); +#else +#define TRUNCDIQI(x) ((QI) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) +extern HI TRUNCDIHI PARAMS ((DI)); +#else +#define TRUNCDIHI(x) ((HI) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) +extern SI TRUNCDISI PARAMS ((DI)); +#else +#define TRUNCDISI(x) ((SI) (DI) (x)) +#endif +#if defined (DF_FN_SUPPORT) || defined (SF_FN_SUPPORT) +extern SF TRUNCDFSF PARAMS ((DF)); +#else +#define TRUNCDFSF(x) ((SF) (DF) (x)) +#endif +#if defined (XF_FN_SUPPORT) || defined (SF_FN_SUPPORT) +extern SF TRUNCXFSF PARAMS ((XF)); +#else +#define TRUNCXFSF(x) ((SF) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) || defined (DF_FN_SUPPORT) +extern DF TRUNCXFDF PARAMS ((XF)); +#else +#define TRUNCXFDF(x) ((DF) (XF) (x)) +#endif +#if defined (TF_FN_SUPPORT) || defined (SF_FN_SUPPORT) +extern SF TRUNCTFSF PARAMS ((TF)); +#else +#define TRUNCTFSF(x) ((SF) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) || defined (DF_FN_SUPPORT) +extern DF TRUNCTFDF PARAMS ((TF)); +#else +#define TRUNCTFDF(x) ((DF) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) || defined (XF_FN_SUPPORT) +extern XF TRUNCTFXF PARAMS ((TF)); +#else +#define TRUNCTFXF(x) ((XF) (TF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF FLOATBISF PARAMS ((BI)); +#else +#define FLOATBISF(x) ((SF) (BI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF FLOATBIDF PARAMS ((BI)); +#else +#define FLOATBIDF(x) ((DF) (BI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF FLOATBIXF PARAMS ((BI)); +#else +#define FLOATBIXF(x) ((XF) (BI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF FLOATBITF PARAMS ((BI)); +#else +#define FLOATBITF(x) ((TF) (BI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF FLOATQISF PARAMS ((QI)); +#else +#define FLOATQISF(x) ((SF) (QI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF FLOATQIDF PARAMS ((QI)); +#else +#define FLOATQIDF(x) ((DF) (QI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF FLOATQIXF PARAMS ((QI)); +#else +#define FLOATQIXF(x) ((XF) (QI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF FLOATQITF PARAMS ((QI)); +#else +#define FLOATQITF(x) ((TF) (QI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF FLOATHISF PARAMS ((HI)); +#else +#define FLOATHISF(x) ((SF) (HI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF FLOATHIDF PARAMS ((HI)); +#else +#define FLOATHIDF(x) ((DF) (HI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF FLOATHIXF PARAMS ((HI)); +#else +#define FLOATHIXF(x) ((XF) (HI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF FLOATHITF PARAMS ((HI)); +#else +#define FLOATHITF(x) ((TF) (HI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF FLOATSISF PARAMS ((SI)); +#else +#define FLOATSISF(x) ((SF) (SI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF FLOATSIDF PARAMS ((SI)); +#else +#define FLOATSIDF(x) ((DF) (SI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF FLOATSIXF PARAMS ((SI)); +#else +#define FLOATSIXF(x) ((XF) (SI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF FLOATSITF PARAMS ((SI)); +#else +#define FLOATSITF(x) ((TF) (SI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (SF_FN_SUPPORT) +extern SF FLOATDISF PARAMS ((DI)); +#else +#define FLOATDISF(x) ((SF) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (DF_FN_SUPPORT) +extern DF FLOATDIDF PARAMS ((DI)); +#else +#define FLOATDIDF(x) ((DF) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (XF_FN_SUPPORT) +extern XF FLOATDIXF PARAMS ((DI)); +#else +#define FLOATDIXF(x) ((XF) (DI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (TF_FN_SUPPORT) +extern TF FLOATDITF PARAMS ((DI)); +#else +#define FLOATDITF(x) ((TF) (DI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF UFLOATBISF PARAMS ((BI)); +#else +#define UFLOATBISF(x) ((SF) (UBI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF UFLOATBIDF PARAMS ((BI)); +#else +#define UFLOATBIDF(x) ((DF) (UBI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF UFLOATBIXF PARAMS ((BI)); +#else +#define UFLOATBIXF(x) ((XF) (UBI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF UFLOATBITF PARAMS ((BI)); +#else +#define UFLOATBITF(x) ((TF) (UBI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF UFLOATQISF PARAMS ((QI)); +#else +#define UFLOATQISF(x) ((SF) (UQI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF UFLOATQIDF PARAMS ((QI)); +#else +#define UFLOATQIDF(x) ((DF) (UQI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF UFLOATQIXF PARAMS ((QI)); +#else +#define UFLOATQIXF(x) ((XF) (UQI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF UFLOATQITF PARAMS ((QI)); +#else +#define UFLOATQITF(x) ((TF) (UQI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF UFLOATHISF PARAMS ((HI)); +#else +#define UFLOATHISF(x) ((SF) (UHI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF UFLOATHIDF PARAMS ((HI)); +#else +#define UFLOATHIDF(x) ((DF) (UHI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF UFLOATHIXF PARAMS ((HI)); +#else +#define UFLOATHIXF(x) ((XF) (UHI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF UFLOATHITF PARAMS ((HI)); +#else +#define UFLOATHITF(x) ((TF) (UHI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SF UFLOATSISF PARAMS ((SI)); +#else +#define UFLOATSISF(x) ((SF) (USI) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern DF UFLOATSIDF PARAMS ((SI)); +#else +#define UFLOATSIDF(x) ((DF) (USI) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern XF UFLOATSIXF PARAMS ((SI)); +#else +#define UFLOATSIXF(x) ((XF) (USI) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern TF UFLOATSITF PARAMS ((SI)); +#else +#define UFLOATSITF(x) ((TF) (USI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (SF_FN_SUPPORT) +extern SF UFLOATDISF PARAMS ((DI)); +#else +#define UFLOATDISF(x) ((SF) (UDI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (DF_FN_SUPPORT) +extern DF UFLOATDIDF PARAMS ((DI)); +#else +#define UFLOATDIDF(x) ((DF) (UDI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (XF_FN_SUPPORT) +extern XF UFLOATDIXF PARAMS ((DI)); +#else +#define UFLOATDIXF(x) ((XF) (UDI) (x)) +#endif +#if defined (DI_FN_SUPPORT) || defined (TF_FN_SUPPORT) +extern TF UFLOATDITF PARAMS ((DI)); +#else +#define UFLOATDITF(x) ((TF) (UDI) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern BI FIXSFBI PARAMS ((SF)); +#else +#define FIXSFBI(x) ((BI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern QI FIXSFQI PARAMS ((SF)); +#else +#define FIXSFQI(x) ((QI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern HI FIXSFHI PARAMS ((SF)); +#else +#define FIXSFHI(x) ((HI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SI FIXSFSI PARAMS ((SF)); +#else +#define FIXSFSI(x) ((SI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI FIXSFDI PARAMS ((SF)); +#else +#define FIXSFDI(x) ((DI) (SF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern BI FIXDFBI PARAMS ((DF)); +#else +#define FIXDFBI(x) ((BI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern QI FIXDFQI PARAMS ((DF)); +#else +#define FIXDFQI(x) ((QI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern HI FIXDFHI PARAMS ((DF)); +#else +#define FIXDFHI(x) ((HI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern SI FIXDFSI PARAMS ((DF)); +#else +#define FIXDFSI(x) ((SI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI FIXDFDI PARAMS ((DF)); +#else +#define FIXDFDI(x) ((DI) (DF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern BI FIXXFBI PARAMS ((XF)); +#else +#define FIXXFBI(x) ((BI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern QI FIXXFQI PARAMS ((XF)); +#else +#define FIXXFQI(x) ((QI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern HI FIXXFHI PARAMS ((XF)); +#else +#define FIXXFHI(x) ((HI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern SI FIXXFSI PARAMS ((XF)); +#else +#define FIXXFSI(x) ((SI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI FIXXFDI PARAMS ((XF)); +#else +#define FIXXFDI(x) ((DI) (XF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern BI FIXTFBI PARAMS ((TF)); +#else +#define FIXTFBI(x) ((BI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern QI FIXTFQI PARAMS ((TF)); +#else +#define FIXTFQI(x) ((QI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern HI FIXTFHI PARAMS ((TF)); +#else +#define FIXTFHI(x) ((HI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern SI FIXTFSI PARAMS ((TF)); +#else +#define FIXTFSI(x) ((SI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI FIXTFDI PARAMS ((TF)); +#else +#define FIXTFDI(x) ((DI) (TF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern BI UFIXSFBI PARAMS ((SF)); +#else +#define UFIXSFBI(x) ((UBI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern QI UFIXSFQI PARAMS ((SF)); +#else +#define UFIXSFQI(x) ((UQI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern HI UFIXSFHI PARAMS ((SF)); +#else +#define UFIXSFHI(x) ((UHI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) +extern SI UFIXSFSI PARAMS ((SF)); +#else +#define UFIXSFSI(x) ((USI) (SF) (x)) +#endif +#if defined (SF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI UFIXSFDI PARAMS ((SF)); +#else +#define UFIXSFDI(x) ((UDI) (SF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern BI UFIXDFBI PARAMS ((DF)); +#else +#define UFIXDFBI(x) ((UBI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern QI UFIXDFQI PARAMS ((DF)); +#else +#define UFIXDFQI(x) ((UQI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern HI UFIXDFHI PARAMS ((DF)); +#else +#define UFIXDFHI(x) ((UHI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) +extern SI UFIXDFSI PARAMS ((DF)); +#else +#define UFIXDFSI(x) ((USI) (DF) (x)) +#endif +#if defined (DF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI UFIXDFDI PARAMS ((DF)); +#else +#define UFIXDFDI(x) ((UDI) (DF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern BI UFIXXFBI PARAMS ((XF)); +#else +#define UFIXXFBI(x) ((UBI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern QI UFIXXFQI PARAMS ((XF)); +#else +#define UFIXXFQI(x) ((UQI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern HI UFIXXFHI PARAMS ((XF)); +#else +#define UFIXXFHI(x) ((UHI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) +extern SI UFIXXFSI PARAMS ((XF)); +#else +#define UFIXXFSI(x) ((USI) (XF) (x)) +#endif +#if defined (XF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI UFIXXFDI PARAMS ((XF)); +#else +#define UFIXXFDI(x) ((UDI) (XF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern BI UFIXTFBI PARAMS ((TF)); +#else +#define UFIXTFBI(x) ((UBI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern QI UFIXTFQI PARAMS ((TF)); +#else +#define UFIXTFQI(x) ((UQI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern HI UFIXTFHI PARAMS ((TF)); +#else +#define UFIXTFHI(x) ((UHI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) +extern SI UFIXTFSI PARAMS ((TF)); +#else +#define UFIXTFSI(x) ((USI) (TF) (x)) +#endif +#if defined (TF_FN_SUPPORT) || defined (DI_FN_SUPPORT) +extern DI UFIXTFDI PARAMS ((TF)); +#else +#define UFIXTFDI(x) ((UDI) (TF) (x)) +#endif + +/* Semantic support utilities. */ + +#ifdef __GNUC__ + +#ifdef SEMOPS_DEFINE_INLINE +#define SEMOPS_INLINE +#else +#define SEMOPS_INLINE extern inline +#endif + +SEMOPS_INLINE SI +ADDCSI (SI a, SI b, UBI c) +{ + SI res = ADDSI (a, ADDSI (b, c)); + return res; +} + +SEMOPS_INLINE UBI +ADDCFSI (SI a, SI b, UBI c) +{ + SI tmp = ADDSI (a, ADDSI (b, c)); + BI res = (USI) tmp < (USI) a || (USI) tmp < (USI) b; + return res; +} + +SEMOPS_INLINE UBI +ADDOFSI (SI a, SI b, UBI c) +{ + SI tmp = ADDSI (a, ADDSI (b, c)); + BI res = (((a < 0) == (b < 0)) + && ((a < 0) != (tmp < 0))); + return res; +} + +SEMOPS_INLINE SI +SUBCSI (SI a, SI b, UBI c) +{ + SI res = SUBSI (a, ADDSI (b, c)); + return res; +} + +SEMOPS_INLINE UBI +SUBCFSI (SI a, SI b, UBI c) +{ + BI res = ((USI) a < (USI) b) || ((a == b) && c); + return res; +} + +SEMOPS_INLINE UBI +SUBOFSI (SI a, SI b, UBI c) +{ + SI tmp = SUBSI (a, ADDSI (b, c)); + BI res = (((a < 0) != (b < 0)) + && ((a < 0) != (tmp < 0))); + return res; +} + +#else + +SI ADDCSI (SI, SI, UBI); +UBI ADDCFSI (SI, SI, UBI); +UBI ADDOFSI (SI, SI, UBI); +SI SUBCSI (SI, SI, UBI); +UBI SUBCFSI (SI, SI, UBI); +UBI SUBOFSI (SI, SI, UBI); + +#endif + +/* DI mode support if "long long" doesn't exist. + At one point CGEN supported K&R C compilers, and ANSI C compilers without + "long long". One can argue the various merits of keeping this in or + throwing it out. I went to the trouble of adding it so for the time being + I'm leaving it in. */ + +#ifdef DI_FN_SUPPORT + +DI make_struct_di (SI, SI); +/* FIXME: needed? */ +DI CONVHIDI (HI); +DI CONVSIDI (SI); +SI CONVDISI (DI); + +#endif /* DI_FN_SUPPORT */ + +#endif /* CGEN_SEMOPS_H */ diff --git a/sim/common/cgen-sim.h b/sim/common/cgen-sim.h new file mode 100644 index 0000000..4cfc7d2 --- /dev/null +++ b/sim/common/cgen-sim.h @@ -0,0 +1,138 @@ +/* Simulator header for Cpu tools GENerated simulators. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#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)); + +/* Decode,extract,semantics. */ + +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 *)); +#if 0 /* wip */ +typedef void (EXTRACT_CACHE_FN) PARAMS ((SIM_CPU *, PCADDR, insn_t, struct argbuf *)); +#endif +typedef PCADDR (SEMANTIC_CACHE_FN) PARAMS ((SIM_CPU *, struct scache *)); + +typedef struct { + /* Using cgen_insn_type requires <cpu>-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; + 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; +#endif +} DECODE; + +/* FIXME: length parm to decode() is currently unneeded. */ +extern DECODE *decode PARAMS ((insn_t /*, int*/)); + +/* Simulator state. */ + +#if WITH_SCACHE +#include "cgen-scache.h" +#endif + +/* ??? Do we *need* to pass state to the semantic routines? */ +extern SIM_DESC current_state; + +/* FIXME: Until sim_open creates one. */ +extern struct sim_state sim_global_state; + +/* Simulator state. */ + +/* Main state struct. + CGEN_STATE contains addition state information not present in + sim_state_base. */ + +typedef struct cgen_state { + /* argv, env */ + char **argv; +#define STATE_ARGV(s) ((s)->cgen_state.argv) + char **envp; +#define STATE_ENVP(s) ((s)->cgen_state.envp) +} CGEN_STATE; + +/* Additional per-cpu data. */ + +typedef struct { + /* Simulator's execution cache. */ +#if WITH_SCACHE + 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) +} 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); + +void +sim_disassemble_insn (const struct cgen_insn *, const struct argbuf *, + PCADDR, char *); + +#endif /* CGEN_SIM_H */ diff --git a/sim/common/cgen-trace.c b/sim/common/cgen-trace.c new file mode 100644 index 0000000..675c369 --- /dev/null +++ b/sim/common/cgen-trace.c @@ -0,0 +1,251 @@ +/* Tracing support for CGEN-based simulators. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "sim-main.h" +#include "bfd.h" +#include "cpu-opc.h" + +#ifndef SIZE_INSTRUCTION +#define SIZE_INSTRUCTION 16 +#endif + +#ifndef SIZE_LOCATION +#define SIZE_LOCATION 20 +#endif + +#ifndef SIZE_PC +#define SIZE_PC 6 +#endif + +#ifndef SIZE_LINE_NUMBER +#define SIZE_LINE_NUMBER 4 +#endif + +#ifndef SIZE_CYCLE_COUNT +#define SIZE_CYCLE_COUNT 2 +#endif + +#ifndef SIZE_TOTAL_CYCLE_COUNT +#define SIZE_TOTAL_CYCLE_COUNT 9 +#endif + +/* Text is queued in TRACE_BUF because we want to output the insn's cycle + count first but that isn't know until after the insn has executed. */ +static char trace_buf[1024]; +/* If NULL, output to stdout directly. */ +static char *bufptr; + +/* For computing an instruction's cycle count. + FIXME: Need to move into cpu struct for smp case. */ +static unsigned long last_cycle_count; + +void +trace_insn_init (SIM_CPU *cpu) +{ + bufptr = trace_buf; + *bufptr = 0; +} + +void +trace_insn_fini (SIM_CPU *cpu) +{ + if (CPU_PROFILE_FLAGS (cpu) [PROFILE_MODEL_IDX]) + { + unsigned long total = PROFILE_TOTAL_CYCLE_COUNT (CPU_PROFILE_DATA (cpu)); + fprintf (stderr, "%-*ld %-*ld ", + SIZE_CYCLE_COUNT, total - last_cycle_count, + SIZE_TOTAL_CYCLE_COUNT, total); + last_cycle_count = total; + } + + fputs (trace_buf, stderr); + fputc ('\n', stderr); +} + +/* For communication between trace_insn and trace_result. */ +static int printed_result_p; + +void +trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode, + const struct argbuf *abuf, PCADDR pc) +{ + const char *filename; + const char *functionname; + unsigned int linenumber; + char *p, buf[256], disasm_buf[50]; + + if (! TRACE_P (cpu, TRACE_LINENUM_IDX)) + { + cgen_trace_printf (cpu, "0x%.*x %-*s ", + SIZE_PC, (unsigned) pc, + SIZE_INSTRUCTION, + CGEN_INSN_SYNTAX (opcode)->mnemonic); + return; + } + + buf[0] = 0; + + if (STATE_TEXT_SECTION (CPU_STATE (cpu)) + && pc >= STATE_TEXT_START (CPU_STATE (cpu)) + && pc < STATE_TEXT_END (CPU_STATE (cpu))) + { + filename = (const char *) 0; + functionname = (const char *) 0; + linenumber = 0; + if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu)), + STATE_TEXT_SECTION (CPU_STATE (cpu)), + (struct symbol_cache_entry **) 0, + pc - STATE_TEXT_START (CPU_STATE (cpu)), + &filename, &functionname, &linenumber)) + { + p = buf; + if (linenumber) + { + sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber); + p += strlen (p); + } + else + { + sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---"); + p += SIZE_LINE_NUMBER+2; + } + + if (functionname) + { + sprintf (p, "%s ", functionname); + p += strlen (p); + } + else if (filename) + { + char *q = (char *) strrchr (filename, '/'); + sprintf (p, "%s ", (q) ? q+1 : filename); + p += strlen (p); + } + + if (*p == ' ') + *p = '\0'; + } + } + + sim_disassemble_insn (opcode, abuf, pc, disasm_buf); + + cgen_trace_printf (cpu, "0x%.*x %-*.*s %-*s ", + SIZE_PC, (unsigned) pc, + SIZE_LOCATION, SIZE_LOCATION, buf, + SIZE_INSTRUCTION, +#if 0 + CGEN_INSN_SYNTAX (opcode)->mnemonic +#else + disasm_buf +#endif + ); + + printed_result_p = 0; +} + +void +trace_extract (SIM_CPU *cpu, PCADDR pc, char *name, ...) +{ + va_list args; + int printed_one_p = 0; + char *fmt; + + va_start (args, name); + + cgen_trace_printf (cpu, "0x%.*x: %s ", SIZE_PC, pc, name); + + do { + int type,ival; + + fmt = va_arg (args, char *); + + if (fmt) + { + if (printed_one_p) + cgen_trace_printf (cpu, ", "); + printed_one_p = 1; + type = va_arg (args, int); + switch (type) + { + case 'x' : + ival = va_arg (args, int); + cgen_trace_printf (cpu, fmt, ival); + break; + default : + abort (); + } + } + } while (fmt); + + va_end (args); + cgen_trace_printf (cpu, "\n"); +} + +void +trace_result (SIM_CPU *cpu, char *name, int type, ...) +{ + va_list args; + + va_start (args, type); + if (printed_result_p) + cgen_trace_printf (cpu, ", "); + switch (type) + { + case 'x' : + default : + cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int)); + break; + case 'D' : + { + DI di; + /* this is separated from previous line for sunos cc */ + di = va_arg (args, DI); + cgen_trace_printf (cpu, "%s <- 0x%x%08x", name, + GETHIDI(di), GETLODI (di)); + break; + } + } + printed_result_p = 1; + va_end (args); +} + +void +cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + + if (bufptr == NULL) + { + if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL) + (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered) + (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args); + else + vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args); + } + else + { + vsprintf (bufptr, fmt, args); + bufptr += strlen (bufptr); + } + + va_end (args); +} diff --git a/sim/common/cgen-types.h b/sim/common/cgen-types.h new file mode 100644 index 0000000..ad22f46 --- /dev/null +++ b/sim/common/cgen-types.h @@ -0,0 +1,176 @@ +/* Types for Cpu tools GENerated simulators. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef CGEN_TYPES_H +#define CGEN_TYPES_H + +#ifdef __GNUC__ +#define HAVE_LONGLONG +#undef DI_FN_SUPPORT +#define SIM_INLINE extern inline +#else +#undef HAVE_LONGLONG +#define DI_FN_SUPPORT +#define SIM_INLINE +#endif + +#ifndef CGEN_CAT3 +#if defined(__STDC__) || defined(ALMOST_STDC) +#define CGEN_XCAT3(a,b,c) a ## b ## c +#define CGEN_CAT3(a,b,c) CGEN_XCAT3 (a, b, c) +#else +#define CGEN_CAT3(a,b,c) a/**/b/**/c +#endif +#endif + +extern const char *mode_names[]; +#define MODE_NAME(m) (mode_names[m]) + +#ifdef __STDC__ +typedef /*FIXME*/ signed char BI; +typedef /*FIXME*/ signed char QI; +#else +typedef /*FIXME*/ char BI; +typedef /*FIXME*/ char QI; +#endif +typedef short HI; +typedef int SI; +typedef unsigned char UBI; +typedef unsigned char UQI; +typedef unsigned short UHI; +typedef unsigned int USI; + +#ifdef HAVE_LONGLONG +typedef long long DI; +typedef unsigned long long UDI; +#define GETLODI(di) ((SI) (di)) +#define GETHIDI(di) ((SI) ((di) >> 32)) +#define SETLODI(di, val) ((di) = (((di) & 0xffffffff00000000LL) | (val))) +#define SETHIDI(di, val) ((di) = (((di) & 0xffffffffLL) | (((DI) (val)) << 32))) +#define SETDI(di, hi, lo) ((di) = MAKEDI (hi, lo)) +#define MAKEDI(hi, lo) ((((DI) (hi)) << 32) | ((DI) (lo))) +#else +typedef struct { SI hi,lo; } DI; +typedef DI UDI; +#define GETLODI(di) ((di).lo) +#define GETHIDI(di) ((di).hi) +#define SETLODI(di, val) ((di).lo = (val)) +#define SETHIDI(di, val) ((di).hi = (val)) +#define SETDI(di, hi, lo) ((di) = MAKEDI (hi, lo)) +extern DI make_struct_di (SI, SI); +#define MAKEDI(hi, lo) (make_struct_di ((hi), (lo))) +#endif + +/* FIXME: Need to provide libraries if these aren't appropriate for target, + or user's needs. */ +typedef float SF; +typedef double DF; +typedef double XF; /* FIXME: configure, provide library */ +typedef double TF; /* FIXME: configure, provide library */ + +struct argbuf; +struct cgen_insn; +struct scache; + +/* This is used to record extracted raw data from an instruction, among other + things. It must be a host data type, and not a target one so USI is + inappropriate. */ +typedef unsigned int UINT; + +typedef unsigned long PCADDR; +typedef unsigned long ADDR; +typedef /*FIXME*/ unsigned long insn_t; + +/* Forward declaration of STATE. + Must be defined before profile.h and other module headers. */ +typedef struct sim_state *STATE; + +/* 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. */ + +/* ??? The cache stuff is still wip, but it at least works. */ + +#ifdef SCACHE_P + +/* iaddr: instruction address */ +typedef PCADDR IADDR; +/* cia: current instruction address */ +typedef PCADDR CIA; +#define CIA_ADDR(cia) (cia) +typedef struct scache *SEM_ARG; +#define EX_FN_NAME(fn) CGEN_CAT3 (exc,_,fn) +#define SEM_FN_NAME(fn) CGEN_CAT3 (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_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 */ + +typedef PCADDR IADDR; +typedef PCADDR CIA; +#define CIA_ADDR(cia) (cia) +typedef struct argbuf *SEM_ARG; +#define EX_FN_NAME(fn) CGEN_CAT3 (ex,_,fn) +#define SEM_FN_NAME(fn) CGEN_CAT3 (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_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 */ + +#define EXTRACT_SIGNED(val, total, start, length) \ +(((((val) >> ((total) - ((start) + (length)))) & ((1 << (length)) - 1)) \ + ^ (1 << ((length) - 1))) \ + - (1 << ((length) - 1))) + +#define EXTRACT_UNSIGNED(val, total, start, length) \ +(((val) >> ((total) - ((start) + (length)))) & ((1 << (length)) - 1)) + +/* Compute number of longs required to hold N bits. */ +#define HOST_LONGS_FOR_BITS(n) \ + (((n) + sizeof (long) * 8 - 1) / sizeof (long) * 8) + +#endif /* CGEN_TYPES_H */ diff --git a/sim/common/cgen-utils.c b/sim/common/cgen-utils.c new file mode 100644 index 0000000..964e16b --- /dev/null +++ b/sim/common/cgen-utils.c @@ -0,0 +1,406 @@ +/* Support code for various pieces of CGEN simulators. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "sim-main.h" +#include "dis-asm.h" +#include "cpu-opc.h" +#include "decode.h" + +#define MEMOPS_DEFINE_INLINE +#include "cgen-mem.h" + +#define SEMOPS_DEFINE_INLINE +#include "cgen-sem.h" + +const char *mode_names[] = { + "VM", + "BI", + "QI", + "HI", + "SI", + "DI", + "UBI", + "UQI", + "UHI", + "USI", + "UDI", + "SF", + "DF", + "XF", + "TF", +}; + +void +engine_halt (cpu, reason, sigrc) + sim_cpu *cpu; + enum exec_state reason; + int sigrc; +{ + CPU_EXEC_STATE (cpu) = reason; + CPU_HALT_SIGRC (cpu) = sigrc; + + longjmp (STATE_HALT_JMP_BUF (CPU_STATE (cpu)), 1); +} + +void +engine_signal (cpu, sig) + sim_cpu *cpu; + enum sim_signal_type sig; +{ + engine_halt (cpu, EXEC_STATE_STOPPED, sig); +} + +/* Convert SIM_SIGFOO to SIGFOO. */ + +int +sim_signal_to_host (sig) + int sig; +{ + switch (sig) + { + case SIM_SIGILL : +#ifdef SIGILL + return SIGILL; +#endif + break; + + case SIM_SIGTRAP : +#ifdef SIGTRAP + return SIGTRAP; +#else +#ifdef _MSC_VER + /* Wingdb uses this value. */ + return 5; +#endif +#endif + break; + + case SIM_SIGALIGN : + case SIM_SIGACCESS : +#ifdef SIGSEGV + return SIGSEGV; +#endif + break; + + case SIM_SIGXCPU : +#ifdef SIGXCPU + return SIGXCPU; +#endif + break; + } + return 1; +} + +/* FIXME: Add "no return" attribute to illegal insn handlers. + They all call longjmp. */ +/* FIXME: May wish to call a target supplied routine which can then call + sim_halt if it wants: to allow target to gain control for moment. */ + +void +ex_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf) +{ + abuf->length = CGEN_BASE_INSN_SIZE; + abuf->addr = pc; + /* Leave signalling to semantic fn. */ +} + +void +exc_illegal (SIM_CPU *cpu, PCADDR pc, insn_t insn, ARGBUF *abuf) +{ + abuf->length = CGEN_BASE_INSN_SIZE; + abuf->addr = pc; + /* Leave signalling to semantic fn. */ +} + +PCADDR +sem_illegal (current_cpu, sem_arg) + SIM_CPU *current_cpu; + struct argbuf *sem_arg; +{ + engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL); + return 0; +} + +PCADDR +semc_illegal (current_cpu, sem_arg) + SIM_CPU *current_cpu; + struct scache *sem_arg; +{ + engine_halt (current_cpu, EXEC_STATE_SIGNALLED, SIM_SIGILL); + return 0; +} + +/* Disassembly support. + ??? While executing an instruction, the insn has been decoded and all its + fields have been extracted. It is certainly possible to do the disassembly + with that data. This seems simpler, but maybe in the future the already + extracted fields will be used. */ + +/* Pseudo FILE object for strings. */ +typedef struct { + char *buffer; + char *current; +} SFILE; + +/* sprintf to a "stream" */ + +static int +disasm_sprintf VPARAMS ((SFILE *f, const char *format, ...)) +{ +#ifndef __STDC__ + SFILE *f; + const char *format; +#endif + int n; + va_list args; + + VA_START (args, format); +#ifndef __STDC__ + f = va_arg (args, SFILE *); + format = va_arg (args, char *); +#endif + vsprintf (f->current, format, args); + f->current += n = strlen (f->current); + va_end (args); + return n; +} + +void +sim_disassemble_insn (insn, abuf, pc, buf) + const struct cgen_insn *insn; + const struct argbuf *abuf; + PCADDR pc; + char *buf; +{ + int length; + unsigned long insn_value; + struct disassemble_info disasm_info; + struct cgen_fields fields; + SFILE sfile; + char insn_buf[20]; + STATE state = current_state; + + sfile.buffer = sfile.current = buf; + INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile, + (fprintf_ftype) disasm_sprintf); + disasm_info.endian = + (bfd_big_endian (STATE_PROG_BFD (state)) ? BFD_ENDIAN_BIG + : bfd_little_endian (STATE_PROG_BFD (state)) ? BFD_ENDIAN_LITTLE + : BFD_ENDIAN_UNKNOWN); + +/* (*STATE_MEM_READ (state)) (state, pc, insn_buf, abuf->length);*/ + + switch (abuf->length) + { + case 1 : + insn_value = insn_buf[0]; + break; + case 2 : + insn_value = disasm_info.endian == BFD_ENDIAN_BIG ? bfd_getb16 (insn_buf) : bfd_getl16 (insn_buf); + break; + case 4 : + insn_value = disasm_info.endian == BFD_ENDIAN_BIG ? bfd_getb32 (insn_buf) : bfd_getl32 (insn_buf); + break; + default: + abort (); + } + + length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields); + if (length != abuf->length) + { + (*CGEN_PRINT_FN (insn)) (&disasm_info, insn, &fields, pc, length); + } + else + { + /* This shouldn't happen, but aborting is too drastic. */ + strcpy (buf, "***unknown***"); + } +} + +#ifdef DI_FN_SUPPORT + +DI +make_struct_di (hi, lo) + SI hi, lo; +{ + DI result; + + result.hi = hi; + result.lo = lo; + return result; +} + +DI +ANDDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + SI alo = GETLODI (a); + SI bhi = GETHIDI (b); + SI blo = GETLODI (b); + return MAKEDI (ahi & bhi, alo & blo); +} + +DI +ORDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + SI alo = GETLODI (a); + SI bhi = GETHIDI (b); + SI blo = GETLODI (b); + return MAKEDI (ahi | bhi, alo | blo); +} + +DI +ADDDI (a, b) + DI a, b; +{ + USI ahi = GETHIDI (a); + USI alo = GETLODI (a); + USI bhi = GETHIDI (b); + USI blo = GETLODI (b); + USI x = alo + blo; + return MAKEDI (ahi + bhi + (x < alo), x); +} + +DI +MULDI (a, b) + DI a, b; +{ + USI ahi = GETHIDI (a); + USI alo = GETLODI (a); + USI bhi = GETHIDI (b); + USI blo = GETLODI (b); + USI rhi,rlo; + USI x0, x1, x2, x3; + + x0 = alo * blo; + x1 = alo * bhi; + x2 = ahi * blo; + x3 = ahi * bhi; + +#define SI_TYPE_SIZE 32 +#define BITS4 (SI_TYPE_SIZE / 4) +#define ll_B (1L << (SI_TYPE_SIZE / 2)) +#define ll_lowpart(t) ((USI) (t) % ll_B) +#define ll_highpart(t) ((USI) (t) / ll_B) + x1 += ll_highpart (x0); /* this can't give carry */ + x1 += x2; /* but this indeed can */ + if (x1 < x2) /* did we get it? */ + x3 += ll_B; /* yes, add it in the proper pos. */ + + rhi = x3 + ll_highpart (x1); + rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0); + return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo); +} + +DI +SHLDI (val, shift) + DI val; + SI shift; +{ + USI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); +} + +DI +SLADI (val, shift) + DI val; + SI shift; +{ + SI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); +} + +DI +SRADI (val, shift) + DI val; + SI shift; +{ + SI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* We use SRASI because the result is implementation defined if hi < 0. */ + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift)); +} + +int +GEDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + USI alo = GETLODI (a); + SI bhi = GETHIDI (b); + USI blo = GETLODI (b); + if (ahi > bhi) + return 1; + if (ahi == bhi) + return alo >= blo; + return 0; +} + +int +LEDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + USI alo = GETLODI (a); + SI bhi = GETHIDI (b); + USI blo = GETLODI (b); + if (ahi < bhi) + return 1; + if (ahi == bhi) + return alo <= blo; + return 0; +} + +DI +CONVHIDI (val) + HI val; +{ + if (val < 0) + return MAKEDI (-1, val); + else + return MAKEDI (0, val); +} + +DI +CONVSIDI (val) + SI val; +{ + if (val < 0) + return MAKEDI (-1, val); + else + return MAKEDI (0, val); +} + +SI +CONVDISI (val) + DI val; +{ + return GETLODI (val); +} + +#endif /* DI_FN_SUPPORT */ diff --git a/sim/common/genmloop.sh b/sim/common/genmloop.sh new file mode 100644 index 0000000..02de664 --- /dev/null +++ b/sim/common/genmloop.sh @@ -0,0 +1,184 @@ +# This shell script emits a C file. -*- C -*- +# Generate the main loop of the simulator. +# Syntax: genmloop.sh mono|multi cpu mainloop.in +# FIXME: "multi" support is wip. + +type=$1 +cpu=$2 +file=$3 + +cat <<EOF +/* This file is is generated by the genmloop script. DO NOT EDIT! */ + +/* Main loop for CGEN-based simulators. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* We want the simcache version of SEM_ARG. */ +#define SCACHE_P + +#include "sim-main.h" +#include "bfd.h" +#include "cgen-mem.h" +#include "cgen-sem.h" +#include "cgen-scache.h" +#include "cpu-opc.h" +#include "cpu-sim.h" + +/* Tell sim_main_loop to use the cache if it's active. + Collecting profile data and tracing slow us down so we don't do them in + "fast mode". + There are 2 possibilities on 2 axes: + - use or don't use the cache + - run normally (full featured) or run fast + Supporting all four possibilities in one executable is a bit much but + supporting normal/fast seems reasonable. + If the cache is configured in it is always used. + ??? Need to see whether it speeds up profiling significantly or not. + Speeding up tracing doesn't seem worth it. + ??? Sometimes supporting more than one set of semantic functions will make + the simulator too large - this should be configurable. +*/ + +#if WITH_SCACHE +#define RUN_FAST_P(cpu) (STATE_RUN_FAST_P (CPU_STATE (cpu))) +#else +#define RUN_FAST_P(cpu) 0 +#endif + +#ifndef SIM_PRE_EXEC_HOOK +#define SIM_PRE_EXEC_HOOK(state) +#endif + +#ifndef SIM_POST_EXEC_HOOK +#define SIM_POST_EXEC_HOOK(state) +#endif + +EOF + +${SHELL} $file support + +cat <<EOF + +static volatile int keep_running; + +int +engine_stop (SIM_DESC sd) +{ + keep_running = 0; + return 1; +} + +void +engine_run (SIM_DESC sd, int step, int siggnal) +{ + current_state = sd; +#if WITH_SCACHE + if (USING_SCACHE_P (sd)) + scache_flush (sd); +#endif + engine_resume (sd, step, siggnal); +} + +void +engine_resume (SIM_DESC sd, int step, int siggnal) +{ +#ifdef __STDC__ + /* These are volatile to survive setjmp/longjmp. + This will slow down the simulation a teensy bit, but we want to + measure simulator speed even in fast mode. */ + volatile unsigned long insn_count; + volatile SIM_ELAPSED_TIME start_time; +#else + /* ??? Not sure what to do for K&R C. */ + static unsigned long insn_count; + static SIM_ELAPSED_TIME start_time; +#endif + SIM_DESC current_state = sd; + sim_cpu *current_cpu = STATE_CPU (sd, 0); + + keep_running = 1; + start_time = sim_elapsed_time_get (); + insn_count = 0; + + if (setjmp (STATE_HALT_JMP_BUF (sd))) + { + TRACE_INSN_FINI (current_cpu); + PROFILE_EXEC_TIME (CPU_PROFILE_DATA (current_cpu)) + += sim_elapsed_time_since (start_time); + PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (current_cpu)) + += insn_count; + return; + } + +EOF + +# Any initialization code before looping starts. +${SHELL} $file init + +cat <<EOF + + /* ??? Restart support to be added in time. */ + + if (step + || !RUN_FAST_P (current_cpu)) + { + do + { +#define FAST 0 /* ??? Hopefully this name won't collide with anything. */ + /* FIXME: Later check every insn for events and such. */ + + SIM_PRE_EXEC_HOOK (current_cpu); + +EOF + +# Copy of main loop that uses the various compiled in features. +# FIXME: May want more than one copy of this. +${SHELL} $file normal + +cat <<EOF + + SIM_POST_EXEC_HOOK (current_cpu); + + if (step) + engine_halt (current_cpu, EXEC_STATE_STOPPED, SIM_SIGTRAP); + } + while (keep_running); +#undef FAST + } + else + { + do + { +#define FAST 1 + +EOF + +# Copy of main loop that is run purely for fast execution. +${SHELL} $file fast + +cat <<EOF + +#undef FAST + ++insn_count; + } + while (keep_running); + } +} +EOF |