New simulator for Fujitsu frv contributed by Red Hat.

This commit is contained in:
Dave Brolley 2003-08-29 16:35:47 +00:00
parent 60fac5b81a
commit b34f6357d0
39 changed files with 145235 additions and 0 deletions

2358
sim/frv/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

133
sim/frv/Makefile.in Normal file
View File

@ -0,0 +1,133 @@
# Makefile template for Configure for the frv simulator
# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
# Contributed by Red Hat.
#
# 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 of the License, 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.
## COMMON_PRE_CONFIG_FRAG
FRV_OBJS = frv.o cpu.o decode.o sem.o model.o mloop.o cgen-par.o
CONFIG_DEVICES = dv-sockser.o
CONFIG_DEVICES =
SIM_OBJS = \
$(SIM_NEW_COMMON_OBJS) \
sim-cpu.o \
sim-hload.o \
sim-hrw.o \
sim-model.o \
sim-reg.o \
cgen-utils.o cgen-trace.o cgen-scache.o cgen-fpu.o cgen-accfp.o \
cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
sim-if.o arch.o \
$(FRV_OBJS) \
traps.o interrupts.o memory.o cache.o pipeline.o \
profile.o profile-fr400.o profile-fr500.o options.o \
devices.o reset.o registers.o \
$(CONFIG_DEVICES)
# Extra headers included by sim-main.h.
SIM_EXTRA_DEPS = \
$(CGEN_INCLUDE_DEPS) \
arch.h cpuall.h frv-sim.h $(srcdir)/../../opcodes/frv-desc.h cache.h \
registers.h profile.h \
$(sim-options_h)
SIM_EXTRA_CFLAGS = @sim_trapdump@
SIM_RUN_OBJS = nrun.o
SIM_EXTRA_CLEAN = frv-clean
# This selects the frv newlib/libgloss syscall definitions.
NL_TARGET = -DNL_TARGET_frv
## COMMON_POST_CONFIG_FRAG
arch = frv
arch.o: arch.c $(SIM_MAIN_DEPS)
devices.o: devices.c $(SIM_MAIN_DEPS)
# FRV objs
FRVBF_INCLUDE_DEPS = \
$(CGEN_MAIN_CPU_DEPS) \
$(SIM_EXTRA_DEPS) \
cpu.h decode.h eng.h
frv.o: frv.c $(FRVBF_INCLUDE_DEPS)
traps.o: traps.c $(FRVBF_INCLUDE_DEPS)
pipeline.o: pipeline.c $(FRVBF_INCLUDE_DEPS)
interrupts.o: interrupts.c $(FRVBF_INCLUDE_DEPS)
memory.o: memory.c $(FRVBF_INCLUDE_DEPS)
cache.o: cache.c $(FRVBF_INCLUDE_DEPS)
options.o: options.c $(FRVBF_INCLUDE_DEPS)
reset.o: reset.c $(FRVBF_INCLUDE_DEPS)
registers.o: registers.c $(FRVBF_INCLUDE_DEPS)
profile.o: profile.c profile-fr400.h profile-fr500.h $(FRVBF_INCLUDE_DEPS)
profile-fr400.o: profile-fr400.c profile-fr400.h $(FRVBF_INCLUDE_DEPS)
profile-fr500.o: profile-fr500.c profile-fr500.h $(FRVBF_INCLUDE_DEPS)
sim-if.o: sim-if.c $(FRVBF_INCLUDE_DEPS) $(srcdir)/../common/sim-core.h eng.h
# FIXME: Use of `mono' is wip.
mloop.c eng.h: stamp-mloop
stamp-mloop: $(srcdir)/../common/genmloop.sh mloop.in Makefile
$(SHELL) $(srccom)/genmloop.sh \
-mono -scache -parallel-generic-write -parallel-only \
-cpu frvbf -infile $(srcdir)/mloop.in
$(SHELL) $(srcroot)/move-if-change eng.hin eng.h
$(SHELL) $(srcroot)/move-if-change mloop.cin mloop.c
touch stamp-mloop
mloop.o: mloop.c $(FRVBF_INCLUDE_DEPS)
cpu.o: cpu.c $(FRVBF_INCLUDE_DEPS)
decode.o: decode.c $(FRVBF_INCLUDE_DEPS)
sem.o: sem.c $(FRVBF_INCLUDE_DEPS)
model.o: model.c $(FRVBF_INCLUDE_DEPS)
frv-clean:
rm -f mloop.c eng.h stamp-mloop
rm -f tmp-*
rm -f stamp-arch stamp-cpu
# cgen support, enable with --enable-cgen-maint
CGEN_MAINT = ; @true
# The following line is commented in or out depending upon --enable-cgen-maint.
@CGEN_MAINT@CGEN_MAINT =
stamp-arch: $(CGEN_READ_SCM) $(CGEN_ARCH_SCM) $(srcdir)/../../cpu/frv.cpu
cp -fp $(srcdir)/../../cpu/frv.cpu $(CGEN_CPU_DIR)/frv.cpu
$(MAKE) cgen-arch $(CGEN_FLAGS_TO_PASS) mach=all \
FLAGS="with-scache"
rm -f $(CGEN_CPU_DIR)/frv.cpu
touch stamp-arch
arch.h arch.c cpuall.h: $(CGEN_MAINT) stamp-arch
# @true
# .cpu and .opc files for frv are kept in a different directory, but cgen has no switch to specify that location, so
# copy those file to the regular place.
stamp-cpu: $(CGEN_READ_SCM) $(CGEN_CPU_SCM) $(CGEN_DECODE_SCM) $(srcdir)/../../cpu/frv.cpu
cp -fp $(srcdir)/../../cpu/frv.cpu $(CGEN_CPU_DIR)/frv.cpu
$(MAKE) cgen-cpu-decode $(CGEN_FLAGS_TO_PASS) \
cpu=frvbf mach=frv,fr500,fr400,tomcat,simple SUFFIX= \
FLAGS="with-scache with-profile=fn with-generic-write with-parallel-only" \
EXTRAFILES="$(CGEN_CPU_SEM)"
rm -f $(CGEN_CPU_DIR)/frv.cpu
touch stamp-cpu
cpu.h sem.c model.c decode.c decode.h: $(CGEN_MAINT) stamp-cpu
# @true

10
sim/frv/README Normal file
View File

@ -0,0 +1,10 @@
This is the frv simulator directory.
It is still work-in-progress. The current sources are
well tested and lots of features are in.
There are lots of machine generated files in the source directory!
They are only generated if you configure with --enable-cgen-maint,
similar in behaviour to Makefile.in, configure under automake/autoconf.
For details on the generator, see ../../cgen.

8
sim/frv/TODO Normal file
View File

@ -0,0 +1,8 @@
- header file dependencies revisit
- hooks cleanup
- testsuites
- FIXME's
- memory accesses still test if profiling is on even in fast mode
- have semantic code use G/SET_H_FOO if not default [incl fun-access]
- have G/SET_H_FOO macros call function if fun-access
- --> can always use G/S_H_FOO macros

47
sim/frv/arch.c Normal file
View File

@ -0,0 +1,47 @@
/* Simulator support for frv.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU simulators.
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"
const MACH *sim_machs[] =
{
#ifdef HAVE_CPU_FRVBF
& frv_mach,
#endif
#ifdef HAVE_CPU_FRVBF
& fr500_mach,
#endif
#ifdef HAVE_CPU_FRVBF
& tomcat_mach,
#endif
#ifdef HAVE_CPU_FRVBF
& fr400_mach,
#endif
#ifdef HAVE_CPU_FRVBF
& simple_mach,
#endif
0
};

69
sim/frv/arch.h Normal file
View File

@ -0,0 +1,69 @@
/* Simulator header for frv.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU simulators.
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 FRV_ARCH_H
#define FRV_ARCH_H
#define TARGET_BIG_ENDIAN 1
/* Enum declaration for model types. */
typedef enum model_type {
MODEL_FRV, MODEL_FR500, MODEL_TOMCAT, MODEL_FR400
, MODEL_SIMPLE, MODEL_MAX
} MODEL_TYPE;
#define MAX_MODELS ((int) MODEL_MAX)
/* Enum declaration for unit types. */
typedef enum unit_type {
UNIT_NONE, UNIT_FRV_U_EXEC, UNIT_FR500_U_DCUL, UNIT_FR500_U_ICUL
, UNIT_FR500_U_DCPL, UNIT_FR500_U_ICPL, UNIT_FR500_U_DCF, UNIT_FR500_U_DCI
, UNIT_FR500_U_ICI, UNIT_FR500_U_MEMBAR, UNIT_FR500_U_BARRIER, UNIT_FR500_U_MEDIA_DUAL_BTOHE
, UNIT_FR500_U_MEDIA_DUAL_HTOB, UNIT_FR500_U_MEDIA_DUAL_BTOH, UNIT_FR500_U_MEDIA_DUAL_UNPACK, UNIT_FR500_U_MEDIA_DUAL_EXPAND
, UNIT_FR500_U_MEDIA_QUAD_COMPLEX, UNIT_FR500_U_MEDIA_QUAD_MUL, UNIT_FR500_U_MEDIA_DUAL_MUL, UNIT_FR500_U_MEDIA_QUAD_ARITH
, UNIT_FR500_U_MEDIA, UNIT_FR500_U_FLOAT_DUAL_CONVERT, UNIT_FR500_U_FLOAT_CONVERT, UNIT_FR500_U_FLOAT_DUAL_COMPARE
, UNIT_FR500_U_FLOAT_COMPARE, UNIT_FR500_U_FLOAT_DUAL_SQRT, UNIT_FR500_U_FLOAT_SQRT, UNIT_FR500_U_FLOAT_DIV
, UNIT_FR500_U_FLOAT_DUAL_ARITH, UNIT_FR500_U_FLOAT_ARITH, UNIT_FR500_U_GR2SPR, UNIT_FR500_U_GR2FR
, UNIT_FR500_U_SPR2GR, UNIT_FR500_U_FR2GR, UNIT_FR500_U_FR2FR, UNIT_FR500_U_SWAP
, UNIT_FR500_U_FR_R_STORE, UNIT_FR500_U_FR_STORE, UNIT_FR500_U_FR_LOAD, UNIT_FR500_U_GR_R_STORE
, UNIT_FR500_U_GR_STORE, UNIT_FR500_U_GR_LOAD, UNIT_FR500_U_SET_HILO, UNIT_FR500_U_CHECK
, UNIT_FR500_U_TRAP, UNIT_FR500_U_BRANCH, UNIT_FR500_U_IDIV, UNIT_FR500_U_IMUL
, UNIT_FR500_U_INTEGER, UNIT_FR500_U_EXEC, UNIT_TOMCAT_U_EXEC, UNIT_FR400_U_DCUL
, UNIT_FR400_U_ICUL, UNIT_FR400_U_DCPL, UNIT_FR400_U_ICPL, UNIT_FR400_U_DCF
, UNIT_FR400_U_DCI, UNIT_FR400_U_ICI, UNIT_FR400_U_MEMBAR, UNIT_FR400_U_BARRIER
, UNIT_FR400_U_MEDIA_DUAL_HTOB, UNIT_FR400_U_MEDIA_DUAL_EXPAND, UNIT_FR400_U_MEDIA_7, UNIT_FR400_U_MEDIA_6
, UNIT_FR400_U_MEDIA_4_ACC_DUAL, UNIT_FR400_U_MEDIA_4_ACCG, UNIT_FR400_U_MEDIA_4, UNIT_FR400_U_MEDIA_3_QUAD
, UNIT_FR400_U_MEDIA_3_DUAL, UNIT_FR400_U_MEDIA_3, UNIT_FR400_U_MEDIA_2_ADD_SUB_DUAL, UNIT_FR400_U_MEDIA_2_ADD_SUB
, UNIT_FR400_U_MEDIA_2_ACC_DUAL, UNIT_FR400_U_MEDIA_2_ACC, UNIT_FR400_U_MEDIA_2_QUAD, UNIT_FR400_U_MEDIA_2
, UNIT_FR400_U_MEDIA_HILO, UNIT_FR400_U_MEDIA_1_QUAD, UNIT_FR400_U_MEDIA_1, UNIT_FR400_U_GR2SPR
, UNIT_FR400_U_GR2FR, UNIT_FR400_U_SPR2GR, UNIT_FR400_U_FR2GR, UNIT_FR400_U_SWAP
, UNIT_FR400_U_FR_STORE, UNIT_FR400_U_FR_LOAD, UNIT_FR400_U_GR_STORE, UNIT_FR400_U_GR_LOAD
, UNIT_FR400_U_SET_HILO, UNIT_FR400_U_CHECK, UNIT_FR400_U_TRAP, UNIT_FR400_U_BRANCH
, UNIT_FR400_U_IDIV, UNIT_FR400_U_IMUL, UNIT_FR400_U_INTEGER, UNIT_FR400_U_EXEC
, UNIT_SIMPLE_U_EXEC, UNIT_MAX
} UNIT_TYPE;
#define MAX_UNITS (1)
#endif /* FRV_ARCH_H */

1561
sim/frv/cache.c Normal file

File diff suppressed because it is too large Load Diff

262
sim/frv/cache.h Normal file
View File

@ -0,0 +1,262 @@
/* Cache support for the FRV simulator
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 CACHE_H
#define CACHE_H
/* A representation of a set-associative cache with LRU replacement,
cache line locking, non-blocking support and multiple read ports. */
/* An enumeration of cache pipeline request kinds. */
typedef enum
{
req_load,
req_store,
req_invalidate,
req_flush,
req_preload,
req_unlock,
req_WAR
} FRV_CACHE_REQUEST_KIND;
/* The cache pipeline requests. */
typedef struct {
int preload;
int lock;
} FRV_CACHE_WAR_REQUEST;
typedef struct {
char *data;
int length;
} FRV_CACHE_STORE_REQUEST;
typedef struct {
int flush;
int all;
} FRV_CACHE_INVALIDATE_REQUEST;
typedef struct {
int lock;
int length;
} FRV_CACHE_PRELOAD_REQUEST;
/* A cache pipeline request. */
typedef struct frv_cache_request
{
struct frv_cache_request *next;
struct frv_cache_request *prev;
FRV_CACHE_REQUEST_KIND kind;
unsigned reqno;
unsigned priority;
SI address;
union {
FRV_CACHE_STORE_REQUEST store;
FRV_CACHE_INVALIDATE_REQUEST invalidate;
FRV_CACHE_PRELOAD_REQUEST preload;
FRV_CACHE_WAR_REQUEST WAR;
} u;
} FRV_CACHE_REQUEST;
/* The buffer for returning data to the caller. */
typedef struct {
unsigned reqno;
SI address;
char *data;
int valid;
} FRV_CACHE_RETURN_BUFFER;
/* The status of flush requests. */
typedef struct {
unsigned reqno;
SI address;
int valid;
} FRV_CACHE_FLUSH_STATUS;
/* Communicate status of requests to the caller. */
typedef struct {
FRV_CACHE_FLUSH_STATUS flush;
FRV_CACHE_RETURN_BUFFER return_buffer;
} FRV_CACHE_STATUS;
/* A cache pipeline stage. */
typedef struct {
FRV_CACHE_REQUEST *request;
} FRV_CACHE_STAGE;
enum {
FIRST_STAGE,
A_STAGE = FIRST_STAGE, /* Addressing stage */
I_STAGE, /* Interference stage */
LAST_STAGE = I_STAGE,
FRV_CACHE_STAGES
};
/* Representation of the WAR register. */
typedef struct {
unsigned reqno;
unsigned priority;
SI address;
int preload;
int lock;
int latency;
int valid;
} FRV_CACHE_WAR;
/* A cache pipeline. */
#define NUM_WARS 2
typedef struct {
FRV_CACHE_REQUEST *requests;
FRV_CACHE_STAGE stages[FRV_CACHE_STAGES];
FRV_CACHE_WAR WAR[NUM_WARS];
FRV_CACHE_STATUS status;
} FRV_CACHE_PIPELINE;
enum {LS, LD, FRV_CACHE_PIPELINES};
/* Representation of the xARS registers. */
typedef struct {
int pipe;
unsigned reqno;
unsigned priority;
SI address;
int preload;
int lock;
int valid;
} FRV_CACHE_ARS;
/* A cache tag. */
typedef struct {
USI tag; /* Address tag. */
int lru; /* Lower values indicates less recently used. */
char *line; /* Points to storage for line in data_storage. */
char dirty; /* line has been written to since last stored? */
char locked; /* line is locked? */
char valid; /* tag is valid? */
} FRV_CACHE_TAG;
/* Cache statistics. */
typedef struct {
unsigned long accesses; /* number of cache accesses. */
unsigned long hits; /* number of cache hits. */
} FRV_CACHE_STATISTICS;
/* The cache itself.
Notes:
- line_size must be a power of 2
- sets must be a power of 2
- ways must be a power of 2
*/
typedef struct {
SIM_CPU *cpu;
unsigned ways; /* Number of ways in each set. */
unsigned sets; /* Number of sets in the cache. */
unsigned line_size; /* Size of each cache line. */
unsigned memory_latency; /* Latency of main memory in cycles. */
FRV_CACHE_TAG *tag_storage; /* Storage for tags. */
char *data_storage; /* Storage for data (cache lines). */
FRV_CACHE_PIPELINE pipeline[2]; /* Cache pipelines. */
FRV_CACHE_ARS BARS; /* BARS register. */
FRV_CACHE_ARS NARS; /* BARS register. */
FRV_CACHE_STATISTICS statistics; /* Operation statistics. */
} FRV_CACHE;
/* The tags are stored by ways within sets in order to make computations
easier. */
#define CACHE_TAG(cache, set, way) ( \
& ((cache)->tag_storage[(set) * (cache)->ways + (way)]) \
)
/* Compute the address tag corresponding to the given address. */
#define CACHE_ADDRESS_TAG(cache, address) ( \
(address) & ~(((cache)->line_size * (cache)->sets) - 1) \
)
/* Determine the index at which the set containing this tag starts. */
#define CACHE_TAG_SET_START(cache, tag) ( \
((tag) - (cache)->tag_storage) & ~((cache)->ways - 1) \
)
/* Determine the number of the set which this cache tag is in. */
#define CACHE_TAG_SET_NUMBER(cache, tag) ( \
CACHE_TAG_SET_START ((cache), (tag)) / (cache)->ways \
)
#define CACHE_RETURN_DATA(cache, slot, address, mode, N) ( \
T2H_##N (*(mode *)(& (cache)->pipeline[slot].status.return_buffer.data \
[((address) & ((cache)->line_size - 1) \
& ~(sizeof (mode) - 1))])) \
)
#define CACHE_RETURN_DATA_ADDRESS(cache, slot, address, N) ( \
((void *)& (cache)->pipeline[slot].status.return_buffer.data[(address) \
& ((cache)->line_size - 1) \
& ~((N) - 1)]) \
)
#define CACHE_INITIALIZED(cache) ((cache)->data_storage != NULL)
/* These functions are used to initialize and terminate a cache. */
void
frv_cache_init (SIM_CPU *, FRV_CACHE *);
void
frv_cache_term (FRV_CACHE *);
int
frv_cache_enabled (FRV_CACHE *);
/* These functions are used to operate the cache in non-cycle-accurate mode.
Each request is handled individually and immediately using the current
cache internal state. */
int
frv_cache_read (FRV_CACHE *, int, SI);
int
frv_cache_write (FRV_CACHE *, SI, char *, unsigned);
int
frv_cache_preload (FRV_CACHE *, SI, USI, int);
int
frv_cache_invalidate (FRV_CACHE *, SI, int);
int
frv_cache_invalidate_all (FRV_CACHE *, int);
/* These functions are used to operate the cache in cycle-accurate mode.
The internal operation of the cache is simulated down to the cycle level. */
#define NO_REQNO 0xffffffff
void
frv_cache_request_load (FRV_CACHE *, unsigned, SI, int);
void
frv_cache_request_store (FRV_CACHE *, SI, int, char *, unsigned);
void
frv_cache_request_invalidate (FRV_CACHE *, unsigned, SI, int, int, int);
void
frv_cache_request_preload (FRV_CACHE *, SI, int, int, int);
void
frv_cache_request_unlock (FRV_CACHE *, SI, int);
void
frv_cache_run (FRV_CACHE *, int);
int
frv_cache_data_in_buffer (FRV_CACHE*, int, SI, unsigned);
int
frv_cache_data_flushed (FRV_CACHE*, int, SI, unsigned);
int
frv_cache_read_passive_SI (FRV_CACHE *, SI, SI *);
#endif /* CACHE_H */

162
sim/frv/config.in Normal file
View File

@ -0,0 +1,162 @@
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
#undef C_ALLOCA
/* Define to empty if the keyword does not work. */
#undef const
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
#undef CRAY_STACKSEG_END
/* Define if you have alloca, as a function or macro. */
#undef HAVE_ALLOCA
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#undef STACK_DIRECTION
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if your processor stores words with the most significant
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 1 if NLS is requested. */
#undef ENABLE_NLS
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define as 1 if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define if you have the __argz_count function. */
#undef HAVE___ARGZ_COUNT
/* Define if you have the __argz_next function. */
#undef HAVE___ARGZ_NEXT
/* Define if you have the __argz_stringify function. */
#undef HAVE___ARGZ_STRINGIFY
/* Define if you have the __setfpucw function. */
#undef HAVE___SETFPUCW
/* Define if you have the dcgettext function. */
#undef HAVE_DCGETTEXT
/* Define if you have the getcwd function. */
#undef HAVE_GETCWD
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the getrusage function. */
#undef HAVE_GETRUSAGE
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the setenv function. */
#undef HAVE_SETENV
/* Define if you have the setlocale function. */
#undef HAVE_SETLOCALE
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
/* Define if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the time function. */
#undef HAVE_TIME
/* Define if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <fpu_control.h> header file. */
#undef HAVE_FPU_CONTROL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <values.h> header file. */
#undef HAVE_VALUES_H

4315
sim/frv/configure vendored Executable file

File diff suppressed because it is too large Load Diff

31
sim/frv/configure.in Normal file
View File

@ -0,0 +1,31 @@
dnl Process this file with autoconf to produce a configure script.
sinclude(../common/aclocal.m4)
AC_PREREQ(2.5)dnl
AC_INIT(Makefile.in)
SIM_AC_COMMON
SIM_AC_OPTION_ENDIAN(BIG_ENDIAN)
SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT)
SIM_AC_OPTION_HOSTENDIAN
SIM_AC_OPTION_SCACHE(16384)
SIM_AC_OPTION_DEFAULT_MODEL(fr500)
SIM_AC_OPTION_ENVIRONMENT
SIM_AC_OPTION_CGEN_MAINT
#
# Enable making unknown traps dump out registers
#
AC_ARG_ENABLE(sim-trapdump,
[ --enable-sim-trapdump Make unknown traps dump the registers],
[case "${enableval}" in
yes) sim_trapdump="-DTRAPDUMP=1";;
no) sim_trapdump="-DTRAPDUMP=0";;
*) AC_MSG_ERROR("Unknown value $enableval passed to --enable-sim-trapdump"); sim_trapdump="";;
esac
if test x"$silent" != x"yes" && test x"$sim_trapdump" != x""; then
echo "Setting sim_trapdump = $sim_trapdump" 6>&1
fi],[sim_trapdump=""])dnl
AC_SUBST(sim_trapdump)
SIM_AC_OUTPUT

677
sim/frv/cpu.c Normal file
View File

