New simulator for Fujitsu frv contributed by Red Hat.
This commit is contained in:
parent
60fac5b81a
commit
b34f6357d0
2358
sim/frv/ChangeLog
Normal file
2358
sim/frv/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
133
sim/frv/Makefile.in
Normal file
133
sim/frv/Makefile.in
Normal 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
10
sim/frv/README
Normal 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
8
sim/frv/TODO
Normal 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
47
sim/frv/arch.c
Normal 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
69
sim/frv/arch.h
Normal 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
1561
sim/frv/cache.c
Normal file
File diff suppressed because it is too large
Load Diff
262
sim/frv/cache.h
Normal file
262
sim/frv/cache.h
Normal 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
162
sim/frv/config.in
Normal 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
4315
sim/frv/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
31
sim/frv/configure.in
Normal file
31
sim/frv/configure.in
Normal 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
677
sim/frv/cpu.c
Normal 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
4310
sim/frv/cpu.h
Normal file
File diff suppressed because it is too large
Load Diff
70
sim/frv/cpuall.h
Normal file
70
sim/frv/cpuall.h
Normal 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
10891
sim/frv/decode.c
Normal file
File diff suppressed because it is too large
Load Diff
399
sim/frv/decode.h
Normal file
399
sim/frv/decode.h
Normal 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
96
sim/frv/devices.c
Normal 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
916
sim/frv/frv-sim.h
Normal 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
1419
sim/frv/frv.c
Normal file
File diff suppressed because it is too large
Load Diff
1329
sim/frv/interrupts.c
Normal file
1329
sim/frv/interrupts.c
Normal file
File diff suppressed because it is too large
Load Diff
750
sim/frv/memory.c
Normal file
750
sim/frv/memory.c
Normal 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
514
sim/frv/mloop.in
Normal 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
72726
sim/frv/model.c
Normal file
File diff suppressed because it is too large
Load Diff
237
sim/frv/options.c
Normal file
237
sim/frv/options.c
Normal 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
92
sim/frv/pipeline.c
Normal 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
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
31
sim/frv/profile-fr400.h
Normal 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
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
30
sim/frv/profile-fr500.h
Normal 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
1807
sim/frv/profile.c
Normal file
File diff suppressed because it is too large
Load Diff
194
sim/frv/profile.h
Normal file
194
sim/frv/profile.h
Normal 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
4405
sim/frv/registers.c
Normal file
File diff suppressed because it is too large
Load Diff
59
sim/frv/registers.h
Normal file
59
sim/frv/registers.h
Normal 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
151
sim/frv/reset.c
Normal 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
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
251
sim/frv/sim-if.c
Normal 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
139
sim/frv/sim-main.h
Normal 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
42
sim/frv/tconfig.in
Normal 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
931
sim/frv/traps.c
Normal 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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user