* cgen-mem.h, cgen-scache.[ch], cgen-sem.h, cgen-sim.h: New files.
authorDavid Edelsohn <dje.gcc@gmail.com>
Thu, 1 May 1997 01:48:27 +0000 (01:48 +0000)
committerDavid Edelsohn <dje.gcc@gmail.com>
Thu, 1 May 1997 01:48:27 +0000 (01:48 +0000)
* cgen-trace.[ch], cgen-types.h, cgen-utils.c, genmloop.sh: New files.
* sim-model.c: New file.

sim/common/.Sanitize
sim/common/ChangeLog
sim/common/cgen-mem.h [new file with mode: 0644]
sim/common/cgen-scache.c [new file with mode: 0644]
sim/common/cgen-scache.h [new file with mode: 0644]
sim/common/cgen-sem.h [new file with mode: 0644]
sim/common/cgen-sim.h [new file with mode: 0644]
sim/common/cgen-trace.c [new file with mode: 0644]
sim/common/cgen-types.h [new file with mode: 0644]
sim/common/cgen-utils.c [new file with mode: 0644]
sim/common/genmloop.sh [new file with mode: 0644]

index 0f892b9..c08bddc 100644 (file)
@@ -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
index e42de0a..4f29d2c 100644 (file)
@@ -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 (file)
index 0000000..9be66d0
--- /dev/null
@@ -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 (file)
index 0000000..ecebff5
--- /dev/null
@@ -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 (file)
index 0000000..9cb2a5f
--- /dev/null
@@ -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);
+\f
+/* 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 (file)
index 0000000..18b8f98
--- /dev/null
@@ -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
+\f
+/* 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
+\f
+/* 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 (file)
index 0000000..4cfc7d2
--- /dev/null
@@ -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));
+\f
+/* 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*/));
+\f
+/* 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;
+\f
+/* 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 (file)
index 0000000..675c369
--- /dev/null
@@ -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 (file)
index 0000000..ad22f46
--- /dev/null
@@ -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
+\f
+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;
+\f
+/* 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 */
+\f
+#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 (file)
index 0000000..964e16b
--- /dev/null
@@ -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;
+}
+\f
+/* 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;
+}
+\f
+/* 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***");
+    }
+}
+\f
+#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 (file)
index 0000000..02de664
--- /dev/null
@@ -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