@ -0,0 +1,677 @@
/* Misc. support for CPU family frvbf.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU simulators.
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 WANT_CPU frvbf
#define WANT_CPU_FRVBF
#include "sim-main.h"
#include "cgen-ops.h"
/* Get the value of h-pc. */
USI
frvbf_h_pc_get (SIM_CPU *current_cpu)
{
return CPU (h_pc);
}
/* Set a value for h-pc. */
void
frvbf_h_pc_set (SIM_CPU *current_cpu, USI newval)
{
CPU (h_pc) = newval;
}
/* Get the value of h-psr_imple. */
UQI
frvbf_h_psr_imple_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_imple);
}
/* Set a value for h-psr_imple. */
void
frvbf_h_psr_imple_set (SIM_CPU *current_cpu, UQI newval)
{
CPU (h_psr_imple) = newval;
}
/* Get the value of h-psr_ver. */
UQI
frvbf_h_psr_ver_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_ver);
}
/* Set a value for h-psr_ver. */
void
frvbf_h_psr_ver_set (SIM_CPU *current_cpu, UQI newval)
{
CPU (h_psr_ver) = newval;
}
/* Get the value of h-psr_ice. */
BI
frvbf_h_psr_ice_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_ice);
}
/* Set a value for h-psr_ice. */
void
frvbf_h_psr_ice_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_ice) = newval;
}
/* Get the value of h-psr_nem. */
BI
frvbf_h_psr_nem_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_nem);
}
/* Set a value for h-psr_nem. */
void
frvbf_h_psr_nem_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_nem) = newval;
}
/* Get the value of h-psr_cm. */
BI
frvbf_h_psr_cm_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_cm);
}
/* Set a value for h-psr_cm. */
void
frvbf_h_psr_cm_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_cm) = newval;
}
/* Get the value of h-psr_be. */
BI
frvbf_h_psr_be_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_be);
}
/* Set a value for h-psr_be. */
void
frvbf_h_psr_be_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_be) = newval;
}
/* Get the value of h-psr_esr. */
BI
frvbf_h_psr_esr_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_esr);
}
/* Set a value for h-psr_esr. */
void
frvbf_h_psr_esr_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_esr) = newval;
}
/* Get the value of h-psr_ef. */
BI
frvbf_h_psr_ef_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_ef);
}
/* Set a value for h-psr_ef. */
void
frvbf_h_psr_ef_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_ef) = newval;
}
/* Get the value of h-psr_em. */
BI
frvbf_h_psr_em_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_em);
}
/* Set a value for h-psr_em. */
void
frvbf_h_psr_em_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_em) = newval;
}
/* Get the value of h-psr_pil. */
UQI
frvbf_h_psr_pil_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_pil);
}
/* Set a value for h-psr_pil. */
void
frvbf_h_psr_pil_set (SIM_CPU *current_cpu, UQI newval)
{
CPU (h_psr_pil) = newval;
}
/* Get the value of h-psr_ps. */
BI
frvbf_h_psr_ps_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_ps);
}
/* Set a value for h-psr_ps. */
void
frvbf_h_psr_ps_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_ps) = newval;
}
/* Get the value of h-psr_et. */
BI
frvbf_h_psr_et_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_et);
}
/* Set a value for h-psr_et. */
void
frvbf_h_psr_et_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_psr_et) = newval;
}
/* Get the value of h-psr_s. */
BI
frvbf_h_psr_s_get (SIM_CPU *current_cpu)
{
return CPU (h_psr_s);
}
/* Set a value for h-psr_s. */
void
frvbf_h_psr_s_set (SIM_CPU *current_cpu, BI newval)
{
SET_H_PSR_S (newval);
}
/* Get the value of h-tbr_tba. */
USI
frvbf_h_tbr_tba_get (SIM_CPU *current_cpu)
{
return CPU (h_tbr_tba);
}
/* Set a value for h-tbr_tba. */
void
frvbf_h_tbr_tba_set (SIM_CPU *current_cpu, USI newval)
{
CPU (h_tbr_tba) = newval;
}
/* Get the value of h-tbr_tt. */
UQI
frvbf_h_tbr_tt_get (SIM_CPU *current_cpu)
{
return CPU (h_tbr_tt);
}
/* Set a value for h-tbr_tt. */
void
frvbf_h_tbr_tt_set (SIM_CPU *current_cpu, UQI newval)
{
CPU (h_tbr_tt) = newval;
}
/* Get the value of h-bpsr_bs. */
BI
frvbf_h_bpsr_bs_get (SIM_CPU *current_cpu)
{
return CPU (h_bpsr_bs);
}
/* Set a value for h-bpsr_bs. */
void
frvbf_h_bpsr_bs_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_bpsr_bs) = newval;
}
/* Get the value of h-bpsr_bet. */
BI
frvbf_h_bpsr_bet_get (SIM_CPU *current_cpu)
{
return CPU (h_bpsr_bet);
}
/* Set a value for h-bpsr_bet. */
void
frvbf_h_bpsr_bet_set (SIM_CPU *current_cpu, BI newval)
{
CPU (h_bpsr_bet) = newval;
}
/* Get the value of h-gr. */
USI
frvbf_h_gr_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_GR (regno);
}
/* Set a value for h-gr. */
void
frvbf_h_gr_set (SIM_CPU *current_cpu, UINT regno, USI newval)
{
SET_H_GR (regno, newval);
}
/* Get the value of h-gr_double. */
DI
frvbf_h_gr_double_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_GR_DOUBLE (regno);
}
/* Set a value for h-gr_double. */
void
frvbf_h_gr_double_set (SIM_CPU *current_cpu, UINT regno, DI newval)
{
SET_H_GR_DOUBLE (regno, newval);
}
/* Get the value of h-gr_hi. */
UHI
frvbf_h_gr_hi_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_GR_HI (regno);
}
/* Set a value for h-gr_hi. */
void
frvbf_h_gr_hi_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_GR_HI (regno, newval);
}
/* Get the value of h-gr_lo. */
UHI
frvbf_h_gr_lo_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_GR_LO (regno);
}
/* Set a value for h-gr_lo. */
void
frvbf_h_gr_lo_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_GR_LO (regno, newval);
}
/* Get the value of h-fr. */
SF
frvbf_h_fr_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR (regno);
}
/* Set a value for h-fr. */
void
frvbf_h_fr_set (SIM_CPU *current_cpu, UINT regno, SF newval)
{
SET_H_FR (regno, newval);
}
/* Get the value of h-fr_double. */
DF
frvbf_h_fr_double_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_DOUBLE (regno);
}
/* Set a value for h-fr_double. */
void
frvbf_h_fr_double_set (SIM_CPU *current_cpu, UINT regno, DF newval)
{
SET_H_FR_DOUBLE (regno, newval);
}
/* Get the value of h-fr_int. */
USI
frvbf_h_fr_int_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_INT (regno);
}
/* Set a value for h-fr_int. */
void
frvbf_h_fr_int_set (SIM_CPU *current_cpu, UINT regno, USI newval)
{
SET_H_FR_INT (regno, newval);
}
/* Get the value of h-fr_hi. */
UHI
frvbf_h_fr_hi_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_HI (regno);
}
/* Set a value for h-fr_hi. */
void
frvbf_h_fr_hi_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_HI (regno, newval);
}
/* Get the value of h-fr_lo. */
UHI
frvbf_h_fr_lo_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_LO (regno);
}
/* Set a value for h-fr_lo. */
void
frvbf_h_fr_lo_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_LO (regno, newval);
}
/* Get the value of h-fr_0. */
UHI
frvbf_h_fr_0_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_0 (regno);
}
/* Set a value for h-fr_0. */
void
frvbf_h_fr_0_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_0 (regno, newval);
}
/* Get the value of h-fr_1. */
UHI
frvbf_h_fr_1_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_1 (regno);
}
/* Set a value for h-fr_1. */
void
frvbf_h_fr_1_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_1 (regno, newval);
}
/* Get the value of h-fr_2. */
UHI
frvbf_h_fr_2_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_2 (regno);
}
/* Set a value for h-fr_2. */
void
frvbf_h_fr_2_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_2 (regno, newval);
}
/* Get the value of h-fr_3. */
UHI
frvbf_h_fr_3_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_FR_3 (regno);
}
/* Set a value for h-fr_3. */
void
frvbf_h_fr_3_set (SIM_CPU *current_cpu, UINT regno, UHI newval)
{
SET_H_FR_3 (regno, newval);
}
/* Get the value of h-cpr. */
SI
frvbf_h_cpr_get (SIM_CPU *current_cpu, UINT regno)
{
return CPU (h_cpr[regno]);
}
/* Set a value for h-cpr. */
void
frvbf_h_cpr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
{
CPU (h_cpr[regno]) = newval;
}
/* Get the value of h-cpr_double. */
DI
frvbf_h_cpr_double_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_CPR_DOUBLE (regno);
}
/* Set a value for h-cpr_double. */
void
frvbf_h_cpr_double_set (SIM_CPU *current_cpu, UINT regno, DI newval)
{
SET_H_CPR_DOUBLE (regno, newval);
}
/* Get the value of h-spr. */
USI
frvbf_h_spr_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_SPR (regno);
}
/* Set a value for h-spr. */
void
frvbf_h_spr_set (SIM_CPU *current_cpu, UINT regno, USI newval)
{
SET_H_SPR (regno, newval);
}
/* Get the value of h-accg. */
USI
frvbf_h_accg_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_ACCG (regno);
}
/* Set a value for h-accg. */
void
frvbf_h_accg_set (SIM_CPU *current_cpu, UINT regno, USI newval)
{
SET_H_ACCG (regno, newval);
}
/* Get the value of h-acc40S. */
DI
frvbf_h_acc40S_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_ACC40S (regno);
}
/* Set a value for h-acc40S. */
void
frvbf_h_acc40S_set (SIM_CPU *current_cpu, UINT regno, DI newval)
{
SET_H_ACC40S (regno, newval);
}
/* Get the value of h-acc40U. */
UDI
frvbf_h_acc40U_get (SIM_CPU *current_cpu, UINT regno)
{
return GET_H_ACC40U (regno);
}
/* Set a value for h-acc40U. */
void
frvbf_h_acc40U_set (SIM_CPU *current_cpu, UINT regno, UDI newval)
{
SET_H_ACC40U (regno, newval);
}
/* Get the value of h-iccr. */
UQI
frvbf_h_iccr_get (SIM_CPU *current_cpu, UINT regno)
{
return CPU (h_iccr[regno]);
}
/* Set a value for h-iccr. */
void
frvbf_h_iccr_set (SIM_CPU *current_cpu, UINT regno, UQI newval)
{
CPU (h_iccr[regno]) = newval;
}
/* Get the value of h-fccr. */
UQI
frvbf_h_fccr_get (SIM_CPU *current_cpu, UINT regno)
{
return CPU (h_fccr[regno]);
}
/* Set a value for h-fccr. */
void
frvbf_h_fccr_set (SIM_CPU *current_cpu, UINT regno, UQI newval)
{
CPU (h_fccr[regno]) = newval;
}
/* Get the value of h-cccr. */
UQI
frvbf_h_cccr_get (SIM_CPU *current_cpu, UINT regno)
{
return CPU (h_cccr[regno]);
}
/* Set a value for h-cccr. */
void
frvbf_h_cccr_set (SIM_CPU *current_cpu, UINT regno, UQI newval)
{
CPU (h_cccr[regno]) = newval;
}
/* Record trace results for INSN. */
void
frvbf_record_trace_results (SIM_CPU *current_cpu, CGEN_INSN *insn,
int *indices, TRACE_RECORD *tr)
{
}

4310
sim/frv/cpu.h Normal file

File diff suppressed because it is too large Load Diff

70
sim/frv/cpuall.h Normal file
View File

@ -0,0 +1,70 @@
/* Simulator CPU header for frv.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU simulators.
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 FRV_CPUALL_H
#define FRV_CPUALL_H
/* Include files for each cpu family. */
#ifdef WANT_CPU_FRVBF
#include "eng.h"
#include "cgen-engine.h"
#include "cpu.h"
#include "decode.h"
#endif
extern const MACH frv_mach;
extern const MACH fr500_mach;
extern const MACH tomcat_mach;
extern const MACH fr400_mach;
extern const MACH simple_mach;
#ifndef WANT_CPU
/* The ARGBUF struct. */
struct argbuf {
/* These are the baseclass definitions. */
IADDR addr;
const IDESC *idesc;
char trace_p;
char profile_p;
/* ??? Temporary hack for skip insns. */
char skip_count;
char unused;
/* cpu specific data follows */
};
#endif
#ifndef WANT_CPU
/* A cached insn.
??? SCACHE used to contain more than just argbuf. We could delete the
type entirely and always just use ARGBUF, but for future concerns and as
a level of abstraction it is left in. */
struct scache {
struct argbuf argbuf;
};
#endif
#endif /* FRV_CPUALL_H */

10891
sim/frv/decode.c Normal file

File diff suppressed because it is too large Load Diff

399
sim/frv/decode.h Normal file
View File

