* 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.
This commit is contained in:
David Edelsohn 1997-05-01 01:48:27 +00:00
parent 070573509f
commit b9c8cd1023
11 changed files with 2953 additions and 0 deletions

View 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

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

503
sim/common/cgen-mem.h Normal file
View File

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

194
sim/common/cgen-scache.c Normal file
View File

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

108
sim/common/cgen-scache.h Normal file
View File

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

978
sim/common/cgen-sem.h Normal file
View File

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

138
sim/common/cgen-sim.h Normal file
View File

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

251
sim/common/cgen-trace.c Normal file
View File

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

176
sim/common/cgen-types.h Normal file
View File

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

406
sim/common/cgen-utils.c Normal file
View File

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

184
sim/common/genmloop.sh Normal file
View File

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