@ -0,0 +1,399 @@
/* Decode header for frvbf.
THIS FILE IS MACHINE GENERATED WITH CGEN.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU simulators.
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 FRVBF_DECODE_H
#define FRVBF_DECODE_H
extern const IDESC *frvbf_decode (SIM_CPU *, IADDR,
CGEN_INSN_INT, CGEN_INSN_INT,
ARGBUF *);
extern void frvbf_init_idesc_table (SIM_CPU *);
extern void frvbf_sem_init_idesc_table (SIM_CPU *);
extern void frvbf_semf_init_idesc_table (SIM_CPU *);
/* Enum declaration for instructions in cpu family frvbf. */
typedef enum frvbf_insn_type {
FRVBF_INSN_X_INVALID, FRVBF_INSN_X_AFTER, FRVBF_INSN_X_BEFORE, FRVBF_INSN_X_CTI_CHAIN
, FRVBF_INSN_X_CHAIN, FRVBF_INSN_X_BEGIN, FRVBF_INSN_ADD, FRVBF_INSN_SUB
, FRVBF_INSN_AND, FRVBF_INSN_OR, FRVBF_INSN_XOR, FRVBF_INSN_NOT
, FRVBF_INSN_SDIV, FRVBF_INSN_NSDIV, FRVBF_INSN_UDIV, FRVBF_INSN_NUDIV
, FRVBF_INSN_SMUL, FRVBF_INSN_UMUL, FRVBF_INSN_SLL, FRVBF_INSN_SRL
, FRVBF_INSN_SRA, FRVBF_INSN_SCAN, FRVBF_INSN_CADD, FRVBF_INSN_CSUB
, FRVBF_INSN_CAND, FRVBF_INSN_COR, FRVBF_INSN_CXOR, FRVBF_INSN_CNOT
, FRVBF_INSN_CSMUL, FRVBF_INSN_CSDIV, FRVBF_INSN_CUDIV, FRVBF_INSN_CSLL
, FRVBF_INSN_CSRL, FRVBF_INSN_CSRA, FRVBF_INSN_CSCAN, FRVBF_INSN_ADDCC
, FRVBF_INSN_SUBCC, FRVBF_INSN_ANDCC, FRVBF_INSN_ORCC, FRVBF_INSN_XORCC
, FRVBF_INSN_SLLCC, FRVBF_INSN_SRLCC, FRVBF_INSN_SRACC, FRVBF_INSN_SMULCC
, FRVBF_INSN_UMULCC, FRVBF_INSN_CADDCC, FRVBF_INSN_CSUBCC, FRVBF_INSN_CSMULCC
, FRVBF_INSN_CANDCC, FRVBF_INSN_CORCC, FRVBF_INSN_CXORCC, FRVBF_INSN_CSLLCC
, FRVBF_INSN_CSRLCC, FRVBF_INSN_CSRACC, FRVBF_INSN_ADDX, FRVBF_INSN_SUBX
, FRVBF_INSN_ADDXCC, FRVBF_INSN_SUBXCC, FRVBF_INSN_ADDI, FRVBF_INSN_SUBI
, FRVBF_INSN_ANDI, FRVBF_INSN_ORI, FRVBF_INSN_XORI, FRVBF_INSN_SDIVI
, FRVBF_INSN_NSDIVI, FRVBF_INSN_UDIVI, FRVBF_INSN_NUDIVI, FRVBF_INSN_SMULI
, FRVBF_INSN_UMULI, FRVBF_INSN_SLLI, FRVBF_INSN_SRLI, FRVBF_INSN_SRAI
, FRVBF_INSN_SCANI, FRVBF_INSN_ADDICC, FRVBF_INSN_SUBICC, FRVBF_INSN_ANDICC
, FRVBF_INSN_ORICC, FRVBF_INSN_XORICC, FRVBF_INSN_SMULICC, FRVBF_INSN_UMULICC
, FRVBF_INSN_SLLICC, FRVBF_INSN_SRLICC, FRVBF_INSN_SRAICC, FRVBF_INSN_ADDXI
, FRVBF_INSN_SUBXI, FRVBF_INSN_ADDXICC, FRVBF_INSN_SUBXICC, FRVBF_INSN_CMPB
, FRVBF_INSN_CMPBA, FRVBF_INSN_SETLO, FRVBF_INSN_SETHI, FRVBF_INSN_SETLOS
, FRVBF_INSN_LDSB, FRVBF_INSN_LDUB, FRVBF_INSN_LDSH, FRVBF_INSN_LDUH
, FRVBF_INSN_LD, FRVBF_INSN_LDBF, FRVBF_INSN_LDHF, FRVBF_INSN_LDF
, FRVBF_INSN_LDC, FRVBF_INSN_NLDSB, FRVBF_INSN_NLDUB, FRVBF_INSN_NLDSH
, FRVBF_INSN_NLDUH, FRVBF_INSN_NLD, FRVBF_INSN_NLDBF, FRVBF_INSN_NLDHF
, FRVBF_INSN_NLDF, FRVBF_INSN_LDD, FRVBF_INSN_LDDF, FRVBF_INSN_LDDC
, FRVBF_INSN_NLDD, FRVBF_INSN_NLDDF, FRVBF_INSN_LDQ, FRVBF_INSN_LDQF
, FRVBF_INSN_LDQC, FRVBF_INSN_NLDQ, FRVBF_INSN_NLDQF, FRVBF_INSN_LDSBU
, FRVBF_INSN_LDUBU, FRVBF_INSN_LDSHU, FRVBF_INSN_LDUHU, FRVBF_INSN_LDU
, FRVBF_INSN_NLDSBU, FRVBF_INSN_NLDUBU, FRVBF_INSN_NLDSHU, FRVBF_INSN_NLDUHU
, FRVBF_INSN_NLDU, FRVBF_INSN_LDBFU, FRVBF_INSN_LDHFU, FRVBF_INSN_LDFU
, FRVBF_INSN_LDCU, FRVBF_INSN_NLDBFU, FRVBF_INSN_NLDHFU, FRVBF_INSN_NLDFU
, FRVBF_INSN_LDDU, FRVBF_INSN_NLDDU, FRVBF_INSN_LDDFU, FRVBF_INSN_LDDCU
, FRVBF_INSN_NLDDFU, FRVBF_INSN_LDQU, FRVBF_INSN_NLDQU, FRVBF_INSN_LDQFU
, FRVBF_INSN_LDQCU, FRVBF_INSN_NLDQFU, FRVBF_INSN_LDSBI, FRVBF_INSN_LDSHI
, FRVBF_INSN_LDI, FRVBF_INSN_LDUBI, FRVBF_INSN_LDUHI, FRVBF_INSN_LDBFI
, FRVBF_INSN_LDHFI, FRVBF_INSN_LDFI, FRVBF_INSN_NLDSBI, FRVBF_INSN_NLDUBI
, FRVBF_INSN_NLDSHI, FRVBF_INSN_NLDUHI, FRVBF_INSN_NLDI, FRVBF_INSN_NLDBFI
, FRVBF_INSN_NLDHFI, FRVBF_INSN_NLDFI, FRVBF_INSN_LDDI, FRVBF_INSN_LDDFI
, FRVBF_INSN_NLDDI, FRVBF_INSN_NLDDFI, FRVBF_INSN_LDQI, FRVBF_INSN_LDQFI
, FRVBF_INSN_NLDQI, FRVBF_INSN_NLDQFI, FRVBF_INSN_STB, FRVBF_INSN_STH
, FRVBF_INSN_ST, FRVBF_INSN_STBF, FRVBF_INSN_STHF, FRVBF_INSN_STF
, FRVBF_INSN_STC, FRVBF_INSN_RSTB, FRVBF_INSN_RSTH, FRVBF_INSN_RST
, FRVBF_INSN_RSTBF, FRVBF_INSN_RSTHF, FRVBF_INSN_RSTF, FRVBF_INSN_STD
, FRVBF_INSN_STDF, FRVBF_INSN_STDC, FRVBF_INSN_RSTD, FRVBF_INSN_RSTDF
, FRVBF_INSN_STQ, FRVBF_INSN_STQF, FRVBF_INSN_STQC, FRVBF_INSN_RSTQ
, FRVBF_INSN_RSTQF, FRVBF_INSN_STBU, FRVBF_INSN_STHU, FRVBF_INSN_STU
, FRVBF_INSN_STBFU, FRVBF_INSN_STHFU, FRVBF_INSN_STFU, FRVBF_INSN_STCU
, FRVBF_INSN_STDU, FRVBF_INSN_STDFU, FRVBF_INSN_STDCU, FRVBF_INSN_STQU
, FRVBF_INSN_STQFU, FRVBF_INSN_STQCU, FRVBF_INSN_CLDSB, FRVBF_INSN_CLDUB
, FRVBF_INSN_CLDSH, FRVBF_INSN_CLDUH, FRVBF_INSN_CLD, FRVBF_INSN_CLDBF
, FRVBF_INSN_CLDHF, FRVBF_INSN_CLDF, FRVBF_INSN_CLDD, FRVBF_INSN_CLDDF
, FRVBF_INSN_CLDQ, FRVBF_INSN_CLDSBU, FRVBF_INSN_CLDUBU, FRVBF_INSN_CLDSHU
, FRVBF_INSN_CLDUHU, FRVBF_INSN_CLDU, FRVBF_INSN_CLDBFU, FRVBF_INSN_CLDHFU
, FRVBF_INSN_CLDFU, FRVBF_INSN_CLDDU, FRVBF_INSN_CLDDFU, FRVBF_INSN_CLDQU
, FRVBF_INSN_CSTB, FRVBF_INSN_CSTH, FRVBF_INSN_CST, FRVBF_INSN_CSTBF
, FRVBF_INSN_CSTHF, FRVBF_INSN_CSTF, FRVBF_INSN_CSTD, FRVBF_INSN_CSTDF
, FRVBF_INSN_CSTQ, FRVBF_INSN_CSTBU, FRVBF_INSN_CSTHU, FRVBF_INSN_CSTU
, FRVBF_INSN_CSTBFU, FRVBF_INSN_CSTHFU, FRVBF_INSN_CSTFU, FRVBF_INSN_CSTDU
, FRVBF_INSN_CSTDFU, FRVBF_INSN_STBI, FRVBF_INSN_STHI, FRVBF_INSN_STI
, FRVBF_INSN_STBFI, FRVBF_INSN_STHFI, FRVBF_INSN_STFI, FRVBF_INSN_STDI
, FRVBF_INSN_STDFI, FRVBF_INSN_STQI, FRVBF_INSN_STQFI, FRVBF_INSN_SWAP
, FRVBF_INSN_SWAPI, FRVBF_INSN_CSWAP, FRVBF_INSN_MOVGF, FRVBF_INSN_MOVFG
, FRVBF_INSN_MOVGFD, FRVBF_INSN_MOVFGD, FRVBF_INSN_MOVGFQ, FRVBF_INSN_MOVFGQ
, FRVBF_INSN_CMOVGF, FRVBF_INSN_CMOVFG, FRVBF_INSN_CMOVGFD, FRVBF_INSN_CMOVFGD
, FRVBF_INSN_MOVGS, FRVBF_INSN_MOVSG, FRVBF_INSN_BRA, FRVBF_INSN_BNO
, FRVBF_INSN_BEQ, FRVBF_INSN_BNE, FRVBF_INSN_BLE, FRVBF_INSN_BGT
, FRVBF_INSN_BLT, FRVBF_INSN_BGE, FRVBF_INSN_BLS, FRVBF_INSN_BHI
, FRVBF_INSN_BC, FRVBF_INSN_BNC, FRVBF_INSN_BN, FRVBF_INSN_BP
, FRVBF_INSN_BV, FRVBF_INSN_BNV, FRVBF_INSN_FBRA, FRVBF_INSN_FBNO
, FRVBF_INSN_FBNE, FRVBF_INSN_FBEQ, FRVBF_INSN_FBLG, FRVBF_INSN_FBUE
, FRVBF_INSN_FBUL, FRVBF_INSN_FBGE, FRVBF_INSN_FBLT, FRVBF_INSN_FBUGE
, FRVBF_INSN_FBUG, FRVBF_INSN_FBLE, FRVBF_INSN_FBGT, FRVBF_INSN_FBULE
, FRVBF_INSN_FBU, FRVBF_INSN_FBO, FRVBF_INSN_BCTRLR, FRVBF_INSN_BRALR
, FRVBF_INSN_BNOLR, FRVBF_INSN_BEQLR, FRVBF_INSN_BNELR, FRVBF_INSN_BLELR
, FRVBF_INSN_BGTLR, FRVBF_INSN_BLTLR, FRVBF_INSN_BGELR, FRVBF_INSN_BLSLR
, FRVBF_INSN_BHILR, FRVBF_INSN_BCLR, FRVBF_INSN_BNCLR, FRVBF_INSN_BNLR
, FRVBF_INSN_BPLR, FRVBF_INSN_BVLR, FRVBF_INSN_BNVLR, FRVBF_INSN_FBRALR
, FRVBF_INSN_FBNOLR, FRVBF_INSN_FBEQLR, FRVBF_INSN_FBNELR, FRVBF_INSN_FBLGLR
, FRVBF_INSN_FBUELR, FRVBF_INSN_FBULLR, FRVBF_INSN_FBGELR, FRVBF_INSN_FBLTLR
, FRVBF_INSN_FBUGELR, FRVBF_INSN_FBUGLR, FRVBF_INSN_FBLELR, FRVBF_INSN_FBGTLR
, FRVBF_INSN_FBULELR, FRVBF_INSN_FBULR, FRVBF_INSN_FBOLR, FRVBF_INSN_BCRALR
, FRVBF_INSN_BCNOLR, FRVBF_INSN_BCEQLR, FRVBF_INSN_BCNELR, FRVBF_INSN_BCLELR
, FRVBF_INSN_BCGTLR, FRVBF_INSN_BCLTLR, FRVBF_INSN_BCGELR, FRVBF_INSN_BCLSLR
, FRVBF_INSN_BCHILR, FRVBF_INSN_BCCLR, FRVBF_INSN_BCNCLR, FRVBF_INSN_BCNLR
, FRVBF_INSN_BCPLR, FRVBF_INSN_BCVLR, FRVBF_INSN_BCNVLR, FRVBF_INSN_FCBRALR
, FRVBF_INSN_FCBNOLR, FRVBF_INSN_FCBEQLR, FRVBF_INSN_FCBNELR, FRVBF_INSN_FCBLGLR
, FRVBF_INSN_FCBUELR, FRVBF_INSN_FCBULLR, FRVBF_INSN_FCBGELR, FRVBF_INSN_FCBLTLR
, FRVBF_INSN_FCBUGELR, FRVBF_INSN_FCBUGLR, FRVBF_INSN_FCBLELR, FRVBF_INSN_FCBGTLR
, FRVBF_INSN_FCBULELR, FRVBF_INSN_FCBULR, FRVBF_INSN_FCBOLR, FRVBF_INSN_JMPL
, FRVBF_INSN_CALLL, FRVBF_INSN_JMPIL, FRVBF_INSN_CALLIL, FRVBF_INSN_CALL
, FRVBF_INSN_RETT, FRVBF_INSN_REI, FRVBF_INSN_TRA, FRVBF_INSN_TNO
, FRVBF_INSN_TEQ, FRVBF_INSN_TNE, FRVBF_INSN_TLE, FRVBF_INSN_TGT
, FRVBF_INSN_TLT, FRVBF_INSN_TGE, FRVBF_INSN_TLS, FRVBF_INSN_THI
, FRVBF_INSN_TC, FRVBF_INSN_TNC, FRVBF_INSN_TN, FRVBF_INSN_TP
, FRVBF_INSN_TV, FRVBF_INSN_TNV, FRVBF_INSN_FTRA, FRVBF_INSN_FTNO
, FRVBF_INSN_FTNE, FRVBF_INSN_FTEQ, FRVBF_INSN_FTLG, FRVBF_INSN_FTUE
, FRVBF_INSN_FTUL, FRVBF_INSN_FTGE, FRVBF_INSN_FTLT, FRVBF_INSN_FTUGE
, FRVBF_INSN_FTUG, FRVBF_INSN_FTLE, FRVBF_INSN_FTGT, FRVBF_INSN_FTULE
, FRVBF_INSN_FTU, FRVBF_INSN_FTO, FRVBF_INSN_TIRA, FRVBF_INSN_TINO
, FRVBF_INSN_TIEQ, FRVBF_INSN_TINE, FRVBF_INSN_TILE, FRVBF_INSN_TIGT
, FRVBF_INSN_TILT, FRVBF_INSN_TIGE, FRVBF_INSN_TILS, FRVBF_INSN_TIHI
, FRVBF_INSN_TIC, FRVBF_INSN_TINC, FRVBF_INSN_TIN, FRVBF_INSN_TIP
, FRVBF_INSN_TIV, FRVBF_INSN_TINV, FRVBF_INSN_FTIRA, FRVBF_INSN_FTINO
, FRVBF_INSN_FTINE, FRVBF_INSN_FTIEQ, FRVBF_INSN_FTILG, FRVBF_INSN_FTIUE
, FRVBF_INSN_FTIUL, FRVBF_INSN_FTIGE, FRVBF_INSN_FTILT, FRVBF_INSN_FTIUGE
, FRVBF_INSN_FTIUG, FRVBF_INSN_FTILE, FRVBF_INSN_FTIGT, FRVBF_INSN_FTIULE
, FRVBF_INSN_FTIU, FRVBF_INSN_FTIO, FRVBF_INSN_BREAK, FRVBF_INSN_MTRAP
, FRVBF_INSN_ANDCR, FRVBF_INSN_ORCR, FRVBF_INSN_XORCR, FRVBF_INSN_NANDCR
, FRVBF_INSN_NORCR, FRVBF_INSN_ANDNCR, FRVBF_INSN_ORNCR, FRVBF_INSN_NANDNCR
, FRVBF_INSN_NORNCR, FRVBF_INSN_NOTCR, FRVBF_INSN_CKRA, FRVBF_INSN_CKNO
, FRVBF_INSN_CKEQ, FRVBF_INSN_CKNE, FRVBF_INSN_CKLE, FRVBF_INSN_CKGT
, FRVBF_INSN_CKLT, FRVBF_INSN_CKGE, FRVBF_INSN_CKLS, FRVBF_INSN_CKHI
, FRVBF_INSN_CKC, FRVBF_INSN_CKNC, FRVBF_INSN_CKN, FRVBF_INSN_CKP
, FRVBF_INSN_CKV, FRVBF_INSN_CKNV, FRVBF_INSN_FCKRA, FRVBF_INSN_FCKNO
, FRVBF_INSN_FCKNE, FRVBF_INSN_FCKEQ, FRVBF_INSN_FCKLG, FRVBF_INSN_FCKUE
, FRVBF_INSN_FCKUL, FRVBF_INSN_FCKGE, FRVBF_INSN_FCKLT, FRVBF_INSN_FCKUGE
, FRVBF_INSN_FCKUG, FRVBF_INSN_FCKLE, FRVBF_INSN_FCKGT, FRVBF_INSN_FCKULE
, FRVBF_INSN_FCKU, FRVBF_INSN_FCKO, FRVBF_INSN_CCKRA, FRVBF_INSN_CCKNO
, FRVBF_INSN_CCKEQ, FRVBF_INSN_CCKNE, FRVBF_INSN_CCKLE, FRVBF_INSN_CCKGT
, FRVBF_INSN_CCKLT, FRVBF_INSN_CCKGE, FRVBF_INSN_CCKLS, FRVBF_INSN_CCKHI
, FRVBF_INSN_CCKC, FRVBF_INSN_CCKNC, FRVBF_INSN_CCKN, FRVBF_INSN_CCKP
, FRVBF_INSN_CCKV, FRVBF_INSN_CCKNV, FRVBF_INSN_CFCKRA, FRVBF_INSN_CFCKNO
, FRVBF_INSN_CFCKNE, FRVBF_INSN_CFCKEQ, FRVBF_INSN_CFCKLG, FRVBF_INSN_CFCKUE
, FRVBF_INSN_CFCKUL, FRVBF_INSN_CFCKGE, FRVBF_INSN_CFCKLT, FRVBF_INSN_CFCKUGE
, FRVBF_INSN_CFCKUG, FRVBF_INSN_CFCKLE, FRVBF_INSN_CFCKGT, FRVBF_INSN_CFCKULE
, FRVBF_INSN_CFCKU, FRVBF_INSN_CFCKO, FRVBF_INSN_CJMPL, FRVBF_INSN_CCALLL
, FRVBF_INSN_ICI, FRVBF_INSN_DCI, FRVBF_INSN_ICEI, FRVBF_INSN_DCEI
, FRVBF_INSN_DCF, FRVBF_INSN_DCEF, FRVBF_INSN_WITLB, FRVBF_INSN_WDTLB
, FRVBF_INSN_ITLBI, FRVBF_INSN_DTLBI, FRVBF_INSN_ICPL, FRVBF_INSN_DCPL
, FRVBF_INSN_ICUL, FRVBF_INSN_DCUL, FRVBF_INSN_BAR, FRVBF_INSN_MEMBAR
, FRVBF_INSN_COP1, FRVBF_INSN_COP2, FRVBF_INSN_CLRGR, FRVBF_INSN_CLRFR
, FRVBF_INSN_CLRGA, FRVBF_INSN_CLRFA, FRVBF_INSN_COMMITGR, FRVBF_INSN_COMMITFR
, FRVBF_INSN_COMMITGA, FRVBF_INSN_COMMITFA, FRVBF_INSN_FITOS, FRVBF_INSN_FSTOI
, FRVBF_INSN_FITOD, FRVBF_INSN_FDTOI, FRVBF_INSN_FDITOS, FRVBF_INSN_FDSTOI
, FRVBF_INSN_NFDITOS, FRVBF_INSN_NFDSTOI, FRVBF_INSN_CFITOS, FRVBF_INSN_CFSTOI
, FRVBF_INSN_NFITOS, FRVBF_INSN_NFSTOI, FRVBF_INSN_FMOVS, FRVBF_INSN_FMOVD
, FRVBF_INSN_FDMOVS, FRVBF_INSN_CFMOVS, FRVBF_INSN_FNEGS, FRVBF_INSN_FNEGD
, FRVBF_INSN_FDNEGS, FRVBF_INSN_CFNEGS, FRVBF_INSN_FABSS, FRVBF_INSN_FABSD
, FRVBF_INSN_FDABSS, FRVBF_INSN_CFABSS, FRVBF_INSN_FSQRTS, FRVBF_INSN_FDSQRTS
, FRVBF_INSN_NFDSQRTS, FRVBF_INSN_FSQRTD, FRVBF_INSN_CFSQRTS, FRVBF_INSN_NFSQRTS
, FRVBF_INSN_FADDS, FRVBF_INSN_FSUBS, FRVBF_INSN_FMULS, FRVBF_INSN_FDIVS
, FRVBF_INSN_FADDD, FRVBF_INSN_FSUBD, FRVBF_INSN_FMULD, FRVBF_INSN_FDIVD
, FRVBF_INSN_CFADDS, FRVBF_INSN_CFSUBS, FRVBF_INSN_CFMULS, FRVBF_INSN_CFDIVS
, FRVBF_INSN_NFADDS, FRVBF_INSN_NFSUBS, FRVBF_INSN_NFMULS, FRVBF_INSN_NFDIVS
, FRVBF_INSN_FCMPS, FRVBF_INSN_FCMPD, FRVBF_INSN_CFCMPS, FRVBF_INSN_FDCMPS
, FRVBF_INSN_FMADDS, FRVBF_INSN_FMSUBS, FRVBF_INSN_FMADDD, FRVBF_INSN_FMSUBD
, FRVBF_INSN_FDMADDS, FRVBF_INSN_NFDMADDS, FRVBF_INSN_CFMADDS, FRVBF_INSN_CFMSUBS
, FRVBF_INSN_NFMADDS, FRVBF_INSN_NFMSUBS, FRVBF_INSN_FMAS, FRVBF_INSN_FMSS
, FRVBF_INSN_FDMAS, FRVBF_INSN_FDMSS, FRVBF_INSN_NFDMAS, FRVBF_INSN_NFDMSS
, FRVBF_INSN_CFMAS, FRVBF_INSN_CFMSS, FRVBF_INSN_FMAD, FRVBF_INSN_FMSD
, FRVBF_INSN_NFMAS, FRVBF_INSN_NFMSS, FRVBF_INSN_FDADDS, FRVBF_INSN_FDSUBS
, FRVBF_INSN_FDMULS, FRVBF_INSN_FDDIVS, FRVBF_INSN_FDSADS, FRVBF_INSN_FDMULCS
, FRVBF_INSN_NFDMULCS, FRVBF_INSN_NFDADDS, FRVBF_INSN_NFDSUBS, FRVBF_INSN_NFDMULS
, FRVBF_INSN_NFDDIVS, FRVBF_INSN_NFDSADS, FRVBF_INSN_NFDCMPS, FRVBF_INSN_MHSETLOS
, FRVBF_INSN_MHSETHIS, FRVBF_INSN_MHDSETS, FRVBF_INSN_MHSETLOH, FRVBF_INSN_MHSETHIH
, FRVBF_INSN_MHDSETH, FRVBF_INSN_MAND, FRVBF_INSN_MOR, FRVBF_INSN_MXOR
, FRVBF_INSN_CMAND, FRVBF_INSN_CMOR, FRVBF_INSN_CMXOR, FRVBF_INSN_MNOT
, FRVBF_INSN_CMNOT, FRVBF_INSN_MROTLI, FRVBF_INSN_MROTRI, FRVBF_INSN_MWCUT
, FRVBF_INSN_MWCUTI, FRVBF_INSN_MCUT, FRVBF_INSN_MCUTI, FRVBF_INSN_MCUTSS
, FRVBF_INSN_MCUTSSI, FRVBF_INSN_MDCUTSSI, FRVBF_INSN_MAVEH, FRVBF_INSN_MSLLHI
, FRVBF_INSN_MSRLHI, FRVBF_INSN_MSRAHI, FRVBF_INSN_MDROTLI, FRVBF_INSN_MCPLHI
, FRVBF_INSN_MCPLI, FRVBF_INSN_MSATHS, FRVBF_INSN_MQSATHS, FRVBF_INSN_MSATHU
, FRVBF_INSN_MCMPSH, FRVBF_INSN_MCMPUH, FRVBF_INSN_MABSHS, FRVBF_INSN_MADDHSS
, FRVBF_INSN_MADDHUS, FRVBF_INSN_MSUBHSS, FRVBF_INSN_MSUBHUS, FRVBF_INSN_CMADDHSS
, FRVBF_INSN_CMADDHUS, FRVBF_INSN_CMSUBHSS, FRVBF_INSN_CMSUBHUS, FRVBF_INSN_MQADDHSS
, FRVBF_INSN_MQADDHUS, FRVBF_INSN_MQSUBHSS, FRVBF_INSN_MQSUBHUS, FRVBF_INSN_CMQADDHSS
, FRVBF_INSN_CMQADDHUS, FRVBF_INSN_CMQSUBHSS, FRVBF_INSN_CMQSUBHUS, FRVBF_INSN_MADDACCS
, FRVBF_INSN_MSUBACCS, FRVBF_INSN_MDADDACCS, FRVBF_INSN_MDSUBACCS, FRVBF_INSN_MASACCS
, FRVBF_INSN_MDASACCS, FRVBF_INSN_MMULHS, FRVBF_INSN_MMULHU, FRVBF_INSN_MMULXHS
, FRVBF_INSN_MMULXHU, FRVBF_INSN_CMMULHS, FRVBF_INSN_CMMULHU, FRVBF_INSN_MQMULHS
, FRVBF_INSN_MQMULHU, FRVBF_INSN_MQMULXHS, FRVBF_INSN_MQMULXHU, FRVBF_INSN_CMQMULHS
, FRVBF_INSN_CMQMULHU, FRVBF_INSN_MMACHS, FRVBF_INSN_MMACHU, FRVBF_INSN_MMRDHS
, FRVBF_INSN_MMRDHU, FRVBF_INSN_CMMACHS, FRVBF_INSN_CMMACHU, FRVBF_INSN_MQMACHS
, FRVBF_INSN_MQMACHU, FRVBF_INSN_CMQMACHS, FRVBF_INSN_CMQMACHU, FRVBF_INSN_MQXMACHS
, FRVBF_INSN_MQXMACXHS, FRVBF_INSN_MQMACXHS, FRVBF_INSN_MCPXRS, FRVBF_INSN_MCPXRU
, FRVBF_INSN_MCPXIS, FRVBF_INSN_MCPXIU, FRVBF_INSN_CMCPXRS, FRVBF_INSN_CMCPXRU
, FRVBF_INSN_CMCPXIS, FRVBF_INSN_CMCPXIU, FRVBF_INSN_MQCPXRS, FRVBF_INSN_MQCPXRU
, FRVBF_INSN_MQCPXIS, FRVBF_INSN_MQCPXIU, FRVBF_INSN_MEXPDHW, FRVBF_INSN_CMEXPDHW
, FRVBF_INSN_MEXPDHD, FRVBF_INSN_CMEXPDHD, FRVBF_INSN_MPACKH, FRVBF_INSN_MDPACKH
, FRVBF_INSN_MUNPACKH, FRVBF_INSN_MDUNPACKH, FRVBF_INSN_MBTOH, FRVBF_INSN_CMBTOH
, FRVBF_INSN_MHTOB, FRVBF_INSN_CMHTOB, FRVBF_INSN_MBTOHE, FRVBF_INSN_CMBTOHE
, FRVBF_INSN_MCLRACC, FRVBF_INSN_MRDACC, FRVBF_INSN_MRDACCG, FRVBF_INSN_MWTACC
, FRVBF_INSN_MWTACCG, FRVBF_INSN_MCOP1, FRVBF_INSN_MCOP2, FRVBF_INSN_FNOP
, FRVBF_INSN__MAX
} FRVBF_INSN_TYPE;
/* Enum declaration for semantic formats in cpu family frvbf. */
typedef enum frvbf_sfmt_type {
FRVBF_SFMT_EMPTY, FRVBF_SFMT_ADD, FRVBF_SFMT_NOT, FRVBF_SFMT_SDIV
, FRVBF_SFMT_SMUL, FRVBF_SFMT_CADD, FRVBF_SFMT_CNOT, FRVBF_SFMT_CSMUL
, FRVBF_SFMT_CSDIV, FRVBF_SFMT_ADDCC, FRVBF_SFMT_ANDCC, FRVBF_SFMT_SMULCC
, FRVBF_SFMT_CADDCC, FRVBF_SFMT_CSMULCC, FRVBF_SFMT_ADDX, FRVBF_SFMT_ADDI
, FRVBF_SFMT_SDIVI, FRVBF_SFMT_SMULI, FRVBF_SFMT_ADDICC, FRVBF_SFMT_ANDICC
, FRVBF_SFMT_SMULICC, FRVBF_SFMT_ADDXI, FRVBF_SFMT_CMPB, FRVBF_SFMT_SETLO
, FRVBF_SFMT_SETHI, FRVBF_SFMT_SETLOS, FRVBF_SFMT_LDSB, FRVBF_SFMT_LDBF
, FRVBF_SFMT_LDC, FRVBF_SFMT_NLDSB, FRVBF_SFMT_NLDBF, FRVBF_SFMT_LDD
, FRVBF_SFMT_LDDF, FRVBF_SFMT_LDDC, FRVBF_SFMT_NLDD, FRVBF_SFMT_NLDDF
, FRVBF_SFMT_LDQ, FRVBF_SFMT_LDQF, FRVBF_SFMT_LDQC, FRVBF_SFMT_NLDQ
, FRVBF_SFMT_NLDQF, FRVBF_SFMT_LDSBU, FRVBF_SFMT_NLDSBU, FRVBF_SFMT_LDBFU
, FRVBF_SFMT_LDCU, FRVBF_SFMT_NLDBFU, FRVBF_SFMT_LDDU, FRVBF_SFMT_NLDDU
, FRVBF_SFMT_LDDFU, FRVBF_SFMT_LDDCU, FRVBF_SFMT_NLDDFU, FRVBF_SFMT_LDQU
, FRVBF_SFMT_NLDQU, FRVBF_SFMT_LDQFU, FRVBF_SFMT_LDQCU, FRVBF_SFMT_NLDQFU
, FRVBF_SFMT_LDSBI, FRVBF_SFMT_LDBFI, FRVBF_SFMT_NLDSBI, FRVBF_SFMT_NLDBFI
, FRVBF_SFMT_LDDI, FRVBF_SFMT_LDDFI, FRVBF_SFMT_NLDDI, FRVBF_SFMT_NLDDFI
, FRVBF_SFMT_LDQI, FRVBF_SFMT_LDQFI, FRVBF_SFMT_NLDQI, FRVBF_SFMT_NLDQFI
, FRVBF_SFMT_STB, FRVBF_SFMT_STBF, FRVBF_SFMT_STC, FRVBF_SFMT_RSTB
, FRVBF_SFMT_RSTBF, FRVBF_SFMT_STD, FRVBF_SFMT_STDF, FRVBF_SFMT_STDC
, FRVBF_SFMT_RSTD, FRVBF_SFMT_RSTDF, FRVBF_SFMT_STBU, FRVBF_SFMT_STBFU
, FRVBF_SFMT_STCU, FRVBF_SFMT_STDU, FRVBF_SFMT_STDFU, FRVBF_SFMT_STDCU
, FRVBF_SFMT_STQU, FRVBF_SFMT_CLDSB, FRVBF_SFMT_CLDBF, FRVBF_SFMT_CLDD
, FRVBF_SFMT_CLDDF, FRVBF_SFMT_CLDQ, FRVBF_SFMT_CLDSBU, FRVBF_SFMT_CLDBFU
, FRVBF_SFMT_CLDDU, FRVBF_SFMT_CLDDFU, FRVBF_SFMT_CLDQU, FRVBF_SFMT_CSTB
, FRVBF_SFMT_CSTBF, FRVBF_SFMT_CSTD, FRVBF_SFMT_CSTDF, FRVBF_SFMT_CSTBU
, FRVBF_SFMT_CSTBFU, FRVBF_SFMT_CSTDU, FRVBF_SFMT_CSTDFU, FRVBF_SFMT_STBI
, FRVBF_SFMT_STBFI, FRVBF_SFMT_STDI, FRVBF_SFMT_STDFI, FRVBF_SFMT_SWAP
, FRVBF_SFMT_SWAPI, FRVBF_SFMT_CSWAP, FRVBF_SFMT_MOVGF, FRVBF_SFMT_MOVFG
, FRVBF_SFMT_MOVGFD, FRVBF_SFMT_MOVFGD, FRVBF_SFMT_MOVGFQ, FRVBF_SFMT_MOVFGQ
, FRVBF_SFMT_CMOVGF, FRVBF_SFMT_CMOVFG, FRVBF_SFMT_CMOVGFD, FRVBF_SFMT_CMOVFGD
, FRVBF_SFMT_MOVGS, FRVBF_SFMT_MOVSG, FRVBF_SFMT_BRA, FRVBF_SFMT_BNO
, FRVBF_SFMT_BEQ, FRVBF_SFMT_FBNE, FRVBF_SFMT_BCTRLR, FRVBF_SFMT_BRALR
, FRVBF_SFMT_BNOLR, FRVBF_SFMT_BEQLR, FRVBF_SFMT_FBEQLR, FRVBF_SFMT_BCRALR
, FRVBF_SFMT_BCNOLR, FRVBF_SFMT_BCEQLR, FRVBF_SFMT_FCBEQLR, FRVBF_SFMT_JMPL
, FRVBF_SFMT_JMPIL, FRVBF_SFMT_CALL, FRVBF_SFMT_RETT, FRVBF_SFMT_REI
, FRVBF_SFMT_TRA, FRVBF_SFMT_TEQ, FRVBF_SFMT_FTNE, FRVBF_SFMT_TIRA
, FRVBF_SFMT_TIEQ, FRVBF_SFMT_FTINE, FRVBF_SFMT_BREAK, FRVBF_SFMT_ANDCR
, FRVBF_SFMT_NOTCR, FRVBF_SFMT_CKRA, FRVBF_SFMT_CKEQ, FRVBF_SFMT_FCKRA
, FRVBF_SFMT_FCKNE, FRVBF_SFMT_CCKRA, FRVBF_SFMT_CCKEQ, FRVBF_SFMT_CFCKRA
, FRVBF_SFMT_CFCKNE, FRVBF_SFMT_CJMPL, FRVBF_SFMT_ICI, FRVBF_SFMT_ICEI
, FRVBF_SFMT_ICPL, FRVBF_SFMT_ICUL, FRVBF_SFMT_CLRGR, FRVBF_SFMT_CLRFR
, FRVBF_SFMT_FITOS, FRVBF_SFMT_FSTOI, FRVBF_SFMT_FITOD, FRVBF_SFMT_FDTOI
, FRVBF_SFMT_FDITOS, FRVBF_SFMT_FDSTOI, FRVBF_SFMT_CFITOS, FRVBF_SFMT_CFSTOI
, FRVBF_SFMT_NFITOS, FRVBF_SFMT_NFSTOI, FRVBF_SFMT_FMOVS, FRVBF_SFMT_FMOVD
, FRVBF_SFMT_FDMOVS, FRVBF_SFMT_CFMOVS, FRVBF_SFMT_NFSQRTS, FRVBF_SFMT_FADDS
, FRVBF_SFMT_FADDD, FRVBF_SFMT_CFADDS, FRVBF_SFMT_NFADDS, FRVBF_SFMT_FCMPS
, FRVBF_SFMT_FCMPD, FRVBF_SFMT_CFCMPS, FRVBF_SFMT_FDCMPS, FRVBF_SFMT_FMADDS
, FRVBF_SFMT_FMADDD, FRVBF_SFMT_FDMADDS, FRVBF_SFMT_CFMADDS, FRVBF_SFMT_NFMADDS
, FRVBF_SFMT_FMAS, FRVBF_SFMT_FDMAS, FRVBF_SFMT_CFMAS, FRVBF_SFMT_NFDCMPS
, FRVBF_SFMT_MHSETLOS, FRVBF_SFMT_MHSETHIS, FRVBF_SFMT_MHDSETS, FRVBF_SFMT_MHSETLOH
, FRVBF_SFMT_MHSETHIH, FRVBF_SFMT_MHDSETH, FRVBF_SFMT_MAND, FRVBF_SFMT_CMAND
, FRVBF_SFMT_MNOT, FRVBF_SFMT_CMNOT, FRVBF_SFMT_MROTLI, FRVBF_SFMT_MWCUT
, FRVBF_SFMT_MWCUTI, FRVBF_SFMT_MCUT, FRVBF_SFMT_MCUTI, FRVBF_SFMT_MDCUTSSI
, FRVBF_SFMT_MSLLHI, FRVBF_SFMT_MDROTLI, FRVBF_SFMT_MCPLHI, FRVBF_SFMT_MCPLI
, FRVBF_SFMT_MSATHS, FRVBF_SFMT_MQSATHS, FRVBF_SFMT_MCMPSH, FRVBF_SFMT_MABSHS
, FRVBF_SFMT_CMADDHSS, FRVBF_SFMT_CMQADDHSS, FRVBF_SFMT_MADDACCS, FRVBF_SFMT_MDADDACCS
, FRVBF_SFMT_MASACCS, FRVBF_SFMT_MDASACCS, FRVBF_SFMT_MMULHS, FRVBF_SFMT_CMMULHS
, FRVBF_SFMT_MQMULHS, FRVBF_SFMT_CMQMULHS, FRVBF_SFMT_MMACHS, FRVBF_SFMT_MMACHU
, FRVBF_SFMT_CMMACHS, FRVBF_SFMT_CMMACHU, FRVBF_SFMT_MQMACHS, FRVBF_SFMT_MQMACHU
, FRVBF_SFMT_CMQMACHS, FRVBF_SFMT_CMQMACHU, FRVBF_SFMT_MCPXRS, FRVBF_SFMT_CMCPXRS
, FRVBF_SFMT_MQCPXRS, FRVBF_SFMT_MEXPDHW, FRVBF_SFMT_CMEXPDHW, FRVBF_SFMT_MEXPDHD
, FRVBF_SFMT_CMEXPDHD, FRVBF_SFMT_MPACKH, FRVBF_SFMT_MDPACKH, FRVBF_SFMT_MUNPACKH
, FRVBF_SFMT_MDUNPACKH, FRVBF_SFMT_MBTOH, FRVBF_SFMT_CMBTOH, FRVBF_SFMT_MHTOB
, FRVBF_SFMT_CMHTOB, FRVBF_SFMT_MBTOHE, FRVBF_SFMT_CMBTOHE, FRVBF_SFMT_MCLRACC
, FRVBF_SFMT_MRDACC, FRVBF_SFMT_MRDACCG, FRVBF_SFMT_MWTACC, FRVBF_SFMT_MWTACCG
} FRVBF_SFMT_TYPE;
/* Function unit handlers (user written). */
extern int frvbf_model_frv_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr500_u_dcul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_icul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_dcpl (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_icpl (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_dcf (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_dci (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_ici (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_membar (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr500_u_barrier (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr500_u_media_dual_btohe (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media_dual_htob (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media_dual_btoh (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media_dual_unpack (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media_dual_expand (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media_quad_complex (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Sk*/);
extern int frvbf_model_fr500_u_media_quad_mul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Sk*/, INT /*ACC40Uk*/);
extern int frvbf_model_fr500_u_media_dual_mul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Sk*/, INT /*ACC40Uk*/);
extern int frvbf_model_fr500_u_media_quad_arith (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_media (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Si*/, INT /*ACCGi*/, INT /*FRintk*/, INT /*ACC40Sk*/, INT /*ACC40Uk*/, INT /*ACCGk*/);
extern int frvbf_model_fr500_u_float_dual_convert (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRj*/, INT /*FRintj*/, INT /*FRk*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_float_convert (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRj*/, INT /*FRintj*/, INT /*FRdoublej*/, INT /*FRk*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_float_dual_compare (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRj*/, INT /*FCCi_2*/);
extern int frvbf_model_fr500_u_float_compare (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRj*/, INT /*FRdoublei*/, INT /*FRdoublej*/, INT /*FCCi_2*/);
extern int frvbf_model_fr500_u_float_dual_sqrt (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRj*/, INT /*FRk*/);
extern int frvbf_model_fr500_u_float_sqrt (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRj*/, INT /*FRdoublej*/, INT /*FRk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_float_div (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRj*/, INT /*FRk*/);
extern int frvbf_model_fr500_u_float_dual_arith (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRj*/, INT /*FRdoublei*/, INT /*FRdoublej*/, INT /*FRk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_float_arith (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRj*/, INT /*FRdoublei*/, INT /*FRdoublej*/, INT /*FRk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_gr2spr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRj*/, INT /*spr*/);
extern int frvbf_model_fr500_u_gr2fr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRj*/, INT /*FRintk*/);
extern int frvbf_model_fr500_u_spr2gr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*spr*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_fr2gr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintk*/, INT /*GRj*/);
extern int frvbf_model_fr500_u_fr2fr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRi*/, INT /*FRk*/);
extern int frvbf_model_fr500_u_swap (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/);
extern int frvbf_model_fr500_u_fr_r_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_fr_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_fr_load (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr500_u_gr_r_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*GRdoublek*/);
extern int frvbf_model_fr500_u_gr_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*GRdoublek*/);
extern int frvbf_model_fr500_u_gr_load (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*GRdoublek*/);
extern int frvbf_model_fr500_u_set_hilo (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRkhi*/, INT /*GRklo*/);
extern int frvbf_model_fr500_u_check (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ICCi_3*/, INT /*FCCi_3*/);
extern int frvbf_model_fr500_u_trap (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*ICCi_2*/, INT /*FCCi_2*/);
extern int frvbf_model_fr500_u_branch (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*ICCi_2*/, INT /*FCCi_2*/);
extern int frvbf_model_fr500_u_idiv (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*ICCi_1*/);
extern int frvbf_model_fr500_u_imul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRdoublek*/, INT /*ICCi_1*/);
extern int frvbf_model_fr500_u_integer (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*ICCi_1*/);
extern int frvbf_model_fr500_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_tomcat_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr400_u_dcul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_icul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_dcpl (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_icpl (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_dcf (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_dci (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_ici (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_membar (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr400_u_barrier (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_fr400_u_media_dual_htob (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_dual_expand (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_7 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FCCk*/);
extern int frvbf_model_fr400_u_media_6 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_4_acc_dual (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_4_accg (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACCGi*/, INT /*FRinti*/, INT /*ACCGk*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_4 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*FRintj*/, INT /*ACC40Sk*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_3_quad (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_3_dual (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_3 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_2_add_sub_dual (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*ACC40Sk*/);
extern int frvbf_model_fr400_u_media_2_add_sub (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*ACC40Sk*/);
extern int frvbf_model_fr400_u_media_2_acc_dual (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*ACC40Sk*/);
extern int frvbf_model_fr400_u_media_2_acc (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ACC40Si*/, INT /*ACC40Sk*/);
extern int frvbf_model_fr400_u_media_2_quad (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Sk*/, INT /*ACC40Uk*/);
extern int frvbf_model_fr400_u_media_2 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*ACC40Sk*/, INT /*ACC40Uk*/);
extern int frvbf_model_fr400_u_media_hilo (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRkhi*/, INT /*FRklo*/);
extern int frvbf_model_fr400_u_media_1_quad (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_media_1 (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRinti*/, INT /*FRintj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_gr2spr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRj*/, INT /*spr*/);
extern int frvbf_model_fr400_u_gr2fr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRj*/, INT /*FRintk*/);
extern int frvbf_model_fr400_u_spr2gr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*spr*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_fr2gr (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*FRintk*/, INT /*GRj*/);
extern int frvbf_model_fr400_u_swap (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/);
extern int frvbf_model_fr400_u_fr_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr400_u_fr_load (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*FRintk*/, INT /*FRdoublek*/);
extern int frvbf_model_fr400_u_gr_store (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*GRdoublek*/);
extern int frvbf_model_fr400_u_gr_load (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*GRdoublek*/);
extern int frvbf_model_fr400_u_set_hilo (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRkhi*/, INT /*GRklo*/);
extern int frvbf_model_fr400_u_check (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*ICCi_3*/, INT /*FCCi_3*/);
extern int frvbf_model_fr400_u_trap (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*ICCi_2*/, INT /*FCCi_2*/);
extern int frvbf_model_fr400_u_branch (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*ICCi_2*/, INT /*FCCi_2*/);
extern int frvbf_model_fr400_u_idiv (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*ICCi_1*/);
extern int frvbf_model_fr400_u_imul (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRdoublek*/, INT /*ICCi_1*/);
extern int frvbf_model_fr400_u_integer (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/, INT /*GRi*/, INT /*GRj*/, INT /*GRk*/, INT /*ICCi_1*/);
extern int frvbf_model_fr400_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
extern int frvbf_model_simple_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
/* Profiling before/after handlers (user written) */
extern void frvbf_model_insn_before (SIM_CPU *, int /*first_p*/);
extern void frvbf_model_insn_after (SIM_CPU *, int /*last_p*/, int /*cycles*/);
#endif /* FRVBF_DECODE_H */

96
sim/frv/devices.c Normal file
View File

@ -0,0 +1,96 @@
/* frv device support
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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. */
/* ??? All of this is just to get something going. wip! */
#include "sim-main.h"
#ifdef HAVE_DV_SOCKSER
#include "dv-sockser.h"
#endif
device frv_devices;
int
device_io_read_buffer (device *me, void *source, int space,
address_word addr, unsigned nr_bytes,
SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
{
if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
return nr_bytes;
#ifdef HAVE_DV_SOCKSER
if (addr == UART_INCHAR_ADDR)
{
int c = dv_sockser_read (sd);
if (c == -1)
return 0;
*(char *) source = c;
return 1;
}
if (addr == UART_STATUS_ADDR)
{
int status = dv_sockser_status (sd);
unsigned char *p = source;
p[0] = 0;
p[1] = (((status & DV_SOCKSER_INPUT_EMPTY)
#ifdef UART_INPUT_READY0
? UART_INPUT_READY : 0)
#else
? 0 : UART_INPUT_READY)
#endif
+ ((status & DV_SOCKSER_OUTPUT_EMPTY) ? UART_OUTPUT_READY : 0));
return 2;
}
#endif
return nr_bytes;
}
int
device_io_write_buffer (device *me, const void *source, int space,
address_word addr, unsigned nr_bytes,
SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
{
#if WITH_SCACHE
if (addr == MCCR_ADDR)
{
if ((*(const char *) source & MCCR_CP) != 0)
scache_flush (sd);
return nr_bytes;
}
#endif
if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
return nr_bytes;
#if HAVE_DV_SOCKSER
if (addr == UART_OUTCHAR_ADDR)
{
int rc = dv_sockser_write (sd, *(char *) source);
return rc == 1;
}
#endif
return nr_bytes;
}
void device_error (device *me, char* message, ...) {}

916
sim/frv/frv-sim.h Normal file
View File

@ -0,0 +1,916 @@
/* collection of junk waiting time to sort out
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 FRV_SIM_H
#define FRV_SIM_H
#include "sim-options.h"
/* Not defined in the cgen cpu file for access restriction purposes. */
#define H_SPR_ACC0 1408
#define H_SPR_ACC63 1471
#define H_SPR_ACCG0 1472
#define H_SPR_ACCG63 1535
/* gdb register numbers. */
#define GR_REGNUM_MAX 63
#define FR_REGNUM_MAX 127
#define PC_REGNUM 128
#define LR_REGNUM 145
/* Initialization of the frv cpu. */
void frv_initialize (SIM_CPU *, SIM_DESC);
void frv_term (SIM_DESC);
void frv_power_on_reset (SIM_CPU *);
void frv_hardware_reset (SIM_CPU *);
void frv_software_reset (SIM_CPU *);
/* The reset register. See FRV LSI section 10.3.1 */
#define RSTR_ADDRESS 0xfeff0500
#define RSTR_INITIAL_VALUE 0x00000400
#define RSTR_HARDWARE_RESET 0x00000200
#define RSTR_SOFTWARE_RESET 0x00000100
#define GET_RSTR_HR(rstr) (((rstr) >> 1) & 1)
#define GET_RSTR_SR(rstr) (((rstr) ) & 1)
#define SET_RSTR_H(rstr) ((rstr) |= (1 << 9))
#define SET_RSTR_S(rstr) ((rstr) |= (1 << 8))
#define CLEAR_RSTR_P(rstr) ((rstr) &= ~(1 << 10))
#define CLEAR_RSTR_H(rstr) ((rstr) &= ~(1 << 9))
#define CLEAR_RSTR_S(rstr) ((rstr) &= ~(1 << 8))
#define CLEAR_RSTR_HR(rstr) ((rstr) &= ~(1 << 1))
#define CLEAR_RSTR_SR(rstr) ((rstr) &= ~1)
/* Cutomized hardware get/set functions. */
extern USI frvbf_h_spr_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_spr_set_handler (SIM_CPU *, UINT, USI);
extern USI frvbf_h_gr_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_gr_set_handler (SIM_CPU *, UINT, USI);
extern UHI frvbf_h_gr_hi_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_gr_hi_set_handler (SIM_CPU *, UINT, UHI);
extern UHI frvbf_h_gr_lo_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_gr_lo_set_handler (SIM_CPU *, UINT, UHI);
extern DI frvbf_h_gr_double_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_gr_double_set_handler (SIM_CPU *, UINT, DI);
extern SF frvbf_h_fr_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_fr_set_handler (SIM_CPU *, UINT, SF);
extern DF frvbf_h_fr_double_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_fr_double_set_handler (SIM_CPU *, UINT, DF);
extern USI frvbf_h_fr_int_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_fr_int_set_handler (SIM_CPU *, UINT, USI);
extern DI frvbf_h_cpr_double_get_handler (SIM_CPU *, UINT);
extern void frvbf_h_cpr_double_set_handler (SIM_CPU *, UINT, DI);
extern void frvbf_h_gr_quad_set_handler (SIM_CPU *, UINT, SI *);
extern void frvbf_h_fr_quad_set_handler (SIM_CPU *, UINT, SI *);
extern void frvbf_h_cpr_quad_set_handler (SIM_CPU *, UINT, SI *);
extern void frvbf_h_psr_s_set_handler (SIM_CPU *, BI);
extern USI spr_psr_get_handler (SIM_CPU *);
extern void spr_psr_set_handler (SIM_CPU *, USI);
extern USI spr_tbr_get_handler (SIM_CPU *);
extern void spr_tbr_set_handler (SIM_CPU *, USI);
extern USI spr_bpsr_get_handler (SIM_CPU *);
extern void spr_bpsr_set_handler (SIM_CPU *, USI);
extern USI spr_ccr_get_handler (SIM_CPU *);
extern void spr_ccr_set_handler (SIM_CPU *, USI);
extern void spr_cccr_set_handler (SIM_CPU *, USI);
extern USI spr_cccr_get_handler (SIM_CPU *);
extern USI spr_isr_get_handler (SIM_CPU *);
extern void spr_isr_set_handler (SIM_CPU *, USI);
extern USI spr_sr_get_handler (SIM_CPU *, UINT);
extern void spr_sr_set_handler (SIM_CPU *, UINT, USI);
extern void frvbf_switch_supervisor_user_context (SIM_CPU *);
extern QI frvbf_set_icc_for_shift_left (SIM_CPU *, SI, SI, QI);
extern QI frvbf_set_icc_for_shift_right (SIM_CPU *, SI, SI, QI);
extern void frvbf_signed_integer_divide (SIM_CPU *, SI, SI, int, int);
extern void frvbf_unsigned_integer_divide (SIM_CPU *, USI, USI, int, int);
extern void frvbf_clear_accumulators (SIM_CPU *, SI, int);
extern SI frvbf_scan_result (SIM_CPU *, SI);
extern SI frvbf_cut (SIM_CPU *, SI, SI, SI);
extern SI frvbf_media_cut (SIM_CPU *, DI, SI);
extern SI frvbf_media_cut_ss (SIM_CPU *, DI, SI);
extern void frvbf_media_cop (SIM_CPU *, int);
extern UQI frvbf_cr_logic (SIM_CPU *, SI, UQI, UQI);
extern void frvbf_set_write_next_vliw_addr_to_LR (SIM_CPU *, int);
extern int frvbf_write_next_vliw_addr_to_LR;
extern void frvbf_set_ne_index (SIM_CPU *, int);
extern void frvbf_force_update (SIM_CPU *);
#define GETTWI GETTSI
#define SETTWI SETTSI
#define LEUINT LEUSI
/* Hardware/device support.
??? Will eventually want to move device stuff to config files. */
/* Support for the MCCR register (Cache Control Register) is needed in order
for overlays to work correctly with the scache: cached instructions need
to be flushed when the instruction space is changed at runtime. */
/* These were just copied from another port and are necessary to build, but
but don't appear to be used. */
#define MCCR_ADDR 0xffffffff
#define MCCR_CP 0x80
/* not supported */
#define MCCR_CM0 2
#define MCCR_CM1 1
/* sim_core_attach device argument. */
extern device frv_devices;
/* FIXME: Temporary, until device support ready. */
struct _device { int foo; };
/* maintain the address of the start of the previous VLIW insn sequence. */
extern IADDR previous_vliw_pc;
/* Hardware status. */
#define GET_HSR0() GET_H_SPR (H_SPR_HSR0)
#define SET_HSR0(hsr0) SET_H_SPR (H_SPR_HSR0, (hsr0))
#define GET_HSR0_ICE(hsr0) (((hsr0) >> 31) & 1)
#define SET_HSR0_ICE(hsr0) ((hsr0) |= (1 << 31))
#define CLEAR_HSR0_ICE(hsr0) ((hsr0) &= ~(1 << 31))
#define GET_HSR0_DCE(hsr0) (((hsr0) >> 30) & 1)
#define SET_HSR0_DCE(hsr0) ((hsr0) |= (1 << 30))
#define CLEAR_HSR0_DCE(hsr0) ((hsr0) &= ~(1 << 30))
#define GET_HSR0_CBM(hsr0) (((hsr0) >> 27) & 1)
#define GET_HSR0_RME(hsr0) (((hsr0) >> 22) & 1)
#define GET_HSR0_SA(hsr0) (((hsr0) >> 12) & 1)
#define GET_HSR0_FRN(hsr0) (((hsr0) >> 11) & 1)
#define GET_HSR0_GRN(hsr0) (((hsr0) >> 10) & 1)
#define GET_HSR0_FRHE(hsr0) (((hsr0) >> 9) & 1)
#define GET_HSR0_FRLE(hsr0) (((hsr0) >> 8) & 1)
#define GET_HSR0_GRHE(hsr0) (((hsr0) >> 7) & 1)
#define GET_HSR0_GRLE(hsr0) (((hsr0) >> 6) & 1)
#define GET_IHSR8() GET_H_SPR (H_SPR_IHSR8)
#define GET_IHSR8_NBC(ihsr8) ((ihsr8) & 1)
void frvbf_insn_cache_preload (SIM_CPU *, SI, USI, int);
void frvbf_data_cache_preload (SIM_CPU *, SI, USI, int);
void frvbf_insn_cache_unlock (SIM_CPU *, SI);
void frvbf_data_cache_unlock (SIM_CPU *, SI);
void frvbf_insn_cache_invalidate (SIM_CPU *, SI, int);
void frvbf_data_cache_invalidate (SIM_CPU *, SI, int);
void frvbf_data_cache_flush (SIM_CPU *, SI, int);
/* FR-V Interrupt classes.
These are declared in order of increasing priority. */
enum frv_interrupt_class
{
FRV_EXTERNAL_INTERRUPT,
FRV_SOFTWARE_INTERRUPT,
FRV_PROGRAM_INTERRUPT,
FRV_BREAK_INTERRUPT,
FRV_RESET_INTERRUPT,
NUM_FRV_INTERRUPT_CLASSES
};
/* FR-V Interrupt kinds.
These are declared in order of increasing priority. */
enum frv_interrupt_kind
{
/* External interrupts */
FRV_INTERRUPT_LEVEL_1,
FRV_INTERRUPT_LEVEL_2,
FRV_INTERRUPT_LEVEL_3,
FRV_INTERRUPT_LEVEL_4,
FRV_INTERRUPT_LEVEL_5,
FRV_INTERRUPT_LEVEL_6,
FRV_INTERRUPT_LEVEL_7,
FRV_INTERRUPT_LEVEL_8,
FRV_INTERRUPT_LEVEL_9,
FRV_INTERRUPT_LEVEL_10,
FRV_INTERRUPT_LEVEL_11,
FRV_INTERRUPT_LEVEL_12,
FRV_INTERRUPT_LEVEL_13,
FRV_INTERRUPT_LEVEL_14,
FRV_INTERRUPT_LEVEL_15,
/* Software interrupt */
FRV_TRAP_INSTRUCTION,
/* Program interrupts */
FRV_COMMIT_EXCEPTION,
FRV_DIVISION_EXCEPTION,
FRV_DATA_STORE_ERROR,
FRV_DATA_ACCESS_EXCEPTION,
FRV_DATA_ACCESS_MMU_MISS,
FRV_DATA_ACCESS_ERROR,
FRV_MP_EXCEPTION,
FRV_FP_EXCEPTION,
FRV_MEM_ADDRESS_NOT_ALIGNED,
FRV_REGISTER_EXCEPTION,
FRV_MP_DISABLED,
FRV_FP_DISABLED,
FRV_PRIVILEGED_INSTRUCTION,
FRV_ILLEGAL_INSTRUCTION,
FRV_INSTRUCTION_ACCESS_EXCEPTION,
FRV_INSTRUCTION_ACCESS_ERROR,
FRV_INSTRUCTION_ACCESS_MMU_MISS,
FRV_COMPOUND_EXCEPTION,
/* Break interrupt */
FRV_BREAK_EXCEPTION,
/* Reset interrupt */
FRV_RESET,
NUM_FRV_INTERRUPT_KINDS
};
/* FRV interrupt exception codes */
enum frv_ec
{
FRV_EC_DATA_STORE_ERROR = 0x00,
FRV_EC_INSTRUCTION_ACCESS_MMU_MISS = 0x01,
FRV_EC_INSTRUCTION_ACCESS_ERROR = 0x02,
FRV_EC_INSTRUCTION_ACCESS_EXCEPTION = 0x03,
FRV_EC_PRIVILEGED_INSTRUCTION = 0x04,
FRV_EC_ILLEGAL_INSTRUCTION = 0x05,
FRV_EC_FP_DISABLED = 0x06,
FRV_EC_MP_DISABLED = 0x07,
FRV_EC_MEM_ADDRESS_NOT_ALIGNED = 0x0b,
FRV_EC_REGISTER_EXCEPTION = 0x0c,
FRV_EC_FP_EXCEPTION = 0x0d,
FRV_EC_MP_EXCEPTION = 0x0e,
FRV_EC_DATA_ACCESS_ERROR = 0x10,
FRV_EC_DATA_ACCESS_MMU_MISS = 0x11,
FRV_EC_DATA_ACCESS_EXCEPTION = 0x12,
FRV_EC_DIVISION_EXCEPTION = 0x13,
FRV_EC_COMMIT_EXCEPTION = 0x14,
FRV_EC_NOT_EXECUTED = 0x1f,
FRV_EC_INTERRUPT_LEVEL_1 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_2 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_3 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_4 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_5 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_6 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_7 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_8 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_9 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_10 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_11 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_12 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_13 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_14 = FRV_EC_NOT_EXECUTED,
FRV_EC_INTERRUPT_LEVEL_15 = FRV_EC_NOT_EXECUTED,
FRV_EC_TRAP_INSTRUCTION = FRV_EC_NOT_EXECUTED,
FRV_EC_COMPOUND_EXCEPTION = FRV_EC_NOT_EXECUTED,
FRV_EC_BREAK_EXCEPTION = FRV_EC_NOT_EXECUTED,
FRV_EC_RESET = FRV_EC_NOT_EXECUTED
};
/* FR-V Interrupt.
This struct contains enough information to describe a particular interrupt
occurance. */
struct frv_interrupt
{
enum frv_interrupt_kind kind;
enum frv_ec ec;
enum frv_interrupt_class iclass;
unsigned char deferred;
unsigned char precise;
unsigned char handler_offset;
};
/* FR-V Interrupt table.
Describes the interrupts supported by the FR-V. */
extern struct frv_interrupt frv_interrupt_table[];
/* FR-V Interrupt State.
Interrupts are queued during execution of parallel insns and the interupt(s)
to be handled determined by analysing the queue after each VLIW insn. */
#define FRV_INTERRUPT_QUEUE_SIZE (4 * 4) /* 4 interrupts x 4 insns for now. */
/* register_exception codes */
enum frv_rec
{
FRV_REC_UNIMPLEMENTED = 0,
FRV_REC_UNALIGNED = 1
};
/* instruction_access_exception codes */
enum frv_iaec
{
FRV_IAEC_PROTECT_VIOLATION = 1
};
/* data_access_exception codes */
enum frv_daec
{
FRV_DAEC_PROTECT_VIOLATION = 1
};
/* division_exception ISR codes */
enum frv_dtt
{
FRV_DTT_NO_EXCEPTION = 0,
FRV_DTT_DIVISION_BY_ZERO = 1,
FRV_DTT_OVERFLOW = 2,
FRV_DTT_BOTH = 3
};
/* data written during an insn causing an interrupt */
struct frv_data_written
{
USI words[4]; /* Actual data in words */
int length; /* length of data written */
};
/* fp_exception info */
/* Trap codes for FSR0 and FQ registers. */
enum frv_fsr_traps
{
FSR_INVALID_OPERATION = 0x20,
FSR_OVERFLOW = 0x10,
FSR_UNDERFLOW = 0x08,
FSR_DIVISION_BY_ZERO = 0x04,
FSR_INEXACT = 0x02,
FSR_DENORMAL_INPUT = 0x01,
FSR_NO_EXCEPTION = 0
};
/* Floating point trap types for FSR. */
enum frv_fsr_ftt
{
FTT_NONE = 0,
FTT_IEEE_754_EXCEPTION = 1,
FTT_UNIMPLEMENTED_FPOP = 3,
FTT_SEQUENCE_ERROR = 4,
FTT_INVALID_FR = 6,
FTT_DENORMAL_INPUT = 7
};
struct frv_fp_exception_info
{
enum frv_fsr_traps fsr_mask; /* interrupt code for FSR */
enum frv_fsr_ftt ftt; /* floating point trap type */
};
struct frv_interrupt_queue_element
{
enum frv_interrupt_kind kind; /* kind of interrupt */
IADDR vpc; /* address of insn causing interrupt */
int slot; /* VLIW slot containing the insn. */
USI eaddress; /* address of data access */
union {
enum frv_rec rec; /* register exception code */
enum frv_iaec iaec; /* insn access exception code */
enum frv_daec daec; /* data access exception code */
enum frv_dtt dtt; /* division exception code */
struct frv_fp_exception_info fp_info;
struct frv_data_written data_written;
} u;
};
struct frv_interrupt_timer
{
int enabled;
unsigned value;
unsigned current;
enum frv_interrupt_kind interrupt;
};
struct frv_interrupt_state
{
/* The interrupt queue */
struct frv_interrupt_queue_element queue[FRV_INTERRUPT_QUEUE_SIZE];
int queue_index;
/* interrupt queue element causing imprecise interrupt. */
struct frv_interrupt_queue_element *imprecise_interrupt;
/* interrupt timer. */
struct frv_interrupt_timer timer;
/* The last data written stored as an array of words. */
struct frv_data_written data_written;
/* The vliw slot of the insn causing the interrupt. */
int slot;
/* target register index for non excepting insns. */
#define NE_NOFLAG (-1)
int ne_index;
/* Accumulated NE flags for non excepting floating point insns. */
SI f_ne_flags[2];
};
extern struct frv_interrupt_state frv_interrupt_state;
/* Macros to manipulate the PSR. */
#define GET_PSR() GET_H_SPR (H_SPR_PSR)
#define SET_PSR_ET(psr, et) ( \
(psr) = ((psr) & ~0x1) | ((et) & 0x1) \
)
#define GET_PSR_PS(psr) (((psr) >> 1) & 1)
#define SET_PSR_S(psr, s) ( \
(psr) = ((psr) & ~(0x1 << 2)) | (((s) & 0x1) << 2) \
)
/* Macros to handle the ISR register. */
#define GET_ISR() GET_H_SPR (H_SPR_ISR)
#define SET_ISR(isr) SET_H_SPR (H_SPR_ISR, (isr))
#define GET_ISR_EDE(isr) (((isr) >> 5) & 1)
#define GET_ISR_DTT(isr) (((isr) >> 3) & 3)
#define SET_ISR_DTT(isr, dtt) ( \
(isr) = ((isr) & ~(0x3 << 3)) | (((dtt) & 0x3) << 3) \
)
#define SET_ISR_AEXC(isr) ((isr) |= (1 << 2))
#define GET_ISR_EMAM(isr) ((isr) & 1)
/* Macros to handle exception status registers.
Get and set the hardware directly, since we may be getting/setting fields
which are not accessible to the user. */
#define GET_ESR(index) \
(CPU (h_spr[H_SPR_ESR0 + (index)]))
#define SET_ESR(index, esr) \
(CPU (h_spr[H_SPR_ESR0 + (index)]) = (esr))
#define SET_ESR_VALID(esr) ((esr) |= 1)
#define CLEAR_ESR_VALID(esr) ((esr) &= ~1)
#define SET_ESR_EC(esr, ec) ( \
(esr) = ((esr) & ~(0x1f << 1)) | (((ec) & 0x1f) << 1) \
)
#define SET_ESR_REC(esr, rec) ( \
(esr) = ((esr) & ~(0x3 << 6)) | (((rec) & 0x3) << 6) \
)
#define SET_ESR_IAEC(esr, iaec) ( \
(esr) = ((esr) & ~(0x1 << 8)) | (((iaec) & 0x1) << 8) \
)
#define SET_ESR_DAEC(esr, daec) ( \
(esr) = ((esr) & ~(0x1 << 9)) | (((daec) & 0x1) << 9) \
)
#define SET_ESR_EAV(esr) ((esr) |= (1 << 11))
#define CLEAR_ESR_EAV(esr) ((esr) &= ~(1 << 11))
#define GET_ESR_EDV(esr) (((esr) >> 12) & 1)
#define SET_ESR_EDV(esr) ((esr) |= (1 << 12))
#define CLEAR_ESR_EDV(esr) ((esr) &= ~(1 << 12))
#define GET_ESR_EDN(esr) ( \
((esr) >> 13) & 0xf \
)
#define SET_ESR_EDN(esr, edn) ( \
(esr) = ((esr) & ~(0xf << 13)) | (((edn) & 0xf) << 13) \
)
#define SET_EPCR(index, address) \
(CPU (h_spr[H_SPR_EPCR0 + (index)]) = (address))
#define SET_EAR(index, address) \
(CPU (h_spr[H_SPR_EAR0 + (index)]) = (address))
#define SET_EDR(index, edr) \
(CPU (h_spr[H_SPR_EDR0 + (index)]) = (edr))
#define GET_ESFR(index) \
(CPU (h_spr[H_SPR_ESFR0 + (index)]))
#define SET_ESFR(index, esfr) \
(CPU (h_spr[H_SPR_ESFR0 + (index)]) = (esfr))
#define GET_ESFR_FLAG(findex) ( \
(findex) > 31 ? \
((CPU (h_spr[H_SPR_ESFR0]) >> ((findex)-32)) & 1) \
: \
((CPU (h_spr[H_SPR_ESFR1]) >> (findex)) & 1) \
)
#define SET_ESFR_FLAG(findex) ( \
(findex) > 31 ? \
(CPU (h_spr[H_SPR_ESFR0]) = \
(CPU (h_spr[H_SPR_ESFR0]) | (1 << ((findex)-32))) \
) : \
(CPU (h_spr[H_SPR_ESFR1]) = \
(CPU (h_spr[H_SPR_ESFR1]) | (1 << (findex))) \
) \
)
/* The FSR registers.
Get and set the hardware directly, since we may be getting/setting fields
which are not accessible to the user. */
#define GET_FSR(index) \
(CPU (h_spr[H_SPR_FSR0 + (index)]))
#define SET_FSR(index, fsr) \
(CPU (h_spr[H_SPR_FSR0 + (index)]) = (fsr))
#define GET_FSR_TEM(fsr) ( \
((fsr) >> 24) & 0x3f \
)
#define SET_FSR_QNE(fsr) ((fsr) |= (1 << 20))
#define GET_FSR_QNE(fsr) (((fsr) >> 20) & 1)
#define SET_FSR_FTT(fsr, ftt) ( \
(fsr) = ((fsr) & ~(0x7 << 17)) | (((ftt) & 0x7) << 17) \
)
#define GET_FSR_AEXC(fsr) ( \
((fsr) >> 10) & 0x3f \
)
#define SET_FSR_AEXC(fsr, aexc) ( \
(fsr) = ((fsr) & ~(0x3f << 10)) | (((aexc) & 0x3f) << 10) \
)
/* SIMD instruction exception codes for FQ. */
enum frv_sie
{
SIE_NIL = 0,
SIE_FRi = 1,
SIE_FRi_1 = 2
};
/* MIV field of FQ. */
enum frv_miv
{
MIV_FLOAT = 0,
MIV_MEDIA = 1
};
/* The FQ registers are 64 bits wide and are implemented as 32 bit pairs. The
index here refers to the low order 32 bit element.
Get and set the hardware directly, since we may be getting/setting fields
which are not accessible to the user. */
#define GET_FQ(index) \
(CPU (h_spr[H_SPR_FQST0 + 2 * (index)]))
#define SET_FQ(index, fq) \
(CPU (h_spr[H_SPR_FQST0 + 2 * (index)]) = (fq))
#define SET_FQ_MIV(fq, miv) ( \
(fq) = ((fq) & ~(0x1 << 31)) | (((miv) & 0x1) << 31) \
)
#define SET_FQ_SIE(fq, sie) ( \
(fq) = ((fq) & ~(0x3 << 15)) | (((sie) & 0x3) << 15) \
)
#define SET_FQ_FTT(fq, ftt) ( \
(fq) = ((fq) & ~(0x7 << 7)) | (((ftt) & 0x7) << 7) \
)
#define SET_FQ_CEXC(fq, cexc) ( \
(fq) = ((fq) & ~(0x3f << 1)) | (((cexc) & 0x3f) << 1) \
)
#define GET_FQ_VALID(fq) ((fq) & 1)
#define SET_FQ_VALID(fq) ((fq) |= 1)
#define SET_FQ_OPC(index, insn) \
(CPU (h_spr[H_SPR_FQOP0 + 2 * (index)]) = (insn))
/* mp_exception support. */
/* Media trap types for MSR. */
enum frv_msr_mtt
{
MTT_NONE = 0,
MTT_OVERFLOW = 1,
MTT_ACC_NOT_ALIGNED = 2,
MTT_ACC_NOT_IMPLEMENTED = 2, /* Yes -- same value as MTT_ACC_NOT_ALIGNED. */
MTT_CR_NOT_ALIGNED = 3,
MTT_UNIMPLEMENTED_MPOP = 5,
MTT_INVALID_FR = 6
};
/* Media status registers.
Get and set the hardware directly, since we may be getting/setting fields
which are not accessible to the user. */
#define GET_MSR(index) \
(CPU (h_spr[H_SPR_MSR0 + (index)]))
#define SET_MSR(index, msr) \
(CPU (h_spr[H_SPR_MSR0 + (index)]) = (msr))
#define GET_MSR_AOVF(msr) ((msr) & 1)
#define SET_MSR_AOVF(msr) ((msr) |= 1)
#define GET_MSR_OVF(msr) ( \
((msr) >> 1) & 0x1 \
)
#define SET_MSR_OVF(msr) ( \
(msr) |= (1 << 1) \
)
#define CLEAR_MSR_OVF(msr) ( \
(msr) &= ~(1 << 1) \
)
#define OR_MSR_SIE(msr, sie) ( \
(msr) |= (((sie) & 0xf) << 2) \
)
#define CLEAR_MSR_SIE(msr) ( \
(msr) &= ~(0xf << 2) \
)
#define GET_MSR_MTT(msr) ( \
((msr) >> 12) & 0x7 \
)
#define SET_MSR_MTT(msr, mtt) ( \
(msr) = ((msr) & ~(0x7 << 12)) | (((mtt) & 0x7) << 12) \
)
#define GET_MSR_EMCI(msr) ( \
((msr) >> 24) & 0x1 \
)
#define GET_MSR_SRDAV(msr) ( \
((msr) >> 28) & 0x1 \
)
#define GET_MSR_RDAV(msr) ( \
((msr) >> 29) & 0x1 \
)
#define GET_MSR_RD(msr) ( \
((msr) >> 30) & 0x3 \
)
void frvbf_media_register_not_aligned (SIM_CPU *);
void frvbf_media_acc_not_aligned (SIM_CPU *);
void frvbf_media_cr_not_aligned (SIM_CPU *);
void frvbf_media_overflow (SIM_CPU *, int);
/* Functions for queuing and processing interrupts. */
struct frv_interrupt_queue_element *
frv_queue_break_interrupt (SIM_CPU *);
struct frv_interrupt_queue_element *
frv_queue_software_interrupt (SIM_CPU *, SI);
struct frv_interrupt_queue_element *
frv_queue_program_interrupt (SIM_CPU *, enum frv_interrupt_kind);
struct frv_interrupt_queue_element *
frv_queue_external_interrupt (SIM_CPU *, enum frv_interrupt_kind);
struct frv_interrupt_queue_element *
frv_queue_illegal_instruction_interrupt (SIM_CPU *, const CGEN_INSN *);
struct frv_interrupt_queue_element *
frv_queue_non_implemented_instruction_interrupt (SIM_CPU *, const CGEN_INSN *);
struct frv_interrupt_queue_element *
frv_queue_register_exception_interrupt (SIM_CPU *, enum frv_rec);
struct frv_interrupt_queue_element *
frv_queue_mem_address_not_aligned_interrupt (SIM_CPU *, USI);
struct frv_interrupt_queue_element *
frv_queue_data_access_error_interrupt (SIM_CPU *, USI);
struct frv_interrupt_queue_element *
frv_queue_instruction_access_error_interrupt (SIM_CPU *);
struct frv_interrupt_queue_element *
frv_queue_instruction_access_exception_interrupt (SIM_CPU *);
struct frv_interrupt_queue_element *
frv_queue_fp_exception_interrupt (SIM_CPU *, struct frv_fp_exception_info *);
enum frv_dtt frvbf_division_exception (SIM_CPU *, enum frv_dtt, int, int);
struct frv_interrupt_queue_element *
frv_queue_interrupt (SIM_CPU *, enum frv_interrupt_kind);
void
frv_set_interrupt_queue_slot (SIM_CPU *, struct frv_interrupt_queue_element *);
void frv_set_mp_exception_registers (SIM_CPU *, enum frv_msr_mtt, int);
void frv_detect_insn_access_interrupts (SIM_CPU *, SCACHE *);
void frv_process_interrupts (SIM_CPU *);
void frv_break_interrupt (SIM_CPU *, struct frv_interrupt *, IADDR);
void frv_non_operating_interrupt (SIM_CPU *, enum frv_interrupt_kind, IADDR);
void frv_program_interrupt (
SIM_CPU *, struct frv_interrupt_queue_element *, IADDR
);
void frv_software_interrupt (
SIM_CPU *, struct frv_interrupt_queue_element *, IADDR
);
void frv_external_interrupt (
SIM_CPU *, struct frv_interrupt_queue_element *, IADDR
);
void frv_program_or_software_interrupt (
SIM_CPU *, struct frv_interrupt *, IADDR
);
void frv_clear_interrupt_classes (
enum frv_interrupt_class, enum frv_interrupt_class
);
void
frv_save_data_written_for_interrupts (SIM_CPU *, CGEN_WRITE_QUEUE_ELEMENT *);
/* Special purpose traps. */
#define TRAP_SYSCALL 0x80
#define TRAP_BREAKPOINT 0x81
#define TRAP_REGDUMP1 0x82
#define TRAP_REGDUMP2 0x83
/* Handle the trap insns */
void frv_itrap (SIM_CPU *, PCADDR, USI, int);
void frv_mtrap (SIM_CPU *);
/* Handle the break insn. */
void frv_break (SIM_CPU *);
/* Handle the rett insn. */
USI frv_rett (SIM_CPU *current_cpu, PCADDR pc, BI debug_field);
/* Parallel write queue flags. */
#define FRV_WRITE_QUEUE_FORCE_WRITE 1
#define CGEN_WRITE_QUEUE_ELEMENT_PIPE(element) CGEN_WRITE_QUEUE_ELEMENT_WORD1 (element)
/* Functions and macros for handling non-excepting instruction side effects.
Get and set the hardware directly, since we may be getting/setting fields
which are not accessible to the user. */
#define GET_NECR() (GET_H_SPR (H_SPR_NECR))
#define GET_NECR_ELOS(necr) (((necr) >> 6) & 1)
#define GET_NECR_NEN(necr) (((necr) >> 1) & 0x1f)
#define GET_NECR_VALID(necr) (((necr) ) & 1)
#define NO_NESR (-1)
/* NESR field values. See Tables 30-33 in section 4.4.2.1 of the FRV
Architecture volume 1. */
#define NESR_MEM_ADDRESS_NOT_ALIGNED 0x0b
#define NESR_REGISTER_NOT_ALIGNED 0x1
#define NESR_UQI_SIZE 0
#define NESR_QI_SIZE 1
#define NESR_UHI_SIZE 2
#define NESR_HI_SIZE 3
#define NESR_SI_SIZE 4
#define NESR_DI_SIZE 5
#define NESR_XI_SIZE 6
#define GET_NESR(index) GET_H_SPR (H_SPR_NESR0 + (index))
#define SET_NESR(index, value) ( \
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, \
H_SPR_NESR0 + (index), (value)), \
frvbf_force_update (current_cpu) \
)
#define GET_NESR_VALID(nesr) ((nesr) & 1)
#define SET_NESR_VALID(nesr) ((nesr) |= 1)
#define SET_NESR_EAV(nesr) ((nesr) |= (1 << 31))
#define GET_NESR_FR(nesr) (((nesr) >> 30) & 1)
#define SET_NESR_FR(nesr) ((nesr) |= (1 << 30))
#define CLEAR_NESR_FR(nesr) ((nesr) &= ~(1 << 30))
#define GET_NESR_DRN(nesr) (((nesr) >> 24) & 0x3f)
#define SET_NESR_DRN(nesr, drn) ( \
(nesr) = ((nesr) & ~(0x3f << 24)) | (((drn) & 0x3f) << 24) \
)
#define SET_NESR_SIZE(nesr, data_size) ( \
(nesr) = ((nesr) & ~(0x7 << 21)) | (((data_size) & 0x7) << 21) \
)
#define SET_NESR_NEAN(nesr, index) ( \
(nesr) = ((nesr) & ~(0x1f << 10)) | (((index) & 0x1f) << 10) \
)
#define GET_NESR_DAEC(nesr) (((nesr) >> 9) & 1)
#define SET_NESR_DAEC(nesr, daec) ( \
(nesr) = ((nesr) & ~(1 << 9)) | (((daec) & 1) << 9) \
)
#define GET_NESR_REC(nesr) (((nesr) >> 6) & 3)
#define SET_NESR_REC(nesr, rec) ( \
(nesr) = ((nesr) & ~(3 << 6)) | (((rec) & 3) << 6) \
)
#define GET_NESR_EC(nesr) (((nesr) >> 1) & 0x1f)
#define SET_NESR_EC(nesr, ec) ( \
(nesr) = ((nesr) & ~(0x1f << 1)) | (((ec) & 0x1f) << 1) \
)
#define SET_NEEAR(index, address) ( \
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, \
H_SPR_NEEAR0 + (index), (address)), \
frvbf_force_update (current_cpu) \
)
#define GET_NE_FLAGS(flags, NE_base) ( \
(flags)[0] = GET_H_SPR ((NE_base)), \
(flags)[1] = GET_H_SPR ((NE_base) + 1) \
)
#define SET_NE_FLAGS(NE_base, flags) ( \
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, (NE_base), \
(flags)[0]), \
frvbf_force_update (current_cpu), \
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, (NE_base) + 1, \
(flags)[1]), \
frvbf_force_update (current_cpu) \
)
#define GET_NE_FLAG(flags, index) ( \
(index) > 31 ? \
((flags[0] >> ((index) - 32)) & 1) \
: \
((flags[1] >> (index)) & 1) \
)
#define SET_NE_FLAG(flags, index) ( \
(index) > 31 ? \
((flags)[0] |= (1 << ((index) - 32))) \
: \
((flags)[1] |= (1 << (index))) \
)
#define CLEAR_NE_FLAG(flags, index) ( \
(index) > 31 ? \
((flags)[0] &= ~(1 << ((index) - 32))) \
: \
((flags)[1] &= ~(1 << (index))) \
)
BI frvbf_check_non_excepting_load (SIM_CPU *, SI, SI, SI, SI, QI, BI);
void frvbf_check_recovering_store (SIM_CPU *, PCADDR, SI, int, int);
void frvbf_clear_ne_flags (SIM_CPU *, SI, BI);
void frvbf_commit (SIM_CPU *, SI, BI);
void frvbf_fpu_error (CGEN_FPU *, int);
void frv_vliw_setup_insn (SIM_CPU *, const CGEN_INSN *);
extern int insns_in_slot[];
#define COUNT_INSNS_IN_SLOT(slot) \
{ \
if (WITH_PROFILE_MODEL_P) \
++insns_in_slot[slot]; \
}
#define INSNS_IN_SLOT(slot) (insns_in_slot[slot])
/* Multiple loads and stores. */
void frvbf_load_multiple_GR (SIM_CPU *, PCADDR, SI, SI, int);
void frvbf_load_multiple_FRint (SIM_CPU *, PCADDR, SI, SI, int);
void frvbf_load_multiple_CPR (SIM_CPU *, PCADDR, SI, SI, int);
void frvbf_store_multiple_GR (SIM_CPU *, PCADDR, SI, SI, int);
void frvbf_store_multiple_FRint (SIM_CPU *, PCADDR, SI, SI, int);
void frvbf_store_multiple_CPR (SIM_CPU *, PCADDR, SI, SI, int);
/* Memory and cache support. */
QI frvbf_read_mem_QI (SIM_CPU *, IADDR, SI);
UQI frvbf_read_mem_UQI (SIM_CPU *, IADDR, SI);
HI frvbf_read_mem_HI (SIM_CPU *, IADDR, SI);
UHI frvbf_read_mem_UHI (SIM_CPU *, IADDR, SI);
SI frvbf_read_mem_SI (SIM_CPU *, IADDR, SI);
SI frvbf_read_mem_WI (SIM_CPU *, IADDR, SI);
DI frvbf_read_mem_DI (SIM_CPU *, IADDR, SI);
DF frvbf_read_mem_DF (SIM_CPU *, IADDR, SI);
USI frvbf_read_imem_USI (SIM_CPU *, PCADDR);
void frvbf_write_mem_QI (SIM_CPU *, IADDR, SI, QI);
void frvbf_write_mem_UQI (SIM_CPU *, IADDR, SI, UQI);
void frvbf_write_mem_HI (SIM_CPU *, IADDR, SI, HI);
void frvbf_write_mem_UHI (SIM_CPU *, IADDR, SI, UHI);
void frvbf_write_mem_SI (SIM_CPU *, IADDR, SI, SI);
void frvbf_write_mem_WI (SIM_CPU *, IADDR, SI, SI);
void frvbf_write_mem_DI (SIM_CPU *, IADDR, SI, DI);
void frvbf_write_mem_DF (SIM_CPU *, IADDR, SI, DF);
void frvbf_mem_set_QI (SIM_CPU *, IADDR, SI, QI);
void frvbf_mem_set_HI (SIM_CPU *, IADDR, SI, HI);
void frvbf_mem_set_SI (SIM_CPU *, IADDR, SI, SI);
void frvbf_mem_set_DI (SIM_CPU *, IADDR, SI, DI);
void frvbf_mem_set_DF (SIM_CPU *, IADDR, SI, DF);
void frvbf_mem_set_XI (SIM_CPU *, IADDR, SI, SI *);
void frv_set_write_queue_slot (SIM_CPU *current_cpu);
/* FRV specific options. */
extern const OPTION frv_options[];
#endif /* FRV_SIM_H */

1419
sim/frv/frv.c Normal file

File diff suppressed because it is too large Load Diff

1329
sim/frv/interrupts.c Normal file

File diff suppressed because it is too large Load Diff

750
sim/frv/memory.c Normal file
View File

@ -0,0 +1,750 @@
/* frv memory model.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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 WANT_CPU frvbf
#define WANT_CPU_FRVBF
#include "sim-main.h"
#include "cgen-mem.h"
#include "bfd.h"
/* Check for alignment and access restrictions. Return the corrected address.
*/
static SI
fr400_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
/* Check access restrictions for double word loads only. */
if (align_mask == 7)
{
if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
frv_queue_data_access_error_interrupt (current_cpu, address);
}
return address;
}
static SI
fr500_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
if (address & align_mask)
{
frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
address &= ~align_mask;
}
if ((USI)address >= 0xfeff0600 && (USI)address <= 0xfeff7fff
|| (USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff)
frv_queue_data_access_error_interrupt (current_cpu, address);
return address;
}
static SI
check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
SIM_DESC sd = CPU_STATE (current_cpu);
switch (STATE_ARCHITECTURE (sd)->mach)
{
case bfd_mach_fr400:
address = fr400_check_data_read_address (current_cpu, address,
align_mask);
break;
case bfd_mach_frvtomcat:
case bfd_mach_fr500:
case bfd_mach_frv:
address = fr500_check_data_read_address (current_cpu, address,
align_mask);
break;
default:
break;
}
return address;
}
static SI
fr400_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
if (address & align_mask)
{
/* Make sure that this exception is not masked. */
USI isr = GET_ISR ();
if (! GET_ISR_EMAM (isr))
{
/* Bad alignment causes a data_access_error on fr400. */
frv_queue_data_access_error_interrupt (current_cpu, address);
}
address &= ~align_mask;
}
/* Nothing to check. */
return address;
}
static SI
fr500_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
if ((USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff
|| (USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
|| (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
|| (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
frv_queue_data_access_exception_interrupt (current_cpu);
return address;
}
static SI
check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
SIM_DESC sd = CPU_STATE (current_cpu);
switch (STATE_ARCHITECTURE (sd)->mach)
{
case bfd_mach_fr400:
address = fr400_check_readwrite_address (current_cpu, address,
align_mask);
break;
case bfd_mach_frvtomcat:
case bfd_mach_fr500:
case bfd_mach_frv:
address = fr500_check_readwrite_address (current_cpu, address,
align_mask);
break;
default:
break;
}
return address;
}
static PCADDR
fr400_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
int align_mask)
{
if (address & align_mask)
{
frv_queue_instruction_access_error_interrupt (current_cpu);
address &= ~align_mask;
}
else if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
frv_queue_instruction_access_error_interrupt (current_cpu);
return address;
}
static PCADDR
fr500_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
int align_mask)
{
if (address & align_mask)
{
frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
address &= ~align_mask;
}
if ((USI)address >= 0xfeff0600 && (USI)address <= 0xfeff7fff
|| (USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff)
frv_queue_instruction_access_error_interrupt (current_cpu);
else if ((USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
|| (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
|| (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
frv_queue_instruction_access_exception_interrupt (current_cpu);
else
{
USI hsr0 = GET_HSR0 ();
if (! GET_HSR0_RME (hsr0)
&& (USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff)
frv_queue_instruction_access_exception_interrupt (current_cpu);
}
return address;
}
static PCADDR
check_insn_read_address (SIM_CPU *current_cpu, PCADDR address, int align_mask)
{
SIM_DESC sd = CPU_STATE (current_cpu);
switch (STATE_ARCHITECTURE (sd)->mach)
{
case bfd_mach_fr400:
address = fr400_check_insn_read_address (current_cpu, address,
align_mask);
break;
case bfd_mach_frvtomcat:
case bfd_mach_fr500:
case bfd_mach_frv:
address = fr500_check_insn_read_address (current_cpu, address,
align_mask);
break;
default:
break;
}
return address;
}
/* Memory reads. */
QI
frvbf_read_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0 = GET_HSR0 ();
FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 0);
address = check_readwrite_address (current_cpu, address, 0);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 1;
CPU_LOAD_SIGNED (current_cpu) = 1;
return 0xb7; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, QI, 1);
}
return GETMEMQI (current_cpu, pc, address);
}
UQI
frvbf_read_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0 = GET_HSR0 ();
FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 0);
address = check_readwrite_address (current_cpu, address, 0);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 1;
CPU_LOAD_SIGNED (current_cpu) = 0;
return 0xb7; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, UQI, 1);
}
return GETMEMUQI (current_cpu, pc, address);
}
HI
frvbf_read_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0;
FRV_CACHE *cache;
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 1);
address = check_readwrite_address (current_cpu, address, 1);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
hsr0 = GET_HSR0 ();
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 2;
CPU_LOAD_SIGNED (current_cpu) = 1;
return 0xb711; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, HI, 2);
}
return GETMEMHI (current_cpu, pc, address);
}
UHI
frvbf_read_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0;
FRV_CACHE *cache;
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 1);
address = check_readwrite_address (current_cpu, address, 1);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
hsr0 = GET_HSR0 ();
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 2;
CPU_LOAD_SIGNED (current_cpu) = 0;
return 0xb711; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, UHI, 2);
}
return GETMEMUHI (current_cpu, pc, address);
}
SI
frvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
FRV_CACHE *cache;
USI hsr0;
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 3);
address = check_readwrite_address (current_cpu, address, 3);
hsr0 = GET_HSR0 ();
cache = CPU_DATA_CACHE (current_cpu);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 4;
return 0x37111319; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, SI, 4);
}
return GETMEMSI (current_cpu, pc, address);
}
SI
frvbf_read_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
return frvbf_read_mem_SI (current_cpu, pc, address);
}
DI
frvbf_read_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0;
FRV_CACHE *cache;
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 7);
address = check_readwrite_address (current_cpu, address, 7);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
hsr0 = GET_HSR0 ();
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 8;
return 0x37111319; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, DI, 8);
}
return GETMEMDI (current_cpu, pc, address);
}
DF
frvbf_read_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address)
{
USI hsr0;
FRV_CACHE *cache;
/* Check for access exceptions. */
address = check_data_read_address (current_cpu, address, 7);
address = check_readwrite_address (current_cpu, address, 7);
/* If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
hsr0 = GET_HSR0 ();
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
CPU_LOAD_ADDRESS (current_cpu) = address;
CPU_LOAD_LENGTH (current_cpu) = 8;
return 0x37111319; /* any random value */
}
if (GET_HSR0_DCE (hsr0))
{
int cycles;
cycles = frv_cache_read (cache, 0, address);
if (cycles != 0)
return CACHE_RETURN_DATA (cache, 0, address, DF, 8);
}
return GETMEMDF (current_cpu, pc, address);
}
USI
frvbf_read_imem_USI (SIM_CPU *current_cpu, PCADDR vpc)
{
USI hsr0;
vpc = check_insn_read_address (current_cpu, vpc, 3);
hsr0 = GET_HSR0 ();
if (GET_HSR0_ICE (hsr0))
{
FRV_CACHE *cache;
USI value;
/* We don't want this to show up in the cache statistics. That read
is done in frvbf_simulate_insn_prefetch. So read the cache or memory
passively here. */
cache = CPU_INSN_CACHE (current_cpu);
if (frv_cache_read_passive_SI (cache, vpc, &value))
return value;
}
return sim_core_read_unaligned_4 (current_cpu, vpc, read_map, vpc);
}
static SI
fr400_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
if (address & align_mask)
{
/* On the fr400, this causes a data_access_error. */
/* Make sure that this exception is not masked. */
USI isr = GET_ISR ();
if (! GET_ISR_EMAM (isr))
{
/* Bad alignment causes a data_access_error on fr400. */
frv_queue_data_access_error_interrupt (current_cpu, address);
}
address &= ~align_mask;
}
if (align_mask == 7
&& address >= 0xfe800000 && address <= 0xfeffffff)
frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
return address;
}
static SI
fr500_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
if (address & align_mask)
{
struct frv_interrupt_queue_element *item =
frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
/* Record the correct vliw slot with the interrupt. */
if (item != NULL)
item->slot = frv_interrupt_state.slot;
address &= ~align_mask;
}
if (address >= 0xfeff0600 && address <= 0xfeff7fff
|| address >= 0xfe800000 && address <= 0xfefeffff)
frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
return address;
}
static SI
check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
{
SIM_DESC sd = CPU_STATE (current_cpu);
switch (STATE_ARCHITECTURE (sd)->mach)
{
case bfd_mach_fr400:
address = fr400_check_write_address (current_cpu, address, align_mask);
break;
case bfd_mach_frvtomcat:
case bfd_mach_fr500:
case bfd_mach_frv:
address = fr500_check_write_address (current_cpu, address, align_mask);
break;
default:
break;
}
return address;
}
void
frvbf_write_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
{
USI hsr0;
hsr0 = GET_HSR0 ();
if (GET_HSR0_DCE (hsr0))
sim_queue_fn_mem_qi_write (current_cpu, frvbf_mem_set_QI, address, value);
else
sim_queue_mem_qi_write (current_cpu, address, value);
frv_set_write_queue_slot (current_cpu);
}
void
frvbf_write_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address, UQI value)
{
frvbf_write_mem_QI (current_cpu, pc, address, value);
}
void
frvbf_write_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
{
USI hsr0;
hsr0 = GET_HSR0 ();
if (GET_HSR0_DCE (hsr0))
sim_queue_fn_mem_hi_write (current_cpu, frvbf_mem_set_HI, address, value);
else
sim_queue_mem_hi_write (current_cpu, address, value);
frv_set_write_queue_slot (current_cpu);
}
void
frvbf_write_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address, UHI value)
{
frvbf_write_mem_HI (current_cpu, pc, address, value);
}
void
frvbf_write_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
{
USI hsr0;
hsr0 = GET_HSR0 ();
if (GET_HSR0_DCE (hsr0))
sim_queue_fn_mem_si_write (current_cpu, frvbf_mem_set_SI, address, value);
else
sim_queue_mem_si_write (current_cpu, address, value);
frv_set_write_queue_slot (current_cpu);
}
void
frvbf_write_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
{
frvbf_write_mem_SI (current_cpu, pc, address, value);
}
void
frvbf_write_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
{
USI hsr0;
hsr0 = GET_HSR0 ();
if (GET_HSR0_DCE (hsr0))
sim_queue_fn_mem_di_write (current_cpu, frvbf_mem_set_DI, address, value);
else
sim_queue_mem_di_write (current_cpu, address, value);
frv_set_write_queue_slot (current_cpu);
}
void
frvbf_write_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
{
USI hsr0;
hsr0 = GET_HSR0 ();
if (GET_HSR0_DCE (hsr0))
sim_queue_fn_mem_df_write (current_cpu, frvbf_mem_set_DF, address, value);
else
sim_queue_mem_df_write (current_cpu, address, value);
frv_set_write_queue_slot (current_cpu);
}
/* Memory writes. These do the actual writing through the cache. */
void
frvbf_mem_set_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
{
FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
/* Check for access errors. */
address = check_write_address (current_cpu, address, 0);
address = check_readwrite_address (current_cpu, address, 0);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot, (char *)&value,
sizeof (value));
}
else
frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
void
frvbf_mem_set_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
{
FRV_CACHE *cache;
/* Check for access errors. */
address = check_write_address (current_cpu, address, 1);
address = check_readwrite_address (current_cpu, address, 1);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
value = H2T_2 (value);
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot,
(char *)&value, sizeof (value));
}
else
frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
void
frvbf_mem_set_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
{
FRV_CACHE *cache;
/* Check for access errors. */
address = check_write_address (current_cpu, address, 3);
address = check_readwrite_address (current_cpu, address, 3);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
cache = CPU_DATA_CACHE (current_cpu);
value = H2T_4 (value);
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot,
(char *)&value, sizeof (value));
}
else
frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
void
frvbf_mem_set_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
{
FRV_CACHE *cache;
/* Check for access errors. */
address = check_write_address (current_cpu, address, 7);
address = check_readwrite_address (current_cpu, address, 7);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
value = H2T_8 (value);
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot,
(char *)&value, sizeof (value));
}
else
frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
void
frvbf_mem_set_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
{
FRV_CACHE *cache;
/* Check for access errors. */
address = check_write_address (current_cpu, address, 7);
address = check_readwrite_address (current_cpu, address, 7);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
value = H2T_8 (value);
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot,
(char *)&value, sizeof (value));
}
else
frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
void
frvbf_mem_set_XI (SIM_CPU *current_cpu, IADDR pc, SI address, SI *value)
{
int i;
FRV_CACHE *cache;
/* Check for access errors. */
address = check_write_address (current_cpu, address, 0xf);
address = check_readwrite_address (current_cpu, address, 0xf);
/* TODO -- reverse word order as well? */
for (i = 0; i < 4; ++i)
value[i] = H2T_4 (value[i]);
/* If we need to count cycles, then submit the write request to the cache
and let it prioritize the request. Otherwise perform the write now. */
cache = CPU_DATA_CACHE (current_cpu);
if (model_insn)
{
int slot = UNIT_I0;
frv_cache_request_store (cache, address, slot, (char*)value, 16);
}
else
frv_cache_write (cache, address, (char*)value, 16);
}
/* Record the current VLIW slot on the element at the top of the write queue.
*/
void
frv_set_write_queue_slot (SIM_CPU *current_cpu)
{
FRV_VLIW *vliw = CPU_VLIW (current_cpu);
int slot = vliw->next_slot - 1;
CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
int ix = CGEN_WRITE_QUEUE_INDEX (q) - 1;
CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, ix);
CGEN_WRITE_QUEUE_ELEMENT_PIPE (item) = (*vliw->current_vliw)[slot];
}

514
sim/frv/mloop.in Normal file
View File

@ -0,0 +1,514 @@
# Simulator main loop for frv. -*- C -*-
# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
# Contributed by Red Hat.
#
# This file is part of the GNU Simulators.
#
# 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.
# Syntax:
# /bin/sh mainloop.in command
#
# Command is one of:
#
# init
# support
# extract-{simple,scache,pbb}
# {full,fast}-exec-{simple,scache,pbb}
#
# A target need only provide a "full" version of one of simple,scache,pbb.
# If the target wants it can also provide a fast version of same.
# It can't provide more than this.
# ??? After a few more ports are done, revisit.
# Will eventually need to machine generate a lot of this.
case "x$1" in
xsupport)
cat <<EOF
static INLINE const IDESC *
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
int fast_p)
{
const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
@cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
if (! fast_p)
{
int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
@cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
}
return id;
}
static INLINE SEM_PC
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
{
SEM_PC vpc;
/* Force gr0 to zero before every insn. */
@cpu@_h_gr_set (current_cpu, 0, 0);
if (fast_p)
{
vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
}
else
{
ARGBUF *abuf = &sc->argbuf;
const IDESC *idesc = abuf->idesc;
#if WITH_SCACHE_PBB
int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
#else
int virtual_p = 0;
#endif
if (! virtual_p)
{
/* FIXME: call x-before */
if (ARGBUF_PROFILE_P (abuf))
PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
/* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))
{
@cpu@_model_insn_before (current_cpu, sc->first_insn_p);
model_insn = FRV_INSN_MODEL_PASS_1;
if (idesc->timing->model_fn != NULL)
(*idesc->timing->model_fn) (current_cpu, sc);
}
else
model_insn = FRV_INSN_NO_MODELING;
TRACE_INSN_INIT (current_cpu, abuf, 1);
TRACE_INSN (current_cpu, idesc->idata,
(const struct argbuf *) abuf, abuf->addr);
}
#if WITH_SCACHE
vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
#else
vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
#endif
if (! virtual_p)
{
/* FIXME: call x-after */
if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))
{
int cycles;
if (idesc->timing->model_fn != NULL)
{
model_insn = FRV_INSN_MODEL_PASS_2;
cycles = (*idesc->timing->model_fn) (current_cpu, sc);
}
else
cycles = 1;
@cpu@_model_insn_after (current_cpu, sc->last_insn_p, cycles);
}
TRACE_INSN_FINI (current_cpu, abuf, 1);
}
}
return vpc;
}
static void
@cpu@_parallel_write_init (SIM_CPU *current_cpu)
{
CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
CGEN_WRITE_QUEUE_CLEAR (q);
previous_vliw_pc = CPU_PC_GET(current_cpu);
frv_interrupt_state.f_ne_flags[0] = 0;
frv_interrupt_state.f_ne_flags[1] = 0;
frv_interrupt_state.imprecise_interrupt = NULL;
}
static void
@cpu@_parallel_write_queued (SIM_CPU *current_cpu)
{
int i;
FRV_VLIW *vliw = CPU_VLIW (current_cpu);
CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
/* Loop over the queued writes, executing them. Set the pc to the address
of the insn which queued each write for the proper context in case an
interrupt is caused. Restore the proper pc after the writes are
completed. */
IADDR save_pc = CPU_PC_GET (current_cpu);
IADDR new_pc = save_pc;
int branch_taken = 0;
int limit = CGEN_WRITE_QUEUE_INDEX (q);
frv_interrupt_state.data_written.length = 0;
for (i = 0; i < limit; ++i)
{
CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, i);
/* If an imprecise interrupt was generated, then, check whether the
result should still be written. */
if (frv_interrupt_state.imprecise_interrupt != NULL)
{
/* Only check writes by the insn causing the exception. */
if (CGEN_WRITE_QUEUE_ELEMENT_IADDR (item)
== frv_interrupt_state.imprecise_interrupt->vpc)
{
/* Execute writes of floating point operations resulting in
overflow, underflow or inexact. */
if (frv_interrupt_state.imprecise_interrupt->kind
== FRV_FP_EXCEPTION)
{
if ((frv_interrupt_state.imprecise_interrupt
->u.fp_info.fsr_mask
& ~(FSR_INEXACT | FSR_OVERFLOW | FSR_UNDERFLOW)))
continue; /* Don't execute */
}
/* Execute writes marked as 'forced'. */
else if (! (CGEN_WRITE_QUEUE_ELEMENT_FLAGS (item)
& FRV_WRITE_QUEUE_FORCE_WRITE))
continue; /* Don't execute */
}
}
/* Only execute the first branch on the queue. */
if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE
|| CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_FN_PC_WRITE)
{
if (branch_taken)
continue;
branch_taken = 1;
if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE)
new_pc = item->kinds.pc_write.value;
else
new_pc = item->kinds.fn_pc_write.value;
}
CPU_PC_SET (current_cpu, CGEN_WRITE_QUEUE_ELEMENT_IADDR (item));
frv_save_data_written_for_interrupts (current_cpu, item);
cgen_write_queue_element_execute (current_cpu, item);
}
/* Update the LR with the address of the next insn if the flag is set.
This flag gets set in frvbf_set_write_next_vliw_to_LR by the JMPL,
JMPIL and CALL insns. */
if (frvbf_write_next_vliw_addr_to_LR)
{
frvbf_h_spr_set_handler (current_cpu, H_SPR_LR, save_pc);
frvbf_write_next_vliw_addr_to_LR = 0;
}
CPU_PC_SET (current_cpu, new_pc);
CGEN_WRITE_QUEUE_CLEAR (q);
}
void
@cpu@_perform_writeback (SIM_CPU *current_cpu)
{
@cpu@_parallel_write_queued (current_cpu);
}
static unsigned cache_reqno = 0x80000000; /* Start value is for debugging. */
#if 0 /* experimental */
/* FR400 has single prefetch. */
static void
fr400_simulate_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc)
{
int cur_ix;
FRV_CACHE *cache;
/* The cpu receives 8 bytes worth of insn data for each fetch aligned
on 8 byte boundary. */
#define FR400_FETCH_SIZE 8
cur_ix = LS;
vpc &= ~(FR400_FETCH_SIZE - 1);
cache = CPU_INSN_CACHE (current_cpu);
/* Request a load of the current address buffer, if necessary. */
if (frv_insn_fetch_buffer[cur_ix].address != vpc)
{
frv_insn_fetch_buffer[cur_ix].address = vpc;
frv_insn_fetch_buffer[cur_ix].reqno = cache_reqno++;
if (FRV_COUNT_CYCLES (current_cpu, 1))
frv_cache_request_load (cache, frv_insn_fetch_buffer[cur_ix].reqno,
frv_insn_fetch_buffer[cur_ix].address,
UNIT_I0 + cur_ix);
}
/* Wait for the current address buffer to be loaded, if necessary. */
if (FRV_COUNT_CYCLES (current_cpu, 1))
{
FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
int wait;
/* Account for any branch penalty. */
if (ps->branch_penalty > 0 && ! ps->past_first_p)
{
frv_model_advance_cycles (current_cpu, ps->branch_penalty);
frv_model_trace_wait_cycles (current_cpu, ps->branch_penalty,
"Branch penalty:");
ps->branch_penalty = 0;
}
/* Account for insn fetch latency. */
wait = 0;
while (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
{
frv_model_advance_cycles (current_cpu, 1);
++wait;
}
frv_model_trace_wait_cycles (current_cpu, wait, "Insn fetch:");
return;
}
/* Otherwise just load the insns directly from the cache.
*/
if (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
{
frv_cache_read (cache, cur_ix, vpc);
frv_insn_fetch_buffer[cur_ix].reqno = NO_REQNO;
}
}
#endif /* experimental */
/* FR500 has dual prefetch. */
static void
simulate_dual_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc, int fetch_size)
{
int i;
int cur_ix, pre_ix;
SI pre_address;
FRV_CACHE *cache;
/* See if the pc is within the addresses specified by either of the
fetch buffers. If so, that will be the current buffer. Otherwise,
arbitrarily select the LD buffer as the current one since it gets
priority in the case of interfering load requests. */
cur_ix = LD;
vpc &= ~(fetch_size - 1);
for (i = LS; i < FRV_CACHE_PIPELINES; ++i)
{
if (frv_insn_fetch_buffer[i].address == vpc)
{
cur_ix = i;
break;
}
}
cache = CPU_INSN_CACHE (current_cpu);
/* Request a load of the current address buffer, if necessary. */
if (frv_insn_fetch_buffer[cur_ix].address != vpc)
{
frv_insn_fetch_buffer[cur_ix].address = vpc;
frv_insn_fetch_buffer[cur_ix].reqno = cache_reqno++;
if (FRV_COUNT_CYCLES (current_cpu, 1))
frv_cache_request_load (cache, frv_insn_fetch_buffer[cur_ix].reqno,
frv_insn_fetch_buffer[cur_ix].address,
UNIT_I0 + cur_ix);
}
/* If the prefetch buffer does not represent the next sequential address, then
request a load of the next sequential address. */
pre_ix = (cur_ix + 1) % FRV_CACHE_PIPELINES;
pre_address = vpc + fetch_size;
if (frv_insn_fetch_buffer[pre_ix].address != pre_address)
{
frv_insn_fetch_buffer[pre_ix].address = pre_address;
frv_insn_fetch_buffer[pre_ix].reqno = cache_reqno++;
if (FRV_COUNT_CYCLES (current_cpu, 1))
frv_cache_request_load (cache, frv_insn_fetch_buffer[pre_ix].reqno,
frv_insn_fetch_buffer[pre_ix].address,
UNIT_I0 + pre_ix);
}
/* If counting cycles, account for any branch penalty and/or insn fetch
latency here. */
if (FRV_COUNT_CYCLES (current_cpu, 1))
{
FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
int wait;
/* Account for any branch penalty. */
if (ps->branch_penalty > 0 && ! ps->past_first_p)
{
frv_model_advance_cycles (current_cpu, ps->branch_penalty);
frv_model_trace_wait_cycles (current_cpu, ps->branch_penalty,
"Branch penalty:");
ps->branch_penalty = 0;
}
/* Account for insn fetch latency. */
wait = 0;
while (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
{
frv_model_advance_cycles (current_cpu, 1);
++wait;
}
frv_model_trace_wait_cycles (current_cpu, wait, "Insn fetch:");
return;
}
/* Otherwise just load the insns directly from the cache.
*/
if (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
{
frv_cache_read (cache, cur_ix, vpc);
frv_insn_fetch_buffer[cur_ix].reqno = NO_REQNO;
}
if (frv_insn_fetch_buffer[pre_ix].reqno != NO_REQNO)
{
frv_cache_read (cache, pre_ix, pre_address);
frv_insn_fetch_buffer[pre_ix].reqno = NO_REQNO;
}
}
static void
@cpu@_simulate_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc)
{
SI hsr0;
SIM_DESC sd;
/* Nothing to do if not counting cycles and the cache is not enabled. */
hsr0 = GET_HSR0 ();
if (! GET_HSR0_ICE (hsr0) && ! FRV_COUNT_CYCLES (current_cpu, 1))
return;
/* Different machines handle prefetch defferently. */
sd = CPU_STATE (current_cpu);
switch (STATE_ARCHITECTURE (sd)->mach)
{
case bfd_mach_fr400:
simulate_dual_insn_prefetch (current_cpu, vpc, 8);
break;
case bfd_mach_frvtomcat:
case bfd_mach_fr500:
case bfd_mach_frv:
simulate_dual_insn_prefetch (current_cpu, vpc, 16);
break;
default:
break;
}
}
int frv_save_profile_model_p;
EOF
;;
xinit)
cat <<EOF
/*xxxinit*/
/* If the timer is enabled, then we will enable model profiling during
execution. This is because the timer needs accurate cycles counts to
work properly. Save the original setting of model profiling. */
if (frv_interrupt_state.timer.enabled)
frv_save_profile_model_p = PROFILE_MODEL_P (current_cpu);
EOF
;;
xextract-simple | xextract-scache)
# Inputs: current_cpu, vpc, sc, FAST_P
# Outputs: sc filled in
# SET_LAST_INSN_P(last_p) called to indicate whether insn is last one
cat <<EOF
{
CGEN_INSN_INT insn = frvbf_read_imem_USI (current_cpu, vpc);
extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
SET_LAST_INSN_P ((insn & 0x80000000) != 0);
}
EOF
;;
xfull-exec-* | xfast-exec-*)
# Inputs: current_cpu, vpc, FAST_P
# Outputs:
# vpc contains the address of the next insn to execute
# pc of current_cpu must be up to date (=vpc) upon exit
# CPU_INSN_COUNT (current_cpu) must be updated by number of insns executed
#
# Unlike the non-parallel case, this version is responsible for doing the
# scache lookup.
cat <<EOF
{
FRV_VLIW *vliw;
int first_insn_p = 1;
int last_insn_p = 0;
int ninsns;
/* If the timer is enabled, then enable model profiling. This is because
the timer needs accurate cycles counts to work properly. */
if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
sim_profile_set_option (current_state, "-model", PROFILE_MODEL_IDX, "1");
/* Init parallel-write queue and vliw. */
@cpu@_parallel_write_init (current_cpu);
vliw = CPU_VLIW (current_cpu);
frv_vliw_reset (vliw, STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach,
CPU_ELF_FLAGS (current_cpu));
for (ninsns = 0; ! last_insn_p && ninsns < FRV_VLIW_SIZE; ++ninsns)
{
SCACHE *sc;
const CGEN_INSN *insn;
int error;
/* Go through the motions of finding the insns in the cache. */
@cpu@_simulate_insn_prefetch (current_cpu, vpc);
sc = @cpu@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
sc->first_insn_p = first_insn_p;
last_insn_p = sc->last_insn_p;
/* Add the insn to the vliw and set up the interrupt state. */
insn = sc->argbuf.idesc->idata;
error = frv_vliw_add_insn (vliw, insn);
if (! error)
frv_vliw_setup_insn (current_cpu, insn);
frv_detect_insn_access_interrupts (current_cpu, sc);
vpc = execute (current_cpu, sc, FAST_P);
SET_H_PC (vpc); /* needed for interrupt handling */
first_insn_p = 0;
}
/* If the timer is enabled, and model profiling was not originally enabled,
then turn it off again. This is the only place we can currently gain
control to do this. */
if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
sim_profile_set_option (current_state, "-model", PROFILE_MODEL_IDX, "0");
/* Check for interrupts. Also handles writeback if necessary. */
frv_process_interrupts (current_cpu);
CPU_INSN_COUNT (current_cpu) += ninsns;
}
EOF
;;
*)
echo "Invalid argument to mainloop.in: $1" >&2
exit 1
;;
esac

72726
sim/frv/model.c Normal file

File diff suppressed because it is too large Load Diff

237
sim/frv/options.c Normal file
View File

@ -0,0 +1,237 @@
/* FRV simulator memory option handling.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Red Hat.
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 WANT_CPU frvbf
#define WANT_CPU_FRVBF
#include "sim-main.h"
#include "sim-assert.h"
#include "sim-options.h"
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
/* FRV specific command line options. */
enum {
OPTION_FRV_DATA_CACHE = OPTION_START,
OPTION_FRV_INSN_CACHE,
OPTION_FRV_PROFILE_CACHE,
OPTION_FRV_PROFILE_PARALLEL,
OPTION_FRV_TIMER,
OPTION_FRV_MEMORY_LATENCY
};
static DECLARE_OPTION_HANDLER (frv_option_handler);
const OPTION frv_options[] =
{
{ {"profile", optional_argument, NULL, 'p'},
'p', "on|off", "Perform profiling",
frv_option_handler },
{ {"data-cache", optional_argument, NULL, OPTION_FRV_DATA_CACHE },
'\0', "WAYS[,SETS[,LINESIZE]]", "Enable data cache",
frv_option_handler },
{ {"insn-cache", optional_argument, NULL, OPTION_FRV_INSN_CACHE },
'\0', "WAYS[,SETS[,LINESIZE]]", "Enable instruction cache",
frv_option_handler },
{ {"profile-cache", optional_argument, NULL, OPTION_FRV_PROFILE_CACHE },
'\0', "on|off", "Profile caches",
frv_option_handler },
{ {"profile-parallel", optional_argument, NULL, OPTION_FRV_PROFILE_PARALLEL },
'\0', "on|off", "Profile parallelism",
frv_option_handler },
{ {"timer", required_argument, NULL, OPTION_FRV_TIMER },
'\0', "CYCLES,INTERRUPT", "Set Interrupt Timer",
frv_option_handler },
{ {"memory-latency", required_argument, NULL, OPTION_FRV_MEMORY_LATENCY },
'\0', "CYCLES", "Set Latency of memory",
frv_option_handler },
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
};
static char *
parse_size (char *chp, address_word *nr_bytes)
{
/* <nr_bytes> */
*nr_bytes = strtoul (chp, &chp, 0);
return chp;
}
static address_word
check_pow2 (address_word value, char *argname, char *optname, SIM_DESC sd)
{
if ((value & (value - 1)) != 0)
{
sim_io_eprintf (sd, "%s argument to %s must be a power of 2\n",
argname, optname);
return 0; /* will enable default value. */
}
return value;
}
static void
parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
{
int i;
address_word ways = 0, sets = 0, linesize = 0;
if (arg != NULL)
{
char *chp = arg;
/* parse the arguments */
chp = parse_size (chp, &ways);
ways = check_pow2 (ways, "WAYS", cache_name, sd);
if (*chp == ',')
{
chp = parse_size (chp + 1, &sets);
sets = check_pow2 (sets, "SETS", cache_name, sd);
if (*chp == ',')
{
chp = parse_size (chp + 1, &linesize);
linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
}
}
}
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
SIM_CPU *current_cpu = STATE_CPU (sd, i);
FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
: CPU_INSN_CACHE (current_cpu);
cache->ways = ways;
cache->sets = sets;
cache->line_size = linesize;
frv_cache_init (current_cpu, cache);
}
}
static SIM_RC
frv_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
char *arg, int is_command)
{
switch (opt)
{
case 'p' :
if (! WITH_PROFILE)
sim_io_eprintf (sd, "Profiling not compiled in, `-p' ignored\n");
else
{
unsigned mask = PROFILE_USEFUL_MASK;
if (WITH_PROFILE_CACHE_P)
mask |= (1 << PROFILE_CACHE_IDX);
if (WITH_PROFILE_PARALLEL_P)
mask |= (1 << PROFILE_PARALLEL_IDX);
return set_profile_option_mask (sd, "profile", mask, arg);
}
break;
case OPTION_FRV_DATA_CACHE:
parse_cache_option (sd, arg, "data_cache", 1/*is_data_cache*/);
return SIM_RC_OK;
case OPTION_FRV_INSN_CACHE:
parse_cache_option (sd, arg, "insn_cache", 0/*is_data_cache*/);
return SIM_RC_OK;
case OPTION_FRV_PROFILE_CACHE:
if (WITH_PROFILE_CACHE_P)
return sim_profile_set_option (sd, "-cache", PROFILE_CACHE_IDX, arg);
else
sim_io_eprintf (sd, "Cache profiling not compiled in, `--profile-cache' ignored\n");
break;
case OPTION_FRV_PROFILE_PARALLEL:
if (WITH_PROFILE_PARALLEL_P)
{
unsigned mask
= (1 << PROFILE_MODEL_IDX) | (1 << PROFILE_PARALLEL_IDX);
return set_profile_option_mask (sd, "-parallel", mask, arg);
}
else
sim_io_eprintf (sd, "Parallel profiling not compiled in, `--profile-parallel' ignored\n");
break;
case OPTION_FRV_TIMER:
{
char *chp = arg;
address_word cycles, interrupt;
chp = parse_size (chp, &cycles);
if (chp == arg)
{
sim_io_eprintf (sd, "Cycle count required for --timer\n");
return SIM_RC_FAIL;
}
if (*chp != ',')
{
sim_io_eprintf (sd, "Interrupt number required for --timer\n");
return SIM_RC_FAIL;
}
chp = parse_size (chp + 1, &interrupt);
if (interrupt < 1 || interrupt > 15)
{
sim_io_eprintf (sd, "Interrupt number for --timer must be greater than 0 and less that 16\n");
return SIM_RC_FAIL;
}
frv_interrupt_state.timer.enabled = 1;
frv_interrupt_state.timer.value = cycles;
frv_interrupt_state.timer.current = 0;
frv_interrupt_state.timer.interrupt =
FRV_INTERRUPT_LEVEL_1 + interrupt - 1;
}
return SIM_RC_OK;
case OPTION_FRV_MEMORY_LATENCY:
{
int i;
char *chp = arg;
address_word cycles;
chp = parse_size (chp, &cycles);
if (chp == arg)
{
sim_io_eprintf (sd, "Cycle count required for --memory-latency\n");
return SIM_RC_FAIL;
}
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
SIM_CPU *current_cpu = STATE_CPU (sd, i);
FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
insn_cache->memory_latency = cycles;
data_cache->memory_latency = cycles;
}
}
return SIM_RC_OK;
default:
sim_io_eprintf (sd, "Unknown FRV option %d\n", opt);
return SIM_RC_FAIL;
}
return SIM_RC_FAIL;
}

92
sim/frv/pipeline.c Normal file
View File

@ -0,0 +1,92 @@
/* frv vliw model.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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 WANT_CPU frvbf
#define WANT_CPU_FRVBF
#include "sim-main.h"
/* Simulator specific vliw related functions. Additional vliw related
code used by both the simulator and the assembler is in frv.opc. */
int insns_in_slot[UNIT_NUM_UNITS] = {0};
void
frv_vliw_setup_insn (SIM_CPU *current_cpu, const CGEN_INSN *insn)
{
FRV_VLIW *vliw;
int index;
/* Always clear the NE index which indicates the target register
of a non excepting insn. This will be reset by the insn if
necessary. */
frv_interrupt_state.ne_index = NE_NOFLAG;
vliw = CPU_VLIW (current_cpu);
index = vliw->next_slot - 1;
if (frv_is_float_insn (insn))
{
/* If the insn is to be added and is a floating point insn and
it is the first floating point insn in the vliw, then clear
FSR0.FTT. */
int i;
for (i = 0; i < index; ++i)
if (frv_is_float_major (vliw->major[i], vliw->mach))
break; /* found float insn. */
if (i >= index)
{
SI fsr0 = GET_FSR (0);
SET_FSR_FTT (fsr0, FTT_NONE);
SET_FSR (0, fsr0);
}
}
else if (frv_is_media_insn (insn))
{
/* Clear the appropriate MSR fields depending on which slot
this insn is in. */
CGEN_ATTR_VALUE_TYPE preserve_ovf;
SI msr0 = GET_MSR (0);
preserve_ovf = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_PRESERVE_OVF);
if ((*vliw->current_vliw)[index] == UNIT_FM0)
{
if (! preserve_ovf)
{
/* Clear MSR0.OVF and MSR0.SIE. */
CLEAR_MSR_SIE (msr0);
CLEAR_MSR_OVF (msr0);
}
}
else
{
if (! preserve_ovf)
{
/* Clear MSR1.OVF and MSR1.SIE. */
SI msr1 = GET_MSR (1);
CLEAR_MSR_SIE (msr1);
CLEAR_MSR_OVF (msr1);
SET_MSR (1, msr1);
}
}
SET_MSR (0, msr0);
} /* Insn is a media insns. */
COUNT_INSNS_IN_SLOT ((*vliw->current_vliw)[index]);
}

2175
sim/frv/profile-fr400.c Normal file

File diff suppressed because it is too large Load Diff

31
sim/frv/profile-fr400.h Normal file
View File

@ -0,0 +1,31 @@
/* Profiling definitions for the fr400 model of the FRV simulator
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 PROFILE_FR400_H
#define PROFILE_FR400_H
void fr400_model_insn_before (SIM_CPU *, int);
void fr400_model_insn_after (SIM_CPU *, int, int);
void fr400_reset_gr_flags (SIM_CPU *, INT);
void fr400_reset_fr_flags (SIM_CPU *, INT);
void fr400_reset_acc_flags (SIM_CPU *, INT);
#endif /* PROFILE_FR400_H */

3060
sim/frv/profile-fr500.c Normal file

File diff suppressed because it is too large Load Diff

30
sim/frv/profile-fr500.h Normal file
View File

@ -0,0 +1,30 @@
/* Profiling definitions for the fr500 model of the FRV simulator
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 PROFILE_FR500_H
#define PROFILE_FR500_H
void fr500_model_insn_before (SIM_CPU *, int);
void fr500_model_insn_after (SIM_CPU *, int, int);
void fr500_reset_fr_flags (SIM_CPU *, INT);
void fr500_reset_cc_flags (SIM_CPU *, INT);
#endif /* PROFILE_FR500_H */

1807
sim/frv/profile.c Normal file

File diff suppressed because it is too large Load Diff

194
sim/frv/profile.h Normal file
View File

@ -0,0 +1,194 @@
/* Profiling definitions for the FRV simulator
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 PROFILE_H
#define PROFILE_H
/* This struct defines the state of profiling. All fields are of general
use to all machines. */
typedef struct
{
long vliw_insns; /* total number of VLIW insns. */
long vliw_wait; /* number of cycles that the current VLIW insn must wait. */
long post_wait; /* number of cycles that post processing in the current
VLIW insn must wait. */
long vliw_cycles;/* number of cycles used by current VLIW insn. */
int past_first_p; /* Not the first insns in the VLIW */
/* Register latencies. Must be signed since they can be temporarily
negative. */
int gr_busy[64]; /* Cycles until GR is available. */
int fr_busy[64]; /* Cycles until FR is available. */
int acc_busy[64]; /* Cycles until FR is available. */
int ccr_busy[8]; /* Cycles until ICC/FCC is available. */
int idiv_busy[2]; /* Cycles until integer division unit is available. */
int fdiv_busy[2]; /* Cycles until float division unit is available. */
int fsqrt_busy[2]; /* Cycles until square root unit is available. */
int branch_penalty; /* Cycles until branch is complete. */
int gr_latency[64]; /* Cycles until target GR is available. */
int fr_latency[64]; /* Cycles until target FR is available. */
int acc_latency[64]; /* Cycles until target FR is available. */
int ccr_latency[8]; /* Cycles until target ICC/FCC is available. */
/* Some registers are busy for a shorter number of cycles than normal
depending on how they are used next. the xxx_busy_adjust arrays keep track
of how many cycles to adjust down.
*/
int fr_busy_adjust[64];
int acc_busy_adjust[64];
/* Register flags. Each bit represents one register. */
DI cur_gr_complex;
DI prev_gr_complex;
/* Keep track of the total queued post-processing time required before a
resource is available. This is applied to the resource's latency once all
pending loads for the resource are completed. */
int fr_ptime[64];
int branch_hint; /* hint field from branch insn. */
USI branch_address; /* Address of predicted branch. */
USI insn_fetch_address;/* Address of sequential insns fetched. */
/* We need to know when the first branch of a vliw insn is taken, so that
we don't consider the remaining branches in the vliw insn. */
int vliw_branch_taken;
/* Keep track of the maximum load stall for each VLIW insn. */
int vliw_load_stall;
/* Need to know if all cache entries are affected by various cache
operations. */
int all_cache_entries;
} FRV_PROFILE_STATE;
#define DUAL_REG(reg) ((reg) >= 0 && (reg) < 63 ? (reg) + 1 : -1)
#define DUAL_DOUBLE(reg) ((reg) >= 0 && (reg) < 61 ? (reg) + 2 : -1)
/* Top up the latency of the given GR by the given number of cycles. */
void update_GR_latency (SIM_CPU *, INT, int);
void update_GRdouble_latency (SIM_CPU *, INT, int);
void update_GR_latency_for_load (SIM_CPU *, INT, int);
void update_GRdouble_latency_for_load (SIM_CPU *, INT, int);
void update_GR_latency_for_swap (SIM_CPU *, INT, int);
void update_FR_latency (SIM_CPU *, INT, int);
void update_FRdouble_latency (SIM_CPU *, INT, int);
void update_FR_latency_for_load (SIM_CPU *, INT, int);
void update_FRdouble_latency_for_load (SIM_CPU *, INT, int);
void decrease_ACC_busy (SIM_CPU *, INT, int);
void decrease_FR_busy (SIM_CPU *, INT, int);
void decrease_GR_busy (SIM_CPU *, INT, int);
void increase_FR_busy (SIM_CPU *, INT, int);
void update_ACC_latency (SIM_CPU *, INT, int);
void update_CCR_latency (SIM_CPU *, INT, int);
void update_idiv_resource_latency (SIM_CPU *, INT, int);
void update_fdiv_resource_latency (SIM_CPU *, INT, int);
void update_fsqrt_resource_latency (SIM_CPU *, INT, int);
void update_branch_penalty (SIM_CPU *, int);
void update_ACC_ptime (SIM_CPU *, INT, int);
void vliw_wait_for_GR (SIM_CPU *, INT);
void vliw_wait_for_GRdouble (SIM_CPU *, INT);
void vliw_wait_for_FR (SIM_CPU *, INT);
void vliw_wait_for_FRdouble (SIM_CPU *, INT);
void vliw_wait_for_CCR (SIM_CPU *, INT);
void vliw_wait_for_ACC (SIM_CPU *, INT);
void vliw_wait_for_idiv_resource (SIM_CPU *, INT);
void vliw_wait_for_fdiv_resource (SIM_CPU *, INT);
void vliw_wait_for_fsqrt_resource (SIM_CPU *, INT);
void load_wait_for_GR (SIM_CPU *, INT);
void load_wait_for_FR (SIM_CPU *, INT);
void load_wait_for_GRdouble (SIM_CPU *, INT);
void load_wait_for_FRdouble (SIM_CPU *, INT);
void enforce_full_fr_latency (SIM_CPU *, INT);
int post_wait_for_FR (SIM_CPU *, INT);
int post_wait_for_FRdouble (SIM_CPU *, INT);
int post_wait_for_ACC (SIM_CPU *, INT);
int post_wait_for_CCR (SIM_CPU *, INT);
int post_wait_for_fdiv (SIM_CPU *, INT);
int post_wait_for_fsqrt (SIM_CPU *, INT);
void trace_vliw_wait_cycles (SIM_CPU *);
void handle_resource_wait (SIM_CPU *);
void request_cache_load (SIM_CPU *, INT, int, int);
void request_cache_flush (SIM_CPU *, FRV_CACHE *, int);
void request_cache_invalidate (SIM_CPU *, FRV_CACHE *, int);
void request_cache_preload (SIM_CPU *, FRV_CACHE *, int);
void request_cache_unlock (SIM_CPU *, FRV_CACHE *, int);
int load_pending_for_register (SIM_CPU *, int, int, int);
void set_use_is_gr_complex (SIM_CPU *, INT);
void set_use_not_gr_complex (SIM_CPU *, INT);
int use_is_gr_complex (SIM_CPU *, INT);
typedef struct
{
SI address;
unsigned reqno;
} FRV_INSN_FETCH_BUFFER;
extern FRV_INSN_FETCH_BUFFER frv_insn_fetch_buffer[];
PROFILE_INFO_CPU_CALLBACK_FN frv_profile_info;
enum {
/* Simulator specific profile bits begin here. */
/* Profile caches. */
PROFILE_CACHE_IDX = PROFILE_NEXT_IDX,
/* Profile parallelization. */
PROFILE_PARALLEL_IDX
};
/* Masks so WITH_PROFILE can have symbolic values.
The case choice here is on purpose. The lowercase parts are args to
--with-profile. */
#define PROFILE_cache (1 << PROFILE_INSN_IDX)
#define PROFILE_parallel (1 << PROFILE_INSN_IDX)
/* Preprocessor macros to simplify tests of WITH_PROFILE. */
#define WITH_PROFILE_CACHE_P (WITH_PROFILE & PROFILE_insn)
#define WITH_PROFILE_PARALLEL_P (WITH_PROFILE & PROFILE_insn)
#define FRV_COUNT_CYCLES(cpu, condition) \
((PROFILE_MODEL_P (cpu) && (condition)) || frv_interrupt_state.timer.enabled)
/* Modelling support. */
extern int frv_save_profile_model_p;
extern enum FRV_INSN_MODELING {
FRV_INSN_NO_MODELING = 0,
FRV_INSN_MODEL_PASS_1,
FRV_INSN_MODEL_PASS_2,
FRV_INSN_MODEL_WRITEBACK
} model_insn;
void
frv_model_advance_cycles (SIM_CPU *, int);
void
frv_model_trace_wait_cycles (SIM_CPU *, int, const char *);
/* Register types for queued load requests. */
#define REGTYPE_NONE 0
#define REGTYPE_FR 1
#define REGTYPE_ACC 2
#endif /* PROFILE_H */

4405
sim/frv/registers.c Normal file

File diff suppressed because it is too large Load Diff

59
sim/frv/registers.h Normal file
View File

@ -0,0 +1,59 @@
/* Register definitions for the FRV simulator
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU Simulators.
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 REGISTERS_H
#define REGISTERS_H
#define FRV_MAX_GR 64
#define FRV_MAX_FR 64
#define FRV_MAX_CPR 64
#define FRV_MAX_SPR 4096
/* Register init, reset values and read_only masks. */
typedef struct
{
USI init_value; /* initial value */
USI reset_value; /* value for software reset */
USI reset_mask; /* bits which are reset */
USI read_only_mask; /* bits which are read-only */
char implemented; /* 1==register is implemented */
char supervisor; /* 1==register is supervisor-only */
} FRV_SPR_CONTROL_INFO;
typedef struct
{
int fr; /* FR registers implemented */
int cpr; /* coprocessor registers implemented */
FRV_SPR_CONTROL_INFO *spr; /* SPR implementation details */
} FRV_REGISTER_CONTROL;
void frv_register_control_init (SIM_CPU *);
void frv_initialize_spr (SIM_CPU *);
void frv_reset_spr (SIM_CPU *);
void frv_check_spr_access (SIM_CPU *, UINT);
void frv_fr_registers_available (SIM_CPU *, int *, int *);
void frv_gr_registers_available (SIM_CPU *, int *, int *);
int frv_check_register_access (SIM_CPU *, SI, int, int);
int frv_check_gr_access (SIM_CPU *, SI);
int frv_check_fr_access (SIM_CPU *, SI);
#endif /* REGISTERS_H */

151
sim/frv/reset.c Normal file
View File

@ -0,0 +1,151 @@
/* frv simulator support code
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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 WANT_CPU
#define WANT_CPU_FRVBF
#include "sim-main.h"
#include "bfd.h"
/* Initialize the frv simulator. */
void
frv_initialize (SIM_CPU *current_cpu, SIM_DESC sd)
{
FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu);
FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
int insn_cache_enabled = CACHE_INITIALIZED (insn_cache);
int data_cache_enabled = CACHE_INITIALIZED (data_cache);
USI hsr0;
/* We need to ensure that the caches are initialized even if they are not
initially enabled (via commandline) because they can be enabled by
software. */
if (! insn_cache_enabled)
frv_cache_init (current_cpu, CPU_INSN_CACHE (current_cpu));
if (! data_cache_enabled)
frv_cache_init (current_cpu, CPU_DATA_CACHE (current_cpu));
/* Set the default cpu frequency if it has not been set on the command
line. */
if (PROFILE_CPU_FREQ (p) == 0)
PROFILE_CPU_FREQ (p) = 266000000; /* 266MHz */
/* Allocate one cache line of memory containing the address of the reset
register Use the largest of the insn cache line size and the data cache
line size. */
{
int addr = RSTR_ADDRESS;
void *aligned_buffer;
int bytes;
if (CPU_INSN_CACHE (current_cpu)->line_size
> CPU_DATA_CACHE (current_cpu)->line_size)
bytes = CPU_INSN_CACHE (current_cpu)->line_size;
else
bytes = CPU_DATA_CACHE (current_cpu)->line_size;
/* 'bytes' is a power of 2. Calculate the starting address of the
cache line. */
addr &= ~(bytes - 1);
aligned_buffer = zalloc (bytes); /* clear */
sim_core_attach (sd, NULL, 0, access_read_write, 0, addr, bytes,
0, NULL, aligned_buffer);
}
PROFILE_INFO_CPU_CALLBACK(p) = frv_profile_info;
ps->insn_fetch_address = -1;
ps->branch_address = -1;
cgen_init_accurate_fpu (current_cpu, CGEN_CPU_FPU (current_cpu),
frvbf_fpu_error);
/* Initialize the register control information. */
frv_register_control_init (current_cpu);
/* Now perform power-on reset. */
frv_power_on_reset (current_cpu);
/* Make sure that HSR0.ICE and HSR0.DCE are set properly. */
hsr0 = GET_HSR0 ();
if (insn_cache_enabled)
SET_HSR0_ICE (hsr0);
else
CLEAR_HSR0_ICE (hsr0);
if (data_cache_enabled)
SET_HSR0_DCE (hsr0);
else
CLEAR_HSR0_DCE (hsr0);
SET_HSR0 (hsr0);
}
/* Initialize the frv simulator. */
void
frv_term (SIM_DESC sd)
{
/* If the timer is enabled, and model profiling was not originally enabled,
then turn it off again. This is the only place we can currently gain
control to do this. */
if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
sim_profile_set_option (current_state, "-model", PROFILE_MODEL_IDX, "0");
}
/* Perform a power on reset. */
void
frv_power_on_reset (SIM_CPU *cpu)
{
/* GR, FR and CPR registers are undefined at initialization time. */
frv_initialize_spr (cpu);
/* Initialize the RSTR register (in memory). */
if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
else
SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
}
/* Perform a hardware reset. */
void
frv_hardware_reset (SIM_CPU *cpu)
{
/* GR, FR and CPR registers are undefined at hardware reset. */
frv_initialize_spr (cpu);
/* Reset the RSTR register (in memory). */
if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
else
SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
/* Reset the insn and data caches. */
frv_cache_invalidate_all (CPU_INSN_CACHE (cpu), 0/* no flush */);
frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 0/* no flush */);
}
/* Perform a software reset. */
void
frv_software_reset (SIM_CPU *cpu)
{
/* GR, FR and CPR registers are undefined at software reset. */
frv_reset_spr (cpu);
/* Reset the RSTR register (in memory). */
if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
else
SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
}

28578
sim/frv/sem.c Normal file

File diff suppressed because it is too large Load Diff

251
sim/frv/sim-if.c Normal file
View File

@ -0,0 +1,251 @@
/* Main simulator entry points specific to the FRV.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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 WANT_CPU
#define WANT_CPU_FRVBF
#include "sim-main.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "sim-options.h"
#include "libiberty.h"
#include "bfd.h"
#include "elf-bfd.h"
static void free_state (SIM_DESC);
static void print_frv_misc_cpu (SIM_CPU *cpu, int verbose);
/* Records simulator descriptor so utilities like frv_dump_regs can be
called from gdb. */
SIM_DESC current_state;
/* Cover function of sim_state_free to free the cpu buffers as well. */
static void
free_state (SIM_DESC sd)
{
if (STATE_MODULES (sd) != NULL)
sim_module_uninstall (sd);
sim_cpu_free_all (sd);
sim_state_free (sd);
}
/* Create an instance of the simulator. */
SIM_DESC
sim_open (kind, callback, abfd, argv)
SIM_OPEN_KIND kind;
host_callback *callback;
bfd *abfd;
char **argv;
{
char c;
int i;
unsigned long elf_flags = 0;
SIM_DESC sd = sim_state_alloc (kind, callback);
/* The cpu data is kept in a separately allocated chunk of memory. */
if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
#if 0 /* FIXME: pc is in mach-specific struct */
/* FIXME: watchpoints code shouldn't need this */
{
SIM_CPU *current_cpu = STATE_CPU (sd, 0);
STATE_WATCHPOINTS (sd)->pc = &(PC);
STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
}
#endif
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* These options override any module options.
Obviously ambiguity should be avoided, however the caller may wish to
augment the meaning of an option. */
sim_add_option_table (sd, NULL, frv_options);
/* getopt will print the error message so we just have to exit if this fails.
FIXME: Hmmm... in the case of gdb we need getopt to call
print_filtered. */
if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
#if 0
/* Allocate a handler for the control registers and other devices
if no memory for that range has been allocated by the user.
All are allocated in one chunk to keep things from being
unnecessarily complicated. */
if (sim_core_read_buffer (sd, NULL, read_map, &c, FRV_DEVICE_ADDR, 1) == 0)
sim_core_attach (sd, NULL,
0 /*level*/,
access_read_write,
0 /*space ???*/,
FRV_DEVICE_ADDR, FRV_DEVICE_LEN /*nr_bytes*/,
0 /*modulo*/,
&frv_devices,
NULL /*buffer*/);
#endif
/* Allocate core managed memory if none specified by user.
Use address 4 here in case the user wanted address 0 unmapped. */
if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
sim_do_commandf (sd, "memory region 0,0x%lx", FRV_DEFAULT_MEM_SIZE);
/* check for/establish the reference program image */
if (sim_analyze_program (sd,
(STATE_PROG_ARGV (sd) != NULL
? *STATE_PROG_ARGV (sd)
: NULL),
abfd) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* set machine and architecture correctly instead of defaulting to frv */
{
bfd *prog_bfd = STATE_PROG_BFD (sd);
if (prog_bfd != NULL)
{
struct elf_backend_data *backend_data;
if (bfd_get_arch (prog_bfd) != bfd_arch_frv)
{
sim_io_eprintf (sd, "%s: \"%s\" is not a FRV object file\n",
STATE_MY_NAME (sd),
bfd_get_filename (prog_bfd));
free_state (sd);
return 0;
}
backend_data = get_elf_backend_data (prog_bfd);
if (backend_data != NULL)
backend_data->elf_backend_object_p (prog_bfd);
elf_flags = elf_elfheader (prog_bfd)->e_flags;
}
}
/* Establish any remaining configuration options. */
if (sim_config (sd) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
if (sim_post_argv_init (sd) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* Open a copy of the cpu descriptor table. */
{
CGEN_CPU_DESC cd = frv_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
CGEN_ENDIAN_BIG);
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
SIM_CPU *cpu = STATE_CPU (sd, i);
CPU_CPU_DESC (cpu) = cd;
CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
CPU_ELF_FLAGS (cpu) = elf_flags;
}
frv_cgen_init_dis (cd);
}
/* Initialize various cgen things not done by common framework.
Must be done after frv_cgen_cpu_open. */
cgen_init (sd);
/* CPU specific initialization. */
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
SIM_CPU* cpu = STATE_CPU (sd, i);
frv_initialize (cpu, sd);
}
/* Store in a global so things like sparc32_dump_regs can be invoked
from the gdb command line. */
current_state = sd;
return sd;
}
void
sim_close (sd, quitting)
SIM_DESC sd;
int quitting;
{
int i;
/* Terminate cache support. */
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
SIM_CPU* cpu = STATE_CPU (sd, i);
frv_cache_term (CPU_INSN_CACHE (cpu));
frv_cache_term (CPU_DATA_CACHE (cpu));
}
frv_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0)));
sim_module_uninstall (sd);
}
SIM_RC
sim_create_inferior (sd, abfd, argv, envp)
SIM_DESC sd;
bfd *abfd;
char **argv;
char **envp;
{
SIM_CPU *current_cpu = STATE_CPU (sd, 0);
SIM_ADDR addr;
if (abfd != NULL)
addr = bfd_get_start_address (abfd);
else
addr = 0;
sim_pc_set (current_cpu, addr);
#if 0
STATE_ARGV (sd) = sim_copy_argv (argv);
STATE_ENVP (sd) = sim_copy_argv (envp);
#endif
return SIM_RC_OK;
}
void
sim_do_command (sd, cmd)
SIM_DESC sd;
char *cmd;
{
if (sim_args_command (sd, cmd) != SIM_RC_OK)
sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
}

139
sim/frv/sim-main.h Normal file
View File

@ -0,0 +1,139 @@
/* frv simulator support code
Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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. */
/* Main header for the frv. */
#define USING_SIM_BASE_H /* FIXME: quick hack */
struct _sim_cpu; /* FIXME: should be in sim-basics.h */
typedef struct _sim_cpu SIM_CPU;
/* Set the mask of unsupported traces. */
#define WITH_TRACE \
(~(TRACE_alu | TRACE_decode | TRACE_memory | TRACE_model | TRACE_fpu \
| TRACE_branch | TRACE_debug))
/* sim-basics.h includes config.h but cgen-types.h must be included before
sim-basics.h and cgen-types.h needs config.h. */
#include "config.h"
#include "symcat.h"
#include "sim-basics.h"
#include "cgen-types.h"
#include "frv-desc.h"
#include "frv-opc.h"
#include "arch.h"
/* These must be defined before sim-base.h. */
typedef USI sim_cia;
#define CIA_GET(cpu) CPU_PC_GET (cpu)
#define CIA_SET(cpu,val) CPU_PC_SET ((cpu), (val))
void frv_sim_engine_halt_hook (SIM_DESC, SIM_CPU *, sim_cia);
#define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) \
frv_sim_engine_halt_hook ((SD), (LAST_CPU), (CIA))
#define SIM_ENGINE_RESTART_HOOK(SD, LAST_CPU, CIA) 0
#include "sim-base.h"
#include "cgen-sim.h"
#include "frv-sim.h"
#include "cache.h"
#include "registers.h"
#include "profile.h"
/* The _sim_cpu struct. */
struct _sim_cpu {
/* sim/common cpu base. */
sim_cpu_base base;
/* Static parts of cgen. */
CGEN_CPU cgen_cpu;
/* CPU specific parts go here.
Note that in files that don't need to access these pieces WANT_CPU_FOO
won't be defined and thus these parts won't appear. This is ok in the
sense that things work. It is a source of bugs though.
One has to of course be careful to not take the size of this
struct and no structure members accessed in non-cpu specific files can
go after here. Oh for a better language. */
#if defined (WANT_CPU_FRVBF)
FRVBF_CPU_DATA cpu_data;
/* Control information for registers */
FRV_REGISTER_CONTROL register_control;
#define CPU_REGISTER_CONTROL(cpu) (& (cpu)->register_control)
FRV_VLIW vliw;
#define CPU_VLIW(cpu) (& (cpu)->vliw)
FRV_CACHE insn_cache;
#define CPU_INSN_CACHE(cpu) (& (cpu)->insn_cache)
FRV_CACHE data_cache;
#define CPU_DATA_CACHE(cpu) (& (cpu)->data_cache)
FRV_PROFILE_STATE profile_state;
#define CPU_PROFILE_STATE(cpu) (& (cpu)->profile_state)
int debug_state;
#define CPU_DEBUG_STATE(cpu) ((cpu)->debug_state)
SI load_address;
#define CPU_LOAD_ADDRESS(cpu) ((cpu)->load_address)
SI load_length;
#define CPU_LOAD_LENGTH(cpu) ((cpu)->load_length)
SI load_flag;
#define CPU_LOAD_SIGNED(cpu) ((cpu)->load_flag)
#define CPU_LOAD_LOCK(cpu) ((cpu)->load_flag)
SI store_flag;
#define CPU_RSTR_INVALIDATE(cpu) ((cpu)->store_flag)
unsigned long elf_flags;
#define CPU_ELF_FLAGS(cpu) ((cpu)->elf_flags)
#endif /* defined (WANT_CPU_FRVBF) */
};
/* The sim_state struct. */
struct sim_state {
sim_cpu *cpu;
#define STATE_CPU(sd, n) (/*&*/ (sd)->cpu)
CGEN_STATE cgen_state;
sim_state_base base;
};
/* Misc. */
/* Catch address exceptions. */
extern SIM_CORE_SIGNAL_FN frv_core_signal;
#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
frv_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), \
(TRANSFER), (ERROR))
/* Default memory size. */
#define FRV_DEFAULT_MEM_SIZE 0x800000 /* 8M */

42
sim/frv/tconfig.in Normal file
View File

@ -0,0 +1,42 @@
/* FRV target configuration file. -*- C -*- */
/* Define this if the simulator can vary the size of memory.
See the xxx simulator for an example.
This enables the `-m size' option.
The memory size is stored in STATE_MEM_SIZE. */
/* Not used for FRV since we use the memory module. TODO -- check this */
/* #define SIM_HAVE_MEM_SIZE */
/* See sim-hload.c. We properly handle LMA. -- TODO: check this */
#define SIM_HANDLES_LMA 1
/* For MSPR support. FIXME: revisit. */
#define WITH_DEVICES 1
/* FIXME: Revisit. */
#ifdef HAVE_DV_SOCKSER
MODULE_INSTALL_FN dv_sockser_install;
#define MODULE_LIST dv_sockser_install,
#endif
#if 0
/* Enable watchpoints. */
#define WITH_WATCHPOINTS 1
#endif
/* ??? Temporary hack until model support unified. */
#define SIM_HAVE_MODEL
/* Define this to enable the intrinsic breakpoint mechanism. */
/* FIXME: may be able to remove SIM_HAVE_BREAKPOINTS since it essentially
duplicates ifdef SIM_BREAKPOINT (right?) */
#if 0
#define SIM_HAVE_BREAKPOINTS
#define SIM_BREAKPOINT { 0x10, 0xf1 }
#define SIM_BREAKPOINT_SIZE 2
#endif
/* This is a global setting. Different cpu families can't mix-n-match -scache
and -pbb. However some cpu families may use -simple while others use
one of -scache/-pbb. ???? */
#define WITH_SCACHE_PBB 0

931
sim/frv/traps.c Normal file
View File

@ -0,0 +1,931 @@
/* frv trap support
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
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 WANT_CPU frvbf
#define WANT_CPU_FRVBF
#include "sim-main.h"
#include "targ-vals.h"
#include "cgen-engine.h"
#include "cgen-par.h"
#include "sim-fpu.h"
#include "bfd.h"
#include "libiberty.h"
/* The semantic code invokes this for invalid (unrecognized) instructions. */
SEM_PC
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
{
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
return vpc;
}
/* Process an address exception. */
void
frv_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
unsigned int map, int nr_bytes, address_word addr,
transfer_type transfer, sim_core_signals sig)
{
if (sig == sim_core_unaligned_signal)
{
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
frv_queue_data_access_error_interrupt (current_cpu, addr);
else
frv_queue_mem_address_not_aligned_interrupt (current_cpu, addr);
}
frv_term (sd);
sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, transfer, sig);
}
void
frv_sim_engine_halt_hook (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia)
{
int i;
if (current_cpu != NULL)
CIA_SET (current_cpu, cia);
/* Invalidate the insn and data caches of all cpus. */
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
current_cpu = STATE_CPU (sd, i);
frv_cache_invalidate_all (CPU_INSN_CACHE (current_cpu), 0);
frv_cache_invalidate_all (CPU_DATA_CACHE (current_cpu), 1);
}
frv_term (sd);
}
/* Read/write functions for system call interface. */
static int
syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
unsigned long taddr, char *buf, int bytes)
{
SIM_DESC sd = (SIM_DESC) sc->p1;
SIM_CPU *cpu = (SIM_CPU *) sc->p2;
frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 1);
return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
}
static int
syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
unsigned long taddr, const char *buf, int bytes)
{
SIM_DESC sd = (SIM_DESC) sc->p1;
SIM_CPU *cpu = (SIM_CPU *) sc->p2;
frv_cache_invalidate_all (CPU_INSN_CACHE (cpu), 0);
frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 1);
return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
}
/* Handle TRA and TIRA insns. */
void
frv_itrap (SIM_CPU *current_cpu, PCADDR pc, USI base, SI offset)
{
SIM_DESC sd = CPU_STATE (current_cpu);
host_callback *cb = STATE_CALLBACK (sd);
USI num = ((base + offset) & 0x7f) + 0x80;
#ifdef SIM_HAVE_BREAKPOINTS
/* Check for breakpoints "owned" by the simulator first, regardless
of --environment. */
if (num == TRAP_BREAKPOINT)
{
/* First try sim-break.c. If it's a breakpoint the simulator "owns"
it doesn't return. Otherwise it returns and let's us try. */
sim_handle_breakpoint (sd, current_cpu, pc);
/* Fall through. */
}
#endif
if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
{
frv_queue_software_interrupt (current_cpu, num);
return;
}
switch (num)
{
case TRAP_SYSCALL :
{
CB_SYSCALL s;
CB_SYSCALL_INIT (&s);
s.func = GET_H_GR (7);
s.arg1 = GET_H_GR (8);
s.arg2 = GET_H_GR (9);
s.arg3 = GET_H_GR (10);
if (s.func == TARGET_SYS_exit)
{
sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
}
s.p1 = (PTR) sd;
s.p2 = (PTR) current_cpu;
s.read_mem = syscall_read_mem;
s.write_mem = syscall_write_mem;
cb_syscall (cb, &s);
SET_H_GR (8, s.result);
SET_H_GR (9, s.result2);
SET_H_GR (10, s.errcode);
break;
}
case TRAP_BREAKPOINT:
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
break;
/* Add support for dumping registers, either at fixed traps, or all
unknown traps if configured with --enable-sim-trapdump. */
default:
#if !TRAPDUMP
frv_queue_software_interrupt (current_cpu, num);
return;
#endif
#ifdef TRAP_REGDUMP1
case TRAP_REGDUMP1:
#endif
#ifdef TRAP_REGDUMP2
case TRAP_REGDUMP2:
#endif
#if TRAPDUMP || (defined (TRAP_REGDUMP1)) || (defined (TRAP_REGDUMP2))
{
char buf[256];
int i, j;
buf[0] = 0;
if (STATE_TEXT_SECTION (sd)
&& pc >= STATE_TEXT_START (sd)
&& pc < STATE_TEXT_END (sd))
{
const char *pc_filename = (const char *)0;
const char *pc_function = (const char *)0;
unsigned int pc_linenum = 0;
if (bfd_find_nearest_line (STATE_PROG_BFD (sd),
STATE_TEXT_SECTION (sd),
(struct symbol_cache_entry **) 0,
pc - STATE_TEXT_START (sd),
&pc_filename, &pc_function, &pc_linenum)
&& (pc_function || pc_filename))
{
char *p = buf+2;
buf[0] = ' ';
buf[1] = '(';
if (pc_function)
{
strcpy (p, pc_function);
p += strlen (p);
}
else
{
char *q = (char *) strrchr (pc_filename, '/');
strcpy (p, (q) ? q+1 : pc_filename);
p += strlen (p);
}
if (pc_linenum)
{
sprintf (p, " line %d", pc_linenum);
p += strlen (p);
}
p[0] = ')';
p[1] = '\0';
if ((p+1) - buf > sizeof (buf))
abort ();
}
}
sim_io_printf (sd,
"\nRegister dump, pc = 0x%.8x%s, base = %u, offset = %d\n",
(unsigned)pc, buf, (unsigned)base, (int)offset);
for (i = 0; i < 64; i += 8)
{
long g0 = (long)GET_H_GR (i);
long g1 = (long)GET_H_GR (i+1);
long g2 = (long)GET_H_GR (i+2);
long g3 = (long)GET_H_GR (i+3);
long g4 = (long)GET_H_GR (i+4);
long g5 = (long)GET_H_GR (i+5);
long g6 = (long)GET_H_GR (i+6);
long g7 = (long)GET_H_GR (i+7);
if ((g0 | g1 | g2 | g3 | g4 | g5 | g6 | g7) != 0)
sim_io_printf (sd,
"\tgr%02d - gr%02d: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
i, i+7, g0, g1, g2, g3, g4, g5, g6, g7);
}
for (i = 0; i < 64; i += 8)
{
long f0 = (long)GET_H_FR (i);
long f1 = (long)GET_H_FR (i+1);
long f2 = (long)GET_H_FR (i+2);
long f3 = (long)GET_H_FR (i+3);
long f4 = (long)GET_H_FR (i+4);
long f5 = (long)GET_H_FR (i+5);
long f6 = (long)GET_H_FR (i+6);
long f7 = (long)GET_H_FR (i+7);
if ((f0 | f1 | f2 | f3 | f4 | f5 | f6 | f7) != 0)
sim_io_printf (sd,
"\tfr%02d - fr%02d: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
i, i+7, f0, f1, f2, f3, f4, f5, f6, f7);
}
sim_io_printf (sd,
"\tlr/lcr/cc/ccc: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
(long)GET_H_SPR (272),
(long)GET_H_SPR (273),
(long)GET_H_SPR (256),
(long)GET_H_SPR (263));
}
break;
#endif
}
}
/* Handle the MTRAP insn. */
void
frv_mtrap (SIM_CPU *current_cpu)
{
/* Check the status of media exceptions in MSR0. */
SI msr = GET_MSR (0);
if (GET_MSR_AOVF (msr) || GET_MSR_MTT (msr))
frv_queue_program_interrupt (current_cpu, FRV_MP_EXCEPTION);
}
/* Handle the BREAK insn. */
void
frv_break (SIM_CPU *current_cpu)
{
IADDR pc;
SIM_DESC sd = CPU_STATE (current_cpu);
#ifdef SIM_HAVE_BREAKPOINTS
/* First try sim-break.c. If it's a breakpoint the simulator "owns"
it doesn't return. Otherwise it returns and let's us try. */
pc = GET_H_PC ();
sim_handle_breakpoint (sd, current_cpu, pc);
/* Fall through. */
#endif
if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
{
/* Invalidate the insn cache because the debugger will presumably
replace the breakpoint insn with the real one. */
#ifndef SIM_HAVE_BREAKPOINTS
pc = GET_H_PC ();
#endif
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
}
frv_queue_break_interrupt (current_cpu);
}
/* Return from trap. */
USI
frv_rett (SIM_CPU *current_cpu, PCADDR pc, BI debug_field)
{
USI new_pc;
/* if (normal running mode and debug_field==0
PC=PCSR
PSR.ET=1
PSR.S=PSR.PS
else if (debug running mode and debug_field==1)
PC=(BPCSR)
PSR.ET=BPSR.BET
PSR.S=BPSR.BS
change to normal running mode
*/
int psr_s = GET_H_PSR_S ();
int psr_et = GET_H_PSR_ET ();
/* Check for exceptions in the priority order listed in the FRV Architecture
Volume 2. */
if (! psr_s)
{
/* Halt if PSR.ET is not set. See chapter 6 of the LSI. */
if (! psr_et)
{
SIM_DESC sd = CPU_STATE (current_cpu);
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
}
/* privileged_instruction interrupt will have already been queued by
frv_detect_insn_access_interrupts. */
new_pc = pc + 4;
}
else if (psr_et)
{
/* Halt if PSR.S is set. See chapter 6 of the LSI. */
if (psr_s)
{
SIM_DESC sd = CPU_STATE (current_cpu);
sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
}
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
new_pc = pc + 4;
}
else if (! CPU_DEBUG_STATE (current_cpu) && debug_field == 0)
{
USI psr = GET_PSR ();
/* Return from normal running state. */
new_pc = GET_H_SPR (H_SPR_PCSR);
SET_PSR_ET (psr, 1);
SET_PSR_S (psr, GET_PSR_PS (psr));
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, H_SPR_PSR, psr);
}
else if (CPU_DEBUG_STATE (current_cpu) && debug_field == 1)
{
USI psr = GET_PSR ();
/* Return from debug state. */
new_pc = GET_H_SPR (H_SPR_BPCSR);
SET_PSR_ET (psr, GET_H_BPSR_BET ());
SET_PSR_S (psr, GET_H_BPSR_BS ());
sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, H_SPR_PSR, psr);
CPU_DEBUG_STATE (current_cpu) = 0;
}
else
new_pc = pc + 4;
return new_pc;
}
/* Functions for handling non-excepting instruction side effects. */
static SI next_available_nesr (SIM_CPU *current_cpu, SI current_index)
{
FRV_REGISTER_CONTROL *control = CPU_REGISTER_CONTROL (current_cpu);
if (control->spr[H_SPR_NECR].implemented)
{
int limit;
USI necr = GET_NECR ();
/* See if any NESRs are implemented. First need to check the validity of
the NECR. */
if (! GET_NECR_VALID (necr))
return NO_NESR;
limit = GET_NECR_NEN (necr);
for (++current_index; current_index < limit; ++current_index)
{
SI nesr = GET_NESR (current_index);
if (! GET_NESR_VALID (nesr))
return current_index;
}
}
return NO_NESR;
}
static SI next_valid_nesr (SIM_CPU *current_cpu, SI current_index)
{
FRV_REGISTER_CONTROL *control = CPU_REGISTER_CONTROL (current_cpu);
if (control->spr[H_SPR_NECR].implemented)
{
int limit;
USI necr = GET_NECR ();
/* See if any NESRs are implemented. First need to check the validity of
the NECR. */
if (! GET_NECR_VALID (necr))
return NO_NESR;
limit = GET_NECR_NEN (necr);
for (++current_index; current_index < limit; ++current_index)
{
SI nesr = GET_NESR (current_index);
if (GET_NESR_VALID (nesr))
return current_index;
}
}
return NO_NESR;
}
BI
frvbf_check_non_excepting_load (
SIM_CPU *current_cpu, SI base_index, SI disp_index, SI target_index,
SI immediate_disp, QI data_size, BI is_float
)
{
BI rc = 1; /* perform the load. */
SIM_DESC sd = CPU_STATE (current_cpu);
int daec = 0;
int rec = 0;
int ec = 0;
USI necr;
int do_elos;
SI NE_flags[2];
SI NE_base;
SI nesr;
SI ne_index;
FRV_REGISTER_CONTROL *control;
SI address = GET_H_GR (base_index);
if (disp_index >= 0)
address += GET_H_GR (disp_index);
else
address += immediate_disp;
/* Check for interrupt factors. */
switch (data_size)
{
case NESR_UQI_SIZE:
case NESR_QI_SIZE:
break;
case NESR_UHI_SIZE:
case NESR_HI_SIZE:
if (address & 1)
ec = 1;
break;
case NESR_SI_SIZE:
if (address & 3)
ec = 1;
break;
case NESR_DI_SIZE:
if (address & 7)
ec = 1;
if (target_index & 1)
rec = 1;
break;
case NESR_XI_SIZE:
if (address & 0xf)
ec = 1;
if (target_index & 3)
rec = 1;
break;
default:
{
IADDR pc = GET_H_PC ();
sim_engine_abort (sd, current_cpu, pc,
"check_non_excepting_load: Incorrect data_size\n");
break;
}
}
control = CPU_REGISTER_CONTROL (current_cpu);
if (control->spr[H_SPR_NECR].implemented)
{
necr = GET_NECR ();
do_elos = GET_NECR_VALID (necr) && GET_NECR_ELOS (necr);
}
else
do_elos = 0;
/* NECR, NESR, NEEAR are only implemented for the full frv machine. */
if (do_elos)
{
ne_index = next_available_nesr (current_cpu, NO_NESR);
if (ne_index == NO_NESR)
{
IADDR pc = GET_H_PC ();
sim_engine_abort (sd, current_cpu, pc,
"No available NESR register\n");
}
/* Fill in the basic fields of the NESR. */
nesr = GET_NESR (ne_index);
SET_NESR_VALID (nesr);
SET_NESR_EAV (nesr);
SET_NESR_DRN (nesr, target_index);
SET_NESR_SIZE (nesr, data_size);
SET_NESR_NEAN (nesr, ne_index);
if (is_float)
SET_NESR_FR (nesr);
else
CLEAR_NESR_FR (nesr);
/* Set the corresponding NEEAR. */
SET_NEEAR (ne_index, address);
SET_NESR_DAEC (nesr, 0);
SET_NESR_REC (nesr, 0);
SET_NESR_EC (nesr, 0);
}
/* Set the NE flag corresponding to the target register if an interrupt
factor was detected.
daec is not checked here yet, but is declared for future reference. */
if (is_float)
NE_base = H_SPR_FNER0;
else
NE_base = H_SPR_GNER0;
GET_NE_FLAGS (NE_flags, NE_base);
if (rec)
{
SET_NE_FLAG (NE_flags, target_index);
if (do_elos)
SET_NESR_REC (nesr, NESR_REGISTER_NOT_ALIGNED);
}
if (ec)
{
SET_NE_FLAG (NE_flags, target_index);
if (do_elos)
SET_NESR_EC (nesr, NESR_MEM_ADDRESS_NOT_ALIGNED);
}
if (do_elos)
SET_NESR (ne_index, nesr);
/* If no interrupt factor was detected then set the NE flag on the
target register if the NE flag on one of the input registers
is already set. */
if (! rec && ! ec && ! daec)
{
BI ne_flag = GET_NE_FLAG (NE_flags, base_index);
if (disp_index >= 0)
ne_flag |= GET_NE_FLAG (NE_flags, disp_index);
if (ne_flag)
{
SET_NE_FLAG (NE_flags, target_index);
rc = 0; /* Do not perform the load. */
}
else
CLEAR_NE_FLAG (NE_flags, target_index);
}
SET_NE_FLAGS (NE_base, NE_flags);
return rc; /* perform the load? */
}
/* Record state for media exception: media_cr_not_aligned. */
void
frvbf_media_cr_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
/* On the fr400 this generates an illegal_instruction interrupt. */
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
else
frv_set_mp_exception_registers (current_cpu, MTT_CR_NOT_ALIGNED, 0);
}
/* Record state for media exception: media_acc_not_aligned. */
void
frvbf_media_acc_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
/* On the fr400 this generates an illegal_instruction interrupt. */
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
else
frv_set_mp_exception_registers (current_cpu, MTT_ACC_NOT_ALIGNED, 0);
}
/* Record state for media exception: media_register_not_aligned. */
void
frvbf_media_register_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
/* On the fr400 this generates an illegal_instruction interrupt. */
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
else
frv_set_mp_exception_registers (current_cpu, MTT_INVALID_FR, 0);
}
/* Record state for media exception: media_overflow. */
void
frvbf_media_overflow (SIM_CPU *current_cpu, int sie)
{
frv_set_mp_exception_registers (current_cpu, MTT_OVERFLOW, sie);
}
/* Queue a division exception. */
enum frv_dtt
frvbf_division_exception (SIM_CPU *current_cpu, enum frv_dtt dtt,
int target_index, int non_excepting)
{
/* If there was an overflow and it is masked, then record it in
ISR.AEXC. */
USI isr = GET_ISR ();
if ((dtt & FRV_DTT_OVERFLOW) && GET_ISR_EDE (isr))
{
dtt &= ~FRV_DTT_OVERFLOW;
SET_ISR_AEXC (isr);
SET_ISR (isr);
}
if (dtt != FRV_DTT_NO_EXCEPTION)
{
if (non_excepting)
{
/* Non excepting instruction, simply set the NE flag for the target
register. */
SI NE_flags[2];
GET_NE_FLAGS (NE_flags, H_SPR_GNER0);
SET_NE_FLAG (NE_flags, target_index);
SET_NE_FLAGS (H_SPR_GNER0, NE_flags);
}
else
frv_queue_division_exception_interrupt (current_cpu, dtt);
}
return dtt;
}
void
frvbf_check_recovering_store (
SIM_CPU *current_cpu, PCADDR address, SI regno, int size, int is_float
)
{
FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
int reg_ix;
CPU_RSTR_INVALIDATE(current_cpu) = 0;
for (reg_ix = next_valid_nesr (current_cpu, NO_NESR);
reg_ix != NO_NESR;
reg_ix = next_valid_nesr (current_cpu, reg_ix))
{
if (address == GET_H_SPR (H_SPR_NEEAR0 + reg_ix))
{
SI nesr = GET_NESR (reg_ix);
int nesr_drn = GET_NESR_DRN (nesr);
BI nesr_fr = GET_NESR_FR (nesr);
SI remain;
/* Invalidate cache block containing this address.
If we need to count cycles, then the cache operation will be
initiated from the model profiling functions.
See frvbf_model_.... */
if (model_insn)
{
CPU_RSTR_INVALIDATE(current_cpu) = 1;
CPU_LOAD_ADDRESS (current_cpu) = address;
}
else
frv_cache_invalidate (cache, address, 1/* flush */);
/* Copy the stored value to the register indicated by NESR.DRN. */
for (remain = size; remain > 0; remain -= 4)
{
SI value;
if (is_float)
value = GET_H_FR (regno);
else
value = GET_H_GR (regno);
switch (size)
{
case 1:
value &= 0xff;
break;
case 2:
value &= 0xffff;
break;
default:
break;
}
if (nesr_fr)
sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, nesr_drn,
value);
else
sim_queue_fn_si_write (current_cpu, frvbf_h_gr_set, nesr_drn,
value);
nesr_drn++;
regno++;
}
break; /* Only consider the first matching register. */
}
} /* loop over active neear registers. */
}
static void
clear_nesr_neear (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
int reg_ix;
/* Only implemented for full frv. */
SIM_DESC sd = CPU_STATE (current_cpu);
if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_frv)
return;
/* Clear the appropriate NESR and NEEAR registers. */
for (reg_ix = next_valid_nesr (current_cpu, NO_NESR);
reg_ix != NO_NESR;
reg_ix = next_valid_nesr (current_cpu, reg_ix))
{
SI nesr;
/* The register is available, now check if it is active. */
nesr = GET_NESR (reg_ix);
if (GET_NESR_FR (nesr) == is_float)
{
if (target_index < 0 || GET_NESR_DRN (nesr) == target_index)
{
SET_NESR (reg_ix, 0);
SET_NEEAR (reg_ix, 0);
}
}
}
}
static void
clear_ne_flags (
SIM_CPU *current_cpu,
SI target_index,
int hi_available,
int lo_available,
SI NE_base
)
{
SI NE_flags[2];
int exception;
GET_NE_FLAGS (NE_flags, NE_base);
if (target_index >= 0)
CLEAR_NE_FLAG (NE_flags, target_index);
else
{
if (lo_available)
NE_flags[1] = 0;
if (hi_available)
NE_flags[0] = 0;
}
SET_NE_FLAGS (NE_base, NE_flags);
}
/* Return 1 if the given register is available, 0 otherwise. TARGET_INDEX==-1
means to check for any register available. */
static void
which_registers_available (
SIM_CPU *current_cpu, int *hi_available, int *lo_available, int is_float
)
{
if (is_float)
frv_fr_registers_available (current_cpu, hi_available, lo_available);
else
frv_gr_registers_available (current_cpu, hi_available, lo_available);
}
void
frvbf_clear_ne_flags (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
int hi_available;
int lo_available;
int exception;
SI NE_base;
USI necr;
FRV_REGISTER_CONTROL *control;
/* Check for availability of the target register(s). */
which_registers_available (current_cpu, & hi_available, & lo_available,
is_float);
/* Check to make sure that the target register is available. */
if (! frv_check_register_access (current_cpu, target_index,
hi_available, lo_available))
return;
/* Determine whether we're working with GR or FR registers. */
if (is_float)
NE_base = H_SPR_FNER0;
else
NE_base = H_SPR_GNER0;
/* Always clear the appropriate NE flags. */
clear_ne_flags (current_cpu, target_index, hi_available, lo_available,
NE_base);
/* Clear the appropriate NESR and NEEAR registers. */
control = CPU_REGISTER_CONTROL (current_cpu);
if (control->spr[H_SPR_NECR].implemented)
{
necr = GET_NECR ();
if (GET_NECR_VALID (necr) && GET_NECR_ELOS (necr))
clear_nesr_neear (current_cpu, target_index, is_float);
}
}
void
frvbf_commit (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
SI NE_base;
SI NE_flags[2];
BI NE_flag;
int exception;
int hi_available;
int lo_available;
USI necr;
FRV_REGISTER_CONTROL *control;
/* Check for availability of the target register(s). */
which_registers_available (current_cpu, & hi_available, & lo_available,
is_float);
/* Check to make sure that the target register is available. */
if (! frv_check_register_access (current_cpu, target_index,
hi_available, lo_available))
return;
/* Determine whether we're working with GR or FR registers. */
if (is_float)
NE_base = H_SPR_FNER0;
else
NE_base = H_SPR_GNER0;
/* Determine whether a ne exception is pending. */
GET_NE_FLAGS (NE_flags, NE_base);
if (target_index >= 0)
NE_flag = GET_NE_FLAG (NE_flags, target_index);
else
{
NE_flag =
hi_available && NE_flags[0] != 0 || lo_available && NE_flags[1] != 0;
}
/* Always clear the appropriate NE flags. */
clear_ne_flags (current_cpu, target_index, hi_available, lo_available,
NE_base);
control = CPU_REGISTER_CONTROL (current_cpu);
if (control->spr[H_SPR_NECR].implemented)
{
necr = GET_NECR ();
if (GET_NECR_VALID (necr) && GET_NECR_ELOS (necr) && NE_flag)
{
/* Clear the appropriate NESR and NEEAR registers. */
clear_nesr_neear (current_cpu, target_index, is_float);
frv_queue_program_interrupt (current_cpu, FRV_COMMIT_EXCEPTION);
}
}
}
/* Generate the appropriate fp_exception(s) based on the given status code. */
void
frvbf_fpu_error (CGEN_FPU* fpu, int status)
{
struct frv_fp_exception_info fp_info = {
FSR_NO_EXCEPTION, FTT_IEEE_754_EXCEPTION
};
if (status &
(sim_fpu_status_invalid_snan |
sim_fpu_status_invalid_qnan |
sim_fpu_status_invalid_isi |
sim_fpu_status_invalid_idi |
sim_fpu_status_invalid_zdz |
sim_fpu_status_invalid_imz |
sim_fpu_status_invalid_cvi |
sim_fpu_status_invalid_cmp |
sim_fpu_status_invalid_sqrt))
fp_info.fsr_mask |= FSR_INVALID_OPERATION;
if (status & sim_fpu_status_invalid_div0)
fp_info.fsr_mask |= FSR_DIVISION_BY_ZERO;
if (status & sim_fpu_status_inexact)
fp_info.fsr_mask |= FSR_INEXACT;
if (status & sim_fpu_status_overflow)
fp_info.fsr_mask |= FSR_OVERFLOW;
if (status & sim_fpu_status_underflow)
fp_info.fsr_mask |= FSR_UNDERFLOW;
if (status & sim_fpu_status_denorm)
{
fp_info.fsr_mask |= FSR_DENORMAL_INPUT;
fp_info.ftt = FTT_DENORMAL_INPUT;
}
if (fp_info.fsr_mask != FSR_NO_EXCEPTION)
{
SIM_CPU *current_cpu = (SIM_CPU *)fpu->owner;
frv_queue_fp_exception_interrupt (current_cpu, & fp_info);
}
}