URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/tags/rel-0-3-0-rc2/or1ksim/cpu
- from Rev 1753 to Rev 1765
- ↔ Reverse comparison
Rev 1753 → Rev 1765
/dlx/arch.h
0,0 → 1,28
/* arch.h -- DLX architecture specific macros |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
#define LINK_REG "r31" |
#define STACK_REG "r29" |
#define FRAME_REG "r30" |
|
#define MAX_GPRS 32 |
typedef unsigned long machword; |
|
/* Should args be passed on stack */ |
#define STACK_ARGS 1 |
/dlx/Makefile.in
0,0 → 1,471
# Makefile.in generated by automake 1.10.1 from Makefile.am. |
# @configure_input@ |
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
# This Makefile.in is free software; the Free Software Foundation |
# gives unlimited permission to copy and/or distribute it, |
# with or without modifications, as long as this notice is preserved. |
|
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without |
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
# PARTICULAR PURPOSE. |
|
@SET_MAKE@ |
|
# Makefile -- Makefile for DLX architecture dependent simulation |
# |
# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
# Copyright (C) 2008 Embecosm Limited |
# |
# Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
# |
# This file is part of OpenRISC 1000 Architectural Simulator. |
# |
# 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 3 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, see <http://www.gnu.org/licenses/>. |
|
VPATH = @srcdir@ |
pkgdatadir = $(datadir)/@PACKAGE@ |
pkglibdir = $(libdir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd |
install_sh_DATA = $(install_sh) -c -m 644 |
install_sh_PROGRAM = $(install_sh) -c |
install_sh_SCRIPT = $(install_sh) -c |
INSTALL_HEADER = $(INSTALL_DATA) |
transform = $(program_transform_name) |
NORMAL_INSTALL = : |
PRE_INSTALL = : |
POST_INSTALL = : |
NORMAL_UNINSTALL = : |
PRE_UNINSTALL = : |
POST_UNINSTALL = : |
build_triplet = @build@ |
host_triplet = @host@ |
target_triplet = @target@ |
subdir = cpu/dlx |
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in |
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
am__aclocal_m4_deps = $(top_srcdir)/configure.ac |
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ |
$(ACLOCAL_M4) |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = $(top_builddir)/config.h |
CONFIG_CLEAN_FILES = |
LTLIBRARIES = $(noinst_LTLIBRARIES) |
libarch_la_LIBADD = |
am_libarch_la_OBJECTS = execute.lo |
libarch_la_OBJECTS = $(am_libarch_la_OBJECTS) |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
am__depfiles_maybe = depfiles |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ |
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ |
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ |
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ |
$(LDFLAGS) -o $@ |
SOURCES = $(libarch_la_SOURCES) |
DIST_SOURCES = $(libarch_la_SOURCES) |
ETAGS = etags |
CTAGS = ctags |
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) |
ACLOCAL = @ACLOCAL@ |
AMTAR = @AMTAR@ |
AR = @AR@ |
ARFLAGS = @ARFLAGS@ |
AUTOCONF = @AUTOCONF@ |
AUTOHEADER = @AUTOHEADER@ |
AUTOMAKE = @AUTOMAKE@ |
AWK = @AWK@ |
BUILD_DIR = @BUILD_DIR@ |
CC = @CC@ |
CCDEPMODE = @CCDEPMODE@ |
CFLAGS = @CFLAGS@ |
CPP = @CPP@ |
CPPFLAGS = @CPPFLAGS@ |
CPU_ARCH = @CPU_ARCH@ |
CXX = @CXX@ |
CXXCPP = @CXXCPP@ |
CXXDEPMODE = @CXXDEPMODE@ |
CXXFLAGS = @CXXFLAGS@ |
CYGPATH_W = @CYGPATH_W@ |
DEBUGFLAGS = @DEBUGFLAGS@ |
DEFS = @DEFS@ |
DEPDIR = @DEPDIR@ |
ECHO = @ECHO@ |
ECHO_C = @ECHO_C@ |
ECHO_N = @ECHO_N@ |
ECHO_T = @ECHO_T@ |
EGREP = @EGREP@ |
EXEEXT = @EXEEXT@ |
F77 = @F77@ |
FFLAGS = @FFLAGS@ |
GREP = @GREP@ |
INCLUDES = @INCLUDES@ |
INSTALL = @INSTALL@ |
INSTALL_DATA = @INSTALL_DATA@ |
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
LDFLAGS = @LDFLAGS@ |
LIBOBJS = @LIBOBJS@ |
LIBS = @LIBS@ |
LIBTOOL = @LIBTOOL@ |
LN_S = @LN_S@ |
LOCAL_CFLAGS = @LOCAL_CFLAGS@ |
LOCAL_DEFS = @LOCAL_DEFS@ |
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@ |
LTLIBOBJS = @LTLIBOBJS@ |
MAKEINFO = @MAKEINFO@ |
MAKE_SHELL = @MAKE_SHELL@ |
MKDIR_P = @MKDIR_P@ |
OBJEXT = @OBJEXT@ |
PACKAGE = @PACKAGE@ |
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ |
PACKAGE_NAME = @PACKAGE_NAME@ |
PACKAGE_STRING = @PACKAGE_STRING@ |
PACKAGE_TARNAME = @PACKAGE_TARNAME@ |
PACKAGE_VERSION = @PACKAGE_VERSION@ |
PATH_SEPARATOR = @PATH_SEPARATOR@ |
POW_LIB = @POW_LIB@ |
RANLIB = @RANLIB@ |
SED = @SED@ |
SET_MAKE = @SET_MAKE@ |
SHELL = @SHELL@ |
STRIP = @STRIP@ |
SUMVERSION = @SUMVERSION@ |
TERMCAP_LIB = @TERMCAP_LIB@ |
VERSION = @VERSION@ |
abs_builddir = @abs_builddir@ |
abs_srcdir = @abs_srcdir@ |
abs_top_builddir = @abs_top_builddir@ |
abs_top_srcdir = @abs_top_srcdir@ |
ac_ct_CC = @ac_ct_CC@ |
ac_ct_CXX = @ac_ct_CXX@ |
ac_ct_F77 = @ac_ct_F77@ |
am__include = @am__include@ |
am__leading_dot = @am__leading_dot@ |
am__quote = @am__quote@ |
am__tar = @am__tar@ |
am__untar = @am__untar@ |
bindir = @bindir@ |
build = @build@ |
build_alias = @build_alias@ |
build_cpu = @build_cpu@ |
build_os = @build_os@ |
build_vendor = @build_vendor@ |
builddir = @builddir@ |
datadir = @datadir@ |
datarootdir = @datarootdir@ |
docdir = @docdir@ |
dvidir = @dvidir@ |
exec_prefix = @exec_prefix@ |
host = @host@ |
host_alias = @host_alias@ |
host_cpu = @host_cpu@ |
host_os = @host_os@ |
host_vendor = @host_vendor@ |
htmldir = @htmldir@ |
includedir = @includedir@ |
infodir = @infodir@ |
install_sh = @install_sh@ |
libdir = @libdir@ |
libexecdir = @libexecdir@ |
localedir = @localedir@ |
localstatedir = @localstatedir@ |
mandir = @mandir@ |
mkdir_p = @mkdir_p@ |
oldincludedir = @oldincludedir@ |
pdfdir = @pdfdir@ |
prefix = @prefix@ |
program_transform_name = @program_transform_name@ |
psdir = @psdir@ |
sbindir = @sbindir@ |
sharedstatedir = @sharedstatedir@ |
srcdir = @srcdir@ |
sysconfdir = @sysconfdir@ |
target = @target@ |
target_alias = @target_alias@ |
target_cpu = @target_cpu@ |
target_os = @target_os@ |
target_vendor = @target_vendor@ |
top_builddir = @top_builddir@ |
top_srcdir = @top_srcdir@ |
noinst_LTLIBRARIES = libarch.la |
libarch_la_SOURCES = execute.c \ |
arch.h |
|
all: all-am |
|
.SUFFIXES: |
.SUFFIXES: .c .lo .o .obj |
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) |
@for dep in $?; do \ |
case '$(am__configure_deps)' in \ |
*$$dep*) \ |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ |
&& exit 0; \ |
exit 1;; \ |
esac; \ |
done; \ |
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/dlx/Makefile'; \ |
cd $(top_srcdir) && \ |
$(AUTOMAKE) --gnu cpu/dlx/Makefile |
.PRECIOUS: Makefile |
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
@case '$?' in \ |
*config.status*) \ |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ |
*) \ |
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ |
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ |
esac; |
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
|
$(top_srcdir)/configure: $(am__configure_deps) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(ACLOCAL_M4): $(am__aclocal_m4_deps) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
|
clean-noinstLTLIBRARIES: |
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) |
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ |
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ |
test "$$dir" != "$$p" || dir=.; \ |
echo "rm -f \"$${dir}/so_locations\""; \ |
rm -f "$${dir}/so_locations"; \ |
done |
libarch.la: $(libarch_la_OBJECTS) $(libarch_la_DEPENDENCIES) |
$(LINK) $(libarch_la_OBJECTS) $(libarch_la_LIBADD) $(LIBS) |
|
mostlyclean-compile: |
-rm -f *.$(OBJEXT) |
|
distclean-compile: |
-rm -f *.tab.c |
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Plo@am__quote@ |
|
.c.o: |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(COMPILE) -c $< |
|
.c.obj: |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` |
|
.c.lo: |
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< |
|
mostlyclean-libtool: |
-rm -f *.lo |
|
clean-libtool: |
-rm -rf .libs _libs |
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
mkid -fID $$unique |
tags: TAGS |
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ |
$(TAGS_FILES) $(LISP) |
tags=; \ |
here=`pwd`; \ |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ |
test -n "$$unique" || unique=$$empty_fix; \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
$$tags $$unique; \ |
fi |
ctags: CTAGS |
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ |
$(TAGS_FILES) $(LISP) |
tags=; \ |
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | \ |
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in files) print i; }; }'`; \ |
test -z "$(CTAGS_ARGS)$$tags$$unique" \ |
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ |
$$tags $$unique |
|
GTAGS: |
here=`$(am__cd) $(top_builddir) && pwd` \ |
&& cd $(top_srcdir) \ |
&& gtags -i $(GTAGS_ARGS) $$here |
|
distclean-tags: |
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags |
|
distdir: $(DISTFILES) |
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ |
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ |
list='$(DISTFILES)'; \ |
dist_files=`for file in $$list; do echo $$file; done | \ |
sed -e "s|^$$srcdirstrip/||;t" \ |
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ |
case $$dist_files in \ |
*/*) $(MKDIR_P) `echo "$$dist_files" | \ |
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ |
sort -u` ;; \ |
esac; \ |
for file in $$dist_files; do \ |
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ |
if test -d $$d/$$file; then \ |
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ |
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ |
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ |
fi; \ |
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ |
else \ |
test -f $(distdir)/$$file \ |
|| cp -p $$d/$$file $(distdir)/$$file \ |
|| exit 1; \ |
fi; \ |
done |
check-am: all-am |
check: check-am |
all-am: Makefile $(LTLIBRARIES) |
installdirs: |
install: install-am |
install-exec: install-exec-am |
install-data: install-data-am |
uninstall: uninstall-am |
|
install-am: all-am |
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am |
|
installcheck: installcheck-am |
install-strip: |
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ |
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ |
`test -z '$(STRIP)' || \ |
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install |
mostlyclean-generic: |
|
clean-generic: |
|
distclean-generic: |
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) |
|
maintainer-clean-generic: |
@echo "This command is intended for maintainers to use" |
@echo "it deletes files that may require special tools to rebuild." |
clean: clean-am |
|
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ |
mostlyclean-am |
|
distclean: distclean-am |
-rm -rf ./$(DEPDIR) |
-rm -f Makefile |
distclean-am: clean-am distclean-compile distclean-generic \ |
distclean-tags |
|
dvi: dvi-am |
|
dvi-am: |
|
html: html-am |
|
info: info-am |
|
info-am: |
|
install-data-am: |
|
install-dvi: install-dvi-am |
|
install-exec-am: |
|
install-html: install-html-am |
|
install-info: install-info-am |
|
install-man: |
|
install-pdf: install-pdf-am |
|
install-ps: install-ps-am |
|
installcheck-am: |
|
maintainer-clean: maintainer-clean-am |
-rm -rf ./$(DEPDIR) |
-rm -f Makefile |
maintainer-clean-am: distclean-am maintainer-clean-generic |
|
mostlyclean: mostlyclean-am |
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic \ |
mostlyclean-libtool |
|
pdf: pdf-am |
|
pdf-am: |
|
ps: ps-am |
|
ps-am: |
|
uninstall-am: |
|
.MAKE: install-am install-strip |
|
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ |
clean-libtool clean-noinstLTLIBRARIES ctags distclean \ |
distclean-compile distclean-generic distclean-libtool \ |
distclean-tags distdir dvi dvi-am html html-am info info-am \ |
install install-am install-data install-data-am install-dvi \ |
install-dvi-am install-exec install-exec-am install-html \ |
install-html-am install-info install-info-am install-man \ |
install-pdf install-pdf-am install-ps install-ps-am \ |
install-strip installcheck installcheck-am installdirs \ |
maintainer-clean maintainer-clean-generic mostlyclean \ |
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ |
pdf pdf-am ps ps-am tags uninstall uninstall-am |
|
# Tell versions [3.59,3.63) of GNU make to not export all variables. |
# Otherwise a system limit (for SysV at least) may be exceeded. |
.NOEXPORT: |
/dlx/Makefile.am
0,0 → 1,26
# Makefile -- Makefile for DLX architecture dependent simulation |
# |
# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
# Copyright (C) 2008 Embecosm Limited |
# |
# Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> |
# |
# This file is part of OpenRISC 1000 Architectural Simulator. |
# |
# 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 3 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, see <http://www.gnu.org/licenses/>. |
|
|
noinst_LTLIBRARIES = libarch.la |
libarch_la_SOURCES = execute.c \ |
arch.h |
/dlx/execute.c
0,0 → 1,754
/* execute.c -- DLX dependent simulation |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
/* Most of the DLX simulation is done in this file. */ |
|
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
|
#include "arch.h" |
|
#include "branch_predict.h" |
#include "abstract.h" |
#include "parse.h" |
#include "trace.h" |
#include "execute.h" |
#include "stats.h" |
|
/* General purpose registers. */ |
machword reg[MAX_GPRS]; |
|
/* Instruction queue */ |
struct iqueue_entry iqueue[20]; |
|
/* Benchmark multi issue execution */ |
int multissue[20]; |
int supercycles; |
|
/* Load and store stalls */ |
int loadcycles, storecycles; |
|
/* Result forwarding stall cycles */ |
int forwardingcycles; |
|
/* Completition queue */ |
struct icomplet_entry icomplet[20]; |
|
/* Program counter */ |
unsigned long pc; |
|
/* Temporary program counter */ |
unsigned long pctemp; |
|
/* Cycles counts fetch stages */ |
int cycles; |
|
/* Implementation specific. |
Get an actual value of a specific register. */ |
|
machword eval_reg(char *regstr) |
{ |
int regno; |
|
regno = atoi(regstr + 1); |
|
if (regno < MAX_GPRS) |
return reg[regno]; |
else { |
PRINTF("\nABORT: read out of registers\n"); |
cont_run = 0; |
return 0; |
} |
} |
|
/* Implementation specific. |
Set a specific register with value. */ |
|
void set_reg32(char *regstr, unsigned long value) |
{ |
int regno; |
|
regno = atoi(regstr + 1); |
|
if (regno == 0) /* gpr0 is always zero */ |
value = 0; |
|
if (regno < MAX_GPRS) |
reg[regno] = value; |
else { |
PRINTF("\nABORT: write out of registers\n"); |
cont_run = 0; |
} |
|
return; |
} |
|
/* Does srcoperand depend on computation of dstoperand? Return |
non-zero if yes. |
|
Cycle t Cycle t+1 |
dst: irrelevant src: immediate always 0 |
dst: reg1 direct src: reg2 direct 0 if reg1 != reg2 |
dst: reg1 disp src: reg2 direct always 0 |
dst: reg1 direct src: reg2 disp 0 if reg1 != reg2 |
dst: reg1 disp src: reg2 disp always 1 (store must |
finish before load) |
*/ |
|
int depend_operands(char *dstoperand, char *srcoperand) |
{ |
char dst[OPERANDNAME_LEN]; |
char src[OPERANDNAME_LEN]; |
|
if (!srcoperand) |
return 0; |
|
if (!dstoperand) |
return 0; |
|
strcpy(dst, dstoperand); |
strcpy(src, srcoperand); |
|
if (*src == '#') /* immediate */ |
return 0; |
else |
if (!strstr(src, "(")) |
if (*src == 'r') { /* src: reg direct */ |
if (!strstr(dst, "(")) |
if (*dst == 'r') |
if (strcmp(dst, src) == 0) |
return 1; /* dst: reg direct */ |
else |
return 0; /* dst: reg direct */ |
else |
return 0; /* dst: addr */ |
else |
return 0; /* dst: reg disp */ |
} else |
return 0; /* src: addr */ |
else { /* src: register disp */ |
char *regstr; |
|
regstr = strstr(src, "(r") + 1; /* regstr == "rXX)" */ |
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
|
if (!strstr(dst, "(")) |
if (*dst == 'r') |
if (strcmp(dst, regstr) == 0) |
return 1; /* dst: reg direct */ |
else |
return 0; /* dst: reg direct */ |
else |
return 0; /* dst: addr */ |
else |
return 1; /* dst: reg disp */ |
} |
|
return 0; |
} |
|
/* Implementation specific. |
Get an actual value represented by operand (register direct, register |
indirect (with displacement), immediate etc.). |
|
#n - immediate n |
rXX - register direct |
XX - relative or absolute address (labels) |
n(XX) - register indirect (with displacement) */ |
|
machword eval_operand(char *srcoperand,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
strcpy(operand, srcoperand); |
|
if (*operand == '#') /* immediate */ |
return strtoul(&operand[1], NULL, 0); |
else |
if (!strstr(operand, "(")) /* not indirect but ...*/ |
if (*operand == 'r') /* ... register direct */ |
return eval_reg(operand); |
|
else /* ... rel. or abs. address */ |
return eval_label(operand); |
else { /* register indirect */ |
int disp; /* with possible displacement */ |
char *regstr; |
unsigned int memaddr; |
|
disp = atoi(operand); /* operand == "nn(rXX)" */ |
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */ |
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
return eval_mem32(memaddr,breakpoint); |
} |
|
return 0; |
} |
|
/* Implementation specific. |
Set destination operand (register direct, register indirect |
(with displacement) with value. */ |
|
void set_operand(char *dstoperand, unsigned long value,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
strcpy(operand, dstoperand); |
|
if (*operand == '#') /* immediate */ |
PRINTF("INTERNAL ERROR: Can't set immediate operand.\n"); |
else |
if (!strstr(operand, "(")) /* not indirect but ...*/ |
if (*operand == 'r') /* ... register direct */ |
set_reg32(operand, value); |
else /* ... rel. or abs. address */ |
PRINTF("INTERNAL ERROR: Can't set addr operand.\n"); |
else { /* register indirect */ |
int disp; /* with possible displacement */ |
char *regstr; |
unsigned int memaddr; |
|
disp = atoi(operand); /* operand == "nn(rXX)" */ |
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */ |
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
set_mem32(memaddr, value, breakpoint); |
} |
|
return; |
} |
|
void reset() |
{ |
cycles = 0; |
supercycles = 0; |
loadcycles = 0; |
storecycles = 0; |
forwardingcycles = 0; |
memset(reg, 0, sizeof(reg)); |
memset(iqueue, 0, sizeof(iqueue)); |
memset(icomplet, 0, sizeof(icomplet)); |
pctemp = eval_label("_main"); |
pc = pctemp; |
set_reg32(STACK_REG , MEMORY_LEN - STACK_SIZE); |
} |
|
void fetch() |
{ |
/* Cycles after reset. */ |
cycles++; |
|
/* Simulate instruction cache */ |
ic_simulate(pc); |
|
/* Fetch instruction. */ |
strcpy(iqueue[0].insn, mem[pc].insn->insn); |
strcpy(iqueue[0].op1, mem[pc].insn->op1); |
strcpy(iqueue[0].op2, mem[pc].insn->op2); |
strcpy(iqueue[0].op3, mem[pc].insn->op3); |
iqueue[0].insn_addr = pc; |
iqueue[0].dependdst = NULL; |
iqueue[0].dependsrc1 = NULL; |
iqueue[0].dependsrc2 = NULL; |
|
/* Increment program counter. */ |
pc = pctemp; |
pctemp += 4; |
|
/* Check for breakpoint. */ |
if (mem[pc].brk) |
cont_run = 0; /* Breakpoint set. */ |
|
return; |
} |
|
void decode(struct iqueue_entry *cur) |
{ |
int breakpoint = 0; |
|
cur->dependdst = cur->op1; |
cur->dependsrc1 = cur->op2; /* for calculating register */ |
cur->dependsrc2 = cur->op3; /* dependency */ |
|
cur->func_unit = unknown; |
|
if (strcmp(cur->insn, "sw") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "sb") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "sh") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "lw") == 0) { |
cur->func_unit = load; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "lb") == 0) { |
signed char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lbu") == 0) { |
unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lh") == 0) { |
signed short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lhu") == 0) { |
unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lwi") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "lhi") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << 16,&breakpoint); |
} else |
if (strcmp(cur->insn, "and") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "andi") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "or") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "ori") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "xor") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "add") == 0) { |
signed long temp3, temp2, temp1; |
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} else |
if (strcmp(cur->insn, "addi") == 0) { |
signed long temp3, temp2, temp1; |
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} else |
if (strcmp(cur->insn, "addui") == 0) { |
unsigned long temp3, temp2, temp1; |
unsigned char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} else |
if (strcmp(cur->insn, "sub") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "subui") == 0) { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "subi") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "mul") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 * temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "div") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "divu") == 0) { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "slli") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "sll") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "srl") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) >> eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "srai") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint); |
} else |
if (strcmp(cur->insn, "sra") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint); |
} else |
if (strcmp(cur->insn, "jal") == 0) { |
cur->func_unit = jump; |
pctemp = eval_operand(cur->op1,&breakpoint); |
set_reg32(LINK_REG, pc + 4); |
} else |
if (strcmp(cur->insn, "jr") == 0) { |
cur->func_unit = jump; |
cur->dependsrc1 = cur->op1; |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
if (strcmp(cur->insn, "j") == 0) { |
cur->func_unit = jump; |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
if (strcmp(cur->insn, "nop") == 0) { |
cur->func_unit = nop; |
} else |
if (strcmp(cur->insn, "beqz") == 0) { |
cur->func_unit = branch; |
cur->dependsrc1 = cur->op1; |
if (eval_operand(cur->op1,&breakpoint) == 0) { |
pctemp = eval_operand(cur->op2,&breakpoint); |
mstats.beqz.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
} else { |
mstats.beqz.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} else |
if (strcmp(cur->insn, "bnez") == 0) { |
cur->func_unit = branch; |
cur->dependsrc1 = cur->op1; |
if (eval_operand(cur->op1,&breakpoint) != 0) { |
pctemp = eval_operand(cur->op2,&breakpoint); |
mstats.bnez.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
} else { |
mstats.bnez.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} else |
if (strcmp(cur->insn, "seq") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "snei") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sne") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "seqi") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgt") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) > |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgtui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2,&breakpoint) > |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgeui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2,&breakpoint) >= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgei") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) >= (signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgti") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) > |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slt") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) < |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slti") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) < |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sle") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) <= |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slei") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2,&breakpoint) <= |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sleui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2,&breakpoint) <= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sleu") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2,&breakpoint) <= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "simrdtsc") == 0) { |
set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles,&breakpoint); |
} else |
if (strcmp(cur->insn, "simprintf") == 0) { |
unsigned long stackaddr; |
|
stackaddr = eval_reg(FRAME_REG); |
simprintf(stackaddr, 0); |
/* PRINTF("simprintf %x %x %x\n", stackaddr, fmtaddr, args); */ |
} else { |
PRINTF("\nABORT: illegal opcode %s ", cur->insn); |
PRINTF("at %.8lx\n", cur->insn_addr); |
cont_run = 0; |
} |
|
/* Dynamic, dependency stats. */ |
adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend()); |
|
/* Dynamic, functional units stats. */ |
addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend()); |
|
/* Dynamic, single stats. */ |
addsstats(iqueue[0].insn, 1, 0); |
|
if (cur->func_unit == store) |
storecycles += 0; |
|
if (cur->func_unit == load) |
loadcycles += 0; |
|
if (check_depend()) |
forwardingcycles += 0; |
|
/* Pseudo multiple issue benchmark */ |
if ((multissue[cur->func_unit] == 0) || (check_depend())) { |
int i; |
for (i = 0; i < 20; i++) |
multissue[i] = 9; |
supercycles++; |
multissue[arith] = 9; |
multissue[store] = 9; |
multissue[load] = 9; |
} |
multissue[cur->func_unit]--; |
|
return; |
} |
|
void execute() |
{ |
int i; |
|
/* Here comes real execution someday... */ |
|
/* Instruction waits in completition buffer until retired. */ |
strcpy(icomplet[0].insn, iqueue[0].insn); |
strcpy(icomplet[0].op1, iqueue[0].op1); |
strcpy(icomplet[0].op2, iqueue[0].op2); |
strcpy(icomplet[0].op3, iqueue[0].op3); |
icomplet[0].func_unit = iqueue[0].func_unit; |
icomplet[0].insn_addr = iqueue[0].insn_addr; |
|
if (iqueue[0].dependdst == iqueue[0].op1) |
icomplet[0].dependdst = icomplet[0].op1; |
else |
if (iqueue[0].dependdst == iqueue[0].op2) |
icomplet[0].dependdst = icomplet[0].op2; |
else |
if (iqueue[0].dependdst == iqueue[0].op3) |
icomplet[0].dependdst = icomplet[0].op3; |
else |
icomplet[0].dependdst = NULL; |
|
if (iqueue[0].dependsrc1 == iqueue[0].op1) |
icomplet[0].dependsrc1 = icomplet[0].op1; |
else |
if (iqueue[0].dependsrc1 == iqueue[0].op2) |
icomplet[0].dependsrc1 = icomplet[0].op2; |
else |
if (iqueue[0].dependsrc1 == iqueue[0].op3) |
icomplet[0].dependsrc1 = icomplet[0].op3; |
else |
icomplet[0].dependsrc1 = NULL; |
|
if (iqueue[0].dependsrc2 == iqueue[0].op1) |
icomplet[0].dependsrc2 = icomplet[0].op1; |
else |
if (iqueue[0].dependsrc2 == iqueue[0].op2) |
icomplet[0].dependsrc2 = icomplet[0].op2; |
else |
if (iqueue[0].dependsrc2 == iqueue[0].op3) |
icomplet[0].dependsrc2 = icomplet[0].op3; |
else |
icomplet[0].dependsrc2 = NULL; |
|
/* History of execution */ |
for (i = HISTEXEC_LEN - 1; i; i--) |
histexec[i] = histexec[i - 1]; |
histexec[0] = icomplet[0].insn_addr; /* add last insn */ |
|
return; |
} |
|
void dumpreg() |
{ |
int i; |
|
PRINTF("\n\nIQ[0]:"); |
dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4); |
PRINTF(" (just executed)\tCYCLES: %u \nSuperscalar CYCLES: %u\n", cycles, supercycles); |
PRINTF("Additional LOAD CYCLES: %u STORE CYCLES: %u\n", loadcycles, storecycles); |
PRINTF("Additional RESULT FORWARDING CYCLES: %u\nPC:", forwardingcycles); |
dumpmemory(pc, pc + 4); |
PRINTF(" (next insn)"); |
for(i = 0; i < MAX_GPRS; i++) { |
if (i % 4 == 0) |
PRINTF("\n"); |
PRINTF("GPR%.2u: %.8lx ", i, reg[i]); |
} |
} |
dlx
Property changes :
Added: svn:ignore
## -0,0 +1 ##
+Makefile
Index: or32/Makefile.in
===================================================================
--- or32/Makefile.in (nonexistent)
+++ or32/Makefile.in (revision 1765)
@@ -0,0 +1,775 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile -- Makefile for OR32 dependent simulation
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@noinst_PROGRAMS = generate$(EXEEXT)
+@DYNAMIC_EXECUTION_TRUE@noinst_PROGRAMS = dyngen$(EXEEXT)
+subdir = cpu/or32
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libarch_la_LIBADD =
+am__libarch_la_SOURCES_DIST = execute.c or32.c common-i386.h \
+ dyn32-defs.h dyngen.h dyn-rec.h i386-regs.h op-arith-op.h \
+ op-comp-op.h op-extend-op.h op-ff1-op.h op-i386.h op-lwhb-op.h \
+ op-mac-op.h op-mftspr-op.h op-support.h op-swhb-op.h \
+ op-t-reg-mov-op.h rec-i386.h sched-i386.h simpl32-defs.h op.c \
+ dyn-rec.c op-support.c
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@am_libarch_la_OBJECTS = \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ execute.lo \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ or32.lo
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@am_libarch_la_OBJECTS = \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ execute.lo \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ or32.lo
+@DYNAMIC_EXECUTION_TRUE@am_libarch_la_OBJECTS = execute.lo or32.lo \
+@DYNAMIC_EXECUTION_TRUE@ op.lo dyn-rec.lo op-support.lo
+@DYNAMIC_EXECUTION_TRUE@nodist_libarch_la_OBJECTS = gen-ops.lo \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops-gen.lo gen-ops-rel.lo
+am__dist_EXTRA_libarch_la_SOURCES_DIST = insnset.c
+libarch_la_OBJECTS = $(am_libarch_la_OBJECTS) \
+ $(nodist_libarch_la_OBJECTS)
+@DYNAMIC_EXECUTION_FALSE@am_libarch_la_rpath =
+@DYNAMIC_EXECUTION_TRUE@am_libarch_la_rpath =
+PROGRAMS = $(noinst_PROGRAMS)
+am__dyngen_SOURCES_DIST = dyngen.c dyngen-i386.c dyngen-elf.c \
+ common-i386.h dyn32-defs.h dyngen.h dyn-rec.h i386-regs.h \
+ op-arith-op.h op-comp-op.h op-extend-op.h op-ff1-op.h \
+ op-i386.h op-lwhb-op.h op-mac-op.h op-mftspr-op.h op-support.h \
+ op-swhb-op.h op-t-reg-mov-op.h rec-i386.h sched-i386.h \
+ simpl32-defs.h
+@DYNAMIC_EXECUTION_TRUE@am_dyngen_OBJECTS = dyngen-dyngen.$(OBJEXT) \
+@DYNAMIC_EXECUTION_TRUE@ dyngen-dyngen-i386.$(OBJEXT) \
+@DYNAMIC_EXECUTION_TRUE@ dyngen-dyngen-elf.$(OBJEXT)
+dyngen_OBJECTS = $(am_dyngen_OBJECTS)
+dyngen_LDADD = $(LDADD)
+dyngen_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(dyngen_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am__generate_SOURCES_DIST = or32.c generate.c common-i386.h \
+ dyn32-defs.h dyngen.h dyn-rec.h i386-regs.h op-arith-op.h \
+ op-comp-op.h op-extend-op.h op-ff1-op.h op-i386.h op-lwhb-op.h \
+ op-mac-op.h op-mftspr-op.h op-support.h op-swhb-op.h \
+ op-t-reg-mov-op.h rec-i386.h sched-i386.h simpl32-defs.h
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@am_generate_OBJECTS = generate-or32.$(OBJEXT) \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ generate-generate.$(OBJEXT)
+generate_OBJECTS = $(am_generate_OBJECTS)
+generate_LDADD = $(LDADD)
+generate_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(generate_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libarch_la_SOURCES) $(nodist_libarch_la_SOURCES) \
+ $(dist_EXTRA_libarch_la_SOURCES) $(dyngen_SOURCES) \
+ $(generate_SOURCES)
+DIST_SOURCES = $(am__libarch_la_SOURCES_DIST) \
+ $(am__dist_EXTRA_libarch_la_SOURCES_DIST) \
+ $(am__dyngen_SOURCES_DIST) $(am__generate_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_ARCH = @CPU_ARCH@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUGFLAGS = @DEBUGFLAGS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INCLUDES = @INCLUDES@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_SHELL = @MAKE_SHELL@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@DYNAMIC_EXECUTION_FALSE@noinst_LTLIBRARIES = libarch.la
+@DYNAMIC_EXECUTION_TRUE@noinst_LTLIBRARIES = libarch.la
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@libarch_la_SOURCES = execute.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ or32.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ common-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ dyn32-defs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ dyngen.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ dyn-rec.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ i386-regs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-arith-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-comp-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-extend-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-ff1-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-lwhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-mac-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-mftspr-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-support.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-swhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ op-t-reg-mov-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ rec-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ sched-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@ simpl32-defs.h
+
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@libarch_la_SOURCES = execute.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ or32.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ common-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyn32-defs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyngen.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyn-rec.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ i386-regs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-arith-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-comp-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-extend-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-ff1-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-lwhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-mac-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-mftspr-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-support.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-swhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-t-reg-mov-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ rec-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ sched-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ simpl32-defs.h
+
+@DYNAMIC_EXECUTION_TRUE@libarch_la_SOURCES = execute.c \
+@DYNAMIC_EXECUTION_TRUE@ or32.c \
+@DYNAMIC_EXECUTION_TRUE@ op.c \
+@DYNAMIC_EXECUTION_TRUE@ dyn-rec.c \
+@DYNAMIC_EXECUTION_TRUE@ op-support.c \
+@DYNAMIC_EXECUTION_TRUE@ common-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ dyn32-defs.h \
+@DYNAMIC_EXECUTION_TRUE@ dyngen.h \
+@DYNAMIC_EXECUTION_TRUE@ dyn-rec.h \
+@DYNAMIC_EXECUTION_TRUE@ i386-regs.h \
+@DYNAMIC_EXECUTION_TRUE@ op-arith-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-comp-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-extend-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-ff1-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ op-lwhb-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-mac-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-mftspr-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-support.h \
+@DYNAMIC_EXECUTION_TRUE@ op-swhb-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-t-reg-mov-op.h \
+@DYNAMIC_EXECUTION_TRUE@ rec-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ sched-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ simpl32-defs.h
+
+@DYNAMIC_EXECUTION_TRUE@nodist_libarch_la_SOURCES = gen-ops.h \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops.c \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops-gen.c \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops-rel.c
+
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@BUILT_SOURCES = execgen.c
+@DYNAMIC_EXECUTION_TRUE@BUILT_SOURCES = gen-ops.h \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops.c \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops-gen.c \
+@DYNAMIC_EXECUTION_TRUE@ gen-ops-rel.c
+
+@DYNAMIC_EXECUTION_TRUE@dyngen_SOURCES = dyngen.c \
+@DYNAMIC_EXECUTION_TRUE@ dyngen-i386.c \
+@DYNAMIC_EXECUTION_TRUE@ dyngen-elf.c \
+@DYNAMIC_EXECUTION_TRUE@ common-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ dyn32-defs.h \
+@DYNAMIC_EXECUTION_TRUE@ dyngen.h \
+@DYNAMIC_EXECUTION_TRUE@ dyn-rec.h \
+@DYNAMIC_EXECUTION_TRUE@ i386-regs.h \
+@DYNAMIC_EXECUTION_TRUE@ op-arith-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-comp-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-extend-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-ff1-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ op-lwhb-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-mac-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-mftspr-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-support.h \
+@DYNAMIC_EXECUTION_TRUE@ op-swhb-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-t-reg-mov-op.h \
+@DYNAMIC_EXECUTION_TRUE@ rec-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ sched-i386.h \
+@DYNAMIC_EXECUTION_TRUE@ simpl32-defs.h
+
+@DYNAMIC_EXECUTION_TRUE@dyngen_CFLAGS = $(AM_CFLAGS)
+@DYNAMIC_EXECUTION_TRUE@OP_CFLAGS = -Wall -fomit-frame-pointer -fno-reorder-blocks -O2
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@EXTRA_DIST = insnset.c
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@generate_SOURCES = or32.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ generate.c \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ common-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyn32-defs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyngen.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ dyn-rec.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ i386-regs.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-arith-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-comp-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-extend-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-ff1-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-lwhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-mac-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-mftspr-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-support.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-swhb-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ op-t-reg-mov-op.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ rec-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ sched-i386.h \
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ simpl32-defs.h
+
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@generate_CFLAGS = $(AM_CFLAGS)
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_FALSE@dist_EXTRA_libarch_la_SOURCES = insnset.c
+
+# If the simulator was first built without --enable-simple and then with it,
+# then also remove these two files
+CLEANFILES = execgen.c \
+ generate \
+ gen-ops.c \
+ gen-ops.h \
+ gen-ops-rel.c \
+ gen-ops-gen.c
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/or32/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/or32/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libarch.la: $(libarch_la_OBJECTS) $(libarch_la_DEPENDENCIES)
+ $(LINK) $(am_libarch_la_rpath) $(libarch_la_OBJECTS) $(libarch_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+dyngen$(EXEEXT): $(dyngen_OBJECTS) $(dyngen_DEPENDENCIES)
+ @rm -f dyngen$(EXEEXT)
+ $(dyngen_LINK) $(dyngen_OBJECTS) $(dyngen_LDADD) $(LIBS)
+generate$(EXEEXT): $(generate_OBJECTS) $(generate_DEPENDENCIES)
+ @rm -f generate$(EXEEXT)
+ $(generate_LINK) $(generate_OBJECTS) $(generate_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyn-rec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyngen-dyngen-elf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyngen-dyngen-i386.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyngen-dyngen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen-ops-gen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen-ops-rel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen-ops.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate-generate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate-or32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insnset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op-support.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or32.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+dyngen-dyngen.o: dyngen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen.o -MD -MP -MF $(DEPDIR)/dyngen-dyngen.Tpo -c -o dyngen-dyngen.o `test -f 'dyngen.c' || echo '$(srcdir)/'`dyngen.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen.Tpo $(DEPDIR)/dyngen-dyngen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen.c' object='dyngen-dyngen.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen.o `test -f 'dyngen.c' || echo '$(srcdir)/'`dyngen.c
+
+dyngen-dyngen.obj: dyngen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen.obj -MD -MP -MF $(DEPDIR)/dyngen-dyngen.Tpo -c -o dyngen-dyngen.obj `if test -f 'dyngen.c'; then $(CYGPATH_W) 'dyngen.c'; else $(CYGPATH_W) '$(srcdir)/dyngen.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen.Tpo $(DEPDIR)/dyngen-dyngen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen.c' object='dyngen-dyngen.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen.obj `if test -f 'dyngen.c'; then $(CYGPATH_W) 'dyngen.c'; else $(CYGPATH_W) '$(srcdir)/dyngen.c'; fi`
+
+dyngen-dyngen-i386.o: dyngen-i386.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen-i386.o -MD -MP -MF $(DEPDIR)/dyngen-dyngen-i386.Tpo -c -o dyngen-dyngen-i386.o `test -f 'dyngen-i386.c' || echo '$(srcdir)/'`dyngen-i386.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen-i386.Tpo $(DEPDIR)/dyngen-dyngen-i386.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen-i386.c' object='dyngen-dyngen-i386.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen-i386.o `test -f 'dyngen-i386.c' || echo '$(srcdir)/'`dyngen-i386.c
+
+dyngen-dyngen-i386.obj: dyngen-i386.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen-i386.obj -MD -MP -MF $(DEPDIR)/dyngen-dyngen-i386.Tpo -c -o dyngen-dyngen-i386.obj `if test -f 'dyngen-i386.c'; then $(CYGPATH_W) 'dyngen-i386.c'; else $(CYGPATH_W) '$(srcdir)/dyngen-i386.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen-i386.Tpo $(DEPDIR)/dyngen-dyngen-i386.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen-i386.c' object='dyngen-dyngen-i386.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen-i386.obj `if test -f 'dyngen-i386.c'; then $(CYGPATH_W) 'dyngen-i386.c'; else $(CYGPATH_W) '$(srcdir)/dyngen-i386.c'; fi`
+
+dyngen-dyngen-elf.o: dyngen-elf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen-elf.o -MD -MP -MF $(DEPDIR)/dyngen-dyngen-elf.Tpo -c -o dyngen-dyngen-elf.o `test -f 'dyngen-elf.c' || echo '$(srcdir)/'`dyngen-elf.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen-elf.Tpo $(DEPDIR)/dyngen-dyngen-elf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen-elf.c' object='dyngen-dyngen-elf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen-elf.o `test -f 'dyngen-elf.c' || echo '$(srcdir)/'`dyngen-elf.c
+
+dyngen-dyngen-elf.obj: dyngen-elf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -MT dyngen-dyngen-elf.obj -MD -MP -MF $(DEPDIR)/dyngen-dyngen-elf.Tpo -c -o dyngen-dyngen-elf.obj `if test -f 'dyngen-elf.c'; then $(CYGPATH_W) 'dyngen-elf.c'; else $(CYGPATH_W) '$(srcdir)/dyngen-elf.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dyngen-dyngen-elf.Tpo $(DEPDIR)/dyngen-dyngen-elf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dyngen-elf.c' object='dyngen-dyngen-elf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyngen_CFLAGS) $(CFLAGS) -c -o dyngen-dyngen-elf.obj `if test -f 'dyngen-elf.c'; then $(CYGPATH_W) 'dyngen-elf.c'; else $(CYGPATH_W) '$(srcdir)/dyngen-elf.c'; fi`
+
+generate-or32.o: or32.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -MT generate-or32.o -MD -MP -MF $(DEPDIR)/generate-or32.Tpo -c -o generate-or32.o `test -f 'or32.c' || echo '$(srcdir)/'`or32.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/generate-or32.Tpo $(DEPDIR)/generate-or32.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='or32.c' object='generate-or32.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -c -o generate-or32.o `test -f 'or32.c' || echo '$(srcdir)/'`or32.c
+
+generate-or32.obj: or32.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -MT generate-or32.obj -MD -MP -MF $(DEPDIR)/generate-or32.Tpo -c -o generate-or32.obj `if test -f 'or32.c'; then $(CYGPATH_W) 'or32.c'; else $(CYGPATH_W) '$(srcdir)/or32.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/generate-or32.Tpo $(DEPDIR)/generate-or32.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='or32.c' object='generate-or32.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -c -o generate-or32.obj `if test -f 'or32.c'; then $(CYGPATH_W) 'or32.c'; else $(CYGPATH_W) '$(srcdir)/or32.c'; fi`
+
+generate-generate.o: generate.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -MT generate-generate.o -MD -MP -MF $(DEPDIR)/generate-generate.Tpo -c -o generate-generate.o `test -f 'generate.c' || echo '$(srcdir)/'`generate.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/generate-generate.Tpo $(DEPDIR)/generate-generate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generate.c' object='generate-generate.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -c -o generate-generate.o `test -f 'generate.c' || echo '$(srcdir)/'`generate.c
+
+generate-generate.obj: generate.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -MT generate-generate.obj -MD -MP -MF $(DEPDIR)/generate-generate.Tpo -c -o generate-generate.obj `if test -f 'generate.c'; then $(CYGPATH_W) 'generate.c'; else $(CYGPATH_W) '$(srcdir)/generate.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/generate-generate.Tpo $(DEPDIR)/generate-generate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generate.c' object='generate-generate.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(generate_CFLAGS) $(CFLAGS) -c -o generate-generate.obj `if test -f 'generate.c'; then $(CYGPATH_W) 'generate.c'; else $(CYGPATH_W) '$(srcdir)/generate.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+@DYNAMIC_EXECUTION_TRUE@gen-ops.h gen-ops.c gen-ops-gen.c gen-ops-rel.c: dyngen$(EXEEXT) op-tmp.o
+@DYNAMIC_EXECUTION_TRUE@ ./dyngen$(EXEEXT) op-tmp.o gen-ops.c gen-ops-gen.c gen-ops-rel.c gen-ops.h
+
+@DYNAMIC_EXECUTION_TRUE@op-tmp.o: op.c op-t-reg-mov-op.h op-i386.h op-arith-op.h op-comp-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-extend-op.h op-ff1-op.h op-mac-op.h op-mftspr-op.h op-lwhb-op.h \
+@DYNAMIC_EXECUTION_TRUE@ op-swhb-op.h
+@DYNAMIC_EXECUTION_TRUE@ $(CC) $(INCLUDES) -I$(top_builddir) $(OP_CFLAGS) -o $@ -c $<
+
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@execgen.c: generate$(EXEEXT) insnset.c
+@DYNAMIC_EXECUTION_FALSE@@GENERATE_NEEDED_TRUE@ ./generate$(EXEEXT) $(srcdir)/insnset.c execgen.c
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: or32/op-mftspr-op.h
===================================================================
--- or32/op-mftspr-op.h (nonexistent)
+++ or32/op-mftspr-op.h (revision 1765)
@@ -0,0 +1,78 @@
+/* op-mftspr-op.h -- Micro operations template for the m{f,t}spr operations
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifdef OP_2T
+__or_dynop void glue (op_mfspr, T) (void)
+{
+ /* FIXME: NPC/PPC Handling is br0ke */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ T0 = mfspr (T1 + OP_PARAM1);
+}
+#endif
+
+#ifdef OP_1T
+__or_dynop void glue (op_mfspr_imm, T) (void)
+{
+ /* FIXME: NPC/PPC Handling is br0ke */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ T0 = mfspr (OP_PARAM1);
+}
+#endif
+
+#ifdef OP_2T
+__or_dynop void glue (op_mtspr, T) (void)
+{
+ /* FIXME: NPC handling DOES NOT WORK like this */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ mtspr (T0 + OP_PARAM1, T1);
+}
+#endif
+
+#ifdef OP_1T
+__or_dynop void glue (op_mtspr_clear, T) (void)
+{
+ /* FIXME: NPC handling DOES NOT WORK like this */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ mtspr (T0 + OP_PARAM1, 0);
+}
+
+__or_dynop void glue (op_mtspr_imm, T) (void)
+{
+ /* FIXME: NPC handling DOES NOT WORK like this */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ mtspr (OP_PARAM1, T0);
+}
+#endif
+
+#if !defined(OP_1T) && !defined(OP_2T)
+__or_dynop void
+op_mtspr_imm_clear (void)
+{
+ /* FIXME: NPC handling DOES NOT WORK like this */
+ if (env->sprs[SPR_SR] & SPR_SR_SM)
+ mtspr (OP_PARAM1, 0);
+}
+#endif
Index: or32/op.c
===================================================================
--- or32/op.c (nonexistent)
+++ or32/op.c (revision 1765)
@@ -0,0 +1,971 @@
+/* op.c -- Micro operations for the recompiler
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "spr-defs.h"
+#include "opcode/or32.h"
+#include "sim-config.h"
+#include "except.h"
+#include "abstract.h"
+#include "execute.h"
+#include "sprs.h"
+#include "sched.h"
+#include "immu.h"
+
+#include "op-support.h"
+
+#include "i386-regs.h"
+
+#include "dyn-rec.h"
+
+register struct cpu_state *env asm(CPU_STATE_REG);
+
+#include "op-i386.h"
+
+/*
+ * WARNING: Before going of and wildly editing everything in this file remember
+ * the following about its contents:
+ * 1) The `functions' don't EVER return. In otherwords haveing return state-
+ * ments _anywere_ in this file is likely not to work. This is because
+ * dyngen just strips away the ret from the end of the function and just uses
+ * the function `body'. If a ret statement is executed _anyware_ inside the
+ * dynamicly generated code, then it is undefined were we shall jump to.
+ * 2) Because of 1), try not to have overly complicated functions. In too
+ * complicated functions, gcc may decide to generate premature `exits'. This
+ * is what passing the -fno-reorder-blocks command line switch to gcc helps
+ * with. This is ofcourse not desired and is rather flaky as we don't (and
+ * can't) control the kind of code that gcc generates: It may work for one
+ * and break for another. The less branches there are the less likely it is
+ * that a premature return shall occur.
+ * 3) If gcc decides that it is going to be a basterd then it will optimise a
+ * very simple condition (if/switch) with a premature exit. But gcc can't
+ * fuck ME over! Just stick a FORCE_RET; at the END of the offending
+ * function.
+ * 4) All operations must start with `op_'. dyngen ignores all other functions.
+ * 5) Local variables are depriciated: They hinder performance.
+ * 6) Function calls are expensive as the stack has to be shifted (twice).
+ */
+
+/*#define __or_dynop __attribute__((noreturn))*/
+#define __or_dynop
+
+/* Temporaries to hold the (simulated) registers in */
+register uint32_t t0 asm(T0_REG);
+register uint32_t t1 asm(T1_REG);
+register uint32_t t2 asm(T2_REG);
+
+#define OP_PARAM1 ((uorreg_t)(&__op_param1))
+#define OP_PARAM2 ((uorreg_t)(&__op_param2))
+#define OP_PARAM3 ((uorreg_t)(&__op_param3))
+
+extern uorreg_t __op_param1;
+extern uorreg_t __op_param2;
+extern uorreg_t __op_param3;
+
+
+static inline void save_t_bound(oraddr_t pc)
+{
+ int reg;
+
+ pc = (pc & immu_state->page_offset_mask) / 4;
+ reg = env->curr_page->ts_bound[pc];
+
+ if(reg & 0x1f)
+ env->reg[reg & 0x1f] = t0;
+
+ if((reg >> 5) & 0x1f)
+ env->reg[(reg >> 5) & 0x1f] = t1;
+
+ if((reg >> 10) & 0x1f)
+ env->reg[(reg >> 10) & 0x1f] = t2;
+}
+
+void do_sched_wrap(void)
+{
+ env->pc += 4;
+ //runtime.cpu.instructions++;
+ runtime.sim.cycles -= env->cycles_dec;
+ scheduler.job_queue->time += env->cycles_dec;
+ if(scheduler.job_queue->time <= 0) {
+ save_t_bound(env->pc - 4);
+ do_scheduler();
+ }
+}
+
+/* do_scheduler wrapper for instructions that are in the delay slot */
+void do_sched_wrap_delay(void)
+{
+ /* FIXME: Can't this be eliminated? */
+ env->pc += 4;
+ //runtime.cpu.instructions++;
+ runtime.sim.cycles -= env->cycles_dec;
+ scheduler.job_queue->time += env->cycles_dec;
+ if(scheduler.job_queue->time <= 0)
+ do_scheduler();
+}
+
+void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
+{
+ uint16_t reg = 0;
+ uint32_t t0_reg = t0, t1_reg = t1, t2_reg = t2;
+ struct cpu_state *cpu_reg = env;
+
+ addr &= immu_state->page_offset_mask;
+ addr >>= 2;
+
+ if(addr)
+ reg = dp->ts_bound[addr - 1];
+
+ t0 = cpu_state.reg[reg & 0x1f];
+ t1 = cpu_state.reg[(reg >> 5) & 0x1f];
+
+ /* Don't we all love gcc? For some heavenly reason gcc 3.2 _knows_ that if I
+ * don't put a condition around the assignment of t2, _all_ the assignments to
+ * t{0,1,2} are useless and not needed. I'm pleasently happy that gcc is so
+ * bright, but on the other hand, t{0,1,2} are globals (!) how can you assume
+ * that the value of a global won't be used in a function further up or
+ * further down the stack?? */
+ if(addr)
+ t2 = cpu_state.reg[(reg >> 10) & 0x1f];
+
+ env = &cpu_state;
+
+ ((gen_code_ent *)dp->locs)[addr]();
+ t0 = t0_reg;
+ t1 = t1_reg;
+ t2 = t2_reg;
+ env = (struct cpu_state *)cpu_reg;
+}
+
+__or_dynop void op_set_pc_pc_delay(void)
+{
+ env->sprs[SPR_PPC] = env->pc;
+ /* pc_delay is pulled back 4 since imediatly after this is run, the scheduler
+ * runs which also increments it by 4 */
+ env->pc = env->pc_delay - 4;
+}
+
+__or_dynop void op_set_pc_delay_imm(void)
+{
+ env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_set_pc_delay_pc(void)
+{
+ env->pc_delay = env->pc;
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_clear_pc_delay(void)
+{
+ env->pc_delay = 0;
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_do_jump_delay(void)
+{
+ env->pc = env->pc_delay;
+}
+
+__or_dynop void op_clear_delay_insn(void)
+{
+ env->delay_insn = 0;
+}
+
+__or_dynop void op_set_delay_insn(void)
+{
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_check_delay_slot(void)
+{
+ if(!env->delay_insn)
+ OP_JUMP(OP_PARAM1);
+}
+
+__or_dynop void op_jmp_imm(void)
+{
+ OP_JUMP(OP_PARAM1);
+}
+
+__or_dynop void op_set_flag(void)
+{
+ env->sprs[SPR_SR] |= SPR_SR_F;
+}
+
+__or_dynop void op_clear_flag(void)
+{
+ env->sprs[SPR_SR] &= ~SPR_SR_F;
+}
+
+/* Used for the l.bf instruction. Therefore if the flag is not set, jump over
+ * all the jumping stuff */
+__or_dynop void op_check_flag(void)
+{
+ if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
+ SPEEDY_CALL(do_sched_wrap);
+ OP_JUMP(OP_PARAM1);
+ }
+}
+
+/* Used for l.bf if the delay slot instruction is on another page */
+__or_dynop void op_check_flag_delay(void)
+{
+ if(env->sprs[SPR_SR] & SPR_SR_F) {
+ env->delay_insn = 1;
+ env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
+ }
+}
+
+/* Used for the l.bnf instruction. Therefore if the flag is set, jump over all
+ * the jumping stuff */
+__or_dynop void op_check_not_flag(void)
+{
+ if(env->sprs[SPR_SR] & SPR_SR_F) {
+ SPEEDY_CALL(do_sched_wrap);
+ OP_JUMP(OP_PARAM1);
+ }
+}
+
+/* Used for l.bnf if the delay slot instruction is on another page */
+__or_dynop void op_check_not_flag_delay(void)
+{
+ if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
+ env->delay_insn = 1;
+ env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
+ }
+}
+
+__or_dynop void op_add_pc(void)
+{
+ env->pc += OP_PARAM1;
+}
+
+__or_dynop void op_nop_exit(void)
+{
+ op_support_nop_exit();
+ FORCE_RET;
+}
+
+__or_dynop void op_nop_reset(void)
+{
+ op_support_nop_reset();
+ FORCE_RET;
+}
+
+__or_dynop void op_nop_printf(void)
+{
+ op_support_nop_printf();
+ FORCE_RET;
+}
+
+__or_dynop void op_nop_report(void)
+{
+ op_support_nop_report();
+ FORCE_RET;
+}
+
+__or_dynop void op_nop_report_imm(void)
+{
+ op_support_nop_report_imm(OP_PARAM1);
+}
+
+/* FIXME: Create another 2 sched functions that to the actual analysis call
+ * instead of bloating the recompiled code with this */
+__or_dynop void op_analysis(void)
+{
+ SPEEDY_CALL(op_support_analysis);
+}
+
+__or_dynop void op_move_gpr1_pc_delay(void)
+{
+ env->pc_delay = env->reg[1];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr2_pc_delay(void)
+{
+ env->pc_delay = env->reg[2];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr3_pc_delay(void)
+{
+ env->pc_delay = env->reg[3];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr4_pc_delay(void)
+{
+ env->pc_delay = env->reg[4];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr5_pc_delay(void)
+{
+ env->pc_delay = env->reg[5];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr6_pc_delay(void)
+{
+ env->pc_delay = env->reg[6];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr7_pc_delay(void)
+{
+ env->pc_delay = env->reg[7];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr8_pc_delay(void)
+{
+ env->pc_delay = env->reg[8];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr9_pc_delay(void)
+{
+ env->pc_delay = env->reg[9];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr10_pc_delay(void)
+{
+ env->pc_delay = env->reg[10];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr11_pc_delay(void)
+{
+ env->pc_delay = env->reg[11];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr12_pc_delay(void)
+{
+ env->pc_delay = env->reg[12];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr13_pc_delay(void)
+{
+ env->pc_delay = env->reg[13];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr14_pc_delay(void)
+{
+ env->pc_delay = env->reg[14];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr15_pc_delay(void)
+{
+ env->pc_delay = env->reg[15];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr16_pc_delay(void)
+{
+ env->pc_delay = env->reg[16];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr17_pc_delay(void)
+{
+ env->pc_delay = env->reg[17];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr18_pc_delay(void)
+{
+ env->pc_delay = env->reg[18];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr19_pc_delay(void)
+{
+ env->pc_delay = env->reg[19];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr20_pc_delay(void)
+{
+ env->pc_delay = env->reg[20];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr21_pc_delay(void)
+{
+ env->pc_delay = env->reg[21];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr22_pc_delay(void)
+{
+ env->pc_delay = env->reg[22];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr23_pc_delay(void)
+{
+ env->pc_delay = env->reg[23];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr24_pc_delay(void)
+{
+ env->pc_delay = env->reg[24];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr25_pc_delay(void)
+{
+ env->pc_delay = env->reg[25];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr26_pc_delay(void)
+{
+ env->pc_delay = env->reg[26];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr27_pc_delay(void)
+{
+ env->pc_delay = env->reg[27];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr28_pc_delay(void)
+{
+ env->pc_delay = env->reg[28];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr29_pc_delay(void)
+{
+ env->pc_delay = env->reg[29];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr30_pc_delay(void)
+{
+ env->pc_delay = env->reg[30];
+ env->delay_insn = 1;
+}
+
+__or_dynop void op_move_gpr31_pc_delay(void)
+{
+ env->pc_delay = env->reg[31];
+ env->delay_insn = 1;
+}
+
+#define OP_FILE "op-1t-op.h"
+#include "op-1t.h"
+#undef OP_FILE
+
+#define OP_FILE "op-2t-op.h"
+#include "op-2t.h"
+#undef OP_FILE
+
+#define OP_FILE "op-3t-op.h"
+#include "op-3t.h"
+#undef OP_FILE
+
+#define OP_FILE "op-arith-op.h"
+#define OP_EXTRA
+
+#define OP /
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME div
+#include "op-3t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP /
+#define OP_CAST(x) (x)
+#define OP_NAME divu
+#include "op-3t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP *
+#define OP_CAST(x) (x)
+#define OP_NAME mulu
+#include "op-3t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP -
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME sub
+#include "op-3t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#undef OP_EXTRA
+
+#define OP_EXTRA + ((env->sprs[SPR_SR] & SPR_SR_CY) >> 10)
+#define OP +
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME addc
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#undef OP_EXTRA
+#define OP_EXTRA
+
+#define OP +
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME add
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP &
+#define OP_CAST(x) (x)
+#define OP_NAME and
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP *
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME mul
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP |
+#define OP_CAST(x) (x)
+#define OP_NAME or
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP <<
+#define OP_CAST(x) (x)
+#define OP_NAME sll
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP >>
+#define OP_CAST(x) (orreg_t)(x)
+#define OP_NAME sra
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP >>
+#define OP_CAST(x) (x)
+#define OP_NAME srl
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#define OP ^
+#define OP_CAST(x) (x)
+#define OP_NAME xor
+#include "op-3t.h"
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP_CAST
+#undef OP
+
+#undef OP_EXTRA
+#undef OP_FILE
+
+#define OP_FILE "op-extend-op.h"
+
+#define EXT_NAME extbs
+#define EXT_TYPE int8_t
+#define EXT_CAST (orreg_t)
+#include "op-2t.h"
+#undef EXT_CAST
+#undef EXT_TYPE
+#undef EXT_NAME
+
+#define EXT_NAME extbz
+#define EXT_TYPE uint8_t
+#define EXT_CAST (uorreg_t)
+#include "op-2t.h"
+#undef EXT_CAST
+#undef EXT_TYPE
+#undef EXT_NAME
+
+#define EXT_NAME exths
+#define EXT_TYPE int16_t
+#define EXT_CAST (orreg_t)
+#include "op-2t.h"
+#undef EXT_CAST
+#undef EXT_TYPE
+#undef EXT_NAME
+
+#define EXT_NAME exthz
+#define EXT_TYPE uint16_t
+#define EXT_CAST (uorreg_t)
+#include "op-2t.h"
+#undef EXT_CAST
+#undef EXT_TYPE
+#undef EXT_NAME
+
+#undef OP_FILE
+
+#define OP_FILE "op-comp-op.h"
+
+#define COMP ==
+#define COMP_NAME sfeq
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP !=
+#define COMP_NAME sfne
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP >
+#define COMP_NAME sfgtu
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP >=
+#define COMP_NAME sfgeu
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP <
+#define COMP_NAME sfltu
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP <=
+#define COMP_NAME sfleu
+#define COMP_CAST(x) (x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP >
+#define COMP_NAME sfgts
+#define COMP_CAST(x) (orreg_t)(x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP >=
+#define COMP_NAME sfges
+#define COMP_CAST(x) (orreg_t)(x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP <
+#define COMP_NAME sflts
+#define COMP_CAST(x) (orreg_t)(x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#define COMP <=
+#define COMP_NAME sfles
+#define COMP_CAST(x) (orreg_t)(x)
+#include "op-2t.h"
+#include "op-1t.h"
+#undef COMP_CAST
+#undef COMP_NAME
+#undef COMP
+
+#undef OP_FILE
+
+#define OP_FILE "op-t-reg-mov-op.h"
+#include "op-1t.h"
+#undef OP_FILE
+
+#define OP_FILE "op-mftspr-op.h"
+#include "op-1t.h"
+#include "op-2t.h"
+#undef OP_FILE
+#include "op-mftspr-op.h"
+
+#define OP_FILE "op-mac-op.h"
+
+#define OP +=
+#define OP_NAME mac
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP
+
+#define OP -=
+#define OP_NAME msb
+#include "op-2t.h"
+#undef OP_NAME
+#undef OP
+
+#undef OP_FILE
+
+#define OP_FILE "op-lwhb-op.h"
+
+#define LS_OP_NAME lbz
+#define LS_OP_CAST
+#define LS_OP_FUNC eval_mem8
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#define LS_OP_NAME lbs
+#define LS_OP_CAST (int8_t)
+#define LS_OP_FUNC eval_mem8
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#define LS_OP_NAME lhz
+#define LS_OP_CAST
+#define LS_OP_FUNC eval_mem16
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#define LS_OP_NAME lhs
+#define LS_OP_CAST (int16_t)
+#define LS_OP_FUNC eval_mem16
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#define LS_OP_NAME lwz
+#define LS_OP_CAST
+#define LS_OP_FUNC eval_mem32
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#define LS_OP_NAME lws
+#define LS_OP_CAST (int32_t)
+#define LS_OP_FUNC eval_mem32
+#include "op-2t.h"
+#include "op-1t.h"
+#undef LS_OP_FUNC
+#undef LS_OP_CAST
+#undef LS_OP_NAME
+
+#undef OP_FILE
+
+#define OP_FILE "op-swhb-op.h"
+
+#define S_OP_NAME sb
+#define S_FUNC set_mem8
+#include "op-swhb-op.h"
+#include "op-2t.h"
+#include "op-1t.h"
+#undef S_FUNC
+#undef S_OP_NAME
+
+#define S_OP_NAME sh
+#define S_FUNC set_mem16
+#include "op-swhb-op.h"
+#include "op-2t.h"
+#include "op-1t.h"
+#undef S_FUNC
+#undef S_OP_NAME
+
+#define S_OP_NAME sw
+#define S_FUNC set_mem32
+#include "op-swhb-op.h"
+#include "op-2t.h"
+#include "op-1t.h"
+#undef S_FUNC
+#undef S_OP_NAME
+
+__or_dynop void op_join_mem_cycles(void)
+{
+ runtime.sim.cycles += runtime.sim.mem_cycles;
+ scheduler.job_queue->time -= runtime.sim.mem_cycles;
+ runtime.sim.mem_cycles = 0;
+}
+
+__or_dynop void op_store_link_addr_gpr(void)
+{
+ env->reg[LINK_REGNO] = env->pc + 8;
+}
+
+__or_dynop void op_prep_rfe(void)
+{
+ env->sprs[SPR_SR] = env->sprs[SPR_ESR_BASE] | SPR_SR_FO;
+ env->sprs[SPR_PPC] = env->pc;
+ env->pc = env->sprs[SPR_EPCR_BASE] - 4;
+}
+
+static inline void prep_except(oraddr_t epcr_base)
+{
+ env->sprs[SPR_EPCR_BASE] = epcr_base;
+
+ env->sprs[SPR_ESR_BASE] = env->sprs[SPR_SR];
+
+ /* Address translation is always disabled when starting exception. */
+ env->sprs[SPR_SR] &= ~SPR_SR_DME;
+ env->sprs[SPR_SR] &= ~SPR_SR_IME;
+
+ env->sprs[SPR_SR] &= ~SPR_SR_OVE; /* Disable overflow flag exception. */
+
+ env->sprs[SPR_SR] |= SPR_SR_SM; /* SUPV mode */
+ env->sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE); /* Disable interrupts. */
+}
+
+/* Before the code in op_{sys,trap}{,_delay} gets run, the scheduler runs.
+ * Therefore the pc will point to the instruction after the l.sys or l.trap
+ * instruction */
+__or_dynop void op_prep_sys_delay(void)
+{
+ env->delay_insn = 0;
+ prep_except(env->pc - 4);
+ env->pc = EXCEPT_SYSCALL - 4;
+}
+
+__or_dynop void op_prep_sys(void)
+{
+ prep_except(env->pc + 4);
+ env->pc = EXCEPT_SYSCALL - 4;
+}
+
+__or_dynop void op_prep_trap_delay(void)
+{
+ env->delay_insn = 0;
+ prep_except(env->pc - 4);
+ env->pc = EXCEPT_TRAP - 4;
+}
+
+__or_dynop void op_prep_trap(void)
+{
+ prep_except(env->pc);
+ env->pc = EXCEPT_TRAP - 4;
+}
+
+/* FIXME: This `instruction' should be split up like the l.trap and l.sys
+ * instructions are done */
+__or_dynop void op_illegal_delay(void)
+{
+ env->delay_insn = 0;
+ env->sprs[SPR_EEAR_BASE] = env->pc - 4;
+ env->pc = EXCEPT_ILLEGAL - 4;
+}
+
+__or_dynop void op_illegal(void)
+{
+ env->sprs[SPR_EEAR_BASE] = env->pc;
+ env->pc = EXCEPT_ILLEGAL;
+}
+
+__or_dynop void op_do_sched(void)
+{
+ SPEEDY_CALL(do_sched_wrap);
+}
+
+__or_dynop void op_do_sched_delay(void)
+{
+ SPEEDY_CALL(do_sched_wrap_delay);
+}
+
+__or_dynop void op_macc(void)
+{
+ env->sprs[SPR_MACLO] = 0;
+ env->sprs[SPR_MACHI] = 0;
+}
+
+__or_dynop void op_store_insn_ea(void)
+{
+ env->insn_ea = OP_PARAM1;
+}
+
Index: or32/dyn32-defs.h
===================================================================
--- or32/dyn32-defs.h (nonexistent)
+++ or32/dyn32-defs.h (revision 1765)
@@ -0,0 +1,139 @@
+/* dyn32-defs.h -- Definitions for the dynamic execution model
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef DYN32_DEFS__H
+#define DYN32_DEFS__H
+
+
+/* Package includes */
+#include "arch.h"
+
+
+struct op_queue {
+ unsigned int num_ops;
+ unsigned int ops_len;
+ unsigned int *ops;
+ unsigned int num_ops_param;
+ unsigned int ops_param_len;
+ unsigned int *ops_param;
+ unsigned int jump_local; /* Parameter index that holds the location of the jump */
+ oraddr_t jump_local_loc; /* Location to jump to (relative to start of page */
+ unsigned int not_jump_loc; /* Location to jump if not jumping (l.bf/l.bnf) */
+ int xref; /* Is this location cross referenced? */
+ oraddr_t insn_addr; /* Physical address of the instruction */
+ unsigned int reg_t[3]; /* Which registers are in the temporaries (after the instruction)? */
+ unsigned int tflags[3];
+
+ int insn_index;
+ unsigned int param_type[5]; /* opd->type */
+ orreg_t param[5]; /* Value of operand */
+ unsigned int param_num; /* Number of operands */
+ uint32_t insn; /* Instruction word */
+
+ struct op_queue *prev;
+ struct op_queue *next;
+};
+
+void gen_l_add PARAMS((struct op_queue *, int *, int));
+void gen_l_addc PARAMS((struct op_queue *, int *, int));
+void gen_l_and PARAMS((struct op_queue *, int *, int));
+void gen_l_bf PARAMS((struct op_queue *, int *, int));
+void gen_l_bnf PARAMS((struct op_queue *, int *, int));
+void gen_l_cmov PARAMS((struct op_queue *, int *, int));
+void gen_l_cust1 PARAMS((struct op_queue *, int *, int));
+void gen_l_cust2 PARAMS((struct op_queue *, int *, int));
+void gen_l_cust3 PARAMS((struct op_queue *, int *, int));
+void gen_l_cust4 PARAMS((struct op_queue *, int *, int));
+void gen_l_div PARAMS((struct op_queue *, int *, int));
+void gen_l_divu PARAMS((struct op_queue *, int *, int));
+void gen_l_extbs PARAMS((struct op_queue *, int *, int));
+void gen_l_extbz PARAMS((struct op_queue *, int *, int));
+void gen_l_exths PARAMS((struct op_queue *, int *, int));
+void gen_l_exthz PARAMS((struct op_queue *, int *, int));
+void gen_l_extws PARAMS((struct op_queue *, int *, int));
+void gen_l_extwz PARAMS((struct op_queue *, int *, int));
+void gen_l_ff1 PARAMS((struct op_queue *, int *, int));
+void gen_l_j PARAMS((struct op_queue *, int *, int));
+void gen_l_jal PARAMS((struct op_queue *, int *, int));
+void gen_l_jr PARAMS((struct op_queue *, int *, int));
+void gen_l_jalr PARAMS((struct op_queue *, int *, int));
+void gen_l_lbs PARAMS((struct op_queue *, int *, int));
+void gen_l_lbz PARAMS((struct op_queue *, int *, int));
+void gen_l_lhs PARAMS((struct op_queue *, int *, int));
+void gen_l_lhz PARAMS((struct op_queue *, int *, int));
+void gen_l_lws PARAMS((struct op_queue *, int *, int));
+void gen_l_lwz PARAMS((struct op_queue *, int *, int));
+void gen_l_mac PARAMS((struct op_queue *, int *, int));
+void gen_l_macrc PARAMS((struct op_queue *, int *, int));
+void gen_l_mfspr PARAMS((struct op_queue *, int *, int));
+void gen_l_movhi PARAMS((struct op_queue *, int *, int));
+void gen_l_msb PARAMS((struct op_queue *, int *, int));
+void gen_l_mtspr PARAMS((struct op_queue *, int *, int));
+void gen_l_mul PARAMS((struct op_queue *, int *, int));
+void gen_l_mulu PARAMS((struct op_queue *, int *, int));
+void gen_l_nop PARAMS((struct op_queue *, int *, int));
+void gen_l_or PARAMS((struct op_queue *, int *, int));
+void gen_l_rfe PARAMS((struct op_queue *, int *, int));
+void gen_l_sb PARAMS((struct op_queue *, int *, int));
+void gen_l_sh PARAMS((struct op_queue *, int *, int));
+void gen_l_sw PARAMS((struct op_queue *, int *, int));
+void gen_l_sfeq PARAMS((struct op_queue *, int *, int));
+void gen_l_sfges PARAMS((struct op_queue *, int *, int));
+void gen_l_sfgeu PARAMS((struct op_queue *, int *, int));
+void gen_l_sfgts PARAMS((struct op_queue *, int *, int));
+void gen_l_sfgtu PARAMS((struct op_queue *, int *, int));
+void gen_l_sfles PARAMS((struct op_queue *, int *, int));
+void gen_l_sfleu PARAMS((struct op_queue *, int *, int));
+void gen_l_sflts PARAMS((struct op_queue *, int *, int));
+void gen_l_sfltu PARAMS((struct op_queue *, int *, int));
+void gen_l_sfne PARAMS((struct op_queue *, int *, int));
+void gen_l_sll PARAMS((struct op_queue *, int *, int));
+void gen_l_sra PARAMS((struct op_queue *, int *, int));
+void gen_l_srl PARAMS((struct op_queue *, int *, int));
+void gen_l_sub PARAMS((struct op_queue *, int *, int));
+void gen_l_sys PARAMS((struct op_queue *, int *, int));
+void gen_l_trap PARAMS((struct op_queue *, int *, int));
+void gen_l_xor PARAMS((struct op_queue *, int *, int));
+void gen_l_invalid PARAMS((struct op_queue *, int *, int));
+
+void gen_lf_add_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_div_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_ftoi_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_itof_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_madd_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_mul_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_rem_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sfeq_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sfge_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sfgt_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sfle_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sflt_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sfne_s PARAMS((struct op_queue *, int *, int));
+void gen_lf_sub_s PARAMS((struct op_queue *, int *, int));
+void l_none(struct op_queue *opq, int *param_t, int delay_slot);
+
+#endif /* DYN32_DEFS__H */
+
Index: or32/op-support.c
===================================================================
--- or32/op-support.c (nonexistent)
+++ or32/op-support.c (revision 1765)
@@ -0,0 +1,114 @@
+/* op-support.c -- Support routines for micro operations
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "opcode/or32.h"
+#include "sim-config.h"
+#include "spr-defs.h"
+#include "except.h"
+#include "immu.h"
+#include "abstract.h"
+#include "execute.h"
+#include "sched.h"
+#include "i386-regs.h"
+#include "dyn-rec.h"
+#include "op-support.h"
+#include "simprintf.h"
+
+
+/* Stuff that is really a `micro' operation but is rather big (or for some other
+ * reason like calling exit()) */
+
+void op_support_nop_exit(void)
+{
+ PRINTF("exit(%"PRIdREG")\n", cpu_state.reg[3]);
+ fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
+ runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
+ fprintf(stderr, "@exit : cycles %lld, insn #%lld\n", runtime.sim.cycles,
+ runtime.cpu.instructions);
+ fprintf(stderr, " diff : cycles %lld, insn #%lld\n",
+ runtime.sim.cycles - runtime.sim.reset_cycles,
+ runtime.cpu.instructions - runtime.cpu.reset_instructions);
+ /* FIXME: Implement emulation of a stalled cpu
+ if (config.debug.gdb_enabled)
+ set_stall_state (1);
+ else {
+ handle_sim_command();
+ sim_done();
+ }
+ */
+ exit(0);
+}
+
+void op_support_nop_reset(void)
+{
+ PRINTF("****************** counters reset ******************\n");
+ PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
+ PRINTF("****************** counters reset ******************\n");
+ runtime.sim.reset_cycles = runtime.sim.cycles;
+ runtime.cpu.reset_instructions = runtime.cpu.instructions;
+}
+
+void op_support_nop_printf(void)
+{
+ simprintf(cpu_state.reg[4], cpu_state.reg[3]);
+}
+
+void op_support_nop_report(void)
+{
+ PRINTF("report(0x%"PRIxREG");\n", cpu_state.reg[3]);
+}
+
+void op_support_nop_report_imm(int imm)
+{
+ PRINTF("report %i (0x%"PRIxREG");\n", imm, cpu_state.reg[3]);
+}
+
+/* Handles a jump */
+/* addr is a VIRTUAL address */
+/* NOTE: We can't use env since this code is compiled like the rest of the
+ * simulator (most likely without -fomit-frame-pointer) and thus env will point
+ * to some bogus value. */
+void do_jump(oraddr_t addr)
+{
+ cpu_state.pc = addr;
+ longjmp(cpu_state.excpt_loc, 0);
+}
+
+/* Wrapper around analysis() that contains all the recompiler specific stuff */
+void op_support_analysis(void)
+{
+ oraddr_t off = (cpu_state.pc & immu_state->page_offset_mask) >> 2;
+ runtime.cpu.instructions++;
+ cpu_state.iqueue.insn_index = cpu_state.curr_page->insn_indexs[off];
+ cpu_state.iqueue.insn = cpu_state.curr_page->insns[off];
+ cpu_state.iqueue.insn_addr = cpu_state.pc;
+ analysis(&cpu_state.iqueue);
+}
+
Index: or32/op-swhb-op.h
===================================================================
--- or32/op-swhb-op.h (nonexistent)
+++ or32/op-swhb-op.h (revision 1765)
@@ -0,0 +1,57 @@
+/* op-swhb-op.h -- Micro operations template for store operations
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+/* FIXME: Do something with breakpoint */
+
+
+#ifdef OP_2T
+__or_dynop void glue (glue (op_, S_OP_NAME), T) (void)
+{
+ int breakpoint;
+ S_FUNC (T0 + OP_PARAM1, T1, &breakpoint);
+}
+#endif
+
+#ifdef OP_1T
+__or_dynop void glue (glue (glue (op_, S_OP_NAME), _imm), T) (void)
+{
+ int breakpoint;
+ S_FUNC (OP_PARAM1, T0, &breakpoint);
+}
+
+__or_dynop void glue (glue (glue (op_, S_OP_NAME), _clear), T) (void)
+{
+ int breakpoint;
+ S_FUNC (T0 + OP_PARAM1, 0, &breakpoint);
+}
+#endif
+
+#if !defined(OP_1T) && !defined(OP_2T)
+__or_dynop void glue (glue (op_, S_OP_NAME), _clear_imm) (void)
+{
+ int breakpoint;
+ S_FUNC (OP_PARAM1, 0, &breakpoint);
+}
+#endif
Index: or32/dyn-rec.c
===================================================================
--- or32/dyn-rec.c (nonexistent)
+++ or32/dyn-rec.c (revision 1765)
@@ -0,0 +1,2451 @@
+/* dyn-rec.c -- Dynamic recompiler implementation for or32
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "immu.h"
+#include "abstract.h"
+#include "opcode/or32.h"
+#include "spr-defs.h"
+#include "execute.h"
+#include "except.h"
+#include "spr-defs.h"
+#include "sim-config.h"
+#include "sched.h"
+#include "i386-regs.h"
+#include "def-op-t.h"
+#include "dyn-rec.h"
+#include "gen-ops.h"
+#include "op-support.h"
+#include "toplevel-support.h"
+
+
+/* NOTE: All openrisc (or) addresses in this file are *PHYSICAL* addresses */
+
+/* FIXME: Optimise sorted list adding */
+
+typedef void (*generic_gen_op)(struct op_queue *opq, int end);
+typedef void (*imm_gen_op)(struct op_queue *opq, int end, uorreg_t imm);
+
+void gen_l_invalid(struct op_queue *opq, int param_t[3], int delay_slot);
+
+/* ttg->temporary to gpr */
+DEF_GPR_OP(generic_gen_op, gen_op_move_gpr_t, gen_op_ttg_gpr);
+/* gtt->gpr to temporary */
+DEF_GPR_OP(generic_gen_op, gen_op_move_t_gpr, gen_op_gtt_gpr);
+
+DEF_1T_OP(imm_gen_op, calc_insn_ea_table, gen_op_calc_insn_ea);
+
+/* Linker stubs. This will allow the linker to link in op.o. The relocations
+ * that the linker does for these will be irrelevent anyway, since we patch the
+ * relocations during recompilation. */
+uorreg_t __op_param1;
+uorreg_t __op_param2;
+uorreg_t __op_param3;
+
+/* The number of bytes that a dynamicly recompiled page should be enlarged by */
+#define RECED_PAGE_ENLARGE_BY 51200
+
+/* The number of entries that the micro operations array in op_queue should be
+ * enlarged by */
+#define OPS_ENLARGE_BY 5
+
+#define T_NONE (-1)
+
+/* Temporary is used as a source operand */
+#define TFLAG_SRC 1
+/* Temporary is used as a destination operand */
+#define TFLAG_DST 2
+/* Temporary has been saved to permanent storage */
+#define TFLAG_SAVED 4
+/* Temporary contains the value of the register before the instruction execution
+ * occurs (either by an explicit reg->t move or implicitly being left over from
+ * a previous instruction) */
+#define TFLAG_SOURCED 8
+
+/* FIXME: Put this into some header */
+extern int do_stats;
+
+static int sigsegv_state = 0;
+static void *sigsegv_addr = NULL;
+
+void dyn_ret_stack_prot(void);
+
+void dyn_sigsegv_debug(int u, siginfo_t *siginf, void *dat)
+{
+ struct dyn_page *dp;
+ FILE *f;
+ char filen[18]; /* 18 == strlen("or_page.%08x") + 1 */
+ int i;
+ struct sigcontext *sigc = dat;
+
+ if(!sigsegv_state) {
+ sigsegv_addr = siginf->si_addr;
+ } else {
+ fprintf(stderr, "Nested SIGSEGV occured, dumping next chuck of info\n");
+ sigsegv_state++;
+ }
+
+ /* First dump all the data that does not need dereferenceing to get */
+ switch(sigsegv_state) {
+ case 0:
+ fflush(stderr);
+ fprintf(stderr, "Segmentation fault on acces to %p at 0x%08lx, (or address: 0x%"PRIxADDR")\n\n",
+ sigsegv_addr, sigc->eip, cpu_state.pc);
+ sigsegv_state++;
+ case 1:
+ /* Run through the recompiled pages, dumping them to disk as we go */
+ for(i = 0; i < (2 << (32 - immu_state->pagesize_log2)); i++) {
+ dp = cpu_state.dyn_pages[i];
+ if(!dp)
+ continue;
+ fprintf(stderr, "Dumping%s page 0x%"PRIxADDR" recompiled to %p (len: %u) to disk\n",
+ dp->dirty ? " dirty" : "", dp->or_page, dp->host_page,
+ dp->host_len);
+ fflush(stdout);
+
+ sprintf(filen, "or_page.%"PRIxADDR, dp->or_page);
+ if(!(f = fopen(filen, "w"))) {
+ fprintf(stderr, "Unable to open %s to dump the recompiled page to: %s\n",
+ filen, strerror(errno));
+ continue;
+ }
+ if(fwrite(dp->host_page, dp->host_len, 1, f) < 1)
+ fprintf(stderr, "Unable to write recompiled data to file: %s\n",
+ strerror(errno));
+
+ fclose(f);
+ }
+ sigsegv_state++;
+ case 2:
+ sim_done();
+ }
+}
+
+struct dyn_page *new_dp(oraddr_t page)
+{
+ struct dyn_page *dp = malloc(sizeof(struct dyn_page));
+ dp->or_page = IADDR_PAGE(page);
+
+ dp->locs = malloc(sizeof(void *) * (immu_state->pagesize / 4));
+
+ dp->host_len = 0;
+ dp->host_page = NULL;
+ dp->dirty = 1;
+
+ if(do_stats) {
+ dp->insns = malloc(immu_state->pagesize);
+ dp->insn_indexs = malloc(sizeof(unsigned int) * (immu_state->pagesize / 4));
+ }
+
+ cpu_state.dyn_pages[dp->or_page >> immu_state->pagesize_log2] = dp;
+ return dp;
+}
+
+void dyn_main(void)
+{
+ struct dyn_page *target_dp;
+ oraddr_t phys_page;
+
+ setjmp(cpu_state.excpt_loc);
+ for(;;) {
+ phys_page = immu_translate(cpu_state.pc);
+
+/*
+ printf("Recompiled code jumping out to %"PRIxADDR" from %"PRIxADDR"\n",
+ phys_page, cpu_state.sprs[SPR_PPC] - 4);
+*/
+
+ /* immu_translate() adds the hit delay to runtime.sim.mem_cycles but we add
+ * it to the cycles when the instruction is executed so if we don't reset it
+ * now it will produce wrong results */
+ runtime.sim.mem_cycles = 0;
+
+ target_dp = cpu_state.dyn_pages[phys_page >> immu_state->pagesize_log2];
+
+ if(!target_dp)
+ target_dp = new_dp(phys_page);
+
+ /* Since writes to the 0x0-0xff range do not dirtyfy a page recompile the
+ * 0x0 page if the jump is to that location */
+ if(phys_page < 0x100)
+ target_dp->dirty = 1;
+
+ if(target_dp->dirty)
+ recompile_page(target_dp);
+
+ cpu_state.curr_page = target_dp;
+
+ /* FIXME: If the page is backed by more than one type of memory, this will
+ * produce wrong results */
+ cpu_state.cycles_dec = target_dp->delayr;
+ if(cpu_state.sprs[SPR_SR] & SPR_SR_IME)
+ /* Add the mmu hit delay to the cycle counter */
+ cpu_state.cycles_dec -= immu_state->hitdelay;
+
+ /* FIXME: ebp, ebx, esi and edi are expected to be preserved across function
+ * calls but the recompiled code trashes them... */
+ enter_dyn_code(phys_page, target_dp);
+ }
+}
+
+static void immu_retranslate(void *dat)
+{
+ int got_en_dis = (int)dat;
+ immu_translate(cpu_state.pc);
+ runtime.sim.mem_cycles = 0;
+
+ /* Only update the cycle decrementer if the mmu got enabled or disabled */
+ if(got_en_dis == IMMU_GOT_ENABLED)
+ /* Add the mmu hit delay to the cycle counter */
+ cpu_state.cycles_dec = cpu_state.curr_page->delayr - immu_state->hitdelay;
+ else if(got_en_dis == IMMU_GOT_DISABLED)
+ cpu_state.cycles_dec = cpu_state.curr_page->delayr;
+}
+
+/* This is called whenever the immu is either enabled/disabled or reconfigured
+ * while enabled. This checks if an itlb miss would occour and updates the immu
+ * hit delay counter */
+void recheck_immu(int got_en_dis)
+{
+ oraddr_t addr;
+
+ if(cpu_state.delay_insn)
+ addr = cpu_state.pc_delay;
+ else
+ addr = cpu_state.pc + 4;
+
+ if(IADDR_PAGE(cpu_state.pc) == IADDR_PAGE(addr))
+ /* Schedule a job to do immu_translate() */
+ SCHED_ADD(immu_retranslate, (void *)got_en_dis, 0);
+}
+
+/* Runs the scheduler. Called from except_handler (and dirtyfy_page below) */
+void run_sched_out_of_line(void)
+{
+ oraddr_t off = (cpu_state.pc & immu_state->page_offset_mask) >> 2;
+
+ if(do_stats) {
+ cpu_state.iqueue.insn_addr = cpu_state.pc;
+ cpu_state.iqueue.insn = cpu_state.curr_page->insns[off];
+ cpu_state.iqueue.insn_index = cpu_state.curr_page->insn_indexs[off];
+ runtime.cpu.instructions++;
+ analysis(&cpu_state.iqueue);
+ }
+
+ /* Run the scheduler */
+ scheduler.job_queue->time += cpu_state.cycles_dec;
+ runtime.sim.cycles -= cpu_state.cycles_dec;
+
+ op_join_mem_cycles();
+ if(scheduler.job_queue->time <= 0)
+ do_scheduler();
+}
+
+/* Signals a page as dirty */
+static void dirtyfy_page(struct dyn_page *dp)
+{
+ oraddr_t check;
+
+ printf("Dirtyfying page 0x%"PRIxADDR"\n", dp->or_page);
+
+ dp->dirty = 1;
+
+ /* If the execution is currently in the page that was touched then recompile
+ * it now and jump back to the point of execution */
+ check = cpu_state.delay_insn ? cpu_state.pc_delay : cpu_state.pc + 4;
+ if(IADDR_PAGE(check) == dp->or_page) {
+ run_sched_out_of_line();
+ recompile_page(dp);
+
+ cpu_state.delay_insn = 0;
+
+ /* Jump out to the next instruction */
+ do_jump(check);
+ }
+}
+
+/* Checks to see if a write happened to a recompiled page. If so marks it as
+ * dirty */
+void dyn_checkwrite(oraddr_t addr)
+{
+ /* FIXME: Do this with mprotect() */
+ struct dyn_page *dp = cpu_state.dyn_pages[addr >> immu_state->pagesize_log2];
+
+ /* Since the locations 0x0-0xff are nearly always written to in an exception
+ * handler, ignore any writes to these locations. If code ends up jumping
+ * out there, we'll recompile when the jump actually happens. */
+ if((addr > 0x100) && dp && !dp->dirty)
+ dirtyfy_page(dp);
+}
+
+/* Moves the temprary t to its permanent storage if it has been used as a
+ * destination register */
+static void ship_t_out(struct op_queue *opq, unsigned int t)
+{
+ unsigned int gpr = opq->reg_t[t];
+
+ for(; opq; opq = opq->prev) {
+ if(opq->reg_t[t] != gpr)
+ return;
+ if((opq->tflags[t] & TFLAG_DST) && !(opq->tflags[t] & TFLAG_SAVED)) {
+ opq->tflags[t] |= TFLAG_SAVED;
+
+ /* FIXME: Check if this is still neccesary */
+ /* Before takeing the temporaries out, temporarily remove the op_do_sched
+ * operation such that dyn_page->ts_bound shall be correct before the
+ * scheduler runs */
+ if(opq->num_ops && (opq->ops[opq->num_ops - 1] == op_do_sched_indx)) {
+ opq->num_ops--;
+ gen_op_move_gpr_t[t][gpr](opq, 1);
+ gen_op_do_sched(opq, 1);
+ return;
+ }
+
+ gen_op_move_gpr_t[t][gpr](opq, 1);
+
+ return;
+ }
+ }
+}
+
+static void ship_gprs_out_t(struct op_queue *opq)
+{
+ int i;
+
+ if(!opq)
+ return;
+
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->reg_t[i] < 32)
+ /* Ship temporaries out in the last opq that actually touched it */
+ ship_t_out(opq, i);
+ }
+}
+
+/* FIXME: Look at the following instructions to make a better guess at which
+ * temporary to return */
+static int find_t(struct op_queue *opq, unsigned int reg)
+{
+ int i, j, t = -1;
+
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->reg_t[i] == reg)
+ return i;
+
+ /* Ok, we have found an as-yet unused temporary, check if it is needed
+ * later in this instruction */
+ for(j = 0; j < opq->param_num; j++) {
+ if((opq->param_type[j] & OPTYPE_REG) && (opq->param[j] == opq->reg_t[i]))
+ break;
+ }
+
+ if(j != opq->param_num)
+ continue;
+
+ /* We have found the temporary (temporarily:) fit for use */
+ if((t == -1) || (opq->reg_t[i] == 32))
+ t = i;
+ }
+
+ return t;
+}
+
+/* Checks if there is enough space in dp->host_page, if not grow it */
+void *enough_host_page(struct dyn_page *dp, void *cur, unsigned int *len,
+ unsigned int amount)
+{
+ unsigned int used = cur - dp->host_page;
+
+ /* The array is long enough */
+ if((used + amount) <= *len)
+ return cur;
+
+ /* Reallocate */
+ *len += RECED_PAGE_ENLARGE_BY;
+
+ if(!(dp->host_page = realloc(dp->host_page, *len))) {
+ fprintf(stderr, "OOM\n");
+ exit(1);
+ }
+
+ return dp->host_page + used;
+}
+
+/* Adds an operation to the opq */
+void add_to_opq(struct op_queue *opq, int end, int op)
+{
+ if(opq->num_ops == opq->ops_len) {
+ opq->ops_len += OPS_ENLARGE_BY;
+ if(!(opq->ops = realloc(opq->ops, opq->ops_len * sizeof(int)))) {
+ fprintf(stderr, "OOM\n");
+ exit(1);
+ }
+ }
+
+ if(end)
+ opq->ops[opq->num_ops] = op;
+ else {
+ /* Shift everything over by one */
+ memmove(opq->ops + 1, opq->ops, opq->num_ops* sizeof(int));
+ opq->ops[0] = op;
+ }
+
+ opq->num_ops++;
+}
+
+static void gen_op_mark_loc(struct op_queue *opq, int end)
+{
+ add_to_opq(opq, end, op_mark_loc_indx);
+}
+
+/* Adds a parameter to the opq */
+void add_to_op_params(struct op_queue *opq, int end, unsigned long param)
+{
+ if(opq->num_ops_param == opq->ops_param_len) {
+ opq->ops_param_len += OPS_ENLARGE_BY;
+ if(!(opq->ops_param = realloc(opq->ops_param, opq->ops_param_len * sizeof(int)))) {
+ fprintf(stderr, "OOM\n");
+ exit(1);
+ }
+ }
+
+ if(end)
+ opq->ops_param[opq->num_ops_param] = param;
+ else {
+ /* Shift everything over by one */
+ memmove(opq->ops_param + 1, opq->ops_param, opq->num_ops_param);
+ opq->ops_param[0] = param;
+ }
+
+ opq->num_ops_param++;
+}
+
+/* Initialises the recompiler */
+void init_dyn_recomp(void)
+{
+ struct sigaction sigact;
+ struct op_queue *opq = NULL;
+ unsigned int i;
+
+ cpu_state.opqs = NULL;
+
+ /* Allocate the operation queue list (+1 for the page chaining) */
+ for(i = 0; i < (immu_state->pagesize / 4) + 1; i++) {
+ if(!(opq = malloc(sizeof(struct op_queue)))) {
+ fprintf(stderr, "OOM\n");
+ exit(1);
+ }
+
+ /* initialise some fields */
+ opq->ops_len = 0;
+ opq->ops = NULL;
+ opq->ops_param_len = 0;
+ opq->ops_param = NULL;
+ opq->xref = 0;
+
+ if(cpu_state.opqs)
+ cpu_state.opqs->prev = opq;
+
+ opq->next = cpu_state.opqs;
+ cpu_state.opqs = opq;
+ }
+
+ opq->prev = NULL;
+
+ cpu_state.curr_page = NULL;
+ if(!(cpu_state.dyn_pages = malloc(sizeof(void *) * (2 << (32 -
+ immu_state->pagesize_log2))))) {
+ fprintf(stderr, "OOM\n");
+ exit(1);
+ }
+ memset(cpu_state.dyn_pages, 0,
+ sizeof(void *) * (2 << (32 - immu_state->pagesize_log2)));
+
+ /* Register our segmentation fault handler */
+ sigact.sa_sigaction = dyn_sigsegv_debug;
+ memset(&sigact.sa_mask, 0, sizeof(sigact.sa_mask));
+ sigact.sa_flags = SA_SIGINFO | SA_NOMASK;
+ if(sigaction(SIGSEGV, &sigact, NULL))
+ printf("WARN: Unable to install SIGSEGV handler! Don't expect to be able to debug the recompiler.\n");
+
+ /* FIXME: Find a better place for this */
+ { /* Needed by execution */
+ extern int do_stats;
+ do_stats = config.cpu.dependstats || config.cpu.superscalar || config.cpu.dependstats
+ || config.sim.history || config.sim.exe_log;
+ }
+
+ printf("Recompile engine up and running\n");
+}
+
+/* Parses instructions and their operands and populates opq with them */
+static void eval_insn_ops(struct op_queue *opq, oraddr_t addr)
+{
+ int breakp;
+ struct insn_op_struct *opd;
+
+ for(; opq->next; opq = opq->next, addr += 4) {
+ opq->param_num = 0;
+ breakp = 0;
+ opq->insn = eval_insn(addr, &breakp);
+
+ /* FIXME: If a breakpoint is set at this location, insert exception code */
+ if(breakp) {
+ fprintf(stderr, "FIXME: Insert breakpoint code\n");
+ }
+
+ opq->insn_index = insn_decode(opq->insn);
+
+ if(opq->insn_index == -1)
+ continue;
+
+ opd = op_start[opq->insn_index];
+
+ do {
+ opq->param[opq->param_num] = eval_operand_val(opq->insn, opd);
+ opq->param_type[opq->param_num] = opd->type;
+
+ opq->param_num++;
+ while(!(opd->type & OPTYPE_OP)) opd++;
+ } while(!(opd++->type & OPTYPE_LAST));
+ }
+}
+
+/* Adds code to the opq for the instruction pointed to by addr */
+static void recompile_insn(struct op_queue *opq, int delay_insn)
+{
+ int j, k;
+ int param_t[5]; /* Which temporary the parameters reside in */
+
+ /* Check if we have an illegal instruction */
+ if(opq->insn_index == -1) {
+ gen_l_invalid(opq, NULL, delay_insn);
+ return;
+ }
+
+ /* If we are recompileing an instruction that has a delay slot and is in the
+ * delay slot, ignore it. This is undefined behavour. */
+ if(delay_insn && (or32_opcodes[opq->insn_index].flags & OR32_IF_DELAY))
+ return;
+
+ param_t[0] = T_NONE;
+ param_t[1] = T_NONE;
+ param_t[2] = T_NONE;
+ param_t[3] = T_NONE;
+ param_t[4] = T_NONE;
+
+ /* Jump instructions are special since they have a delay slot and thus they
+ * need to control the exact operation sequence. Special case these here to
+ * avoid haveing loads of if(!(.& OR32_IF_DELAY)) below */
+ if(or32_opcodes[opq->insn_index].flags & OR32_IF_DELAY) {
+ /* Jump instructions don't have a disposition */
+ or32_opcodes[opq->insn_index].exec(opq, param_t, delay_insn);
+
+ /* Analysis is done by the individual jump instructions */
+ /* Jump instructions don't touch runtime.sim.mem_cycles */
+ /* Jump instructions run their own scheduler */
+ return;
+ }
+
+ /* Before an exception takes place, all registers must be stored. */
+ if((or32_opcodes[opq->insn_index].func_unit == it_exception)) {
+ ship_gprs_out_t(opq);
+
+ or32_opcodes[opq->insn_index].exec(opq, param_t, delay_insn);
+ return;
+ }
+
+ for(j = 0; j < opq->param_num; j++) {
+ if(!(opq->param_type[j] & OPTYPE_REG))
+ continue;
+
+ /* Never, ever, move r0 into a temporary */
+ if(!opq->param[j])
+ continue;
+
+ k = find_t(opq, opq->param[j]);
+
+ param_t[j] = k;
+
+ if(opq->reg_t[k] == opq->param[j]) {
+ if(!(opq->param_type[j] & OPTYPE_DST) &&
+ !(opq->tflags[k] & TFLAG_SOURCED)) {
+ gen_op_move_t_gpr[k][opq->reg_t[k]](opq, 0);
+ opq->tflags[k] |= TFLAG_SOURCED;
+ }
+
+ if(opq->param_type[j] & OPTYPE_DST)
+ opq->tflags[k] |= TFLAG_DST;
+ else
+ opq->tflags[k] |= TFLAG_SRC;
+
+ continue;
+ }
+
+ if(opq->reg_t[k] < 32) {
+ /* Only ship the temporary out if it has been used as a destination
+ * register */
+ ship_t_out(opq, k);
+ }
+
+ if(opq->param_type[j] & OPTYPE_DST)
+ opq->tflags[k] = TFLAG_DST;
+ else
+ opq->tflags[k] = TFLAG_SRC;
+
+ opq->reg_t[k] = opq->param[j];
+
+ /* Only generate code to move the register into a temporary if it is used as
+ * a source operand */
+ if(!(opq->param_type[j] & OPTYPE_DST)) {
+ gen_op_move_t_gpr[k][opq->reg_t[k]](opq, 0);
+ opq->tflags[k] |= TFLAG_SOURCED;
+ }
+ }
+
+ /* To get the execution log correct for instructions like l.lwz r4,0(r4) the
+ * effective address needs to be calculated before the instruction is
+ * simulated */
+ if(do_stats) {
+ for(j = 0; j < opq->param_num; j++) {
+ if(!(opq->param_type[j] & OPTYPE_DIS))
+ continue;
+
+ if(!opq->param[j + 1])
+ gen_op_store_insn_ea(opq, 1, opq->param[j]);
+ else
+ calc_insn_ea_table[param_t[j + 1]](opq, 1, opq->param[j]);
+ }
+ }
+
+ or32_opcodes[opq->insn_index].exec(opq, param_t, delay_insn);
+
+ if(do_stats) {
+ ship_gprs_out_t(opq);
+ gen_op_analysis(opq, 1);
+ }
+
+ /* The call to join_mem_cycles() could be put into the individual operations
+ * that emulate the load/store instructions, but then it would be added to
+ * the cycle counter before analysis() is called, which is not how the complex
+ * execution model does it. */
+ if((or32_opcodes[opq->insn_index].func_unit == it_load) ||
+ (or32_opcodes[opq->insn_index].func_unit == it_store))
+ gen_op_join_mem_cycles(opq, 1);
+
+ /* Delay slot instructions get a special scheduler, thus don't generate it
+ * here */
+ if(!delay_insn)
+ gen_op_do_sched(opq, 1);
+}
+
+/* Recompiles the page associated with *dyn */
+void recompile_page(struct dyn_page *dyn)
+{
+ unsigned int j;
+ struct op_queue *opq = cpu_state.opqs;
+ oraddr_t rec_addr = dyn->or_page;
+ oraddr_t rec_page = dyn->or_page;
+ void **loc;
+
+ /* The start of the next page */
+ rec_page += immu_state->pagesize;
+
+ printf("Recompileing page %"PRIxADDR"\n", rec_addr);
+ fflush(stdout);
+
+ /* Mark all temporaries as not containing a register */
+ for(j = 0; j < NUM_T_REGS; j++) {
+ opq->reg_t[j] = 32; /* Out-of-range registers */
+ opq->tflags[j] = 0;
+ }
+
+ dyn->delayr = -verify_memoryarea(rec_addr)->ops.delayr;
+
+ opq->num_ops = 0;
+ opq->num_ops_param = 0;
+
+ eval_insn_ops(opq, rec_addr);
+
+ /* Insert code to check if the first instruction is exeucted in a delay slot*/
+ gen_op_check_delay_slot(opq, 1, 0);
+ recompile_insn(opq, 1);
+ ship_gprs_out_t(opq);
+ gen_op_do_sched_delay(opq, 1);
+ gen_op_clear_delay_insn(opq, 1);
+ gen_op_do_jump_delay(opq, 1);
+ gen_op_do_jump(opq, 1);
+ gen_op_mark_loc(opq, 1);
+
+ for(j = 0; j < NUM_T_REGS; j++)
+ opq->reg_t[j] = 32; /* Out-of-range registers */
+
+ for(; rec_addr < rec_page; rec_addr += 4, opq = opq->next) {
+ if(opq->prev) {
+ opq->num_ops = 0;
+ opq->num_ops_param = 0;
+ }
+ opq->jump_local = -1;
+ opq->not_jump_loc = -1;
+
+ opq->insn_addr = rec_addr;
+
+ for(j = 0; j < NUM_T_REGS; j++)
+ opq->tflags[j] = TFLAG_SOURCED;
+
+ /* Check if this location is cross referenced */
+ if(opq->xref) {
+ /* If the current address is cross-referenced, the temporaries shall be
+ * in an undefined state, so we must assume that no registers reside in
+ * them */
+ /* Ship out the current set of registers from the temporaries */
+ if(opq->prev) {
+ ship_gprs_out_t(opq->prev);
+ for(j = 0; j < NUM_T_REGS; j++) {
+ opq->reg_t[j] = 32;
+ opq->prev->reg_t[j] = 32;
+ }
+ }
+ }
+
+ recompile_insn(opq, 0);
+
+ /* Store the state of the temporaries */
+ memcpy(opq->next->reg_t, opq->reg_t, sizeof(opq->reg_t));
+ }
+
+ dyn->dirty = 0;
+
+ /* Ship temporaries out to the corrisponding registers */
+ ship_gprs_out_t(opq->prev);
+
+ opq->num_ops = 0;
+ opq->num_ops_param = 0;
+ opq->not_jump_loc = -1;
+ opq->jump_local = -1;
+
+ /* Insert code to jump to the next page */
+ gen_op_do_jump(opq, 1);
+
+ /* Generate the code */
+ gen_code(cpu_state.opqs, dyn);
+
+ /* Fix up the locations */
+ for(loc = dyn->locs; loc < &dyn->locs[immu_state->pagesize / 4]; loc++)
+ *loc += (unsigned int)dyn->host_page;
+
+ cpu_state.opqs->ops_param[0] += (unsigned int)dyn->host_page;
+
+ /* Search for page-local jumps */
+ opq = cpu_state.opqs;
+ for(j = 0; j < (immu_state->pagesize / 4); opq = opq->next, j++) {
+ if(opq->jump_local != -1)
+ opq->ops_param[opq->jump_local] =
+ (unsigned int)dyn->locs[opq->jump_local_loc >> 2];
+
+ if(opq->not_jump_loc != -1)
+ opq->ops_param[opq->not_jump_loc] = (unsigned int)dyn->locs[j + 1];
+
+ /* Store the state of the temporaries into dyn->ts_bound */
+ dyn->ts_bound[j] = 0;
+ if(opq->reg_t[0] < 32)
+ dyn->ts_bound[j] = opq->reg_t[0];
+ if(opq->reg_t[1] < 32)
+ dyn->ts_bound[j] |= opq->reg_t[1] << 5;
+ if(opq->reg_t[2] < 32)
+ dyn->ts_bound[j] |= opq->reg_t[2] << 10;
+
+ /* Reset for the next page to be recompiled */
+ opq->xref = 0;
+ }
+
+ /* Patch the relocations */
+ patch_relocs(cpu_state.opqs, dyn->host_page);
+
+ if(do_stats) {
+ opq = cpu_state.opqs;
+ for(j = 0; j < (immu_state->pagesize / 4); j++, opq = opq->next) {
+ dyn->insns[j] = opq->insn;
+ dyn->insn_indexs[j] = opq->insn_index;
+ }
+ }
+
+ /* FIXME: Fix the issue below in a more elegent way */
+ /* Since eval_insn is called to get the instruction, runtime.sim.mem_cycles is
+ * updated but the recompiler expectes it to start a 0, so reset it */
+ runtime.sim.mem_cycles = 0;
+}
+
+/* Recompiles a delay-slot instruction (opq is the opq of the instruction
+ * haveing the delay-slot) */
+static void recompile_delay_insn(struct op_queue *opq)
+{
+ struct op_queue delay_opq;
+ int i;
+
+ /* Setup a fake opq that looks very much like the delay slot instruction */
+ memcpy(&delay_opq, opq, sizeof(struct op_queue));
+ /* `Fix' a couple of bits */
+ for(i = 0; i < NUM_T_REGS; i++)
+ delay_opq.tflags[i] = TFLAG_SOURCED;
+ delay_opq.insn_index = opq->next->insn_index;
+ memcpy(delay_opq.param_type, opq->next->param_type, sizeof(delay_opq.param_type));
+ memcpy(delay_opq.param, opq->next->param, sizeof(delay_opq.param));
+ delay_opq.param_num = opq->next->param_num;
+ delay_opq.insn = opq->next->insn;
+
+ delay_opq.xref = 0;
+ delay_opq.insn_addr = opq->insn_addr + 4;
+ delay_opq.prev = opq->prev;
+ delay_opq.next = NULL;
+
+ /* Generate the delay slot instruction */
+ recompile_insn(&delay_opq, 1);
+
+ ship_gprs_out_t(&delay_opq);
+
+ opq->num_ops = delay_opq.num_ops;
+ opq->ops_len = delay_opq.ops_len;
+ opq->ops = delay_opq.ops;
+ opq->num_ops_param = delay_opq.num_ops_param;
+ opq->ops_param_len = delay_opq.ops_param_len;
+ opq->ops_param = delay_opq.ops_param;
+
+ for(i = 0; i < NUM_T_REGS; i++)
+ opq->reg_t[i] = 32;
+}
+
+/* Returns non-zero if the jump is into this page, 0 otherwise */
+static int find_jump_loc(oraddr_t j_ea, struct op_queue *opq)
+{
+ int i;
+
+ /* Mark the jump as non page local if the delay slot instruction is on the
+ * next page to the jump instruction. This should not be needed */
+ if(IADDR_PAGE(j_ea) != IADDR_PAGE(opq->insn_addr))
+ /* We can't do anything as the j_ea (as passed to find_jump_loc) is a
+ * VIRTUAL offset and the next physical page may not be the next VIRTUAL
+ * page */
+ return 0;
+
+ /* The jump is into the page currently undergoing dynamic recompilation */
+
+ /* If we haven't got to the location of the jump, everything is ok */
+ if(j_ea > opq->insn_addr) {
+ /* Find the corissponding opq and mark it as cross referenced */
+ for(i = (j_ea - opq->insn_addr) / 4; i; i--)
+ opq = opq->next;
+ opq->xref = 1;
+ return 1;
+ }
+
+ /* Insert temporary -> register code before the jump ea and register ->
+ * temporary at the x-ref address */
+ for(i = (opq->insn_addr - j_ea) / 4; i; i--)
+ opq = opq->prev;
+
+ if(!opq->prev)
+ /* We're at the begining of a page, no need to do anything */
+ return 1;
+
+ /* Found location, insert code */
+
+ ship_gprs_out_t(opq->prev);
+
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->prev->reg_t[i] < 32)
+ /* FIXME: Ship temporaries in the begining of the opq that needs it */
+ gen_op_move_t_gpr[i][opq->prev->reg_t[i]](opq, 0);
+ }
+
+ opq->xref = 1;
+
+ return 1;
+}
+
+static void gen_j_imm(struct op_queue *opq, oraddr_t off)
+{
+ int jump_local;
+
+ off <<= 2;
+
+ if(IADDR_PAGE(opq->insn_addr) != IADDR_PAGE(opq->insn_addr + 4)) {
+ gen_op_set_pc_delay_imm(opq, 1, off);
+ gen_op_do_sched(opq, 1);
+ return;
+ }
+
+ jump_local = find_jump_loc(opq->insn_addr + off, opq);
+
+ gen_op_set_delay_insn(opq, 1);
+ gen_op_do_sched(opq, 1);
+
+ recompile_delay_insn(opq);
+
+ gen_op_add_pc(opq, 1, (orreg_t)off - 8);
+ gen_op_clear_delay_insn(opq, 1);
+ gen_op_do_sched_delay(opq, 1);
+
+ if(jump_local) {
+ gen_op_jmp_imm(opq, 1, 0);
+ opq->jump_local = opq->num_ops_param - 1;
+ opq->jump_local_loc = (opq->insn_addr + (orreg_t)off) & immu_state->page_offset_mask;
+ } else
+ gen_op_do_jump(opq, 1);
+}
+
+static const generic_gen_op set_pc_delay_gpr[32] = {
+ NULL,
+ gen_op_move_gpr1_pc_delay,
+ gen_op_move_gpr2_pc_delay,
+ gen_op_move_gpr3_pc_delay,
+ gen_op_move_gpr4_pc_delay,
+ gen_op_move_gpr5_pc_delay,
+ gen_op_move_gpr6_pc_delay,
+ gen_op_move_gpr7_pc_delay,
+ gen_op_move_gpr8_pc_delay,
+ gen_op_move_gpr9_pc_delay,
+ gen_op_move_gpr10_pc_delay,
+ gen_op_move_gpr11_pc_delay,
+ gen_op_move_gpr12_pc_delay,
+ gen_op_move_gpr13_pc_delay,
+ gen_op_move_gpr14_pc_delay,
+ gen_op_move_gpr15_pc_delay,
+ gen_op_move_gpr16_pc_delay,
+ gen_op_move_gpr17_pc_delay,
+ gen_op_move_gpr18_pc_delay,
+ gen_op_move_gpr19_pc_delay,
+ gen_op_move_gpr20_pc_delay,
+ gen_op_move_gpr21_pc_delay,
+ gen_op_move_gpr22_pc_delay,
+ gen_op_move_gpr23_pc_delay,
+ gen_op_move_gpr24_pc_delay,
+ gen_op_move_gpr25_pc_delay,
+ gen_op_move_gpr26_pc_delay,
+ gen_op_move_gpr27_pc_delay,
+ gen_op_move_gpr28_pc_delay,
+ gen_op_move_gpr29_pc_delay,
+ gen_op_move_gpr30_pc_delay,
+ gen_op_move_gpr31_pc_delay };
+
+static void gen_j_reg(struct op_queue *opq, unsigned int gpr)
+{
+ int i;
+
+ /* Ship the jump-to register out (if it exists). It requires special
+ * handleing */
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->reg_t[i] == opq->param[0])
+ /* Ship temporary out in the last opq that used it */
+ ship_t_out(opq, i);
+ }
+
+ if(do_stats)
+ gen_op_analysis(opq, 1);
+
+ if(!gpr)
+ gen_op_clear_pc_delay(opq, 1);
+ else
+ set_pc_delay_gpr[gpr](opq, 1);
+
+ gen_op_do_sched(opq, 1);
+
+ if(IADDR_PAGE(opq->insn_addr) != IADDR_PAGE(opq->insn_addr + 4))
+ return;
+
+ recompile_delay_insn(opq);
+
+ gen_op_set_pc_pc_delay(opq, 1);
+ gen_op_clear_delay_insn(opq, 1);
+ gen_op_do_sched_delay(opq, 1);
+
+ gen_op_do_jump_delay(opq, 1);
+ gen_op_do_jump(opq, 1);
+}
+
+/*------------------------------[ Operation generation for an instruction ]---*/
+/* FIXME: Flag setting is not done in any instruction */
+/* FIXME: Since r0 is not moved into a temporary, check all arguments below! */
+
+DEF_1T_OP(generic_gen_op, clear_t, gen_op_clear);
+DEF_2T_OP_NEQ(generic_gen_op, move_t_t, gen_op_move);
+DEF_1T_OP(imm_gen_op, mov_t_imm, gen_op_imm);
+
+DEF_2T_OP(imm_gen_op, l_add_imm_t_table, gen_op_add_imm);
+DEF_3T_OP(generic_gen_op, l_add_t_table, gen_op_add);
+
+void gen_l_add(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ /* Screw this, the operation shall do nothing */
+ return;
+
+ if(!opq->param[1] && !opq->param[2]) {
+ /* Just clear param_t[0] */
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ if(opq->param[0] != opq->param[1])
+ /* This just moves a register */
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ /* Check if we are moveing an immediate */
+ if(param_t[2] == T_NONE) {
+ /* Yep, an immediate */
+ mov_t_imm[param_t[0]](opq, 1, opq->param[2]);
+ return;
+ }
+ /* Just another move */
+ if(opq->param[0] != opq->param[2])
+ move_t_t[param_t[0]][param_t[2]](opq, 1);
+ return;
+ }
+
+ /* Ok, This _IS_ an add... */
+ if(param_t[2] == T_NONE)
+ /* immediate */
+ l_add_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_add_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_3T_OP(generic_gen_op, l_addc_t_table, gen_op_addc);
+
+void gen_l_addc(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ /* Screw this, the operation shall do nothing */
+ return;
+
+ /* FIXME: More optimisations !! (...and immediate...) */
+ l_addc_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_2T_OP(imm_gen_op, l_and_imm_t_table, gen_op_and_imm);
+DEF_3T_OP_NEQ(generic_gen_op, l_and_t_table, gen_op_and);
+
+void gen_l_and(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ /* Screw this, the operation shall do nothing */
+ return;
+
+ if(!opq->param[1] || !opq->param[2]) {
+ /* Just clear param_t[0] */
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if((opq->param[0] == opq->param[1]) &&
+ (opq->param[0] == opq->param[2]) &&
+ (param_t[2] != T_NONE))
+ return;
+
+ if(param_t[2] == T_NONE)
+ l_and_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_and_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+void gen_l_bf(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ /* The temporaries are expected to be shiped out after the execution of the
+ * branch instruction wether it branched or not */
+ ship_gprs_out_t(opq->prev);
+
+ if(IADDR_PAGE(opq->insn_addr) != IADDR_PAGE(opq->insn_addr + 4)) {
+ gen_op_check_flag_delay(opq, 1, opq->param[0] << 2);
+ gen_op_do_sched(opq, 1);
+ opq->not_jump_loc = -1;
+ return;
+ }
+
+ gen_op_check_flag(opq, 1, 0);
+ opq->not_jump_loc = opq->num_ops_param - 1;
+
+ gen_j_imm(opq, opq->param[0]);
+}
+
+void gen_l_bnf(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ /* The temporaries are expected to be shiped out after the execution of the
+ * branch instruction wether it branched or not */
+ ship_gprs_out_t(opq->prev);
+
+ if(IADDR_PAGE(opq->insn_addr) != IADDR_PAGE(opq->insn_addr + 4)) {
+ gen_op_check_not_flag_delay(opq, 1, opq->param[0] << 2);
+ gen_op_do_sched(opq, 1);
+ opq->not_jump_loc = -1;
+ return;
+ }
+
+ gen_op_check_not_flag(opq, 1, 0);
+ opq->not_jump_loc = opq->num_ops_param - 1;
+
+ gen_j_imm(opq, opq->param[0]);
+}
+
+DEF_3T_OP_NEQ(generic_gen_op, l_cmov_t_table, gen_op_cmov);
+
+/* FIXME: Check if either opperand 1 or 2 is r0 */
+void gen_l_cmov(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1] && !opq->param[2]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if((opq->param[1] == opq->param[2]) && (opq->param[0] == opq->param[1]))
+ return;
+
+ if(opq->param[1] == opq->param[2]) {
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ l_cmov_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+void gen_l_cust1(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust2(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust3(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust4(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust5(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust6(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust7(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+void gen_l_cust8(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+}
+
+/* FIXME: All registers need to be stored before the div instructions as they
+ * have the potenticial to cause an exception */
+
+DEF_1T_OP(generic_gen_op, check_null_excpt, gen_op_check_null_except);
+DEF_1T_OP(generic_gen_op, check_null_excpt_delay, gen_op_check_null_except_delay);
+DEF_3T_OP(generic_gen_op, l_div_t_table, gen_op_div);
+
+void gen_l_div(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[2]) {
+ /* There is no option. This _will_ cause an illeagal exception */
+ if(!delay_slot) {
+ gen_op_illegal(opq, 1);
+ gen_op_do_jump(opq, 1);
+ } else {
+ gen_op_illegal(opq, 1);
+ gen_op_do_jump(opq, 1);
+ }
+ return;
+ }
+
+ if(!delay_slot)
+ check_null_excpt[param_t[2]](opq, 1);
+ else
+ check_null_excpt_delay[param_t[2]](opq, 1);
+
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ /* Clear param_t[0] */
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_div_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_3T_OP(generic_gen_op, l_divu_t_table, gen_op_divu);
+
+void gen_l_divu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[2]) {
+ /* There is no option. This _will_ cause an illeagal exception */
+ if(!delay_slot) {
+ gen_op_illegal(opq, 1);
+ gen_op_do_jump(opq, 1);
+ } else {
+ gen_op_illegal(opq, 1);
+ gen_op_do_jump(opq, 1);
+ }
+ return;
+ }
+
+ if(!delay_slot)
+ check_null_excpt[param_t[2]](opq, 1);
+ else
+ check_null_excpt_delay[param_t[2]](opq, 1);
+
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ /* Clear param_t[0] */
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_divu_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_extbs_t_table, gen_op_extbs);
+
+void gen_l_extbs(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_extbs_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_extbz_t_table, gen_op_extbz);
+
+void gen_l_extbz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_extbz_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_exths_t_table, gen_op_exths);
+
+void gen_l_exths(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_exths_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_exthz_t_table, gen_op_exthz);
+
+void gen_l_exthz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_exthz_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+void gen_l_extws(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(opq->param[0] == opq->param[1])
+ return;
+
+ /* In the 32-bit architechture this instruction reduces to a move */
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+}
+
+void gen_l_extwz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(opq->param[0] == opq->param[1])
+ return;
+
+ /* In the 32-bit architechture this instruction reduces to a move */
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_ff1_t_table, gen_op_ff1);
+
+void gen_l_ff1(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_ff1_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+void gen_l_j(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ gen_j_imm(opq, opq->param[0]);
+}
+
+void gen_l_jal(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ int i;
+
+ /* In the case of a l.jal instruction, make sure that LINK_REGNO is not in
+ * a temporary. The problem is that the l.jal(r) instruction stores the
+ * `return address' in LINK_REGNO. The temporaries are shiped out only
+ * after the delay slot instruction has executed and so it overwrittes the
+ * `return address'. */
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->reg_t[i] == LINK_REGNO) {
+ /* Don't bother storeing the register, it is going to get clobered in this
+ * instruction anyway */
+ opq->reg_t[i] = 32;
+ break;
+ }
+ }
+
+ /* Store the return address */
+ gen_op_store_link_addr_gpr(opq, 1);
+
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ gen_j_imm(opq, opq->param[0]);
+}
+
+void gen_l_jr(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_j_reg(opq, opq->param[0]);
+}
+
+void gen_l_jalr(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ int i;
+
+ /* In the case of a l.jal instruction, make sure that LINK_REGNO is not in
+ * a temporary. The problem is that the l.jal(r) instruction stores the
+ * `return address' in LINK_REGNO. The temporaries are shiped out only
+ * after the delay slot instruction has executed and so it overwrittes the
+ * `return address'. */
+ for(i = 0; i < NUM_T_REGS; i++) {
+ if(opq->reg_t[i] == LINK_REGNO) {
+ /* Don't bother storeing the register, it is going to get clobered in this
+ * instruction anyway */
+ opq->reg_t[i] = 32;
+ break;
+ }
+ }
+
+ /* Store the return address */
+ gen_op_store_link_addr_gpr(opq, 1);
+
+ gen_j_reg(opq, opq->param[0]);
+}
+
+/* FIXME: Optimise all load instruction when the disposition == 0 */
+
+DEF_1T_OP(imm_gen_op, l_lbs_imm_t_table, gen_op_lbs_imm);
+DEF_2T_OP(imm_gen_op, l_lbs_t_table, gen_op_lbs);
+
+void gen_l_lbs(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lbs_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lbs_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_lbz_imm_t_table, gen_op_lbz_imm);
+DEF_2T_OP(imm_gen_op, l_lbz_t_table, gen_op_lbz);
+
+void gen_l_lbz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lbz_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lbz_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_lhs_imm_t_table, gen_op_lhs_imm);
+DEF_2T_OP(imm_gen_op, l_lhs_t_table, gen_op_lhs);
+
+void gen_l_lhs(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lhs_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lhs_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_lhz_imm_t_table, gen_op_lhz_imm);
+DEF_2T_OP(imm_gen_op, l_lhz_t_table, gen_op_lhz);
+
+void gen_l_lhz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lhz_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lhz_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_lws_imm_t_table, gen_op_lws_imm);
+DEF_2T_OP(imm_gen_op, l_lws_t_table, gen_op_lws);
+
+void gen_l_lws(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lws_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lws_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_lwz_imm_t_table, gen_op_lwz_imm);
+DEF_2T_OP(imm_gen_op, l_lwz_t_table, gen_op_lwz);
+
+void gen_l_lwz(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ /* FIXME: This will work, but the statistics need to be updated... */
+ return;
+ }
+
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ /* Load the data from the immediate */
+ l_lwz_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ return;
+ }
+
+ l_lwz_t_table[param_t[0]][param_t[2]](opq, 1, opq->param[1]);
+}
+
+DEF_1T_OP(imm_gen_op, l_mac_imm_t_table, gen_op_mac_imm);
+DEF_2T_OP(generic_gen_op, l_mac_t_table, gen_op_mac);
+
+void gen_l_mac(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] || !opq->param[1])
+ return;
+
+ if(param_t[1] == T_NONE)
+ l_mac_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_mac_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_macrc_t_table, gen_op_macrc);
+
+void gen_l_macrc(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0]) {
+ gen_op_macc(opq, 1);
+ return;
+ }
+
+ l_macrc_t_table[param_t[0]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_mfspr_imm_t_table, gen_op_mfspr_imm);
+DEF_2T_OP(imm_gen_op, l_mfspr_t_table, gen_op_mfspr);
+
+void gen_l_mfspr(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ l_mfspr_imm_t_table[param_t[0]](opq, 1, opq->param[2]);
+ return;
+ }
+
+ l_mfspr_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+}
+
+void gen_l_movhi(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ mov_t_imm[param_t[0]](opq, 1, opq->param[1] << 16);
+}
+
+DEF_2T_OP(generic_gen_op, l_msb_t_table, gen_op_msb);
+
+void gen_l_msb(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] || !opq->param[1])
+ return;
+
+ l_msb_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_mtspr_clear_t_table, gen_op_mtspr_clear);
+DEF_1T_OP(imm_gen_op, l_mtspr_imm_t_table, gen_op_mtspr_imm);
+DEF_2T_OP(imm_gen_op, l_mtspr_t_table, gen_op_mtspr);
+
+void gen_l_mtspr(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[0]) {
+ if(!opq->param[1]) {
+ /* Clear the immediate SPR */
+ gen_op_mtspr_imm_clear(opq, 1, opq->param[2]);
+ return;
+ }
+ l_mtspr_imm_t_table[param_t[1]](opq, 1, opq->param[2]);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_mtspr_clear_t_table[param_t[0]](opq, 1, opq->param[2]);
+ return;
+ }
+
+ l_mtspr_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+}
+
+DEF_2T_OP(imm_gen_op, l_mul_imm_t_table, gen_op_mul_imm);
+DEF_3T_OP(generic_gen_op, l_mul_t_table, gen_op_mul);
+
+void gen_l_mul(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1] || !opq->param[2]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_mul_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_mul_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_3T_OP(generic_gen_op, l_mulu_t_table, gen_op_mulu);
+
+void gen_l_mulu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1] || !opq->param[2]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ l_mulu_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+void gen_l_nop(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ /* Do parameter switch now */
+ switch(opq->param[0]) {
+ case NOP_NOP:
+ break;
+ case NOP_EXIT:
+ ship_gprs_out_t(opq->prev);
+ gen_op_nop_exit(opq, 1);
+ break;
+ case NOP_CNT_RESET:
+ gen_op_nop_reset(opq, 1);
+ break;
+ case NOP_PRINTF:
+ ship_gprs_out_t(opq->prev);
+ gen_op_nop_printf(opq, 1);
+ break;
+ case NOP_REPORT:
+ ship_gprs_out_t(opq->prev);
+ gen_op_nop_report(opq, 1);
+ break;
+ default:
+ if((opq->param[0] >= NOP_REPORT_FIRST) && (opq->param[0] <= NOP_REPORT_LAST)) {
+ ship_gprs_out_t(opq->prev);
+ gen_op_nop_report_imm(opq, 1, opq->param[0] - NOP_REPORT_FIRST);
+ }
+ break;
+ }
+}
+
+DEF_2T_OP(imm_gen_op, l_or_imm_t_table, gen_op_or_imm);
+DEF_3T_OP_NEQ(generic_gen_op, l_or_t_table, gen_op_or);
+
+void gen_l_or(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if((opq->param[0] == opq->param[1]) &&
+ (opq->param[0] == opq->param[2]) &&
+ (param_t[2] != T_NONE))
+ return;
+
+ if(!opq->param[1] && !opq->param[2]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ if((param_t[2] == T_NONE) && (opq->param[0] == opq->param[1]))
+ return;
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ /* Check if we are moveing an immediate */
+ if(param_t[2] == T_NONE) {
+ /* Yep, an immediate */
+ mov_t_imm[param_t[0]](opq, 1, opq->param[2]);
+ return;
+ }
+ /* Just another move */
+ move_t_t[param_t[0]][param_t[2]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_or_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_or_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+void gen_l_rfe(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ gen_op_prep_rfe(opq, 1);
+ /* FIXME: rename op_do_sched_delay */
+ gen_op_do_sched_delay(opq, 1);
+ gen_op_do_jump(opq, 1);
+}
+
+/* FIXME: All store instructions should be optimised when the disposition = 0 */
+
+DEF_1T_OP(imm_gen_op, l_sb_clear_table, gen_op_sb_clear);
+DEF_1T_OP(imm_gen_op, l_sb_imm_t_table, gen_op_sb_imm);
+DEF_2T_OP(imm_gen_op, l_sb_t_table, gen_op_sb);
+
+void gen_l_sb(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ if(!opq->param[1]) {
+ gen_op_sb_clear_imm(opq, 1, opq->param[0]);
+ return;
+ }
+ l_sb_clear_table[param_t[1]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ /* Store the data to the immediate */
+ l_sb_imm_t_table[param_t[2]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ l_sb_t_table[param_t[1]][param_t[2]](opq, 1, opq->param[0]);
+}
+
+DEF_1T_OP(imm_gen_op, l_sh_clear_table, gen_op_sh_clear);
+DEF_1T_OP(imm_gen_op, l_sh_imm_t_table, gen_op_sh_imm);
+DEF_2T_OP(imm_gen_op, l_sh_t_table, gen_op_sh);
+
+void gen_l_sh(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ if(!opq->param[1]) {
+ gen_op_sh_clear_imm(opq, 1, opq->param[0]);
+ return;
+ }
+ l_sh_clear_table[param_t[1]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ /* Store the data to the immediate */
+ l_sh_imm_t_table[param_t[2]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ l_sh_t_table[param_t[1]][param_t[2]](opq, 1, opq->param[0]);
+}
+
+DEF_1T_OP(imm_gen_op, l_sw_clear_table, gen_op_sw_clear);
+DEF_1T_OP(imm_gen_op, l_sw_imm_t_table, gen_op_sw_imm);
+DEF_2T_OP(imm_gen_op, l_sw_t_table, gen_op_sw);
+
+void gen_l_sw(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ /* Just in case an exception happens */
+ ship_gprs_out_t(opq->prev);
+
+ if(!opq->param[2]) {
+ if(!opq->param[1]) {
+ gen_op_sw_clear_imm(opq, 1, opq->param[0]);
+ return;
+ }
+ l_sw_clear_table[param_t[1]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ /* Store the data to the immediate */
+ l_sw_imm_t_table[param_t[2]](opq, 1, opq->param[0]);
+ return;
+ }
+
+ l_sw_t_table[param_t[1]][param_t[2]](opq, 1, opq->param[0]);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfeq_null_t_table, gen_op_sfeq_null);
+DEF_1T_OP(imm_gen_op, l_sfeq_imm_t_table, gen_op_sfeq_imm);
+DEF_2T_OP(generic_gen_op, l_sfeq_t_table, gen_op_sfeq);
+
+void gen_l_sfeq(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ if(param_t[1] == T_NONE) {
+ if(!opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfeq_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfeq_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfeq_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfeq_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfges_null_t_table, gen_op_sfges_null);
+DEF_1T_OP(generic_gen_op, l_sfles_null_t_table, gen_op_sfles_null);
+DEF_1T_OP(imm_gen_op, l_sfges_imm_t_table, gen_op_sfges_imm);
+DEF_2T_OP(generic_gen_op, l_sfges_t_table, gen_op_sfges);
+
+void gen_l_sfges(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfles IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 >= (orreg_t)opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfles_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfges_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfges_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfges_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfgeu_null_t_table, gen_op_sfgeu_null);
+DEF_1T_OP(generic_gen_op, l_sfleu_null_t_table, gen_op_sfleu_null);
+DEF_1T_OP(imm_gen_op, l_sfgeu_imm_t_table, gen_op_sfgeu_imm);
+DEF_2T_OP(generic_gen_op, l_sfgeu_t_table, gen_op_sfgeu);
+
+void gen_l_sfgeu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfleu IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 >= opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfleu_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfgeu_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+ if(param_t[1] == T_NONE)
+ l_sfgeu_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfgeu_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfgts_null_t_table, gen_op_sfgts_null);
+DEF_1T_OP(generic_gen_op, l_sflts_null_t_table, gen_op_sflts_null);
+DEF_1T_OP(imm_gen_op, l_sfgts_imm_t_table, gen_op_sfgts_imm);
+DEF_2T_OP(generic_gen_op, l_sfgts_t_table, gen_op_sfgts);
+
+void gen_l_sfgts(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_clear_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sflts IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 > (orreg_t)opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sflts_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfgts_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfgts_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfgts_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfgtu_null_t_table, gen_op_sfgtu_null);
+DEF_1T_OP(generic_gen_op, l_sfltu_null_t_table, gen_op_sfltu_null);
+DEF_1T_OP(imm_gen_op, l_sfgtu_imm_t_table, gen_op_sfgtu_imm);
+DEF_2T_OP(generic_gen_op, l_sfgtu_t_table, gen_op_sfgtu);
+
+void gen_l_sfgtu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_clear_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfltu IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 > opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfltu_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfgtu_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfgtu_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfgtu_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_sfles_imm_t_table, gen_op_sfles_imm);
+DEF_2T_OP(generic_gen_op, l_sfles_t_table, gen_op_sfles);
+
+void gen_l_sfles(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfges IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 <= (orreg_t)opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfges_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfles_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfles_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfles_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_sfleu_imm_t_table, gen_op_sfleu_imm);
+DEF_2T_OP(generic_gen_op, l_sfleu_t_table, gen_op_sfleu);
+
+void gen_l_sfleu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfleu IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 <= opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfgeu_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfleu_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfleu_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfleu_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_sflts_imm_t_table, gen_op_sflts_imm);
+DEF_2T_OP(generic_gen_op, l_sflts_t_table, gen_op_sflts);
+
+void gen_l_sflts(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_clear_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfgts IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 < (orreg_t)opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfgts_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sflts_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sflts_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sflts_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(imm_gen_op, l_sfltu_imm_t_table, gen_op_sfltu_imm);
+DEF_2T_OP(generic_gen_op, l_sfltu_t_table, gen_op_sfltu);
+
+void gen_l_sfltu(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_clear_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ /* sfgtu IS correct */
+ if(param_t[1] == T_NONE) {
+ if(0 < opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ } else
+ l_sfgtu_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfltu_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfltu_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfltu_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_1T_OP(generic_gen_op, l_sfne_null_t_table, gen_op_sfne_null);
+DEF_1T_OP(imm_gen_op, l_sfne_imm_t_table, gen_op_sfne_imm);
+DEF_2T_OP(generic_gen_op, l_sfne_t_table, gen_op_sfne);
+
+void gen_l_sfne(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0] && !opq->param[1]) {
+ gen_op_set_flag(opq, 1);
+ return;
+ }
+
+ if(!opq->param[0]) {
+ if(param_t[1] == T_NONE)
+ if(opq->param[1])
+ gen_op_set_flag(opq, 1);
+ else
+ gen_op_clear_flag(opq, 1);
+ else
+ l_sfne_null_t_table[param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ l_sfne_null_t_table[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(param_t[1] == T_NONE)
+ l_sfne_imm_t_table[param_t[0]](opq, 1, opq->param[1]);
+ else
+ l_sfne_t_table[param_t[0]][param_t[1]](opq, 1);
+}
+
+DEF_2T_OP(imm_gen_op, l_sll_imm_t_table, gen_op_sll_imm);
+DEF_3T_OP(generic_gen_op, l_sll_t_table, gen_op_sll);
+
+void gen_l_sll(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_sll_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_sll_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_2T_OP(imm_gen_op, l_sra_imm_t_table, gen_op_sra_imm);
+DEF_3T_OP(generic_gen_op, l_sra_t_table, gen_op_sra);
+
+void gen_l_sra(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_sra_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_sra_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_2T_OP(imm_gen_op, l_srl_imm_t_table, gen_op_srl_imm);
+DEF_3T_OP(generic_gen_op, l_srl_t_table, gen_op_srl);
+
+void gen_l_srl(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if(!opq->param[1]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_srl_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_srl_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+DEF_2T_OP(generic_gen_op, l_neg_t_table, gen_op_neg);
+DEF_3T_OP(generic_gen_op, l_sub_t_table, gen_op_sub);
+
+void gen_l_sub(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if((param_t[2] != T_NONE) && (opq->param[1] == opq->param[2])) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1] && !opq->param[2]) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ if(param_t[2] == T_NONE)
+ mov_t_imm[param_t[0]](opq, 1, -opq->param[2]);
+ else
+ l_neg_t_table[param_t[0]][param_t[2]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ l_sub_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+/* FIXME: This will not work if the l.sys is in a delay slot */
+void gen_l_sys(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ if(!delay_slot)
+ gen_op_prep_sys(opq, 1);
+ else
+ gen_op_prep_sys_delay(opq, 1);
+
+ gen_op_do_sched(opq, 1);
+ gen_op_do_jump(opq, 1);
+}
+
+/* FIXME: This will not work if the l.trap is in a delay slot */
+void gen_l_trap(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(do_stats)
+ /* All gprs are current since this insn doesn't touch any reg */
+ gen_op_analysis(opq, 1);
+
+ if(!delay_slot)
+ gen_op_prep_trap(opq, 1);
+ else
+ gen_op_prep_trap_delay(opq, 1);
+}
+
+DEF_2T_OP(imm_gen_op, l_xor_imm_t_table, gen_op_xor_imm);
+/* FIXME: Make unused elements NULL */
+DEF_3T_OP_NEQ(generic_gen_op, l_xor_t_table, gen_op_xor);
+
+void gen_l_xor(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!opq->param[0])
+ return;
+
+ if((param_t[2] != T_NONE) && (opq->param[1] == opq->param[2])) {
+ clear_t[param_t[0]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[2]) {
+ if((param_t[2] == T_NONE) && (opq->param[0] == opq->param[1]))
+ return;
+ move_t_t[param_t[0]][param_t[1]](opq, 1);
+ return;
+ }
+
+ if(!opq->param[1]) {
+ if(param_t[2] == T_NONE) {
+ mov_t_imm[param_t[0]](opq, 1, opq->param[2]);
+ return;
+ }
+ move_t_t[param_t[0]][param_t[2]](opq, 1);
+ return;
+ }
+
+ if(param_t[2] == T_NONE)
+ l_xor_imm_t_table[param_t[0]][param_t[1]](opq, 1, opq->param[2]);
+ else
+ l_xor_t_table[param_t[0]][param_t[1]][param_t[2]](opq, 1);
+}
+
+void gen_l_invalid(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ if(!delay_slot) {
+ gen_op_illegal(opq, 1);
+ gen_op_do_jump(opq, 1);
+ } else {
+ gen_op_illegal_delay(opq, 1);
+ gen_op_do_jump(opq, 1);
+ }
+}
+
+/*----------------------------------[ Floating point instructions (stubs) ]---*/
+void gen_lf_add_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_div_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_ftoi_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_itof_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_madd_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_mul_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_rem_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sfeq_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sfge_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sfgt_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sfle_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sflt_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sfne_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
+void gen_lf_sub_s(struct op_queue *opq, int param_t[3], int delay_slot)
+{
+ gen_l_invalid(opq, param_t, delay_slot);
+}
+
Index: or32/execute.c
===================================================================
--- or32/execute.c (nonexistent)
+++ or32/execute.c (revision 1765)
@@ -0,0 +1,1180 @@
+/* execute.c -- OR1K architecture dependent simulation
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Most of the OR1K simulation is done in here.
+
+ When SIMPLE_EXECUTION is defined below a file insnset.c is included!
+*/
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "execute.h"
+#include "toplevel-support.h"
+#include "except.h"
+#include "labels.h"
+#include "gdbcomm.h"
+#include "sched.h"
+#include "stats.h"
+#include "opcode/or32.h"
+#include "dmmu.h"
+#include "immu.h"
+#include "sim-cmd.h"
+#include "vapi.h"
+#include "debug-unit.h"
+#include "branch-predict.h"
+#include "support/simprintf.h"
+#include "sprs.h"
+#include "rsp-server.h"
+
+
+/* Includes and macros for simple execution */
+#if SIMPLE_EXECUTION
+
+#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn)
+
+#define PARAM0 eval_operand(0, current->insn_index, current->insn)
+#define PARAM1 eval_operand(1, current->insn_index, current->insn)
+#define PARAM2 eval_operand(2, current->insn_index, current->insn)
+
+#define INSTRUCTION(name) void name (struct iqueue_entry *current)
+
+#endif /* SIMPLE_EXECUTION */
+
+
+/*! Current cpu state. Globally available. */
+struct cpu_state cpu_state;
+
+/*! Temporary program counter. Globally available */
+oraddr_t pcnext;
+
+/*! Num cycles waiting for stores to complete. Globally available */
+int sbuf_wait_cyc = 0;
+
+/*! Number of total store cycles. Globally available */
+int sbuf_total_cyc = 0;
+
+/*! Whether we are doing statistical analysis. Globally available */
+int do_stats = 0;
+
+/*! History of execution. Globally available */
+struct hist_exec *hist_exec_tail = NULL;
+
+/* Benchmark multi issue execution. This file only */
+static int multissue[20];
+static int issued_per_cycle = 4;
+
+/* Store buffer analysis - stores are accumulated and commited when IO is
+ idle. This file only */
+static int sbuf_head = 0;
+static int sbuf_tail = 0;
+static int sbuf_count = 0;
+#if !(DYNAMIC_EXECUTION)
+static int sbuf_buf[MAX_SBUF_LEN] = { 0 };
+#endif
+
+static int sbuf_prev_cycles = 0;
+
+/* Variables used throughout this file to share information */
+static int breakpoint;
+static int next_delay_insn;
+
+/* Forward declaration of static functions */
+#if !(DYNAMIC_EXECUTION)
+static void decode_execute (struct iqueue_entry *current);
+#endif
+
+/*---------------------------------------------------------------------------*/
+/*!Get an actual value of a specific register
+
+ Implementation specific. Abort if we are given a duff register. Only used
+ externally to support simprintf().
+
+ @param[in] regno The register of interest
+
+ @return The value of the register */
+/*---------------------------------------------------------------------------*/
+uorreg_t
+evalsim_reg (unsigned int regno)
+{
+ if (regno < MAX_GPRS)
+ {
+#if RAW_RANGE_STATS
+ int delta = (runtime.sim.cycles - raw_stats.reg[regno]);
+
+ if ((unsigned long) delta < (unsigned long) RAW_RANGE)
+ {
+ raw_stats.range[delta]++;
+ }
+#endif /* RAW_RANGE */
+
+ return cpu_state.reg[regno];
+ }
+ else
+ {
+ PRINTF ("\nABORT: read out of registers\n");
+ sim_done ();
+ return 0;
+ }
+} /* evalsim_reg() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Set a specific register with value
+
+ Implementation specific. Abort if we are given a duff register.
+
+ @param[in] regno The register of interest
+ @param[in] value The value to be set */
+/*---------------------------------------------------------------------------*/
+void
+setsim_reg (unsigned int regno,
+ uorreg_t value)
+{
+ if (regno == 0) /* gpr0 is always zero */
+ {
+ value = 0;
+ }
+
+ if (regno < MAX_GPRS)
+ {
+ cpu_state.reg[regno] = value;
+ }
+ else
+ {
+ PRINTF ("\nABORT: write out of registers\n");
+ sim_done ();
+ }
+
+#if RAW_RANGE_STATS
+ raw_stats.reg[regno] = runtime.sim.cycles;
+#endif /* RAW_RANGE */
+
+} /* setsim_reg() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Evaluates source operand operand
+
+ Implementation specific. Declared global, although this is only actually
+ required for DYNAMIC_EXECUTION,
+
+ @param[in] insn The instruction
+ @param[in] opd The operand
+
+ @return The value of the source operand */
+/*---------------------------------------------------------------------------*/
+uorreg_t
+eval_operand_val (uint32_t insn,
+ struct insn_op_struct *opd)
+{
+ unsigned long operand = 0;
+ unsigned long sbit;
+ unsigned int nbits = 0;
+
+ while (1)
+ {
+ operand |=
+ ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
+ nbits;
+ nbits += opd->data;
+
+ if (opd->type & OPTYPE_OP)
+ {
+ break;
+ }
+
+ opd++;
+ }
+
+ if (opd->type & OPTYPE_SIG)
+ {
+ sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
+
+ if (operand & (1 << sbit))
+ {
+ operand |= ~REG_C (0) << sbit;
+ }
+ }
+
+ return operand;
+
+} /* eval_operand_val() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Does source operand depend on computation of dest operand?
+
+ Cycle t Cycle t+1
+ dst: irrelevant src: immediate always 0
+ dst: reg1 direct src: reg2 direct 0 if reg1 != reg2
+ dst: reg1 disp src: reg2 direct always 0
+ dst: reg1 direct src: reg2 disp 0 if reg1 != reg2
+ dst: reg1 disp src: reg2 disp always 1 (store must
+ finish before load)
+ dst: flag src: flag always 1
+
+ @param[in] prev Previous instruction
+ @param[in] next Next instruction
+
+ @return Non-zero if yes. */
+/*---------------------------------------------------------------------------*/
+static int
+check_depend (struct iqueue_entry *prev,
+ struct iqueue_entry *next)
+{
+ /* Find destination type. */
+ unsigned long type = 0;
+ int prev_dis;
+ int next_dis;
+ orreg_t prev_reg_val = 0;
+ struct insn_op_struct *opd;
+
+ if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
+ && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
+ {
+ return 1;
+ }
+
+ opd = op_start[prev->insn_index];
+ prev_dis = 0;
+
+ while (1)
+ {
+ if (opd->type & OPTYPE_DIS)
+ {
+ prev_dis = 1;
+ }
+
+ if (opd->type & OPTYPE_DST)
+ {
+ type = opd->type;
+
+ if (prev_dis)
+ {
+ type |= OPTYPE_DIS;
+ }
+
+ /* Destination is always a register */
+ prev_reg_val = eval_operand_val (prev->insn, opd);
+ break;
+ }
+
+ if (opd->type & OPTYPE_LAST)
+ {
+ return 0; /* Doesn't have a destination operand */
+ }
+
+ if (opd->type & OPTYPE_OP)
+ {
+ prev_dis = 0;
+ }
+
+ opd++;
+ }
+
+ /* We search all source operands - if we find confict => return 1 */
+ opd = op_start[next->insn_index];
+ next_dis = 0;
+
+ while (1)
+ {
+ if (opd->type & OPTYPE_DIS)
+ {
+ next_dis = 1;
+ }
+
+ /* This instruction sequence also depends on order of execution:
+ l.lw r1, k(r1)
+ l.sw k(r1), r4
+ Here r1 is a destination in l.sw */
+
+ /* FIXME: This situation is not handeld here when r1 == r2:
+ l.sw k(r1), r4
+ l.lw r3, k(r2) */
+ if (!(opd->type & OPTYPE_DST) || (next_dis && (opd->type & OPTYPE_DST)))
+ {
+ if (opd->type & OPTYPE_REG)
+ {
+ if (eval_operand_val (next->insn, opd) == prev_reg_val)
+ {
+ return 1;
+ }
+ }
+ }
+
+ if (opd->type & OPTYPE_LAST)
+ {
+ break;
+ }
+
+ opd++;
+ }
+
+ return 0;
+
+} /* check_depend() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Should instruction NOT be executed?
+
+ Modified by CZ 26/05/01 for new mode execution.
+
+ @return Nonzero if instruction should NOT be executed */
+/*---------------------------------------------------------------------------*/
+static int
+fetch ()
+{
+ static int break_just_hit = 0;
+
+ if (NULL != breakpoints)
+ {
+ /* MM: Check for breakpoint. This has to be done in fetch cycle,
+ because of peripheria.
+ MM1709: if we cannot access the memory entry, we could not set the
+ breakpoint earlier, so just check the breakpoint list. */
+ if (has_breakpoint (peek_into_itlb (cpu_state.pc)) && !break_just_hit)
+ {
+ break_just_hit = 1;
+ return 1; /* Breakpoint set. */
+ }
+ break_just_hit = 0;
+ }
+
+ breakpoint = 0;
+ cpu_state.iqueue.insn_addr = cpu_state.pc;
+ cpu_state.iqueue.insn = eval_insn (cpu_state.pc, &breakpoint);
+
+ /* Fetch instruction. */
+ if (!except_pending)
+ {
+ runtime.cpu.instructions++;
+ }
+
+ /* update_pc will be called after execution */
+ return 0;
+
+} /* fetch() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!This code actually updates the PC value */
+/*---------------------------------------------------------------------------*/
+static void
+update_pc ()
+{
+ cpu_state.delay_insn = next_delay_insn;
+ cpu_state.sprs[SPR_PPC] = cpu_state.pc; /* Store value for later */
+ cpu_state.pc = pcnext;
+ pcnext = cpu_state.delay_insn ? cpu_state.pc_delay :
+ pcnext + 4;
+} /* update_pc() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Perform analysis of the instruction being executed
+
+ This could be static for SIMPLE_EXECUTION, but made global for general use.
+
+ @param[in] current The instruction being executed */
+/*---------------------------------------------------------------------------*/
+void
+analysis (struct iqueue_entry *current)
+{
+ if (config.cpu.dependstats)
+ {
+ /* Dynamic, dependency stats. */
+ adddstats (cpu_state.icomplet.insn_index, current->insn_index, 1,
+ check_depend (&cpu_state.icomplet, current));
+
+ /* Dynamic, functional units stats. */
+ addfstats (or32_opcodes[cpu_state.icomplet.insn_index].func_unit,
+ or32_opcodes[current->insn_index].func_unit, 1,
+ check_depend (&cpu_state.icomplet, current));
+
+ /* Dynamic, single stats. */
+ addsstats (current->insn_index, 1);
+ }
+
+ if (config.cpu.superscalar)
+ {
+ if ((or32_opcodes[current->insn_index].func_unit == it_branch) ||
+ (or32_opcodes[current->insn_index].func_unit == it_jump))
+ runtime.sim.storecycles += 0;
+
+ if (or32_opcodes[current->insn_index].func_unit == it_store)
+ runtime.sim.storecycles += 1;
+
+ if (or32_opcodes[current->insn_index].func_unit == it_load)
+ runtime.sim.loadcycles += 1;
+
+ /* Pseudo multiple issue benchmark */
+ if ((multissue[or32_opcodes[current->insn_index].func_unit] < 1) ||
+ (check_depend (&cpu_state.icomplet, current))
+ || (issued_per_cycle < 1))
+ {
+ int i;
+ for (i = 0; i < 20; i++)
+ multissue[i] = 2;
+ issued_per_cycle = 2;
+ runtime.cpu.supercycles++;
+ if (check_depend (&cpu_state.icomplet, current))
+ runtime.cpu.hazardwait++;
+ multissue[it_unknown] = 2;
+ multissue[it_shift] = 2;
+ multissue[it_compare] = 1;
+ multissue[it_branch] = 1;
+ multissue[it_jump] = 1;
+ multissue[it_extend] = 2;
+ multissue[it_nop] = 2;
+ multissue[it_move] = 2;
+ multissue[it_movimm] = 2;
+ multissue[it_arith] = 2;
+ multissue[it_store] = 2;
+ multissue[it_load] = 2;
+ }
+ multissue[or32_opcodes[current->insn_index].func_unit]--;
+ issued_per_cycle--;
+ }
+
+ if (config.cpu.dependstats)
+ /* Instruction waits in completition buffer until retired. */
+ memcpy (&cpu_state.icomplet, current, sizeof (struct iqueue_entry));
+
+ if (config.sim.history)
+ {
+ /* History of execution */
+ hist_exec_tail = hist_exec_tail->next;
+ hist_exec_tail->addr = cpu_state.icomplet.insn_addr;
+ }
+
+ if (config.sim.exe_log)
+ dump_exe_log ();
+
+} /* analysis() */
+
+
+#if !(DYNAMIC_EXECUTION)
+
+/*---------------------------------------------------------------------------*/
+/*!Store buffer analysis for store instructions
+
+ Stores are accumulated and commited when IO is idle
+
+ @param[in] cyc Number of cycles being analysed */
+/*---------------------------------------------------------------------------*/
+static void
+sbuf_store (int cyc)
+{
+ int delta = runtime.sim.cycles - sbuf_prev_cycles;
+
+ sbuf_total_cyc += cyc;
+ sbuf_prev_cycles = runtime.sim.cycles;
+
+ /* Take stores from buffer, that occured meanwhile */
+ while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
+ {
+ delta -= sbuf_buf[sbuf_tail];
+ sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
+ sbuf_count--;
+ }
+
+ if (sbuf_count)
+ {
+ sbuf_buf[sbuf_tail] -= delta;
+ }
+
+ /* Store buffer is full, take one out */
+ if (sbuf_count >= config.cpu.sbuf_len)
+ {
+ sbuf_wait_cyc += sbuf_buf[sbuf_tail];
+ runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
+ sbuf_prev_cycles += sbuf_buf[sbuf_tail];
+ sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
+ sbuf_count--;
+ }
+
+ /* Put newest store in the buffer */
+ sbuf_buf[sbuf_head] = cyc;
+ sbuf_head = (sbuf_head + 1) % MAX_SBUF_LEN;
+ sbuf_count++;
+
+} /* sbuf_store() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Store buffer analysis for load instructions
+
+ Previous stores should commit, before any load */
+/*---------------------------------------------------------------------------*/
+static void
+sbuf_load ()
+{
+ int delta = runtime.sim.cycles - sbuf_prev_cycles;
+ sbuf_prev_cycles = runtime.sim.cycles;
+
+ /* Take stores from buffer, that occured meanwhile */
+ while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
+ {
+ delta -= sbuf_buf[sbuf_tail];
+ sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
+ sbuf_count--;
+ }
+
+ if (sbuf_count)
+ {
+ sbuf_buf[sbuf_tail] -= delta;
+ }
+
+ /* Wait for all stores to complete */
+ while (sbuf_count > 0)
+ {
+ sbuf_wait_cyc += sbuf_buf[sbuf_tail];
+ runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
+ sbuf_prev_cycles += sbuf_buf[sbuf_tail];
+ sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
+ sbuf_count--;
+ }
+} /* sbuf_load() */
+
+#endif /* !DYNAMIC_EXECUTION */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Outputs dissasembled instruction */
+/*---------------------------------------------------------------------------*/
+void
+dump_exe_log ()
+{
+ oraddr_t insn_addr = cpu_state.iqueue.insn_addr;
+ unsigned int i;
+ unsigned int j;
+ uorreg_t operand;
+
+ if (insn_addr == 0xffffffff)
+ {
+ return;
+ }
+
+ if ((config.sim.exe_log_start <= runtime.cpu.instructions) &&
+ ((config.sim.exe_log_end <= 0) ||
+ (runtime.cpu.instructions <= config.sim.exe_log_end)))
+ {
+ struct label_entry *entry;
+
+ if (config.sim.exe_log_marker &&
+ !(runtime.cpu.instructions % config.sim.exe_log_marker))
+ {
+ fprintf (runtime.sim.fexe_log,
+ "--------------------- %8lli instruction "
+ "---------------------\n",
+ runtime.cpu.instructions);
+ }
+
+ switch (config.sim.exe_log_type)
+ {
+ case EXE_LOG_HARDWARE:
+ fprintf (runtime.sim.fexe_log,
+ "\nEXECUTED(%11llu): %" PRIxADDR ": ",
+ runtime.cpu.instructions, insn_addr);
+ fprintf (runtime.sim.fexe_log, "%.2x%.2x",
+ eval_direct8 (insn_addr, 0, 0),
+ eval_direct8 (insn_addr + 1, 0, 0));
+ fprintf (runtime.sim.fexe_log, "%.2x%.2x",
+ eval_direct8 (insn_addr + 2, 0, 0),
+ eval_direct8 (insn_addr + 3, 0, 0));
+
+ for (i = 0; i < MAX_GPRS; i++)
+ {
+ if (i % 4 == 0)
+ {
+ fprintf (runtime.sim.fexe_log, "\n");
+ }
+
+ fprintf (runtime.sim.fexe_log, "GPR%2u: %" PRIxREG " ", i,
+ cpu_state.reg[i]);
+ }
+
+ fprintf (runtime.sim.fexe_log, "\n");
+ fprintf (runtime.sim.fexe_log, "SR : %.8" PRIx32 " ",
+ cpu_state.sprs[SPR_SR]);
+ fprintf (runtime.sim.fexe_log, "EPCR0: %" PRIxADDR " ",
+ cpu_state.sprs[SPR_EPCR_BASE]);
+ fprintf (runtime.sim.fexe_log, "EEAR0: %" PRIxADDR " ",
+ cpu_state.sprs[SPR_EEAR_BASE]);
+ fprintf (runtime.sim.fexe_log, "ESR0 : %.8" PRIx32 "\n",
+ cpu_state.sprs[SPR_ESR_BASE]);
+ break;
+
+ case EXE_LOG_SIMPLE:
+ case EXE_LOG_SOFTWARE:
+ disassemble_index (cpu_state.iqueue.insn,
+ cpu_state.iqueue.insn_index);
+
+ entry = get_label (insn_addr);
+ if (entry)
+ {
+ fprintf (runtime.sim.fexe_log, "%s:\n", entry->name);
+ }
+
+ if (config.sim.exe_log_type == EXE_LOG_SOFTWARE)
+ {
+ struct insn_op_struct *opd =
+ op_start[cpu_state.iqueue.insn_index];
+
+ j = 0;
+ while (1)
+ {
+ operand = eval_operand_val (cpu_state.iqueue.insn, opd);
+ while (!(opd->type & OPTYPE_OP))
+ {
+ opd++;
+ }
+ if (opd->type & OPTYPE_DIS)
+ {
+ fprintf (runtime.sim.fexe_log,
+ "EA =%" PRIxADDR " PA =%" PRIxADDR " ",
+ cpu_state.insn_ea,
+ peek_into_dtlb (cpu_state.insn_ea, 0, 0));
+ opd++; /* Skip of register operand */
+ j++;
+ }
+ else if ((opd->type & OPTYPE_REG) && operand)
+ {
+ fprintf (runtime.sim.fexe_log, "r%-2i=%" PRIxREG " ",
+ (int) operand, evalsim_reg (operand));
+ }
+ else
+ {
+ fprintf (runtime.sim.fexe_log, " ");
+ }
+ j++;
+ if (opd->type & OPTYPE_LAST)
+ {
+ break;
+ }
+ opd++;
+ }
+ if (or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG)
+ {
+ fprintf (runtime.sim.fexe_log, "SR =%" PRIxREG " ",
+ cpu_state.sprs[SPR_SR]);
+ j++;
+ }
+ while (j < 3)
+ {
+ fprintf (runtime.sim.fexe_log, " ");
+ j++;
+ }
+ }
+ fprintf (runtime.sim.fexe_log, "%" PRIxADDR " ", insn_addr);
+ fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
+ }
+ }
+} /* dump_exe_log() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Dump registers
+
+ Supports the CLI 'r' and 't' commands */
+/*---------------------------------------------------------------------------*/
+void
+dumpreg ()
+{
+ int i;
+ oraddr_t physical_pc;
+
+ if ((physical_pc = peek_into_itlb (cpu_state.iqueue.insn_addr)))
+ {
+ disassemble_memory (physical_pc, physical_pc + 4, 0);
+ }
+ else
+ {
+ PRINTF ("INTERNAL SIMULATOR ERROR:\n");
+ PRINTF ("no translation for currently executed instruction\n");
+ }
+
+ // generate_time_pretty (temp, runtime.sim.cycles * config.sim.clkcycle_ps);
+ PRINTF (" (executed) [cycle %lld, #%lld]\n", runtime.sim.cycles,
+ runtime.cpu.instructions);
+ if (config.cpu.superscalar)
+ {
+ PRINTF ("Superscalar CYCLES: %u", runtime.cpu.supercycles);
+ }
+ if (config.cpu.hazards)
+ {
+ PRINTF (" HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
+ }
+ else if (config.cpu.superscalar)
+ {
+ PRINTF ("\n");
+ }
+
+ if ((physical_pc = peek_into_itlb (cpu_state.pc)))
+ {
+ disassemble_memory (physical_pc, physical_pc + 4, 0);
+ }
+ else
+ {
+ PRINTF ("%" PRIxADDR ": : xxxxxxxx ITLB miss follows", cpu_state.pc);
+ }
+
+ PRINTF (" (next insn) %s", (cpu_state.delay_insn ? "(delay insn)" : ""));
+
+ for (i = 0; i < MAX_GPRS; i++)
+ {
+ if (i % 4 == 0)
+ {
+ PRINTF ("\n");
+ }
+
+ PRINTF ("GPR%.2u: %" PRIxREG " ", i, evalsim_reg (i));
+ }
+
+ PRINTF ("flag: %u\n", cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
+
+} /* dumpreg() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Wrapper around real decode_execute function
+
+ Some statistics here only
+
+ @param[in] current Instruction being executed */
+/*---------------------------------------------------------------------------*/
+static void
+decode_execute_wrapper (struct iqueue_entry *current)
+{
+ breakpoint = 0;
+
+#ifndef HAVE_EXECUTION
+#error HAVE_EXECUTION has to be defined in order to execute programs.
+#endif
+
+ /* FIXME: Most of this file is not needed with DYNAMIC_EXECUTION */
+#if !(DYNAMIC_EXECUTION)
+ decode_execute (current);
+#endif
+
+#if SET_OV_FLAG
+ /* Check for range exception */
+ if ((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) &&
+ (cpu_state.sprs[SPR_SR] & SPR_SR_OV))
+ {
+ except_handle (EXCEPT_RANGE, cpu_state.sprs[SPR_EEAR_BASE]);
+ }
+#endif
+
+ if (breakpoint)
+ {
+ except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
+ }
+} /* decode_execute_wrapper() */
+
+/*---------------------------------------------------------------------------*/
+/*!Reset the CPU */
+/*---------------------------------------------------------------------------*/
+void
+cpu_reset ()
+{
+ int i;
+ struct hist_exec *hist_exec_head = NULL;
+ struct hist_exec *hist_exec_new;
+
+ runtime.sim.cycles = 0;
+ runtime.sim.loadcycles = 0;
+ runtime.sim.storecycles = 0;
+ runtime.cpu.instructions = 0;
+ runtime.cpu.supercycles = 0;
+ runtime.cpu.hazardwait = 0;
+
+ for (i = 0; i < MAX_GPRS; i++)
+ {
+ setsim_reg (i, 0);
+ }
+
+ memset (&cpu_state.iqueue, 0, sizeof (cpu_state.iqueue));
+ memset (&cpu_state.icomplet, 0, sizeof (cpu_state.icomplet));
+
+ sbuf_head = 0;
+ sbuf_tail = 0;
+ sbuf_count = 0;
+ sbuf_prev_cycles = 0;
+
+ /* Initialise execution history circular buffer */
+ for (i = 0; i < HISTEXEC_LEN; i++)
+ {
+ hist_exec_new = malloc (sizeof (struct hist_exec));
+
+ if (!hist_exec_new)
+ {
+ fprintf (stderr, "Out-of-memory\n");
+ exit (1);
+ }
+
+ if (!hist_exec_head)
+ {
+ hist_exec_head = hist_exec_new;
+ }
+ else
+ {
+ hist_exec_tail->next = hist_exec_new;
+ }
+
+ hist_exec_new->prev = hist_exec_tail;
+ hist_exec_tail = hist_exec_new;
+ }
+
+ /* Make hist_exec_tail->next point to hist_exec_head */
+ hist_exec_tail->next = hist_exec_head;
+ hist_exec_head->prev = hist_exec_tail;
+
+ /* MM1409: All progs should start at reset vector entry! This sorted out by
+ setting the cpu_state.pc field below. Not clear this is very good code! */
+ pcnext = 0x0;
+
+ if (config.sim.verbose)
+ {
+ PRINTF ("Starting at 0x%" PRIxADDR "\n", pcnext);
+ }
+
+ cpu_state.pc = pcnext;
+ pcnext += 4;
+
+ /* MM1409: All programs should set their stack pointer! */
+#if !(DYNAMIC_EXECUTION)
+ except_handle (EXCEPT_RESET, 0);
+ update_pc ();
+#endif
+
+ except_pending = 0;
+ cpu_state.pc = EXCEPT_RESET;
+
+} /* cpu_reset() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Simulates one CPU clock cycle
+
+ @return non-zero if a breakpoint is hit, zero otherwise. */
+/*---------------------------------------------------------------------------*/
+int
+cpu_clock ()
+{
+ except_pending = 0;
+ next_delay_insn = 0;
+
+ if (fetch ())
+ {
+ PRINTF ("Breakpoint hit.\n");
+ return 1;
+ }
+
+ if (except_pending)
+ {
+ update_pc ();
+ except_pending = 0;
+ return 0;
+ }
+
+ if (breakpoint)
+ {
+ except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
+ update_pc ();
+ except_pending = 0;
+ return 0;
+ }
+
+ decode_execute_wrapper (&cpu_state.iqueue);
+ update_pc ();
+ return 0;
+
+} /* cpu_clock() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!If decoding cannot be found, call this function */
+/*---------------------------------------------------------------------------*/
+#if SIMPLE_EXECUTION
+void
+l_invalid (struct iqueue_entry *current)
+{
+#else
+void
+l_invalid ()
+{
+#endif
+ except_handle (EXCEPT_ILLEGAL, cpu_state.iqueue.insn_addr);
+
+} /* l_invalid() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!The main execution loop */
+/*---------------------------------------------------------------------------*/
+void
+exec_main ()
+{
+ long long time_start;
+
+ while (1)
+ {
+ time_start = runtime.sim.cycles;
+ if (config.debug.enabled)
+ {
+ while (runtime.cpu.stalled)
+ {
+ if (config.debug.rsp_enabled)
+ {
+ handle_rsp ();
+ }
+ else if (config.debug.gdb_enabled)
+ {
+ block_jtag ();
+ handle_server_socket (FALSE);
+ }
+ else
+ {
+ fprintf (stderr, "ERROR: CPU stalled and GDB connection not "
+ "enabled: Invoking CLI and terminating.\n");
+ /* Dump the user into interactive mode. From there he or
+ she can decide what to do. */
+ handle_sim_command ();
+ sim_done ();
+ }
+ if (runtime.sim.iprompt)
+ handle_sim_command ();
+ }
+ }
+
+ /* Each cycle has counter of mem_cycles; this value is joined with cycles
+ at the end of the cycle; no sim originated memory accesses should be
+ performed inbetween. */
+ runtime.sim.mem_cycles = 0;
+
+ if (!config.pm.enabled ||
+ !(config.pm.enabled &
+ (cpu_state.sprs[SPR_PMR] & (SPR_PMR_DME | SPR_PMR_SME))))
+ {
+ if (cpu_clock ())
+ {
+ /* A breakpoint has been hit, drop to interactive mode */
+ handle_sim_command ();
+ }
+ }
+
+ if (config.vapi.enabled && runtime.vapi.enabled)
+ {
+ vapi_check ();
+ }
+
+ if (config.debug.gdb_enabled)
+ {
+ handle_server_socket (FALSE); /* block & check_stdin = false */
+ }
+
+ if (config.debug.enabled)
+ {
+ if (cpu_state.sprs[SPR_DMR1] & SPR_DMR1_ST)
+ {
+ set_stall_state (1);
+
+ if (config.debug.rsp_enabled)
+ {
+ rsp_exception (EXCEPT_TRAP);
+ }
+ }
+ }
+
+ runtime.sim.cycles += runtime.sim.mem_cycles;
+ scheduler.job_queue->time -= runtime.sim.cycles - time_start;
+
+ if (scheduler.job_queue->time <= 0)
+ {
+ do_scheduler ();
+ }
+ }
+} /* exec_main() */
+
+#if COMPLEX_EXECUTION
+
+/* Include generated/built in decode_execute function */
+#include "execgen.c"
+
+#elif SIMPLE_EXECUTION
+
+
+/*---------------------------------------------------------------------------*/
+/*!Evaluates source operand
+
+ Implementation specific.
+
+ @param[in] op_no The operand
+ @param[in] insn_index Address of the instruction
+ @param[in] insn The instruction
+
+ @return The value of the operand */
+/*---------------------------------------------------------------------------*/
+static uorreg_t
+eval_operand (int op_no,
+ unsigned long insn_index,
+ uint32_t insn)
+{
+ struct insn_op_struct *opd = op_start[insn_index];
+ uorreg_t ret;
+
+ while (op_no)
+ {
+ if (opd->type & OPTYPE_LAST)
+ {
+ fprintf (stderr,
+ "Instruction requested more operands than it has\n");
+ exit (1);
+ }
+
+ if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
+ {
+ op_no--;
+ }
+
+ opd++;
+ }
+
+ if (opd->type & OPTYPE_DIS)
+ {
+ ret = eval_operand_val (insn, opd);
+
+ while (!(opd->type & OPTYPE_OP))
+ {
+ opd++;
+ }
+
+ opd++;
+ ret += evalsim_reg (eval_operand_val (insn, opd));
+ cpu_state.insn_ea = ret;
+
+ return ret;
+ }
+
+ if (opd->type & OPTYPE_REG)
+ {
+ return evalsim_reg (eval_operand_val (insn, opd));
+ }
+
+ return eval_operand_val (insn, opd);
+
+} /* eval_operand() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Set destination operand (register direct) with value.
+
+ Implementation specific.
+
+ @param[in] op_no The operand
+ @param[in] value The value to set
+ @param[in] insn_index Address of the instruction
+ @param[in] insn The instruction */
+/*---------------------------------------------------------------------------*/
+static void
+set_operand (int op_no,
+ orreg_t value,
+ unsigned long insn_index,
+ uint32_t insn)
+{
+ struct insn_op_struct *opd = op_start[insn_index];
+
+ while (op_no)
+ {
+ if (opd->type & OPTYPE_LAST)
+ {
+ fprintf (stderr,
+ "Instruction requested more operands than it has\n");
+ exit (1);
+ }
+
+ if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
+ {
+ op_no--;
+ }
+
+ opd++;
+ }
+
+ if (!(opd->type & OPTYPE_REG))
+ {
+ fprintf (stderr, "Trying to set a non-register operand\n");
+ exit (1);
+ }
+
+ setsim_reg (eval_operand_val (insn, opd), value);
+
+} /* set_operand() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Simple and rather slow decoding function
+
+ Based on built automata.
+
+ @param[in] current The current instruction to execute */
+/*---------------------------------------------------------------------------*/
+static void
+decode_execute (struct iqueue_entry *current)
+{
+ int insn_index;
+
+ current->insn_index = insn_index = insn_decode (current->insn);
+
+ if (insn_index < 0)
+ {
+ l_invalid (current);
+ }
+ else
+ {
+ or32_opcodes[insn_index].exec (current);
+ }
+
+ if (do_stats)
+ analysis (&cpu_state.iqueue);
+}
+
+#include "insnset.c"
+
+#elif defined(DYNAMIC_EXECUTION)
+
+#else
+# error "Must define SIMPLE_EXECUTION, COMPLEX_EXECUTION or DYNAMIC_EXECUTION"
+#endif
Index: or32/op-arith-op.h
===================================================================
--- or32/op-arith-op.h (nonexistent)
+++ or32/op-arith-op.h (revision 1765)
@@ -0,0 +1,33 @@
+/* op-arith-op.h -- Micro operations template for arithmetic operations
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef OP_3T
+__or_dynop void glue(glue(op_, OP_NAME), T)(void)
+{
+ T0 = OP_CAST(T1) OP OP_CAST(T2) OP_EXTRA;
+}
+#endif
+
+#ifdef OP_2T
+__or_dynop void glue(glue(glue(op_, OP_NAME), _imm), T)(void)
+{
+ T0 = OP_CAST(T1) OP OP_CAST(OP_PARAM1) OP_EXTRA;
+}
+#endif
+
Index: or32/dyn-rec.h
===================================================================
--- or32/dyn-rec.h (nonexistent)
+++ or32/dyn-rec.h (revision 1765)
@@ -0,0 +1,70 @@
+/* dyn-rec.h -- Recompiler specific definitions
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef DYN_REC__H
+#define DYN_REC__H
+
+typedef void (*gen_code_ent)(void);
+
+/* Each dynamically recompiled page has one of these */
+struct dyn_page {
+ oraddr_t or_page;
+ void *host_page;
+ unsigned int host_len;
+ int dirty; /* Is recompiled page invalid? */
+ int delayr; /* delayr of memory backing this page */
+ uint16_t ts_bound[2049]; /* What registers the temporaries back (on the
+ * begining boundry of the instruction) */
+ void **locs; /* Openrisc locations in the recompiled code */
+ uint32_t *insns; /* Copy of instructions on this page */
+ unsigned int *insn_indexs; /* Decoded instructions on this page */
+};
+
+/* Function prototypes for external use */
+extern void recompile_page(struct dyn_page *dyn);
+extern struct dyn_page *new_dp(oraddr_t page);
+extern void add_to_opq(struct op_queue *opq, int end, int op);
+extern void add_to_op_params(struct op_queue *opq, int end, unsigned long param);
+extern void *enough_host_page(struct dyn_page *dp, void *cur, unsigned int *len,
+ unsigned int amount);
+extern void init_dyn_recomp(void);
+extern void run_sched_out_of_line(void);
+extern void recheck_immu(int got_en_dis);
+extern void enter_dyn_code(oraddr_t addr, struct dyn_page *dp);
+extern void dyn_checkwrite(oraddr_t addr);
+extern void dyn_main(void);
+
+/* Global variables for external use */
+extern void *rec_stack_base;
+
+#define IMMU_GOT_ENABLED 1
+#define IMMU_GOT_DISABLED 2
+
+#define xglue(x, y) x ## y
+#define glue(x, y) xglue(x, y)
+
+#endif /* DYN_REC__H */
+
Index: or32/simpl32-defs.h
===================================================================
--- or32/simpl32-defs.h (nonexistent)
+++ or32/simpl32-defs.h (revision 1765)
@@ -0,0 +1,112 @@
+/* simpl32-defs.h -- Definitions for the simple execution model
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributed by Damjan Lampret (lampret@opencores.org).
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+ This file is also part of or1k_gen_isa, GDB and GAS.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef SIMPLE32_DEFS__H
+#define SIMPLE32_DEFS__H
+
+/* Package includes */
+#include "abstract.h"
+
+
+extern void l_invalid PARAMS((struct iqueue_entry *));
+extern void l_sfne PARAMS((struct iqueue_entry *));
+extern void l_bf PARAMS((struct iqueue_entry *));
+extern void l_add PARAMS((struct iqueue_entry *));
+extern void l_addc PARAMS((struct iqueue_entry *));
+extern void l_sw PARAMS((struct iqueue_entry *));
+extern void l_sb PARAMS((struct iqueue_entry *));
+extern void l_sh PARAMS((struct iqueue_entry *));
+extern void l_lwz PARAMS((struct iqueue_entry *));
+extern void l_lbs PARAMS((struct iqueue_entry *));
+extern void l_lbz PARAMS((struct iqueue_entry *));
+extern void l_lhs PARAMS((struct iqueue_entry *));
+extern void l_lhz PARAMS((struct iqueue_entry *));
+extern void l_movhi PARAMS((struct iqueue_entry *));
+extern void l_and PARAMS((struct iqueue_entry *));
+extern void l_or PARAMS((struct iqueue_entry *));
+extern void l_xor PARAMS((struct iqueue_entry *));
+extern void l_sub PARAMS((struct iqueue_entry *));
+extern void l_mul PARAMS((struct iqueue_entry *));
+extern void l_div PARAMS((struct iqueue_entry *));
+extern void l_divu PARAMS((struct iqueue_entry *));
+extern void l_sll PARAMS((struct iqueue_entry *));
+extern void l_sra PARAMS((struct iqueue_entry *));
+extern void l_srl PARAMS((struct iqueue_entry *));
+extern void l_j PARAMS((struct iqueue_entry *));
+extern void l_jal PARAMS((struct iqueue_entry *));
+extern void l_jalr PARAMS((struct iqueue_entry *));
+extern void l_jr PARAMS((struct iqueue_entry *));
+extern void l_rfe PARAMS((struct iqueue_entry *));
+extern void l_nop PARAMS((struct iqueue_entry *));
+extern void l_bnf PARAMS((struct iqueue_entry *));
+extern void l_sfeq PARAMS((struct iqueue_entry *));
+extern void l_sfgts PARAMS((struct iqueue_entry *));
+extern void l_sfges PARAMS((struct iqueue_entry *));
+extern void l_sflts PARAMS((struct iqueue_entry *));
+extern void l_sfles PARAMS((struct iqueue_entry *));
+extern void l_sfgtu PARAMS((struct iqueue_entry *));
+extern void l_sfgeu PARAMS()(struct iqueue_entry *);
+extern void l_sfltu PARAMS((struct iqueue_entry *));
+extern void l_sfleu PARAMS((struct iqueue_entry *));
+extern void l_extbs PARAMS((struct iqueue_entry *));
+extern void l_extbz PARAMS((struct iqueue_entry *));
+extern void l_exths PARAMS((struct iqueue_entry *));
+extern void l_exthz PARAMS((struct iqueue_entry *));
+extern void l_extws PARAMS((struct iqueue_entry *));
+extern void l_extwz PARAMS((struct iqueue_entry *));
+extern void l_mtspr PARAMS((struct iqueue_entry *));
+extern void l_mfspr PARAMS((struct iqueue_entry *));
+extern void l_sys PARAMS((struct iqueue_entry *));
+extern void l_trap PARAMS((struct iqueue_entry *)); /* CZ 21/06/01 */
+extern void l_macrc PARAMS((struct iqueue_entry *));
+extern void l_mac PARAMS((struct iqueue_entry *));
+extern void l_msb PARAMS((struct iqueue_entry *));
+extern void l_invalid PARAMS((struct iqueue_entry *));
+extern void l_cmov PARAMS ((struct iqueue_entry *));
+extern void l_ff1 PARAMS ((struct iqueue_entry *));
+extern void l_cust1 PARAMS ((struct iqueue_entry *));
+extern void l_cust2 PARAMS ((struct iqueue_entry *));
+extern void l_cust3 PARAMS ((struct iqueue_entry *));
+extern void l_cust4 PARAMS ((struct iqueue_entry *));
+extern void lf_add_s PARAMS ((struct iqueue_entry *));
+extern void lf_div_s PARAMS ((struct iqueue_entry *));
+extern void lf_ftoi_s PARAMS ((struct iqueue_entry *));
+extern void lf_itof_s PARAMS ((struct iqueue_entry *));
+extern void lf_madd_s PARAMS ((struct iqueue_entry *));
+extern void lf_mul_s PARAMS ((struct iqueue_entry *));
+extern void lf_rem_s PARAMS ((struct iqueue_entry *));
+extern void lf_sfeq_s PARAMS ((struct iqueue_entry *));
+extern void lf_sfge_s PARAMS ((struct iqueue_entry *));
+extern void lf_sfgt_s PARAMS ((struct iqueue_entry *));
+extern void lf_sfle_s PARAMS ((struct iqueue_entry *));
+extern void lf_sflt_s PARAMS ((struct iqueue_entry *));
+extern void lf_sfne_s PARAMS ((struct iqueue_entry *));
+extern void lf_sub_s PARAMS((struct iqueue_entry *));
+extern void l_none PARAMS((struct iqueue_entry *));
+
+#endif /* SIMPLE32_DEFS__H */
Index: or32/def-op-t.h
===================================================================
--- or32/def-op-t.h (nonexistent)
+++ or32/def-op-t.h (revision 1765)
@@ -0,0 +1,138 @@
+/* def_op_t.h -- Operation-generation strucutre definitions helpers
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define GPR_T(op_name, temp) \
+ { NULL, \
+ glue(glue(op_name, 1), temp), \
+ glue(glue(op_name, 2), temp), \
+ glue(glue(op_name, 3), temp), \
+ glue(glue(op_name, 4), temp), \
+ glue(glue(op_name, 5), temp), \
+ glue(glue(op_name, 6), temp), \
+ glue(glue(op_name, 7), temp), \
+ glue(glue(op_name, 8), temp), \
+ glue(glue(op_name, 9), temp), \
+ glue(glue(op_name, 10), temp), \
+ glue(glue(op_name, 11), temp), \
+ glue(glue(op_name, 12), temp), \
+ glue(glue(op_name, 13), temp), \
+ glue(glue(op_name, 14), temp), \
+ glue(glue(op_name, 15), temp), \
+ glue(glue(op_name, 16), temp), \
+ glue(glue(op_name, 17), temp), \
+ glue(glue(op_name, 18), temp), \
+ glue(glue(op_name, 19), temp), \
+ glue(glue(op_name, 20), temp), \
+ glue(glue(op_name, 21), temp), \
+ glue(glue(op_name, 22), temp), \
+ glue(glue(op_name, 23), temp), \
+ glue(glue(op_name, 24), temp), \
+ glue(glue(op_name, 25), temp), \
+ glue(glue(op_name, 26), temp), \
+ glue(glue(op_name, 27), temp), \
+ glue(glue(op_name, 28), temp), \
+ glue(glue(op_name, 29), temp), \
+ glue(glue(op_name, 30), temp), \
+ glue(glue(op_name, 31), temp) }
+
+#if NUM_T_REGS == 3
+
+#define OP_ROW(op_name) \
+ { glue(op_name, _t0), glue(op_name, _t1), glue(op_name, _t2) }
+
+#define OP_ROW_NEQ0(op_name) \
+ { NULL, glue(op_name, _t1), glue(op_name, _t2) }
+
+#define OP_ROW_NEQ1(op_name) \
+ { glue(op_name, _t0), NULL, glue(op_name, _t2) }
+
+#define OP_ROW_NEQ2(op_name) \
+ { glue(op_name, _t0), glue(op_name, _t1), NULL }
+
+#define OP_ROW_COL(op_name) { \
+ OP_ROW(glue(op_name, _t0)), \
+ OP_ROW(glue(op_name, _t1)), \
+ OP_ROW(glue(op_name, _t2)), }
+
+/* In 3D space: row, column, ??? */
+#define OP_ROW_COL_3D(op_name) { \
+ OP_ROW_COL(glue(op_name, _t0)), \
+ OP_ROW_COL(glue(op_name, _t1)), \
+ OP_ROW_COL(glue(op_name, _t2)) }
+
+#define OP_ROW_COL_NEQ(op_name) { \
+ OP_ROW_NEQ0(glue(op_name, _t0)), \
+ OP_ROW_NEQ1(glue(op_name, _t1)), \
+ OP_ROW_NEQ2(glue(op_name, _t2)) }
+
+#define OP_ROW_COL_NEQ0(op_name) { \
+ OP_ROW_NEQ0(glue(op_name, _t0)), \
+ OP_ROW(glue(op_name, _t1)), \
+ OP_ROW(glue(op_name, _t2)) }
+
+#define OP_ROW_COL_NEQ1(op_name) { \
+ OP_ROW(glue(op_name, _t0)), \
+ OP_ROW_NEQ1(glue(op_name, _t1)), \
+ OP_ROW(glue(op_name, _t2)) }
+
+#define OP_ROW_COL_NEQ2(op_name) { \
+ OP_ROW(glue(op_name, _t0)), \
+ OP_ROW(glue(op_name, _t1)), \
+ OP_ROW_NEQ2(glue(op_name, _t2)) }
+
+#define OP_ROW_COL_3D_NEQ(op_name) { \
+ OP_ROW_COL_NEQ0(glue(op_name, _t0)), \
+ OP_ROW_COL_NEQ1(glue(op_name, _t1)), \
+ OP_ROW_COL_NEQ2(glue(op_name, _t2)) }
+
+#define GPR_ROW_COL(op_name) { \
+ GPR_T(op_name, _t0), \
+ GPR_T(op_name, _t1), \
+ GPR_T(op_name, _t2) }
+
+#else
+#error Update def_op_t.h for NUM_T_REGS temporaries
+#endif
+
+#define DEF_1T_OP(type, name, op_name) \
+ static const type name[NUM_T_REGS] = \
+ OP_ROW(op_name)
+
+#define DEF_2T_OP(type, name, op_name) \
+ static const type name[NUM_T_REGS][NUM_T_REGS] = \
+ OP_ROW_COL(op_name)
+
+#define DEF_3T_OP(type, name, op_name) \
+ static const type name[NUM_T_REGS][NUM_T_REGS][NUM_T_REGS] = \
+ OP_ROW_COL_3D(op_name)
+
+/* Same as above but put NULL in places where T0 == T1 */
+#define DEF_2T_OP_NEQ(type, name, op_name) \
+ static const type name[NUM_T_REGS][NUM_T_REGS] = \
+ OP_ROW_COL_NEQ(op_name)
+
+/* Same as above but put NULL in places where T0 == T1 == T2 */
+#define DEF_3T_OP_NEQ(type, name, op_name) \
+ static const type name[NUM_T_REGS][NUM_T_REGS][NUM_T_REGS] = \
+ OP_ROW_COL_3D_NEQ(op_name)
+
+#define DEF_GPR_OP(type, name, op_name) \
+ static const generic_gen_op name[NUM_T_REGS][32] = \
+ GPR_ROW_COL(op_name)
+
Index: or32/insnset.c
===================================================================
--- or32/insnset.c (nonexistent)
+++ or32/insnset.c (revision 1765)
@@ -0,0 +1,614 @@
+/* insnset.c -- Instruction specific functions.
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ 2000-2002 Marko Mlinar, markom@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+INSTRUCTION (l_add) {
+ orreg_t temp1, temp2, temp3;
+ int8_t temp4;
+
+ temp2 = (orreg_t)PARAM2;
+ temp3 = (orreg_t)PARAM1;
+ temp1 = temp2 + temp3;
+ SET_PARAM0(temp1);
+ SET_OV_FLAG_FN (temp1);
+ if (ARITH_SET_FLAG) {
+ if(!temp1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+ }
+ if ((uorreg_t) temp1 < (uorreg_t) temp2)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
+
+ temp4 = temp1;
+ if (temp4 == temp1)
+ or1k_mstats.byteadd++;
+}
+INSTRUCTION (l_addc) {
+ orreg_t temp1, temp2, temp3;
+ int8_t temp4;
+
+ temp2 = (orreg_t)PARAM2;
+ temp3 = (orreg_t)PARAM1;
+ temp1 = temp2 + temp3;
+ if(cpu_state.sprs[SPR_SR] & SPR_SR_CY)
+ temp1++;
+ SET_PARAM0(temp1);
+ SET_OV_FLAG_FN (temp1);
+ if (ARITH_SET_FLAG) {
+ if(!temp1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+ }
+ if ((uorreg_t) temp1 < (uorreg_t) temp2)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
+
+ temp4 = temp1;
+ if (temp4 == temp1)
+ or1k_mstats.byteadd++;
+}
+INSTRUCTION (l_sw) {
+ int old_cyc = 0;
+ if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
+ set_mem32(PARAM0, PARAM1, &breakpoint);
+ if (config.cpu.sbuf_len) {
+ int t = runtime.sim.mem_cycles;
+ runtime.sim.mem_cycles = old_cyc;
+ sbuf_store (t - old_cyc);
+ }
+}
+INSTRUCTION (l_sb) {
+ int old_cyc = 0;
+ if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
+ set_mem8(PARAM0, PARAM1, &breakpoint);
+ if (config.cpu.sbuf_len) {
+ int t = runtime.sim.mem_cycles;
+ runtime.sim.mem_cycles = old_cyc;
+ sbuf_store (t- old_cyc);
+ }
+}
+INSTRUCTION (l_sh) {
+ int old_cyc = 0;
+ if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
+ set_mem16(PARAM0, PARAM1, &breakpoint);
+ if (config.cpu.sbuf_len) {
+ int t = runtime.sim.mem_cycles;
+ runtime.sim.mem_cycles = old_cyc;
+ sbuf_store (t - old_cyc);
+ }
+}
+INSTRUCTION (l_lwz) {
+ uint32_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem32(PARAM1, &breakpoint);
+ /* If eval operand produced exception don't set anything. JPB changed to
+ trigger on breakpoint, as well as except_pending (seemed to be a bug). */
+ if (!(except_pending || breakpoint))
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lbs) {
+ int8_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem8(PARAM1, &breakpoint);
+ /* If eval operand produced exception don't set anything. JPB changed to
+ trigger on breakpoint, as well as except_pending (seemed to be a bug). */
+ if (!(except_pending || breakpoint))
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lbz) {
+ uint8_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem8(PARAM1, &breakpoint);
+ /* If eval operand produced exception don't set anything. JPB changed to
+ trigger on breakpoint, as well as except_pending (seemed to be a bug). */
+ if (!(except_pending || breakpoint))
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lhs) {
+ int16_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem16(PARAM1, &breakpoint);
+ /* If eval operand produced exception don't set anything. JPB changed to
+ trigger on breakpoint, as well as except_pending (seemed to be a bug). */
+ if (!(except_pending || breakpoint))
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lhz) {
+ uint16_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem16(PARAM1, &breakpoint);
+ /* If eval operand produced exception don't set anything. JPB changed to
+ trigger on breakpoint, as well as except_pending (seemed to be a bug). */
+ if (!(except_pending || breakpoint))
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_movhi) {
+ SET_PARAM0(PARAM1 << 16);
+}
+INSTRUCTION (l_and) {
+ uorreg_t temp1;
+ temp1 = PARAM1 & PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ if (ARITH_SET_FLAG) {
+ if(!temp1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+ }
+}
+INSTRUCTION (l_or) {
+ uorreg_t temp1;
+ temp1 = PARAM1 | PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+}
+INSTRUCTION (l_xor) {
+ uorreg_t temp1;
+ temp1 = PARAM1 ^ PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+}
+INSTRUCTION (l_sub) {
+ orreg_t temp1;
+ temp1 = (orreg_t)PARAM1 - (orreg_t)PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+}
+/*int mcount = 0;*/
+INSTRUCTION (l_mul) {
+ orreg_t temp1;
+
+ temp1 = (orreg_t)PARAM1 * (orreg_t)PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ /*if (!(mcount++ & 1023)) {
+ PRINTF ("[%i]\n",mcount);
+ }*/
+}
+INSTRUCTION (l_div) {
+ orreg_t temp3, temp2, temp1;
+
+ temp3 = PARAM2;
+ temp2 = PARAM1;
+ if (temp3)
+ temp1 = temp2 / temp3;
+ else {
+ except_handle(EXCEPT_ILLEGAL, cpu_state.pc);
+ return;
+ }
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+}
+INSTRUCTION (l_divu) {
+ uorreg_t temp3, temp2, temp1;
+
+ temp3 = PARAM2;
+ temp2 = PARAM1;
+ if (temp3)
+ temp1 = temp2 / temp3;
+ else {
+ except_handle(EXCEPT_ILLEGAL, cpu_state.pc);
+ return;
+ }
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 16; */
+}
+INSTRUCTION (l_sll) {
+ uorreg_t temp1;
+
+ temp1 = PARAM1 << PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 2; */
+}
+INSTRUCTION (l_sra) {
+ orreg_t temp1;
+
+ temp1 = (orreg_t)PARAM1 >> PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 2; */
+}
+INSTRUCTION (l_srl) {
+ uorreg_t temp1;
+ temp1 = PARAM1 >> PARAM2;
+ SET_OV_FLAG_FN (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 2; */
+}
+INSTRUCTION (l_bf) {
+ if (config.bpb.enabled) {
+ int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
+ or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
+ bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
+ }
+ if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
+ btic_update(pcnext);
+ next_delay_insn = 1;
+ } else {
+ btic_update(cpu_state.pc);
+ }
+}
+INSTRUCTION (l_bnf) {
+ if (config.bpb.enabled) {
+ int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
+ or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
+ bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
+ }
+ if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
+ btic_update(pcnext);
+ next_delay_insn = 1;
+ } else {
+ btic_update(cpu_state.pc);
+ }
+}
+INSTRUCTION (l_j) {
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
+ next_delay_insn = 1;
+}
+INSTRUCTION (l_jal) {
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
+
+ setsim_reg(LINK_REGNO, cpu_state.pc + 8);
+ next_delay_insn = 1;
+ if (config.sim.profile) {
+ struct label_entry *tmp;
+ if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
+ fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
+ runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
+ tmp->name);
+ else
+ fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
+ runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
+ cpu_state.pc_delay);
+ }
+}
+INSTRUCTION (l_jalr) {
+ cpu_state.pc_delay = PARAM0;
+ setsim_reg(LINK_REGNO, cpu_state.pc + 8);
+ next_delay_insn = 1;
+}
+INSTRUCTION (l_jr) {
+ cpu_state.pc_delay = PARAM0;
+ next_delay_insn = 1;
+ if (config.sim.profile)
+ fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n", runtime.sim.cycles,
+ cpu_state.pc_delay);
+}
+INSTRUCTION (l_rfe) {
+ pcnext = cpu_state.sprs[SPR_EPCR_BASE];
+ mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
+}
+INSTRUCTION (l_nop) {
+ oraddr_t stackaddr;
+ uint32_t k = PARAM0;
+ switch (k) {
+ case NOP_NOP:
+ break;
+ case NOP_EXIT:
+ PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
+ fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
+ runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
+ fprintf(stderr, "@exit : cycles %lld, insn #%lld\n", runtime.sim.cycles,
+ runtime.cpu.instructions);
+ fprintf(stderr, " diff : cycles %lld, insn #%lld\n",
+ runtime.sim.cycles - runtime.sim.reset_cycles,
+ runtime.cpu.instructions - runtime.cpu.reset_instructions);
+ if (config.debug.gdb_enabled)
+ set_stall_state (1);
+ else
+ sim_done();
+ break;
+ case NOP_CNT_RESET:
+ PRINTF("****************** counters reset ******************\n");
+ PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
+ PRINTF("****************** counters reset ******************\n");
+ runtime.sim.reset_cycles = runtime.sim.cycles;
+ runtime.cpu.reset_instructions = runtime.cpu.instructions;
+ break;
+ case NOP_PRINTF:
+ stackaddr = evalsim_reg(4);
+ simprintf(stackaddr, evalsim_reg(3));
+ break;
+ case NOP_PUTC: /*JPB */
+ printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
+ fflush( stdout );
+ break;
+ case NOP_REPORT:
+ PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
+ default:
+ if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
+ PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
+ evalsim_reg(3));
+ break;
+ }
+}
+INSTRUCTION (l_sfeq) {
+ if(PARAM0 == PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfne) {
+ if(PARAM0 != PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfgts) {
+ if((orreg_t)PARAM0 > (orreg_t)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfges) {
+ if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sflts) {
+ if((orreg_t)PARAM0 < (orreg_t)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfles) {
+ if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfgtu) {
+ if(PARAM0 > PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfgeu) {
+ if(PARAM0 >= PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfltu) {
+ if(PARAM0 < PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_sfleu) {
+ if(PARAM0 <= PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (l_extbs) {
+ int8_t x;
+ x = PARAM1;
+ SET_PARAM0((orreg_t)x);
+}
+INSTRUCTION (l_extbz) {
+ uint8_t x;
+ x = PARAM1;
+ SET_PARAM0((uorreg_t)x);
+}
+INSTRUCTION (l_exths) {
+ int16_t x;
+ x = PARAM1;
+ SET_PARAM0((orreg_t)x);
+}
+INSTRUCTION (l_exthz) {
+ uint16_t x;
+ x = PARAM1;
+ SET_PARAM0((uorreg_t)x);
+}
+INSTRUCTION (l_extws) {
+ int32_t x;
+ x = PARAM1;
+ SET_PARAM0((orreg_t)x);
+}
+INSTRUCTION (l_extwz) {
+ uint32_t x;
+ x = PARAM1;
+ SET_PARAM0((uorreg_t)x);
+}
+INSTRUCTION (l_mtspr) {
+ uint16_t regno = PARAM0 + PARAM2;
+ uorreg_t value = PARAM1;
+
+ if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
+ mtspr(regno, value);
+ else {
+ PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
+ sim_done();
+ }
+}
+INSTRUCTION (l_mfspr) {
+ uint16_t regno = PARAM1 + PARAM2;
+ uorreg_t value = mfspr(regno);
+
+ if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
+ SET_PARAM0(value);
+ else {
+ SET_PARAM0(0);
+ PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
+ sim_done();
+ }
+}
+INSTRUCTION (l_sys) {
+ except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
+}
+INSTRUCTION (l_trap) {
+ /* TODO: some SR related code here! */
+ except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
+}
+INSTRUCTION (l_mac) {
+ uorreg_t lo, hi;
+ LONGEST l;
+ orreg_t x, y;
+
+ lo = cpu_state.sprs[SPR_MACLO];
+ hi = cpu_state.sprs[SPR_MACHI];
+ x = PARAM0;
+ y = PARAM1;
+ PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y);
+ l = (ULONGEST)lo | ((LONGEST)hi << 32);
+ l += (LONGEST) x * (LONGEST) y;
+
+ /* This implementation is very fast - it needs only one cycle for mac. */
+ lo = ((ULONGEST)l) & 0xFFFFFFFF;
+ hi = ((LONGEST)l) >> 32;
+ cpu_state.sprs[SPR_MACLO] = lo;
+ cpu_state.sprs[SPR_MACHI] = hi;
+ PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo);
+}
+INSTRUCTION (l_msb) {
+ uorreg_t lo, hi;
+ LONGEST l;
+ orreg_t x, y;
+
+ lo = cpu_state.sprs[SPR_MACLO];
+ hi = cpu_state.sprs[SPR_MACHI];
+ x = PARAM0;
+ y = PARAM1;
+
+ PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y);
+
+ l = (ULONGEST)lo | ((LONGEST)hi << 32);
+ l -= x * y;
+
+ /* This implementation is very fast - it needs only one cycle for msb. */
+ lo = ((ULONGEST)l) & 0xFFFFFFFF;
+ hi = ((LONGEST)l) >> 32;
+ cpu_state.sprs[SPR_MACLO] = lo;
+ cpu_state.sprs[SPR_MACHI] = hi;
+ PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo);
+}
+INSTRUCTION (l_macrc) {
+ uorreg_t lo, hi;
+ LONGEST l;
+ /* No need for synchronization here -- all MAC instructions are 1 cycle long. */
+ lo = cpu_state.sprs[SPR_MACLO];
+ hi = cpu_state.sprs[SPR_MACHI];
+ l = (ULONGEST) lo | ((LONGEST)hi << 32);
+ l >>= 28;
+ //PRINTF ("<%08x>\n", (unsigned long)l);
+ SET_PARAM0((orreg_t)l);
+ cpu_state.sprs[SPR_MACLO] = 0;
+ cpu_state.sprs[SPR_MACHI] = 0;
+}
+INSTRUCTION (l_cmov) {
+ SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
+}
+INSTRUCTION (l_ff1) {
+ SET_PARAM0(ffs(PARAM1));
+}
+/******* Floating point instructions *******/
+/* Single precision */
+INSTRUCTION (lf_add_s) {
+ SET_PARAM0((float)PARAM1 + (float)PARAM2);
+}
+INSTRUCTION (lf_div_s) {
+ SET_PARAM0((float)PARAM1 / (float)PARAM2);
+}
+INSTRUCTION (lf_ftoi_s) {
+// set_operand32(0, freg[get_operand(1)], &breakpoint);
+}
+INSTRUCTION (lf_itof_s) {
+// freg[get_operand(0)] = eval_operand32(1, &breakpoint);
+}
+INSTRUCTION (lf_madd_s) {
+ SET_PARAM0((float)PARAM0 + (float)PARAM1 * (float)PARAM2);
+}
+INSTRUCTION (lf_mul_s) {
+ SET_PARAM0((float)PARAM1 * (float)PARAM2);
+}
+INSTRUCTION (lf_rem_s) {
+ float temp = (float)PARAM1 / (float)PARAM2;
+ SET_PARAM0(temp - (uint32_t)temp);
+}
+INSTRUCTION (lf_sfeq_s) {
+ if((float)PARAM0 == (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sfge_s) {
+ if((float)PARAM0 >= (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sfgt_s) {
+ if((float)PARAM0 > (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sfle_s) {
+ if((float)PARAM0 <= (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sflt_s) {
+ if((float)PARAM0 < (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sfne_s) {
+ if((float)PARAM0 != (float)PARAM1)
+ cpu_state.sprs[SPR_SR] |= SPR_SR_F;
+ else
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
+}
+INSTRUCTION (lf_sub_s) {
+ SET_PARAM0((float)PARAM1 - (float)PARAM2);
+}
+
+/******* Custom instructions *******/
+INSTRUCTION (l_cust1) {
+ /*int destr = current->insn >> 21;
+ int src1r = current->insn >> 15;
+ int src2r = current->insn >> 9;*/
+}
+INSTRUCTION (l_cust2) {
+}
+INSTRUCTION (l_cust3) {
+}
+INSTRUCTION (l_cust4) {
+}
or32/insnset.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: or32/dyngen.c
===================================================================
--- or32/dyngen.c (nonexistent)
+++ or32/dyngen.c (revision 1765)
@@ -0,0 +1,289 @@
+/* dyngen.c -- Generates micro operation generating functions
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#include
+#include
+#include
+
+#include "dyngen.h"
+
+#define OP_FUNC_PREFIX "op_"
+#define OP_FUNC_PARAM_PREFIX "__op_param"
+/* Have to add to to make sure that the param[] is 0 */
+#define MAX_PARAMS (3 + 1)
+
+static const char *c_file_head =
+"#include \"config.h\"\n"
+"\n"
+"#include \n"
+"\n"
+"#include \"arch.h\"\n"
+"#include \"opcode/or32.h\"\n"
+"#include \"spr-defs.h\"\n"
+"#include \"i386-regs.h\"\n"
+"#include \"abstract.h\"\n"
+"\n"
+"#include \"dyn-rec.h\"\n"
+"#include \"%s\"\n"
+"\n";
+
+static const char *gen_code_proto =
+"void gen_code(struct op_queue *opq, struct dyn_page *dp);\n"
+"void patch_relocs(struct op_queue *opq, void *host_page);\n"
+"\n";
+
+static const char *c_sw_file_head =
+"#include \n"
+"#include \n"
+"\n"
+"#include \"config.h\"\n"
+"\n"
+"#include \n"
+"\n"
+"#include \"arch.h\"\n"
+"#include \"opcode/or32.h\"\n"
+"#include \"spr-defs.h\"\n"
+"#include \"i386-regs.h\"\n"
+"#include \"abstract.h\"\n"
+"#include \"dyn-rec.h\"\n"
+"#include \"%s\"\n"
+"\n"
+"void gen_code(struct op_queue *opq, struct dyn_page *dp)\n"
+"{\n"
+" unsigned int *ops, i;\n"
+" unsigned int host_len = dp->host_len;\n"
+" void *host_cur = dp->host_page;\n"
+" oraddr_t pc = dp->or_page;\n"
+" void **loc = dp->locs;\n"
+"\n"
+" while(opq) {\n"
+" if(opq->next)\n"
+" *loc++ = (void *)(host_cur - dp->host_page);"
+"\n"
+" for(i = 0, ops = opq->ops; i < opq->num_ops; i++, ops++) {\n"
+" switch(*ops) {\n"
+" case op_mark_loc_indx:\n"
+" opq->ops_param[0] = host_cur - dp->host_page;\n"
+" break;\n";
+
+static const char *c_sw_file_tail =
+" }\n"
+" }\n"
+" opq = opq->next;\n"
+" pc += 4;\n"
+" }\n"
+"\n"
+" dp->host_len = host_cur - dp->host_page;\n"
+" dp->host_page = realloc(dp->host_page, dp->host_len);\n"
+"}\n";
+
+static const char *c_rel_file_head =
+"#include /* To get printf... */\n"
+"#include \n"
+"\n"
+"#include \"config.h\"\n"
+"\n"
+"#include \n"
+"\n"
+"#include \"arch.h\"\n"
+"#include \"spr-defs.h\"\n"
+"#include \"i386-regs.h\"\n"
+"#include \"opcode/or32.h\"\n"
+"#include \"abstract.h\"\n"
+"#include \"tick.h\"\n"
+"#include \"execute.h\"\n"
+"#include \"sprs.h\"\n"
+"#include \"dyn-rec.h\"\n"
+"#include \"op-support.h\"\n"
+"#include \"%s\"\n"
+"\n"
+"void do_scheduler(void); /* FIXME: Remove */\n"
+"void do_sched_wrap(void); /* FIXME: Remove */\n"
+"void do_sched_wrap_delay(void); /* FIXME: Remove */\n"
+"void simprintf(oraddr_t stackaddr, unsigned long regparam); /* FIXME: Remove */\n"
+"\n"
+"void patch_relocs(struct op_queue *opq, void *host_page)\n"
+"{\n"
+" unsigned int *ops, *ops_param, i;\n"
+"\n"
+" while(opq) {\n"
+" for(i = 0, ops = opq->ops, ops_param = opq->ops_param; i < opq->num_ops; i++, ops++) {\n"
+" switch(*ops) {\n";
+
+static const char *c_rel_file_tail =
+" }\n"
+" }\n"
+" opq = opq->next;\n"
+" }\n"
+"}\n";
+
+static void gen_func_proto(FILE *f, const char *name, int *params)
+{
+ int i;
+
+ fprintf(f, "void gen_%s(struct op_queue *opq, int end", name);
+ for(i = 0; (i < MAX_PARAMS) && params[i]; i++) {
+ fprintf(f, ", uorreg_t param%i", i + 1);
+ }
+ fprintf(f, ")");
+}
+
+int main(int argc, char **argv)
+{
+ void *obj;
+ int i, j;
+ unsigned int len;
+ char *name;
+ int params[MAX_PARAMS];
+ struct reloc reloc;
+
+ FILE *c_file;
+ FILE *h_file;
+ FILE *c_sw_file;
+ FILE *c_rel_file;
+
+ if(argc != 6) {
+ fprintf(stderr, "Usage: %s
or32/generate.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: or32/i386-regs.h
===================================================================
--- or32/i386-regs.h (nonexistent)
+++ or32/i386-regs.h (revision 1765)
@@ -0,0 +1,26 @@
+/* i386_regs.h -- Register definitions for i386
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#define CPU_STATE_REG "ebp"
+#define T0_REG "ebx"
+#define T1_REG "esi"
+#define T2_REG "edi"
+
+#define NUM_T_REGS 3
Index: or32/op-mac-op.h
===================================================================
--- or32/op-mac-op.h (nonexistent)
+++ or32/op-mac-op.h (revision 1765)
@@ -0,0 +1,30 @@
+/* op-mac-op.h -- Micro operations template for mac operations
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+__or_dynop void glue(glue(op_, OP_NAME), T)(void)
+{
+ int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
+
+ temp OP (int64_t)T0 * (int64_t)T1;
+
+ env->sprs[SPR_MACLO] = temp & 0xffffffff;
+ env->sprs[SPR_MACHI] = temp >> 32;
+}
+
Index: or32/dyngen.h
===================================================================
--- or32/dyngen.h (nonexistent)
+++ or32/dyngen.h (revision 1765)
@@ -0,0 +1,45 @@
+/* dyngen.h -- Definitions for dyngen.c
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+
+This file is part of OpenRISC 1000 Architectural Simulator.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+struct reloc {
+ unsigned int func_offset;
+ unsigned int addend;
+ int type;
+ const char *name;
+};
+
+struct bff {
+ void *(*open_obj)(const char *object); /* Open the object file */
+ void (*close_obj)(void *);
+ char *(*get_func_name)(void *, unsigned int func); /* Gets the name of func */
+ void *(*get_func_start)(void *, unsigned int func);
+ unsigned int (*get_func_len)(void *, unsigned int func);
+ int (*get_func_reloc)(void *, unsigned int func, unsigned int relocn, struct reloc *reloc);
+};
+
+extern const struct bff bffs;
+
+struct archf {
+ unsigned int (*get_real_func_len)(void *func, unsigned int len, char *name);
+ void (*gen_reloc)(FILE *f, struct reloc *reloc, unsigned int param);
+ void (*gen_func_reloc)(FILE *f, struct reloc *reloc);
+};
+
+extern const struct archf archfs;
Index: or32
===================================================================
--- or32 (nonexistent)
+++ or32 (revision 1765)
or32
Property changes :
Added: svn:ignore
## -0,0 +1,3 ##
+Makefile
+.deps
+generate
Index: common/stats.c
===================================================================
--- common/stats.c (nonexistent)
+++ common/stats.c (revision 1765)
@@ -0,0 +1,427 @@
+/* stats.c -- Various statistics about instruction scheduling etc.
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* Package includes */
+#include "stats.h"
+#include "sim-config.h"
+#include "icache-model.h"
+#include "spr-defs.h"
+#include "execute.h"
+
+
+#define DSTATS_LEN 3000
+#define SSTATS_LEN 300
+#define FSTATS_LEN 200
+
+/* Used by safe division - increment divisor by one if it is zero */
+#define SD(X) (X != 0 ? X : 1)
+
+struct branchstat
+{
+ int taken;
+ int nottaken;
+ int forward;
+ int backward;
+};
+
+/*! @see also enum insn_type in abstract.h */
+static const char func_unit_str[30][30] = {
+ "unknown",
+ "exception",
+ "arith",
+ "shift",
+ "compare",
+ "branch",
+ "jump",
+ "load",
+ "store",
+ "movimm",
+ "move",
+ "extend",
+ "nop",
+ "mac"
+};
+
+struct dstats_entry
+{
+ int insn1;
+ int insn2;
+ int cnt_dynamic;
+ int depend;
+}; /*!< double stats */
+
+struct sstats_entry
+{
+ int insn;
+ int cnt_dynamic;
+}; /*!< single stats */
+
+struct fstats_entry
+{
+ enum insn_type insn1;
+ enum insn_type insn2;
+ int cnt_dynamic;
+ int depend;
+}; /*!< functional units stats */
+
+/* Globally visible statistics data. Renamed mstats to or1k_mstats because Mac
+ OS X has a lib function called mstats */
+struct mstats_entry or1k_mstats = { 0 }; /*!< misc units stats */
+struct cachestats_entry ic_stats = { 0 }; /*!< instruction cache stats */
+struct cachestats_entry dc_stats = { 0 }; /*!< data cache stats */
+struct immustats_entry immu_stats = { 0 }; /*!< insn MMU stats */
+struct dmmustats_entry dmmu_stats = { 0 }; /*!< data MMU stats */
+struct raw_stats raw_stats; /*!< RAW hazard stats */
+
+/* Statistics data strutures used just here */
+static struct dstats_entry dstats[DSTATS_LEN]; /*!< dependency stats */
+static struct sstats_entry sstats[SSTATS_LEN]; /*!< single stats */
+static struct fstats_entry fstats[FSTATS_LEN]; /*!< func units stats */
+
+
+void
+addsstats (int item, int cnt_dynamic)
+{
+ int i = 0;
+
+ while (sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN)
+ i++;
+
+ if (i >= SSTATS_LEN - 1)
+ return;
+
+ if (sstats[i].insn >= 0)
+ {
+ sstats[i].cnt_dynamic += cnt_dynamic;
+ }
+ else
+ {
+ sstats[i].insn = item;
+ sstats[i].cnt_dynamic = cnt_dynamic;
+ }
+}
+
+void
+adddstats (int item1, int item2, int cnt_dynamic, int depend)
+{
+ int i = 0;
+
+ while ((dstats[i].insn1 != item1 || dstats[i].insn2 != item2)
+ && (i < DSTATS_LEN) && dstats[i].insn1 >= 0)
+ i++;
+
+ if (i >= DSTATS_LEN - 1)
+ return;
+
+ if (dstats[i].insn1 >= 0)
+ {
+ dstats[i].cnt_dynamic += cnt_dynamic;
+ dstats[i].depend += depend;
+ }
+ else
+ {
+ dstats[i].insn1 = item1;
+ dstats[i].insn2 = item2;
+ dstats[i].cnt_dynamic = cnt_dynamic;
+ dstats[i].depend = depend;
+ }
+}
+
+void
+addfstats (enum insn_type item1, enum insn_type item2, int cnt_dynamic,
+ int depend)
+{
+ int i = 0;
+
+ while (((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) &&
+ (fstats[i].insn1 != it_unknown) && (i < FSTATS_LEN))
+ i++;
+
+ if (i >= FSTATS_LEN - 1)
+ return;
+
+ if ((fstats[i].insn1 == item1) && (fstats[i].insn2 == item2))
+ {
+ fstats[i].cnt_dynamic += cnt_dynamic;
+ fstats[i].depend += depend;
+ }
+ else
+ {
+ fstats[i].insn1 = item1;
+ fstats[i].insn2 = item2;
+ fstats[i].cnt_dynamic = cnt_dynamic;
+ fstats[i].depend = depend;
+ }
+}
+
+void
+initstats ()
+{
+ int i;
+ memset (sstats, 0, sizeof (sstats));
+ for (i = 0; i < SSTATS_LEN; i++)
+ sstats[i].insn = -1;
+ memset (dstats, 0, sizeof (dstats));
+ for (i = 0; i < DSTATS_LEN; i++)
+ dstats[i].insn1 = dstats[i].insn2 = -1;
+ memset (fstats, 0, sizeof (fstats));
+ memset (&or1k_mstats, 0, sizeof (or1k_mstats));
+ memset (&ic_stats, 0, sizeof (ic_stats));
+ memset (&dc_stats, 0, sizeof (dc_stats));
+ memset (&raw_stats, 0, sizeof (raw_stats));
+}
+
+static void
+printotherstats (int which)
+{
+ PRINTF ("\n");
+ if (config.bpb.enabled)
+ {
+ struct branchstat bf;
+ struct branchstat bnf;
+ long bf_all, bnf_all;
+ bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1];
+ bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1];
+ bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1];
+ bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0];
+ bf_all = bf.forward + bf.backward;
+
+ bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1];
+ bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1];
+ bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1];
+ bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0];
+ bnf_all = bnf.forward + bnf.backward;
+
+ PRINTF ("bnf: %d (%ld%%) taken,", bf.taken,
+ (bf.taken * 100) / SD (bf_all));
+ PRINTF (" %d (%ld%%) not taken,", bf.nottaken,
+ (bf.nottaken * 100) / SD (bf_all));
+ PRINTF (" %d (%ld%%) forward,", bf.forward,
+ (bf.forward * 100) / SD (bf_all));
+ PRINTF (" %d (%ld%%) backward\n", bf.backward,
+ (bf.backward * 100) / SD (bf_all));
+ PRINTF ("bf: %d (%ld%%) taken,", bnf.taken,
+ (bnf.taken * 100) / SD (bnf_all));
+ PRINTF (" %d (%ld%%) not taken,", bnf.nottaken,
+ (bnf.nottaken * 100) / SD (bnf_all));
+ PRINTF (" %d (%ld%%) forward,", bnf.forward,
+ (bnf.forward * 100) / SD (bnf_all));
+ PRINTF (" %d (%ld%%) backward\n", bnf.backward,
+ (bnf.backward * 100) / SD (bnf_all));
+
+ PRINTF ("StaticBP bnf(%s): correct %ld%%\n",
+ config.bpb.sbp_bnf_fwd ? "forward" : "backward",
+ (or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) /
+ SD (bnf_all));
+ PRINTF ("StaticBP bf(%s): correct %ld%%\n",
+ config.bpb.sbp_bf_fwd ? "forward" : "backward",
+ (or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) /
+ SD (bf_all));
+ PRINTF ("BPB: hit %d (correct %d%%), miss %d\n", or1k_mstats.bpb.hit,
+ (or1k_mstats.bpb.correct * 100) / SD (or1k_mstats.bpb.hit),
+ or1k_mstats.bpb.miss);
+ }
+ else
+ PRINTF ("BPB simulation disabled. Enable it to see BPB analysis\n");
+
+ if (config.bpb.btic)
+ {
+ PRINTF ("BTIC: hit %d(%d%%), miss %d\n", or1k_mstats.btic.hit,
+ (or1k_mstats.btic.hit * 100) / SD (or1k_mstats.btic.hit +
+ or1k_mstats.btic.miss),
+ or1k_mstats.btic.miss);
+ }
+ else
+ PRINTF ("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
+
+ if ((NULL != ic_state) && ic_state->enabled)
+ {
+ PRINTF ("IC read: hit %d(%d%%), miss %d\n", ic_stats.readhit,
+ (ic_stats.readhit * 100) / SD (ic_stats.readhit +
+ ic_stats.readmiss),
+ ic_stats.readmiss);
+ }
+ else
+ PRINTF ("No ICache. Enable it to see IC results.\n");
+
+ if (config.dc.enabled)
+ {
+ PRINTF ("DC read: hit %d(%d%%), miss %d\n", dc_stats.readhit,
+ (dc_stats.readhit * 100) / SD (dc_stats.readhit +
+ dc_stats.readmiss),
+ dc_stats.readmiss);
+ PRINTF ("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit,
+ (dc_stats.writehit * 100) / SD (dc_stats.writehit +
+ dc_stats.writemiss),
+ dc_stats.writemiss);
+ }
+ else
+ PRINTF ("No DCache. Enable it to see DC results.\n");
+
+ if (cpu_state.sprs[SPR_UPR] & SPR_UPR_IMP)
+ {
+ PRINTF ("IMMU read: hit %d(%d%%), miss %d\n", immu_stats.fetch_tlbhit,
+ (immu_stats.fetch_tlbhit * 100) / SD (immu_stats.fetch_tlbhit +
+ immu_stats.fetch_tlbmiss),
+ immu_stats.fetch_tlbmiss);
+ }
+ else
+ PRINTF ("No IMMU. Set UPR[IMP]\n");
+
+ if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP)
+ {
+ PRINTF ("DMMU read: hit %d(%d%%), miss %d\n", dmmu_stats.loads_tlbhit,
+ (dmmu_stats.loads_tlbhit * 100) / SD (dmmu_stats.loads_tlbhit +
+ dmmu_stats.loads_tlbmiss),
+ dmmu_stats.loads_tlbmiss);
+ }
+ else
+ PRINTF ("No DMMU. Set UPR[DMP]\n");
+
+ PRINTF ("Additional LOAD CYCLES: %u STORE CYCLES: %u\n",
+ runtime.sim.loadcycles, runtime.sim.storecycles);
+}
+
+void
+printstats (int which)
+{
+ int i, all = 0, dependall = 0;
+
+ if (which > 1 && which <= 5 && !config.cpu.dependstats)
+ {
+ PRINTF
+ ("Hazard analysis disabled. Enable it to see analysis results.\n");
+ return;
+ }
+
+ switch (which)
+ {
+ case 1:
+ PRINTF ("stats 1: Misc stats\n");
+ printotherstats (which);
+ break;
+ case 2:
+ PRINTF ("stats 2: Instruction usage\n");
+ for (i = 0; i < SSTATS_LEN; i++)
+ all += sstats[i].cnt_dynamic;
+
+ for (i = 0; i < SSTATS_LEN; i++)
+ if (sstats[i].cnt_dynamic)
+ PRINTF (" %-15s used %6dx (%5.1f%%)\n", insn_name (sstats[i].insn),
+ sstats[i].cnt_dynamic,
+ (sstats[i].cnt_dynamic * 100.) / SD (all));
+
+ PRINTF ("%d instructions (dynamic, single stats)\n", all);
+ break;
+
+ case 3:
+ PRINTF ("stats 3: Instruction dependencies\n");
+ for (i = 0; i < DSTATS_LEN; i++)
+ {
+ all += dstats[i].cnt_dynamic;
+ dependall += dstats[i].depend;
+ }
+
+ for (i = 0; i < DSTATS_LEN; i++)
+ if (dstats[i].cnt_dynamic)
+ {
+ char temp[100];
+ sprintf (temp, "%s, %s ", insn_name (dstats[i].insn1),
+ insn_name (dstats[i].insn2));
+ PRINTF (" %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic,
+ (dstats[i].cnt_dynamic * 100.) / SD (all));
+ PRINTF (" depend: %5.1f%%\n",
+ (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
+ }
+
+ PRINTF ("%d instructions (dynamic, dependency stats) depend: %d%%\n",
+ all, (dependall * 100) / SD (all));
+ break;
+
+ case 4:
+ PRINTF ("stats 4: Functional units dependencies\n");
+ for (i = 0; i < FSTATS_LEN; i++)
+ {
+ all += fstats[i].cnt_dynamic;
+ dependall += fstats[i].depend;
+ }
+
+ for (i = 0; i < FSTATS_LEN; i++)
+ if (fstats[i].cnt_dynamic)
+ {
+ char temp[100];
+ sprintf (temp, "%s, %s", func_unit_str[fstats[i].insn1],
+ func_unit_str[fstats[i].insn2]);
+ PRINTF (" %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic,
+ (fstats[i].cnt_dynamic * 100.) / SD (all));
+ PRINTF (" depend: %5.1f%%\n",
+ (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
+ }
+ PRINTF
+ ("%d instructions (dynamic, functional units stats) depend: %d%%\n\n",
+ all, (dependall * 100) / SD (all));
+ break;
+
+ case 5:
+ PRINTF ("stats 5: Raw register usage over time\n");
+#if RAW_RANGE_STATS
+ for (i = 0; (i < RAW_RANGE); i++)
+ PRINTF (" Register set and reused in %d. cycle: %d cases\n", i,
+ raw_stats.range[i]);
+#endif
+ break;
+ case 6:
+ if (config.cpu.sbuf_len)
+ {
+ extern int sbuf_total_cyc, sbuf_wait_cyc;
+ PRINTF ("stats 6: Store buffer analysis\n");
+ PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len);
+ PRINTF ("Number of total memory store cycles: %i/%lli\n",
+ sbuf_total_cyc,
+ runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc);
+ PRINTF ("Number of cycles waiting for memory stores: %i\n",
+ sbuf_wait_cyc);
+ PRINTF ("Number of memory cycles spared: %i\n",
+ sbuf_total_cyc - sbuf_wait_cyc);
+ PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n",
+ 100. * (sbuf_total_cyc - sbuf_wait_cyc) / sbuf_total_cyc,
+ 100. * (sbuf_total_cyc -
+ sbuf_wait_cyc) / (runtime.sim.cycles +
+ sbuf_total_cyc - sbuf_wait_cyc));
+ }
+ else
+ PRINTF
+ ("Store buffer analysis disabled. Enable it to see analysis results.\n");
+ break;
+ default:
+ PRINTF ("Please specify a stats group (1-6).\n");
+ break;
+ }
+}
Index: common/abstract.c
===================================================================
--- common/abstract.c (nonexistent)
+++ common/abstract.c (revision 1765)
@@ -0,0 +1,1251 @@
+/* abstract.c -- Abstract entities
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+/* Abstract memory and routines that go with this. I need to add all sorts of
+ other abstract entities. Currently we have only memory. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "abstract.h"
+#include "except.h"
+#include "support/profile.h"
+#include "debug-unit.h"
+#include "icache-model.h"
+#include "dcache-model.h"
+#include "labels.h"
+#include "opcode/or32.h"
+#include "dmmu.h"
+#include "immu.h"
+
+#if DYNAMIC_EXECUTION
+#include "dyn-rec.h"
+#endif
+
+
+/*! Global temporary variable to increase speed. */
+struct dev_memarea *cur_area;
+
+/* Glboal variables set by MMU if cache inhibit bit is set for current
+ access. */
+int data_ci; /*!< Global var: data cache inhibit bit set */
+int insn_ci; /*!< Global var: instr cache inhibit bit set */
+
+/* Pointer to memory area descriptions that are assigned to individual
+ peripheral devices. */
+static struct dev_memarea *dev_list;
+
+/* Pointer to memory controller device descriptor. */
+static struct dev_memarea *mc_area = NULL;
+
+/* Virtual address of current access. */
+static oraddr_t cur_vadd;
+
+/* Forward declarations */
+static uint32_t eval_mem_32_inv (oraddr_t, void *);
+static uint16_t eval_mem_16_inv (oraddr_t, void *);
+static uint8_t eval_mem_8_inv (oraddr_t, void *);
+static uint32_t eval_mem_32_inv_direct (oraddr_t, void *);
+static uint16_t eval_mem_16_inv_direct (oraddr_t, void *);
+static uint8_t eval_mem_8_inv_direct (oraddr_t, void *);
+static void set_mem_32_inv (oraddr_t, uint32_t, void *);
+static void set_mem_16_inv (oraddr_t, uint16_t, void *);
+static void set_mem_8_inv (oraddr_t, uint8_t, void *);
+static void set_mem_32_inv_direct (oraddr_t, uint32_t, void *);
+static void set_mem_16_inv_direct (oraddr_t, uint16_t, void *);
+static void set_mem_8_inv_direct (oraddr_t, uint8_t, void *);
+
+/* Calculates bit mask to fit the data */
+static unsigned int
+bit_mask (uint32_t data)
+{
+ int i = 0;
+ data--;
+ while (data >> i)
+ data |= 1 << i++;
+ return data;
+}
+
+/* Register read and write function for a memory area.
+ addr is inside the area, if addr & addr_mask == addr_compare
+ (used also by peripheral devices like 16450 UART etc.) */
+static struct dev_memarea *
+register_memoryarea_mask (oraddr_t addr_mask,
+ oraddr_t addr_compare,
+ uint32_t size, unsigned mc_dev)
+{
+ struct dev_memarea **pptmp;
+ unsigned int size_mask = bit_mask (size);
+ int found_error = 0;
+ addr_compare &= addr_mask;
+
+ /* Go to the end of the list. */
+ for (pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
+ if (((addr_compare >= (*pptmp)->addr_compare) &&
+ (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) ||
+ ((addr_compare + size > (*pptmp)->addr_compare) &&
+ (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)))
+ {
+ if (!found_error)
+ {
+ fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
+ fprintf (stderr,
+ "\taddr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR
+ ", size %08" PRIx32 "\n", addr_mask, addr_compare,
+ addr_compare | bit_mask (size), size);
+ }
+ found_error = 1;
+ fprintf (stderr,
+ "and\taddr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR
+ ", size %08" PRIx32 "\n", (*pptmp)->addr_mask,
+ (*pptmp)->addr_compare,
+ (*pptmp)->addr_compare | (*pptmp)->size_mask,
+ (*pptmp)->size);
+ }
+
+ if (found_error)
+ exit (-1);
+
+ cur_area = *pptmp =
+ (struct dev_memarea *) malloc (sizeof (struct dev_memarea));
+
+ if (mc_dev)
+ mc_area = *pptmp;
+
+ (*pptmp)->addr_mask = addr_mask;
+ (*pptmp)->addr_compare = addr_compare;
+ (*pptmp)->size = size;
+ (*pptmp)->size_mask = size_mask;
+ (*pptmp)->log = NULL;
+ (*pptmp)->valid = 1;
+ (*pptmp)->next = NULL;
+
+ return *pptmp;
+}
+
+/* Register read and write function for a memory area.
+ Memory areas should be aligned. Memory area is rounded up to
+ fit the nearest 2^n aligment.
+ (used also by peripheral devices like 16450 UART etc.)
+ If mc_dev is 1, this device will be checked first for a match
+ and will be accessed in case of overlaping memory areas.
+ Only one device can have this set to 1 (used for memory controller) */
+struct dev_memarea *
+reg_mem_area (oraddr_t addr, uint32_t size, unsigned mc_dev,
+ struct mem_ops *ops)
+{
+ unsigned int size_mask = bit_mask (size);
+ unsigned int addr_mask = ~size_mask;
+ struct dev_memarea *mem;
+
+ mem = register_memoryarea_mask (addr_mask, addr & addr_mask, size_mask + 1,
+ mc_dev);
+
+ memcpy (&mem->ops, ops, sizeof (struct mem_ops));
+ memcpy (&mem->direct_ops, ops, sizeof (struct mem_ops));
+
+ if (!ops->readfunc32)
+ {
+ mem->ops.readfunc32 = eval_mem_32_inv;
+ mem->direct_ops.readfunc32 = eval_mem_32_inv_direct;
+ mem->direct_ops.read_dat32 = mem;
+ }
+ if (!ops->readfunc16)
+ {
+ mem->ops.readfunc16 = eval_mem_16_inv;
+ mem->direct_ops.readfunc16 = eval_mem_16_inv_direct;
+ mem->direct_ops.read_dat16 = mem;
+ }
+ if (!ops->readfunc8)
+ {
+ mem->ops.readfunc8 = eval_mem_8_inv;
+ mem->direct_ops.readfunc8 = eval_mem_8_inv_direct;
+ mem->direct_ops.read_dat8 = mem;
+ }
+
+ if (!ops->writefunc32)
+ {
+ mem->ops.writefunc32 = set_mem_32_inv;
+ mem->direct_ops.writefunc32 = set_mem_32_inv_direct;
+ mem->direct_ops.write_dat32 = mem;
+ }
+ if (!ops->writefunc16)
+ {
+ mem->ops.writefunc16 = set_mem_16_inv;
+ mem->direct_ops.writefunc16 = set_mem_16_inv_direct;
+ mem->direct_ops.write_dat16 = mem;
+ }
+ if (!ops->writefunc8)
+ {
+ mem->ops.writefunc8 = set_mem_8_inv;
+ mem->direct_ops.writefunc8 = set_mem_8_inv_direct;
+ mem->direct_ops.write_dat8 = mem;
+ }
+
+ if (!ops->writeprog8)
+ {
+ mem->ops.writeprog8 = mem->ops.writefunc8;
+ mem->ops.writeprog8_dat = mem->ops.write_dat8;
+ }
+
+ if (!ops->writeprog32)
+ {
+ mem->ops.writeprog32 = mem->ops.writefunc32;
+ mem->ops.writeprog32_dat = mem->ops.write_dat32;
+ }
+
+ if (ops->log)
+ {
+ if (!(mem->log = fopen (ops->log, "w")))
+ PRINTF ("ERR: Unable to open %s to log memory acesses to\n",
+ ops->log);
+ }
+
+ return mem;
+}
+
+/* Check if access is to registered area of memory. */
+struct dev_memarea *
+verify_memoryarea (oraddr_t addr)
+{
+ struct dev_memarea *ptmp;
+
+ /* Check memory controller space first */
+ if (mc_area
+ && (addr & mc_area->addr_mask) ==
+ (mc_area->addr_compare & mc_area->addr_mask))
+ return cur_area = mc_area;
+
+ /* Check cached value */
+ if (cur_area
+ && (addr & cur_area->addr_mask) ==
+ (cur_area->addr_compare & cur_area->addr_mask))
+ return cur_area;
+
+ /* When mc is enabled, we must check valid also, otherwise we assume it is
+ nonzero */
+ /* Check list of registered devices. */
+ for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
+ if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask)
+ && ptmp->valid)
+ return cur_area = ptmp;
+ return cur_area = NULL;
+}
+
+/* Sets the valid bit (Used only by memory controllers) */
+void
+set_mem_valid (struct dev_memarea *mem, int valid)
+{
+ mem->valid = valid;
+}
+
+/* Adjusts the read and write delays for the memory area pointed to by mem. */
+void
+adjust_rw_delay (struct dev_memarea *mem, int delayr, int delayw)
+{
+ mem->ops.delayr = delayr;
+ mem->ops.delayw = delayw;
+}
+
+static uint8_t
+eval_mem_8_inv (oraddr_t memaddr, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+ return 0;
+}
+
+static uint16_t
+eval_mem_16_inv (oraddr_t memaddr, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+ return 0;
+}
+
+static uint32_t
+eval_mem_32_inv (oraddr_t memaddr, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+ return 0;
+}
+
+static void
+set_mem_8_inv (oraddr_t memaddr, uint8_t val, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+}
+
+static void
+set_mem_16_inv (oraddr_t memaddr, uint16_t val, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+}
+
+static void
+set_mem_32_inv (oraddr_t memaddr, uint32_t val, void *dat)
+{
+ except_handle (EXCEPT_BUSERR, cur_vadd);
+}
+
+uint8_t
+eval_mem_8_inv_direct (oraddr_t memaddr, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 8-bit direct read from memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+ return 0;
+}
+
+uint16_t
+eval_mem_16_inv_direct (oraddr_t memaddr, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 16-bit direct read from memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+ return 0;
+}
+
+uint32_t
+eval_mem_32_inv_direct (oraddr_t memaddr, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 32-bit direct read from memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+ return 0;
+}
+
+void
+set_mem_8_inv_direct (oraddr_t memaddr, uint8_t val, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+}
+
+void
+set_mem_16_inv_direct (oraddr_t memaddr, uint16_t val, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 16-bit direct write to memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+}
+
+void
+set_mem_32_inv_direct (oraddr_t memaddr, uint32_t val, void *dat)
+{
+ struct dev_memarea *mem = dat;
+
+ PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n",
+ mem->addr_compare | memaddr);
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from eval_mem32 below and
+ * {i,d}c_simulate_read. _Don't_ call it from anywere else.
+ */
+uint32_t
+evalsim_mem32 (oraddr_t memaddr, oraddr_t vaddr)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ runtime.sim.mem_cycles += mem->ops.delayr;
+ return mem->ops.readfunc32 (memaddr & mem->size_mask,
+ mem->ops.read_dat32);
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: read out of memory (32-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+
+ return 0;
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from eval_mem16 below and
+ * {i,d}c_simulate_read. _Don't_ call it from anywere else.
+ */
+uint16_t
+evalsim_mem16 (oraddr_t memaddr, oraddr_t vaddr)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ runtime.sim.mem_cycles += mem->ops.delayr;
+ return mem->ops.readfunc16 (memaddr & mem->size_mask,
+ mem->ops.read_dat16);
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: read out of memory (16-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+
+ return 0;
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from eval_mem8 below and
+ * {i,d}c_simulate_read. _Don't_ call it from anywere else.
+ */
+uint8_t
+evalsim_mem8 (oraddr_t memaddr, oraddr_t vaddr)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ runtime.sim.mem_cycles += mem->ops.delayr;
+ return mem->ops.readfunc8 (memaddr & mem->size_mask,
+ mem->ops.read_dat8);
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: read out of memory (8-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+
+ return 0;
+}
+
+/* Returns 32-bit values from mem array. Big endian version.
+ *
+ * STATISTICS OK (only used for cpu_access, that is architectural access)
+ */
+uint32_t
+eval_mem32 (oraddr_t memaddr, int *breakpoint)
+{
+ uint32_t temp;
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_32 | MPROF_READ);
+
+ if (memaddr & 3)
+ {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return 0;
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */
+
+ phys_memaddr = dmmu_translate (memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = dc_simulate_read (phys_memaddr, memaddr, 4);
+ else
+ temp = evalsim_mem32 (phys_memaddr, memaddr);
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */
+
+ return temp;
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do
+ *
+ * STATISTICS OK
+ */
+uint32_t
+eval_direct32 (oraddr_t memaddr, int through_mmu, int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ if (memaddr & 3)
+ {
+ PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
+ __FUNCTION__);
+ return 0;
+ }
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
+
+ if (through_dc)
+ return dc_simulate_read (phys_memaddr, memaddr, 4);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ return mem->direct_ops.readfunc32 (phys_memaddr & mem->size_mask,
+ mem->direct_ops.read_dat32);
+ else
+ PRINTF ("ERR: 32-bit read out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr);
+ }
+
+ return 0;
+}
+
+
+/* Returns 32-bit values from mem array. Big endian version.
+ *
+ * STATISTICS OK (only used for cpu_access, that is architectural access)
+ */
+uint32_t
+eval_insn (oraddr_t memaddr, int *breakpoint)
+{
+ uint32_t temp;
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_32 | MPROF_FETCH);
+
+ phys_memaddr = memaddr;
+#if !(DYNAMIC_EXECUTION)
+ phys_memaddr = immu_translate (memaddr);
+
+ if (except_pending)
+ return 0;
+#endif
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugInstructionFetch, memaddr);
+
+ if ((NULL != ic_state) && ic_state->enabled)
+ temp = ic_simulate_fetch (phys_memaddr, memaddr);
+ else
+ temp = evalsim_mem32 (phys_memaddr, memaddr);
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadData, temp);
+ return temp;
+}
+
+/* Returns 16-bit values from mem array. Big endian version.
+ *
+ * STATISTICS OK (only used for cpu_access, that is architectural access)
+ */
+uint16_t
+eval_mem16 (oraddr_t memaddr, int *breakpoint)
+{
+ uint16_t temp;
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_16 | MPROF_READ);
+
+ if (memaddr & 1)
+ {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return 0;
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */
+
+ phys_memaddr = dmmu_translate (memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = dc_simulate_read (phys_memaddr, memaddr, 2);
+ else
+ temp = evalsim_mem16 (phys_memaddr, memaddr);
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */
+
+ return temp;
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do
+ *
+ * STATISTICS OK.
+ */
+uint16_t
+eval_direct16 (oraddr_t memaddr, int through_mmu, int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ if (memaddr & 1)
+ {
+ PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
+ __FUNCTION__);
+ return 0;
+ }
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
+
+ if (through_dc)
+ return dc_simulate_read (phys_memaddr, memaddr, 2);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ return mem->direct_ops.readfunc16 (phys_memaddr & mem->size_mask,
+ mem->direct_ops.read_dat16);
+ else
+ PRINTF ("ERR: 16-bit read out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
+ }
+
+ return 0;
+}
+
+/* Returns 8-bit values from mem array.
+ *
+ * STATISTICS OK (only used for cpu_access, that is architectural access)
+ */
+uint8_t
+eval_mem8 (oraddr_t memaddr, int *breakpoint)
+{
+ uint8_t temp;
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_8 | MPROF_READ);
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); /* 28/05/01 CZ */
+
+ phys_memaddr = dmmu_translate (memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = dc_simulate_read (phys_memaddr, memaddr, 1);
+ else
+ temp = evalsim_mem8 (phys_memaddr, memaddr);
+
+ if (config.debug.enabled)
+ *breakpoint += check_debug_unit (DebugLoadData, temp); /* MM170901 */
+ return temp;
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do
+ *
+ * STATISTICS OK.
+ */
+uint8_t
+eval_direct8 (oraddr_t memaddr, int through_mmu, int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
+
+ if (through_dc)
+ return dc_simulate_read (phys_memaddr, memaddr, 1);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ return mem->direct_ops.readfunc8 (phys_memaddr & mem->size_mask,
+ mem->direct_ops.read_dat8);
+ else
+ PRINTF ("ERR: 8-bit read out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
+ }
+
+ return 0;
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from set_mem32 below and
+ * dc_simulate_write. _Don't_ call it from anywere else.
+ */
+void
+setsim_mem32 (oraddr_t memaddr, oraddr_t vaddr, uint32_t value)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ cur_vadd = vaddr;
+ runtime.sim.mem_cycles += mem->ops.delayw;
+ mem->ops.writefunc32 (memaddr & mem->size_mask, value,
+ mem->ops.write_dat32);
+#if DYNAMIC_EXECUTION
+ dyn_checkwrite (memaddr);
+#endif
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: write out of memory (32-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from set_mem16 below and
+ * dc_simulate_write. _Don't_ call it from anywere else.
+ */
+void
+setsim_mem16 (oraddr_t memaddr, oraddr_t vaddr, uint16_t value)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ cur_vadd = vaddr;
+ runtime.sim.mem_cycles += mem->ops.delayw;
+ mem->ops.writefunc16 (memaddr & mem->size_mask, value,
+ mem->ops.write_dat16);
+#if DYNAMIC_EXECUTION
+ dyn_checkwrite (memaddr);
+#endif
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: write out of memory (16-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+}
+
+/* For cpu accesses
+ *
+ * NOTE: This function _is_ only called from set_mem8 below and
+ * dc_simulate_write. _Don't_ call it from anywere else.
+ */
+void
+setsim_mem8 (oraddr_t memaddr, oraddr_t vaddr, uint8_t value)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ cur_vadd = vaddr;
+ runtime.sim.mem_cycles += mem->ops.delayw;
+ mem->ops.writefunc8 (memaddr & mem->size_mask, value,
+ mem->ops.write_dat8);
+#if DYNAMIC_EXECUTION
+ dyn_checkwrite (memaddr);
+#endif
+ }
+ else
+ {
+ PRINTF ("EXCEPTION: write out of memory (8-bit access to %" PRIxADDR
+ ")\n", memaddr);
+ except_handle (EXCEPT_BUSERR, vaddr);
+ }
+}
+
+/* Set mem, 32-bit. Big endian version.
+ *
+ * STATISTICS OK. (the only suspicious usage is in sim-cmd.c,
+ * where this instruction is used for patching memory,
+ * wether this is cpu or architectual access is yet to
+ * be decided)
+ */
+void
+set_mem32 (oraddr_t memaddr, uint32_t value, int *breakpoint)
+{
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_32 | MPROF_WRITE);
+
+ if (memaddr & 3)
+ {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return;
+ }
+
+ phys_memaddr = dmmu_translate (memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending)
+ return;
+
+ if (config.debug.enabled)
+ {
+ *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */
+ *breakpoint += check_debug_unit (DebugStoreData, value);
+ }
+
+ if (config.dc.enabled)
+ dc_simulate_write (phys_memaddr, memaddr, value, 4);
+ else
+ setsim_mem32 (phys_memaddr, memaddr, value);
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> write %08" PRIx32 "\n",
+ memaddr, value);
+}
+
+/*
+ * STATISTICS NOT OK.
+ */
+void
+set_direct32 (oraddr_t memaddr, uint32_t value, int through_mmu,
+ int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ if (memaddr & 3)
+ {
+ PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
+ __FUNCTION__);
+ return;
+ }
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ phys_memaddr = peek_into_dtlb (memaddr, 1, through_dc);
+ }
+
+ if (through_dc)
+ dc_simulate_write (memaddr, memaddr, value, 4);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ mem->direct_ops.writefunc32 (phys_memaddr & mem->size_mask, value,
+ mem->direct_ops.write_dat32);
+ else
+ PRINTF ("ERR: 32-bit write out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr);
+ }
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %08" PRIx32 "\n",
+ memaddr, value);
+}
+
+
+/* Set mem, 16-bit. Big endian version. */
+
+void
+set_mem16 (oraddr_t memaddr, uint16_t value, int *breakpoint)
+{
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_16 | MPROF_WRITE);
+
+ if (memaddr & 1)
+ {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return;
+ }
+
+ phys_memaddr = dmmu_translate (memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending)
+ return;
+
+ if (config.debug.enabled)
+ {
+ *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */
+ *breakpoint += check_debug_unit (DebugStoreData, value);
+ }
+
+ if (config.dc.enabled)
+ dc_simulate_write (phys_memaddr, memaddr, value, 2);
+ else
+ setsim_mem16 (phys_memaddr, memaddr, value);
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> write %04" PRIx16 "\n",
+ memaddr, value);
+}
+
+/*
+ * STATISTICS NOT OK.
+ */
+void
+set_direct16 (oraddr_t memaddr, uint16_t value, int through_mmu,
+ int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ if (memaddr & 1)
+ {
+ PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
+ __FUNCTION__);
+ return;
+ }
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
+ }
+
+ if (through_dc)
+ dc_simulate_write (memaddr, memaddr, value, 2);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ mem->direct_ops.writefunc16 (phys_memaddr & mem->size_mask, value,
+ mem->direct_ops.write_dat16);
+ else
+ PRINTF ("ERR: 16-bit write out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
+ }
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %04" PRIx16 "\n",
+ memaddr, value);
+}
+
+/* Set mem, 8-bit. */
+void
+set_mem8 (oraddr_t memaddr, uint8_t value, int *breakpoint)
+{
+ oraddr_t phys_memaddr;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_8 | MPROF_WRITE);
+
+ phys_memaddr = memaddr;
+
+ phys_memaddr = dmmu_translate (memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending)
+ return;
+
+ if (config.debug.enabled)
+ {
+ *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */
+ *breakpoint += check_debug_unit (DebugStoreData, value);
+ }
+
+ if (config.dc.enabled)
+ dc_simulate_write (phys_memaddr, memaddr, value, 1);
+ else
+ setsim_mem8 (phys_memaddr, memaddr, value);
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> write %02" PRIx8 "\n",
+ memaddr, value);
+}
+
+/*
+ * STATISTICS NOT OK.
+ */
+void
+set_direct8 (oraddr_t memaddr, uint8_t value, int through_mmu, int through_dc)
+{
+ oraddr_t phys_memaddr;
+ struct dev_memarea *mem;
+
+ phys_memaddr = memaddr;
+
+ if (through_mmu)
+ {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
+ }
+
+ if (through_dc)
+ dc_simulate_write (phys_memaddr, memaddr, value, 1);
+ else
+ {
+ if ((mem = verify_memoryarea (phys_memaddr)))
+ mem->direct_ops.writefunc8 (phys_memaddr & mem->size_mask, value,
+ mem->direct_ops.write_dat8);
+ else
+ PRINTF ("ERR: 8-bit write out of memory area: %" PRIxADDR
+ " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
+ }
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %02" PRIx8 "\n",
+ memaddr, value);
+}
+
+
+/* set_program32 - same as set_direct32, but it also writes to memory that is
+ * non-writeable to the rest of the sim. Used to do program
+ * loading.
+ */
+void
+set_program32 (oraddr_t memaddr, uint32_t value)
+{
+ struct dev_memarea *mem;
+
+ if (memaddr & 3)
+ {
+ PRINTF ("%s(): ERR unaligned 32-bit program write\n", __FUNCTION__);
+ return;
+ }
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ mem->ops.writeprog32 (memaddr & mem->size_mask, value,
+ mem->ops.writeprog32_dat);
+ }
+ else
+ PRINTF ("ERR: 32-bit program load out of memory area: %" PRIxADDR "\n",
+ memaddr);
+}
+
+/* set_program8 - same as set_direct8, but it also writes to memory that is
+ * non-writeable to the rest of the sim. Used to do program
+ * loading.
+ */
+void
+set_program8 (oraddr_t memaddr, uint8_t value)
+{
+ struct dev_memarea *mem;
+
+ if ((mem = verify_memoryarea (memaddr)))
+ {
+ mem->ops.writeprog8 (memaddr & mem->size_mask, value,
+ mem->ops.writeprog8_dat);
+ }
+ else
+ PRINTF ("ERR: 8-bit program load out of memory area: %" PRIxADDR "\n",
+ memaddr);
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*!Dump memory to the current output
+
+ Output format is hex bytes, 16 bytes per line. Start each line with its
+ address and (optionally) its symbolic name. Always end with a newline.
+
+ There are all sorts of ways to trip this up, but they are unlikely. The
+ validity of a memory area is taken from the address of the start of a line
+ to be printed, so assumes the following 15 bytes are present. This could be
+ fooled by ridiculous memory declarations.
+
+ @param[in] from Start address of the area of memory
+ @param[in] to End address of the area of memory */
+/*---------------------------------------------------------------------------*/
+void
+dump_memory (oraddr_t from, oraddr_t to)
+{
+ const int ROW_LEN = 16;
+ oraddr_t i; /* Row counter */
+
+ for (i = from; i < to; i += ROW_LEN)
+ {
+ struct label_entry *entry = get_label (i);
+ oraddr_t j; /* Index in row */
+
+ PRINTF ("%" PRIxADDR, i);
+
+ if (NULL != entry)
+ {
+ int padding = 11 - strlen (entry->name);
+
+ PRINTF (" <%s>: ", entry->name);
+ PRINTF ("%*s ", padding < 0 ? 0 : padding, " ");
+ }
+ else
+ {
+ PRINTF (": ");
+ }
+
+
+ for (j = 0; j < ROW_LEN; j++)
+ {
+ if (verify_memoryarea (i + j))
+ {
+ PRINTF ("%02" PRIx8 " ", eval_direct8 (i + j, 0, 0));
+ }
+ else
+ {
+ /* Not a valid memory area. Print Xs as required */
+ PRINTF ("XX ");
+ }
+ }
+
+ PRINTF ("\n");
+ }
+} /* dump_memory() */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Disassemble memory to the current output
+
+ Output format is symbolic disassembly, one instruction per line. Start each
+ line with its address and (optionally) its symbolic name.
+
+ There are all sorts of ways to trip this up, but they are unlikely. The
+ validity of a memory area is taken from the address of the start of a line
+ to be printed, so assumes the following 3 bytes are present. This could be
+ fooled by ridiculous memory declarations.
+
+ @param[in] from Start address of the area of memory
+ @param[in] to End address of the area of memory
+ @param[in] nl If non-zero (true) print a newline at the end of each
+ line */
+/*---------------------------------------------------------------------------*/
+void
+disassemble_memory (oraddr_t from, oraddr_t to, int nl)
+{
+ const int INSTR_LEN = 4;
+ oraddr_t i; /* Row counter */
+
+ for (i = from; i < to; i += INSTR_LEN)
+ {
+ struct label_entry *entry = get_label (i);
+
+ PRINTF ("%" PRIxADDR, i);
+
+ if (NULL != entry)
+ {
+ int padding = 11 - strlen (entry->name);
+
+ PRINTF (" <%s>: ", entry->name);
+ PRINTF ("%*s ", padding < 0 ? 0 : padding, " ");
+ }
+ else
+ {
+ PRINTF (": ");
+ }
+
+ if (verify_memoryarea (i))
+ {
+ uint32_t insn = eval_direct32 (i, 0, 0);
+ int index = insn_decode (insn);
+
+ PRINTF ("%08" PRIx32 " ", insn);
+
+ if (index >= 0)
+ {
+ disassemble_insn (insn);
+ PRINTF (" %s", disassembled);
+ }
+ else
+ {
+ PRINTF ("");
+ }
+
+ }
+ else
+ {
+ /* Not a valid memory area. Print Xs as required */
+ PRINTF ("XXXXXXXX");
+ }
+
+ if (nl)
+ {
+ PRINTF ("\n");
+ }
+ }
+} /* disassemble_memory() */
+
+
+/* Closes files, etc. */
+
+void
+done_memory_table ()
+{
+ struct dev_memarea *ptmp;
+
+ /* Check list of registered devices. */
+ for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
+ {
+ if (ptmp->log)
+ fclose (ptmp->log);
+ }
+}
+
+/* Displays current memory configuration */
+
+void
+memory_table_status (void)
+{
+ struct dev_memarea *ptmp;
+
+ /* Check list of registered devices. */
+ for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
+ {
+ PRINTF ("addr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR ", size %"
+ PRIx32 "\n", ptmp->addr_mask, ptmp->addr_compare,
+ ptmp->addr_compare | bit_mask (ptmp->size), ptmp->size);
+ PRINTF ("\t");
+ if (ptmp->ops.delayr >= 0)
+ PRINTF ("read delay = %i cycles, ", ptmp->ops.delayr);
+ else
+ PRINTF ("reads not possible, ");
+
+ if (ptmp->ops.delayw >= 0)
+ PRINTF ("write delay = %i cycles", ptmp->ops.delayw);
+ else
+ PRINTF ("writes not possible");
+
+ if (ptmp->log)
+ PRINTF (", (logged)\n");
+ else
+ PRINTF ("\n");
+ }
+}
+
+/* Outputs time in pretty form to dest string */
+
+char *
+generate_time_pretty (char *dest, long time_ps)
+{
+ int exp3 = 0;
+ if (time_ps)
+ {
+ while ((time_ps % 1000) == 0)
+ {
+ time_ps /= 1000;
+ exp3++;
+ }
+ }
+ sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
+ return dest;
+}
Index: common/stats.h
===================================================================
--- common/stats.h (nonexistent)
+++ common/stats.h (revision 1765)
@@ -0,0 +1,105 @@
+/* stats.h -- Header file for stats.c
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef STATS__H
+#define STATS__H
+
+/* Package includes */
+#include "opcode/or32.h"
+
+#define RAW_RANGE 1000
+
+struct bpbstat
+{
+ int hit;
+ int miss;
+ int correct;
+ int incorrect;
+};
+
+struct bticstat
+{
+ int hit;
+ int miss;
+};
+
+struct mstats_entry
+{
+ int byteadd;
+ int bf[2][2]; /* [taken][fwd/bwd] */
+ int bnf[2][2]; /* [taken][fwd/bwd] */
+ struct bpbstat bpb;
+ struct bticstat btic;
+}; /*!< misc units stats */
+
+struct cachestats_entry
+{
+ int readhit;
+ int readmiss;
+ int writehit;
+ int writemiss;
+}; /*!< cache stats */
+
+struct immustats_entry
+{
+ int fetch_tlbhit;
+ int fetch_tlbmiss;
+ int fetch_pagefaults;
+}; /*!< IMMU stats */
+
+struct dmmustats_entry
+{
+ int loads_tlbhit;
+ int loads_tlbmiss;
+ int loads_pagefaults;
+ int stores_tlbhit;
+ int stores_tlbmiss;
+ int stores_pagefaults;
+}; /*!< DMMU stats */
+
+struct raw_stats
+{
+ int reg[64];
+ int range[RAW_RANGE];
+}; /*!< RAW hazard stats */
+
+/* Globally visible data structures */
+extern struct mstats_entry or1k_mstats;
+extern struct cachestats_entry ic_stats;
+extern struct cachestats_entry dc_stats;
+extern struct immustats_entry immu_stats;
+extern struct dmmustats_entry dmmu_stats;
+extern struct raw_stats raw_stats;
+
+/* Function prototypes for external use */
+extern void addsstats (int item, int cnt_dynamic);
+extern void adddstats (int item1, int item2, int cnt_dynamic, int depend);
+extern void addfstats (enum insn_type item1, enum insn_type item2,
+ int cnt_dynamic, int depend);
+extern void initstats ();
+extern void printstats ();
+
+#endif /* STATS__H */
Index: common/execute.h
===================================================================
--- common/execute.h (nonexistent)
+++ common/execute.h (revision 1765)
@@ -0,0 +1,117 @@
+/* execute.h -- Header file for architecture dependent execute.c
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef EXECUTE__H
+#define EXECUTE__H
+
+#include "spr-defs.h"
+#include "opcode/or32.h"
+#include "abstract.h"
+
+#if DYNAMIC_EXECUTION
+#include "setjmp.h"
+#include "dyn-rec.h"
+#endif
+
+
+#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0)
+
+/*! Sets a new SPR_SR_OV value, based on next register value */
+#if SET_OV_FLAG
+#define SET_OV_FLAG_FN(value) \
+ if((value) & 0x80000000) \
+ cpu_state.sprs[SPR_SR] |= SPR_SR_OV; \
+ else \
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV
+#else
+#define SET_OV_FLAG_FN(value)
+#endif
+
+/*!The main structure holding the current execution state of the CPU
+
+ Not to be confused with @c runtime, which holds the state of the
+ simulation.
+
+ @c insn_ea field is only used to get dump_exe_log() correct.
+
+ @c iqueue and @c icomplet fields are only used in analysis().
+
+ The micro-operation queue, @c opqs, is only used to speed up
+ recompile_page(). */
+struct cpu_state {
+ uorreg_t reg[MAX_GPRS]; /*!< General purpose registers */
+ uorreg_t sprs[MAX_SPRS]; /*!< Special purpose registers */
+ oraddr_t insn_ea; /*!< EA of instrs that have an EA */
+ int delay_insn; /*!< Is current instr in delay slot */
+ oraddr_t pc; /*!< PC (and translated PC) */
+ oraddr_t pc_delay; /*!< Delay instr EA register */
+ uint32_t pic_lines; /*!< State of PIC lines */
+ struct iqueue_entry iqueue; /*!< Decode of just executed instr */
+ struct iqueue_entry icomplet; /*!< Decode of instr before this */
+
+#if DYNAMIC_EXECUTION
+ jmp_buf excpt_loc; /*!< Longjump here for exception */
+ struct dyn_page *curr_page; /*!< Current page in execution */
+ struct dyn_page **dyn_pages; /*!< Pointers to recompiled pages */
+ int32_t cycles_dec;
+ struct op_queue *opqs; /*!< Micro-operation queue */
+#endif
+};
+
+/*! History of execution */
+struct hist_exec
+{
+ oraddr_t addr;
+ struct hist_exec *prev;
+ struct hist_exec *next;
+};
+
+/* Globally visible data structures */
+extern struct cpu_state cpu_state;
+extern oraddr_t pcnext;
+extern int sbuf_wait_cyc;
+extern int sbuf_total_cyc;
+extern int do_stats;
+extern struct hist_exec *hist_exec_tail;
+
+
+/* Prototypes for external use */
+extern void dumpreg ();
+extern void dump_exe_log ();
+extern int cpu_clock ();
+extern void cpu_reset ();
+extern uorreg_t evalsim_reg (unsigned int regno);
+extern void setsim_reg (unsigned int regno,
+ uorreg_t value);
+extern uorreg_t eval_operand_val (uint32_t insn,
+ struct insn_op_struct *opd);
+extern void analysis (struct iqueue_entry *current);
+extern void cpu_reset ();
+extern int cpu_clock ();
+extern void exec_main ();
+extern int depend_operands (struct iqueue_entry *prev,
+ struct iqueue_entry *next);
+#endif /* EXECUTE__H */
Index: common/parse.c
===================================================================
--- common/parse.c (nonexistent)
+++ common/parse.c (revision 1765)
@@ -0,0 +1,883 @@
+/* parse.c -- Architecture independent load
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "parse.h"
+#include "sim-config.h"
+#include "debug.h"
+#include "abstract.h"
+#include "opcode/or32.h"
+#include "coff.h"
+#include "elf.h"
+#include "labels.h"
+
+
+DECLARE_DEBUG_CHANNEL (coff)
+
+#define MEMORY_LEN 0x100000000ULL
+
+/*!Whether to do immediate statistics. This seems to be for local debugging
+ of parse.c */
+#define IMM_STATS 0
+
+/*!Unused mem memory marker. It is used when allocating program and data
+ memory during parsing */
+static unsigned int freemem;
+
+/*!Translation table provided by microkernel. Only used if simulating
+ microkernel. */
+static oraddr_t transl_table;
+
+/*!Used to signal whether during loading of programs a translation fault
+ occured. */
+static uint32_t transl_error;
+
+#if IMM_STATS
+static int bcnt[33][3] = { 0 };
+static int bsum[3] = { 0 };
+static uint32_t movhi = 0;
+#endif /* IMM_STATS */
+
+/*---------------------------------------------------------------------------*/
+/*!Copy a string with null termination
+
+ This function is very similar to strncpy, except it null terminates the
+ string. A global function also used by the CUC.
+
+ @param[in] dst The destination string
+ @param[in] src The source string
+ @param[in] n Number of chars to copy EXCLUDING the null terminator
+ (i.e. dst had better have room for n+1 chars)
+
+ @return A pointer to dst */
+/*---------------------------------------------------------------------------*/
+char *
+strstrip (char *dst,
+ const char *src,
+ int n)
+{
+ strncpy (dst, src, n);
+ *(dst + n) = '\0';
+
+ return dst;
+
+} /* strstrip () */
+
+/*---------------------------------------------------------------------------*/
+/*!Translate logical to physical addresses for the loader
+
+ Used only by the simulator loader to translate logical addresses into
+ physical. If loadcode() is called with valid @c virtphy_transl pointer to
+ a table of translations then translate() performs translation otherwise
+ physical address is equal to logical.
+
+ @param[in] laddr Logical address
+ @param[in] breakpoint Unused
+
+ @return The physical address */
+/*---------------------------------------------------------------------------*/
+static oraddr_t
+translate (oraddr_t laddr,
+ int *breakpoint)
+{
+ int i;
+
+ /* No translation (i.e. when loading kernel into simulator) */
+ if (transl_table == 0)
+ {
+ return laddr;
+ }
+
+ /* Try to find our translation in the table. */
+ for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
+ {
+ if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0))
+ {
+ /* Page modified */
+ set_direct32 (transl_table + i + 8, -2, 0, 0);
+ PRINTF ("found paddr=%" PRIx32 "\n",
+ eval_direct32 (transl_table + i + 4, 0, 0) |
+ (laddr & (PAGE_SIZE - 1)));
+ return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
+ (laddr & (oraddr_t) (PAGE_SIZE - 1));
+ }
+ }
+
+ /* Allocate new phy page for us. */
+ for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
+ {
+ if (eval_direct32 (transl_table + i + 8, 0, 0) == 0)
+ {
+ /* VPN */
+ set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0);
+ /* PPN */
+ set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0);
+ /* Page modified */
+ set_direct32 (transl_table + i + 8, -2, 0, 0);
+ PRINTF ("newly allocated ppn=%" PRIx32 "\n",
+ eval_direct32 (transl_table + i + 4, 0, 0));
+ PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4);
+ PRINTF ("newly allocated ofs=%" PRIxADDR "\n",
+ (laddr & (PAGE_SIZE - 1)));
+ PRINTF ("newly allocated paddr=%" PRIx32 "\n",
+ eval_direct32 (transl_table + i + 4, 0,
+ 0) | (laddr & (PAGE_SIZE - 1)));
+ return (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
+ (laddr & (oraddr_t) (PAGE_SIZE - 1));
+ }
+ }
+
+ /* If we come this far then all phy memory is used and we can't find our
+ page nor allocate new page. */
+ transl_error = 1;
+ PRINTF ("can't translate %" PRIxADDR "\n", laddr);
+ exit (1);
+
+ return -1;
+
+} /* translate() */
+
+#if IMM_STATS
+static int
+bits (uint32_t val)
+{
+ int i = 1;
+ if (!val)
+ return 0;
+ while (val != 0 && (int32_t) val != -1)
+ {
+ i++;
+ val = (int32_t) val >> 1;
+ }
+ return i;
+}
+
+static void
+check_insn (uint32_t insn)
+{
+ int insn_index = insn_decode (insn);
+ struct insn_op_struct *opd = op_start[insn_index];
+ uint32_t data = 0;
+ int dis = 0;
+ const char *name;
+ if (!insn || insn_index < 0)
+ return;
+ name = insn_name (insn_index);
+ if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0)
+ return;
+
+ while (1)
+ {
+ uint32_t tmp = 0 unsigned int nbits = 0;
+ while (1)
+ {
+ tmp |=
+ ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
+ nbits;
+ nbits += opd->data;
+ if (opd->type & OPTYPE_OP)
+ break;
+ opd++;
+ }
+
+ /* Do we have to sign extend? */
+ if (opd->type & OPTYPE_SIG)
+ {
+ int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
+ if (tmp & (1 << sbit))
+ tmp |= 0xFFFFFFFF << sbit;
+ }
+ if (opd->type & OPTYPE_DIS)
+ {
+ /* We have to read register later. */
+ data += tmp;
+ dis = 1;
+ }
+ else
+ {
+ if (!(opd->type & OPTYPE_REG) || dis)
+ {
+ if (!dis)
+ data = tmp;
+ if (strcmp (name, "l.movhi") == 0)
+ {
+ movhi = data << 16;
+ }
+ else
+ {
+ data |= movhi;
+ //PRINTF ("%08x %s\n", data, name);
+ if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY))
+ {
+ bcnt[bits (data)][0]++;
+ bsum[0]++;
+ }
+ else
+ {
+ if (strcmp (name, "l.bf") == 0
+ || strcmp (name, "l.bnf") == 0)
+ {
+ bcnt[bits (data)][1]++;
+ bsum[1]++;
+ }
+ else
+ {
+ bcnt[bits (data)][2]++;
+ bsum[2]++;
+ }
+ }
+ }
+ }
+ data = 0;
+ dis = 0;
+ }
+ if (opd->type & OPTYPE_LAST)
+ {
+ return;
+ }
+ opd++;
+ }
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
+/*!Add an instruction to the program
+
+ @note insn must be in big endian format
+
+ @param[in] address The address to use
+ @param[in] insn The instruction to add
+ @param[in] breakpoint Not used (it is passed to the translate() function,
+ which also does not use it. */
+/*---------------------------------------------------------------------------*/
+static void
+addprogram (oraddr_t address,
+ uint32_t insn,
+ int *breakpoint)
+{
+ int vaddr = (!runtime.sim.filename) ? translate (address, breakpoint) :
+ translate (freemem, breakpoint);
+
+ /* We can't have set_program32 functions since it is not gauranteed that the
+ section we're loading is aligned on a 4-byte boundry */
+ set_program8 (vaddr, (insn >> 24) & 0xff);
+ set_program8 (vaddr + 1, (insn >> 16) & 0xff);
+ set_program8 (vaddr + 2, (insn >> 8) & 0xff);
+ set_program8 (vaddr + 3, insn & 0xff);
+
+#if IMM_STATS
+ check_insn (insn);
+#endif
+
+ if (runtime.sim.filename)
+ {
+ freemem += insn_len (insn_decode (insn));
+ }
+} /* addprogram () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Load big-endian COFF file
+
+ @param[in] filename File to load
+ @param[in] sections Number of sections in file */
+/*---------------------------------------------------------------------------*/
+static void
+readfile_coff (char *filename,
+ short sections)
+{
+ FILE *inputfs;
+ char inputbuf[4];
+ uint32_t insn;
+ int32_t sectsize;
+ COFF_AOUTHDR coffaouthdr;
+ struct COFF_scnhdr coffscnhdr;
+ int len;
+ int firstthree = 0;
+ int breakpoint = 0;
+
+ if (!(inputfs = fopen (filename, "r")))
+ {
+ perror ("readfile_coff");
+ exit (1);
+ }
+
+ if (fseek (inputfs, sizeof (struct COFF_filehdr), SEEK_SET) == -1)
+ {
+ fclose (inputfs);
+ perror ("readfile_coff");
+ exit (1);
+ }
+
+ if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1)
+ {
+ fclose (inputfs);
+ perror ("readfile_coff");
+ exit (1);
+ }
+
+ while (sections--)
+ {
+ uint32_t scnhdr_pos =
+ sizeof (struct COFF_filehdr) + sizeof (coffaouthdr) +
+ sizeof (struct COFF_scnhdr) * firstthree;
+ if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1)
+ {
+ fclose (inputfs);
+ perror ("readfile_coff");
+ exit (1);
+ }
+ if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1)
+ {
+ fclose (inputfs);
+ perror ("readfile_coff");
+ exit (1);
+ }
+ PRINTF ("Section: %s,", coffscnhdr.s_name);
+ PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr));
+ PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr));
+ PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size));
+ PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr));
+
+ sectsize = COFF_LONG_H (coffscnhdr.s_size);
+ ++firstthree;
+
+ /* loading section */
+ freemem = COFF_LONG_H (coffscnhdr.s_paddr);
+ if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1)
+ {
+ fclose (inputfs);
+ perror ("readfile_coff");
+ exit (1);
+ }
+ while (sectsize > 0
+ && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
+ {
+ insn = COFF_LONG_H (inputbuf);
+ len = insn_len (insn_decode (insn));
+ if (len == 2)
+ {
+ fseek (inputfs, -2, SEEK_CUR);
+ }
+
+ addprogram (freemem, insn, &breakpoint);
+ sectsize -= len;
+ }
+ }
+ if (firstthree < 3)
+ {
+ PRINTF ("One or more missing sections. At least");
+ PRINTF (" three sections expected (.text, .data, .bss).\n");
+ exit (1);
+ }
+ if (firstthree > 3)
+ {
+ PRINTF ("Warning: one or more extra sections. These");
+ PRINTF (" sections were handled as .data sections.\n");
+ }
+
+ fclose (inputfs);
+ PRINTF ("Finished loading COFF.\n");
+ return;
+
+} /* readfile_coff () */
+
+
+/* Load symbols from big-endian COFF file. */
+
+static void
+readsyms_coff (char *filename, uint32_t symptr, uint32_t syms)
+{
+ FILE *inputfs;
+ struct COFF_syment coffsymhdr;
+ int count = 0;
+ uint32_t nsyms = syms;
+ if (!(inputfs = fopen (filename, "r")))
+ {
+ perror ("readsyms_coff");
+ exit (1);
+ }
+
+ if (fseek (inputfs, symptr, SEEK_SET) == -1)
+ {
+ fclose (inputfs);
+ perror ("readsyms_coff");
+ exit (1);
+ }
+
+ while (syms--)
+ {
+ int i, n;
+ if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
+ {
+ fclose (inputfs);
+ perror ("readsyms_coff");
+ exit (1);
+ }
+
+ n = (unsigned char) coffsymhdr.e_numaux[0];
+
+ /* check whether this symbol belongs to a section and is external
+ symbol; ignore all others */
+ if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0
+ && coffsymhdr.e_sclass[0] == C_EXT)
+ {
+ if (*((uint32_t *) coffsymhdr.e.e.e_zeroes))
+ {
+ if (strlen (coffsymhdr.e.e_name)
+ && strlen (coffsymhdr.e.e_name) < 9)
+ add_label (COFF_LONG_H (coffsymhdr.e_value),
+ coffsymhdr.e.e_name);
+ }
+ else
+ {
+ uint32_t fpos = ftell (inputfs);
+
+ if (fseek
+ (inputfs,
+ symptr + nsyms * COFF_SYMESZ +
+ COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0)
+ {
+ char tmp[33], *s = &tmp[0];
+ while (s != &tmp[32])
+ if ((*(s++) = fgetc (inputfs)) == 0)
+ break;
+ tmp[32] = 0;
+ add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]);
+ }
+ fseek (inputfs, fpos, SEEK_SET);
+ }
+ }
+
+ for (i = 0; i < n; i++)
+ if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
+ {
+ fclose (inputfs);
+ perror ("readsyms_coff3");
+ exit (1);
+ }
+ syms -= n;
+ count += n;
+ }
+
+ fclose (inputfs);
+ PRINTF ("Finished loading symbols.\n");
+ return;
+}
+
+static void
+readfile_elf (char *filename)
+{
+
+ FILE *inputfs;
+ struct elf32_hdr elfhdr;
+ struct elf32_phdr *elf_phdata = NULL;
+ struct elf32_shdr *elf_spnt, *elf_shdata;
+ struct elf32_sym *sym_tbl = (struct elf32_sym *) 0;
+ uint32_t syms = 0;
+ char *str_tbl = (char *) 0;
+ char *s_str = (char *) 0;
+ int breakpoint = 0;
+ uint32_t inputbuf;
+ uint32_t padd;
+ uint32_t insn;
+ int i, j, sectsize, len;
+
+ if (!(inputfs = fopen (filename, "r")))
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if ((elf_shdata =
+ (struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) *
+ ELF_SHORT_H (elfhdr.e_shnum))) == NULL)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread
+ (elf_shdata,
+ ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1,
+ inputfs) != 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (ELF_LONG_H (elfhdr.e_phoff))
+ {
+ if ((elf_phdata =
+ (struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) *
+ ELF_SHORT_H (elfhdr.e_phentsize))) ==
+ NULL)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread
+ (elf_phdata,
+ ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize),
+ 1, inputfs) != 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+ }
+
+ for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
+ i++, elf_spnt++)
+ {
+
+ if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB)
+ {
+ if (NULL != str_tbl)
+ {
+ free (str_tbl);
+ }
+
+ if ((str_tbl =
+ (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
+ 0)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
+ 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+ }
+ else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB)
+ {
+
+ if (NULL != sym_tbl)
+ {
+ free (sym_tbl);
+ }
+
+ if ((sym_tbl =
+ (struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size)))
+ == NULL)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
+ 0)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
+ 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ syms =
+ ELF_LONG_H (elf_spnt->sh_size) /
+ ELF_LONG_H (elf_spnt->sh_entsize);
+ }
+ }
+
+ if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF)
+ {
+ elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)];
+
+ if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+
+ if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1)
+ {
+ perror ("readfile_elf");
+ exit (1);
+ }
+ }
+
+
+ for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
+ i++, elf_spnt++)
+ {
+
+ if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS)
+ && (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC))
+ {
+
+ padd = ELF_LONG_H (elf_spnt->sh_addr);
+ for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++)
+ {
+ if (ELF_LONG_H (elf_phdata[j].p_offset) &&
+ ELF_LONG_H (elf_phdata[j].p_offset) <=
+ ELF_LONG_H (elf_spnt->sh_offset)
+ && (ELF_LONG_H (elf_phdata[j].p_offset) +
+ ELF_LONG_H (elf_phdata[j].p_memsz)) >
+ ELF_LONG_H (elf_spnt->sh_offset))
+ padd =
+ ELF_LONG_H (elf_phdata[j].p_paddr) +
+ ELF_LONG_H (elf_spnt->sh_offset) -
+ ELF_LONG_H (elf_phdata[j].p_offset);
+ }
+
+
+
+ if (ELF_LONG_H (elf_spnt->sh_name) && s_str)
+ PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
+ else
+ PRINTF ("Section: noname,");
+ PRINTF (" vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr));
+ PRINTF (" paddr: 0x%" PRIx32, padd);
+ PRINTF (" offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset));
+ PRINTF (" size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size));
+
+ freemem = padd;
+ sectsize = ELF_LONG_H (elf_spnt->sh_size);
+
+ if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
+ 0)
+ {
+ perror ("readfile_elf");
+ free (elf_phdata);
+ exit (1);
+ }
+
+ while (sectsize > 0
+ && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
+ {
+ insn = ELF_LONG_H (inputbuf);
+ addprogram (freemem, insn, &breakpoint);
+ sectsize -= 4;
+ }
+ }
+ }
+
+ if (str_tbl)
+ {
+ i = 0;
+ while (syms--)
+ {
+ if (sym_tbl[i].st_name && sym_tbl[i].st_info
+ && ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000)
+ {
+ add_label (ELF_LONG_H (sym_tbl[i].st_value),
+ &str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]);
+ }
+ i++;
+ }
+ }
+
+ if (NULL != str_tbl)
+ {
+ free (str_tbl);
+ }
+
+ if (NULL != sym_tbl)
+ {
+ free (sym_tbl);
+ }
+
+ free (s_str);
+ free (elf_phdata);
+ free (elf_shdata);
+
+}
+
+/* Identify file type and call appropriate readfile_X routine. It only
+handles orX-coff-big executables at the moment. */
+
+static void
+identifyfile (char *filename)
+{
+ FILE *inputfs;
+ struct COFF_filehdr coffhdr;
+ struct elf32_hdr elfhdr;
+
+ if (!(inputfs = fopen (filename, "r")))
+ {
+ perror (filename);
+ fflush (stdout);
+ fflush (stderr);
+ exit (1);
+ }
+
+ if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1)
+ {
+ if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a)
+ {
+ uint32_t opthdr_size;
+ PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic));
+ PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags));
+ PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr));
+ if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC)
+ {
+ PRINTF ("This COFF is not an executable.\n");
+ exit (1);
+ }
+ opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr);
+ if (opthdr_size != sizeof (COFF_AOUTHDR))
+ {
+ PRINTF ("COFF optional header is missing or not recognized.\n");
+ PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size);
+ exit (1);
+ }
+ fclose (inputfs);
+ readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns));
+ readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr),
+ COFF_LONG_H (coffhdr.f_nsyms));
+ return;
+ }
+ else
+ {
+ PRINTF ("Not COFF file format\n");
+ fseek (inputfs, 0, SEEK_SET);
+ }
+ }
+ if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1)
+ {
+ if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45
+ && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46)
+ {
+ PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type));
+ PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine));
+ PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version));
+ PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum));
+ if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC)
+ {
+ PRINTF ("This ELF is not an executable.\n");
+ exit (1);
+ }
+ fclose (inputfs);
+ readfile_elf (filename);
+ return;
+ }
+ else
+ {
+ PRINTF ("Not ELF file format.\n");
+ fseek (inputfs, 0, SEEK_SET);
+ }
+ }
+
+ perror ("identifyfile2");
+ fclose (inputfs);
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*!Load file to memory
+
+ Loads file to memory starting at address startaddr and returns freemem.
+
+ @param[in] filename File to load
+ @param[in] startaddr Start address at which to load
+ @param[in] virtphy_transl Virtual to physical transation table if
+ required. Only used for microkernel simulation,
+ and not used in Ork1sim at present (set to NULL)
+
+ @return zero on success, negative on failure. */
+/*---------------------------------------------------------------------------*/
+uint32_t
+loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
+{
+ int breakpoint = 0;
+
+ transl_error = 0;
+ transl_table = virtphy_transl;
+ freemem = startaddr;
+ PRINTF ("loadcode: filename %s startaddr=%" PRIxADDR " virtphy_transl=%"
+ PRIxADDR "\n", filename, startaddr, virtphy_transl);
+ identifyfile (filename);
+
+#if IMM_STATS
+ {
+ int i = 0, a = 0, b = 0, c = 0;
+ PRINTF ("index:arith/branch/jump\n");
+ for (i = 0; i < 33; i++)
+ PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i,
+ 100. * (a += bcnt[i][0]) / bsum[0], 100. * (b +=
+ bcnt[i][1]) /
+ bsum[1], 100. * (c +=
+ bcnt[i][2]) / bsum[2], bcnt[i][0],
+ bcnt[i][1], bcnt[i][2]);
+ PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
+ }
+#endif
+
+ if (transl_error)
+ return -1;
+ else
+ return translate (freemem, &breakpoint);
+
+}
Index: common/trace.c
===================================================================
--- common/trace.c (nonexistent)
+++ common/trace.c (revision 1765)
@@ -0,0 +1,66 @@
+/* trace.c -- Simulator breakpoints
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+
+/* Package includes */
+#include "trace.h"
+#include "sim-config.h"
+#include "abstract.h"
+#include "labels.h"
+
+
+/*---------------------------------------------------------------------------*/
+/*!Set instruction execution breakpoint
+
+ @param[in] addr The address for the breakpoint */
+/*---------------------------------------------------------------------------*/
+void
+set_insnbrkpoint (oraddr_t addr)
+{
+ addr &= ~ADDR_C (3); /* 32-bit aligned */
+
+ if (!verify_memoryarea (addr))
+ {
+ PRINTF
+ ("WARNING: This breakpoint is out of the simulated memory range.\n");
+ }
+
+ if (has_breakpoint (addr))
+ {
+ remove_breakpoint (addr);
+ PRINTF ("\nBreakpoint at 0x%" PRIxADDR " cleared.\n", addr);
+ }
+ else
+ {
+ add_breakpoint (addr);
+ PRINTF ("\nBreakpoint at 0x%" PRIxADDR " set.\n", addr);
+ }
+
+ return;
+
+} /* set_insnbrkpoint () */
Index: common/parse.h
===================================================================
--- common/parse.h (nonexistent)
+++ common/parse.h (revision 1765)
@@ -0,0 +1,41 @@
+/* parse.h -- Header file for parse.c
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* Here we define some often used caharcters in assembly files. This wil
+ probably go into architecture dependent directory. */
+
+
+#ifndef PARSE__H
+#define PARSE__H
+
+/* Package includes */
+#include "sim-config.h"
+
+/* Function prototypes for external use */
+char *strstrip (char *dst,
+ const char *src,
+ int n);
+uint32_t loadcode (char *filename,
+ oraddr_t startaddr,
+ oraddr_t virtphy_transl);
+
+#endif /* PARSE__H */
Index: common/Makefile.in
===================================================================
--- common/Makefile.in (nonexistent)
+++ common/Makefile.in (revision 1765)
@@ -0,0 +1,487 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile -- Makefile for cpu architecture independent simulation
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = cpu/common
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libcommon_la_LIBADD =
+am_libcommon_la_OBJECTS = abstract.lo parse.lo stats.lo trace.lo \
+ labels.lo
+libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libcommon_la_SOURCES)
+DIST_SOURCES = $(libcommon_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_ARCH = @CPU_ARCH@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUGFLAGS = @DEBUGFLAGS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INCLUDES = @INCLUDES@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_SHELL = @MAKE_SHELL@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libcommon.la
+libcommon_la_SOURCES = abstract.c \
+ parse.c \
+ stats.c \
+ trace.c \
+ labels.c \
+ abstract.h \
+ coff.h \
+ elf.h \
+ execute.h \
+ labels.h \
+ parse.h \
+ stats.h \
+ trace.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/common/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/common/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES)
+ $(LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/labels.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: common/labels.c
===================================================================
--- common/labels.c (nonexistent)
+++ common/labels.c (revision 1765)
@@ -0,0 +1,187 @@
+/* abstract.c -- Abstract entities, handling labels
+
+ Copyright (C) 2001 Marko Mlinar, markom@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+/* Abstract memory and routines that go with this. I need to add all sorts of
+ other abstract entities. Currently we have only memory. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "labels.h"
+
+#define LABELS_HASH_SIZE 119
+
+/* Globally visible list of breakpoints */
+struct breakpoint_entry *breakpoints;
+
+/* Local list of labels (symbols) */
+static struct label_entry *label_hash[LABELS_HASH_SIZE];
+
+
+void
+init_labels ()
+{
+ int i;
+ for (i = 0; i < LABELS_HASH_SIZE; i++)
+ label_hash[i] = NULL;
+}
+
+void
+add_label (oraddr_t addr, char *name)
+{
+ struct label_entry **tmp;
+ tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
+ for (; *tmp; tmp = &((*tmp)->next));
+ *tmp = malloc (sizeof (**tmp));
+ (*tmp)->name = malloc (strlen (name) + 1);
+ (*tmp)->addr = addr;
+ strcpy ((*tmp)->name, name);
+ (*tmp)->next = NULL;
+}
+
+struct label_entry *
+get_label (oraddr_t addr)
+{
+ struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
+ while (tmp)
+ {
+ if (tmp->addr == addr)
+ return tmp;
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+struct label_entry *
+find_label (char *name)
+{
+ int i;
+ for (i = 0; i < LABELS_HASH_SIZE; i++)
+ {
+ struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
+ while (tmp)
+ {
+ if (strcmp (tmp->name, name) == 0)
+ return tmp;
+ tmp = tmp->next;
+ }
+ }
+ return NULL;
+}
+
+/* Searches mem array for a particular label and returns label's address.
+ If label does not exist, returns 0. */
+oraddr_t
+eval_label (char *name)
+{
+ struct label_entry *le;
+ char *plus;
+ char *minus;
+ int positive_offset = 0;
+ int negative_offset = 0;
+
+ if ((plus = strchr (name, '+')))
+ {
+ *plus = '\0';
+ positive_offset = atoi (++plus);
+ }
+
+ if ((minus = strchr (name, '-')))
+ {
+ *minus = '\0';
+ negative_offset = atoi (++minus);
+ }
+ le = find_label (name);
+ if (!le)
+ return 0;
+
+ return le->addr + positive_offset - negative_offset;
+}
+
+void
+init_breakpoints ()
+{
+ breakpoints = 0;
+}
+
+void
+add_breakpoint (oraddr_t addr)
+{
+ struct breakpoint_entry *tmp;
+ tmp = (struct breakpoint_entry *) malloc (sizeof (struct breakpoint_entry));
+ tmp->next = breakpoints;
+ tmp->addr = addr;
+ breakpoints = tmp;
+}
+
+void
+remove_breakpoint (oraddr_t addr)
+{
+ struct breakpoint_entry **tmp = &breakpoints;
+ while (*tmp)
+ {
+ if ((*tmp)->addr == addr)
+ {
+ struct breakpoint_entry *t = *tmp;
+ (*tmp) = t->next;
+ free (t);
+ }
+ else
+ tmp = &((*tmp)->next);
+ }
+}
+
+void
+print_breakpoints ()
+{
+ struct breakpoint_entry **tmp = &breakpoints;
+ int i = 1;
+ printf ("---[breakpoints]------------------\n");
+ while (*tmp)
+ {
+ printf ("Breakpoint %i at 0x%" PRIxADDR "\n", i, (*tmp)->addr);
+ tmp = &((*tmp)->next);
+ }
+ printf ("---[breakpoints end]--------------\n");
+}
+
+int
+has_breakpoint (oraddr_t addr)
+{
+ struct breakpoint_entry *tmp = breakpoints;
+ while (tmp)
+ {
+ if (tmp->addr == addr)
+ return 1;
+ tmp = tmp->next;
+ }
+ return 0;
+}
common/labels.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: common/trace.h
===================================================================
--- common/trace.h (nonexistent)
+++ common/trace.h (revision 1765)
@@ -0,0 +1,36 @@
+/* trace.h -- Simulator breakpoints header
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef TRACE__H
+#define TRACE__H
+
+/* Package includes */
+#include "sim-config.h"
+
+/* Function prototype for external use */
+void set_insnbrkpoint (oraddr_t addr);
+
+#endif /* TRACE__H */
Index: common/labels.h
===================================================================
--- common/labels.h (nonexistent)
+++ common/labels.h (revision 1765)
@@ -0,0 +1,64 @@
+/* labels.h -- Abstract entities header file handling labels
+
+ Copyright (C) 2001 Marko Mlinar, markom@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef LABELS__H_
+#define LABELS__H_
+
+/* Package include */
+#include "abstract.h"
+
+/*! Structure for holding one label per particular memory location */
+struct label_entry
+{
+ char *name;
+ oraddr_t addr;
+ struct label_entry *next;
+};
+
+/*! Structure repesenting a breakpoint */
+struct breakpoint_entry
+{
+ oraddr_t addr;
+ struct breakpoint_entry *next;
+};
+
+/* Globally visible variables */
+extern struct breakpoint_entry *breakpoints;
+
+/* Function prototypes for external use */
+extern void init_labels ();
+extern void add_label (oraddr_t addr,
+ char *name);
+extern struct label_entry *get_label (oraddr_t addr);
+extern struct label_entry *find_label (char *name);
+extern oraddr_t eval_label (char *name);
+extern void add_breakpoint (oraddr_t addr);
+extern void remove_breakpoint (oraddr_t addr);
+extern void print_breakpoints ();
+extern int has_breakpoint (oraddr_t addr);
+extern void init_breakpoints ();
+
+#endif /* LABELS__H_ */
common/labels.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: common/abstract.h
===================================================================
--- common/abstract.h (nonexistent)
+++ common/abstract.h (revision 1765)
@@ -0,0 +1,189 @@
+/* abstract.h -- Abstract entities header file
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef ABSTRACT__H
+#define ABSTRACT__H
+
+/* Autoconf and/or portability configuration */
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "arch.h"
+
+#define DEFAULT_MEMORY_START 0
+#define DEFAULT_MEMORY_LEN 0x800000
+#define STACK_SIZE 20
+#define LABELNAME_LEN 50
+#define INSNAME_LEN 15
+#define OPERANDNAME_LEN 50
+#define MAX_OPERANDS 5
+
+#define OP_MEM_ACCESS 0x80000000
+
+/* Cache tag types. */
+#define CT_NONE 0
+#define CT_VIRTUAL 1
+#define CT_PHYSICAL 2
+
+/* History of execution */
+#define HISTEXEC_LEN 200
+
+/* Added by MM */
+#ifndef LONGEST
+#define LONGEST long long
+#endif /* LONGEST */
+
+#ifndef ULONGEST
+#define ULONGEST unsigned long long
+#endif /* ULONGEST */
+
+/* Endianness convenience macros */
+#define LE16(x) bswap_16(x)
+
+/*! Instruction queue */
+struct iqueue_entry
+{
+ int insn_index;
+ uint32_t insn;
+ oraddr_t insn_addr;
+};
+
+/*! All the memory operations possible */
+struct mem_ops
+{
+
+ /* Read functions */
+ uint32_t (*readfunc32) (oraddr_t, void *);
+ uint16_t (*readfunc16) (oraddr_t, void *);
+ uint8_t (*readfunc8) (oraddr_t, void *);
+
+ /* Read functions' data */
+ void *read_dat8;
+ void *read_dat16;
+ void *read_dat32;
+
+ /* Write functions */
+ void (*writefunc32) (oraddr_t, uint32_t, void *);
+ void (*writefunc16) (oraddr_t, uint16_t, void *);
+ void (*writefunc8) (oraddr_t, uint8_t, void *);
+
+ /* Write functions' data */
+ void *write_dat8;
+ void *write_dat16;
+ void *write_dat32;
+
+ /* Program load function. If you have unwritteable memory but you would like
+ * it if a program would be loaded here, make sure to set this. If this is
+ * not set, then writefunc8 will be called to load the program */
+ void (*writeprog32) (oraddr_t, uint32_t, void *);
+ void (*writeprog8) (oraddr_t, uint8_t, void *);
+
+ /* Program load functions' data */
+ void *writeprog32_dat;
+ void *writeprog8_dat;
+
+ /* Read/Write delays */
+ int delayr;
+ int delayw;
+
+ /* Name of log file */
+ const char *log;
+};
+
+/*! Memory regions assigned to devices */
+struct dev_memarea
+{
+ struct dev_memarea *next;
+ oraddr_t addr_mask;
+ oraddr_t addr_compare;
+ uint32_t size;
+ oraddr_t size_mask; /* Addr mask, calculated out of size */
+ int valid; /* Mirrors memory controler valid bit */
+ FILE *log; /* log file (NULL if no logging) */
+ struct mem_ops ops;
+ struct mem_ops direct_ops;
+};
+
+/* Externally visible data */
+extern struct dev_memarea *cur_area;
+extern int data_ci;
+extern int insn_ci;
+extern struct hist_exec *hist_exec_tail;
+
+/* Function prototypes for external use */
+extern uint32_t eval_mem32 (oraddr_t memaddr, int *);
+extern uint16_t eval_mem16 (oraddr_t memaddr, int *);
+extern uint8_t eval_mem8 (oraddr_t memaddr, int *);
+extern void set_mem32 (oraddr_t memaddr, uint32_t value, int *);
+extern void set_mem16 (oraddr_t memaddr, uint16_t value, int *);
+extern void set_mem8 (oraddr_t memaddr, uint8_t value, int *);
+extern void dump_memory (oraddr_t from,
+ oraddr_t to);
+extern void disassemble_memory (oraddr_t from,
+ oraddr_t to,
+ int nl);
+extern uint32_t evalsim_mem32 (oraddr_t, oraddr_t);
+extern uint16_t evalsim_mem16 (oraddr_t, oraddr_t);
+extern uint8_t evalsim_mem8 (oraddr_t, oraddr_t);
+extern void setsim_mem32 (oraddr_t, oraddr_t, uint32_t);
+extern void setsim_mem16 (oraddr_t, oraddr_t, uint16_t);
+extern void setsim_mem8 (oraddr_t, oraddr_t, uint8_t);
+extern void done_memory_table ();
+extern void memory_table_status (void);
+extern struct dev_memarea *reg_mem_area (oraddr_t addr,
+ uint32_t size,
+ unsigned mc_dev,
+ struct mem_ops *ops);
+extern void adjust_rw_delay (struct dev_memarea *mem,
+ int delayr,
+ int delayw);
+extern void set_mem_valid (struct dev_memarea *mem,
+ int valid);
+extern struct dev_memarea *verify_memoryarea (oraddr_t addr);
+extern char *generate_time_pretty (char *dest,
+ long time_ps);
+extern uint32_t eval_insn (oraddr_t, int *);
+extern uint32_t eval_direct32 (oraddr_t addr,
+ int through_mmu,
+ int through_dc);
+extern uint16_t eval_direct16 (oraddr_t memaddr,
+ int through_mmu,
+ int through_dc);
+extern uint8_t eval_direct8 (oraddr_t memaddr,
+ int through_mmu,
+ int through_dc);
+extern void set_direct8 (oraddr_t, uint8_t, int, int);
+extern void set_direct16 (oraddr_t, uint16_t, int, int);
+extern void set_direct32 (oraddr_t, uint32_t, int, int);
+extern void set_program32 (oraddr_t memaddr,
+ uint32_t value);
+extern void set_program8 (oraddr_t memaddr,
+ uint8_t value);
+
+#endif /* ABSTRACT__H */
Index: common/Makefile.am
===================================================================
--- common/Makefile.am (nonexistent)
+++ common/Makefile.am (revision 1765)
@@ -0,0 +1,36 @@
+# Makefile -- Makefile for cpu architecture independent simulation
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+noinst_LTLIBRARIES = libcommon.la
+libcommon_la_SOURCES = abstract.c \
+ parse.c \
+ stats.c \
+ trace.c \
+ labels.c \
+ abstract.h \
+ coff.h \
+ elf.h \
+ execute.h \
+ labels.h \
+ parse.h \
+ stats.h \
+ trace.h
Index: common/elf.h
===================================================================
--- common/elf.h (nonexistent)
+++ common/elf.h (revision 1765)
@@ -0,0 +1,447 @@
+#ifndef _LINUX_ELF_H
+#define _LINUX_ELF_H
+
+#if HAVE_CONFIG_H
+#include
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define ELF_SHORT_H
+#define ELF_LONG_H
+#else
+/* Load a short int from the following tables with big-endian formats */
+#define ELF_SHORT_H(ps) ((((unsigned short)(ps) >> 8) & 0xff) |\
+ (((unsigned short)(ps) << 8) & 0xff00))
+
+/* Load a long int from the following tables with big-endian formats */
+#define ELF_LONG_H(ps) ((((unsigned long)(ps) >> 24) & 0xff) |\
+ (((unsigned long)(ps) >> 8) & 0xff00)|\
+ (((unsigned long)(ps) << 8) & 0xff0000)|\
+ (((unsigned long)(ps) << 24) & 0xff000000))
+#endif
+
+#ifdef OR32_TYPES
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+#else
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+#endif
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6 /* Perhaps disused */
+#define EM_860 7
+
+#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
+
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
+
+#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
+
+#define EM_PARISC 15 /* HPPA */
+
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+
+#define EM_PPC 20 /* PowerPC */
+
+/*
+ * This is an interim value that we will use until the committee comes
+ * up with a final number.
+ */
+#define EM_ALPHA 0x9026
+
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+/* Symbolic values for the entries in the auxiliary table
+ put on the initial stack */
+#define AT_NULL 0 /* end of vector */
+#define AT_IGNORE 1 /* entry should be ignored */
+#define AT_EXECFD 2 /* file descriptor of program */
+#define AT_PHDR 3 /* program headers for program */
+#define AT_PHENT 4 /* size of program header entry */
+#define AT_PHNUM 5 /* number of program headers */
+#define AT_PAGESZ 6 /* system page size */
+#define AT_BASE 7 /* base address of interpreter */
+#define AT_FLAGS 8 /* flags */
+#define AT_ENTRY 9 /* entry point of program */
+#define AT_NOTELF 10 /* program is not ELF */
+#define AT_UID 11 /* real uid */
+#define AT_EUID 12 /* effective uid */
+#define AT_GID 13 /* real gid */
+#define AT_EGID 14 /* effective gid */
+
+
+typedef struct dynamic{
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ unsigned long long d_tag; /* entry tag value */
+ union {
+ unsigned long long d_val;
+ unsigned long long d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+ unsigned long long r_offset; /* Location at which to apply the action */
+ unsigned long long r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+ unsigned long long r_offset; /* Location at which to apply the action */
+ unsigned long long r_info; /* index and type of relocation */
+ unsigned long long r_addend; /* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+ unsigned int st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* No defined meaning, 0 */
+ unsigned short st_shndx; /* Associated section index */
+ unsigned long long st_value; /* Value of the symbol */
+ unsigned long long st_size; /* Associated symbol size */
+} Elf64_Sym;
+
+
+#define EI_NIDENT 16
+
+typedef struct elf32_hdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+ unsigned char e_ident[16]; /* ELF "magic number" */
+ short int e_type;
+ short unsigned int e_machine;
+ int e_version;
+ unsigned long long e_entry; /* Entry point virtual address */
+ unsigned long long e_phoff; /* Program header table file offset */
+ unsigned long long e_shoff; /* Section header table file offset */
+ int e_flags;
+ short int e_ehsize;
+ short int e_phentsize;
+ short int e_phnum;
+ short int e_shentsize;
+ short int e_shnum;
+ short int e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf32_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+ int p_type;
+ int p_flags;
+ unsigned long long p_offset; /* Segment file offset */
+ unsigned long long p_vaddr; /* Segment virtual address */
+ unsigned long long p_paddr; /* Segment physical address */
+ unsigned long long p_filesz; /* Segment size in file */
+ unsigned long long p_memsz; /* Segment size in memory */
+ unsigned long long p_align; /* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+typedef struct elf32_shdr {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+ unsigned int sh_name; /* Section name, index in string tbl */
+ unsigned int sh_type; /* Type of section */
+ unsigned long long sh_flags; /* Miscellaneous section attributes */
+ unsigned long long sh_addr; /* Section virtual addr at execution */
+ unsigned long long sh_offset; /* Section file offset */
+ unsigned long long sh_size; /* Size of section in bytes */
+ unsigned int sh_link; /* Index of another section */
+ unsigned int sh_info; /* Additional section information */
+ unsigned long long sh_addralign; /* Section alignment */
+ unsigned long long sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+/*
+ * For now we use the 32 bit version of the structure until we figure
+ * out whether we need anything better. Note - on the Alpha, "unsigned int"
+ * is only 32 bits.
+ */
+typedef struct elf64_note {
+ unsigned int n_namesz; /* Name size */
+ unsigned int n_descsz; /* Content size */
+ unsigned int n_type; /* Content type */
+} Elf64_Nhdr;
+
+#ifdef __mc68000__
+#define ELF_START_MMAP 0xC0000000
+#endif
+#ifdef __i386__
+#define ELF_START_MMAP 0x80000000
+#endif
+
+#if ELF_CLASS == ELFCLASS32
+
+extern Elf32_Dyn _DYNAMIC [];
+#define elfhdr elf32_hdr
+#define elf_phdr elf32_phdr
+#define elf_note elf32_note
+
+#else
+
+extern Elf64_Dyn _DYNAMIC [];
+#define elfhdr elf64_hdr
+#define elf_phdr elf64_phdr
+#define elf_note elf64_note
+
+#endif
+
+
+#endif /* _LINUX_ELF_H */
Index: common/coff.h
===================================================================
--- common/coff.h (nonexistent)
+++ common/coff.h (revision 1765)
@@ -0,0 +1,457 @@
+#if HAVE_CONFIG_H
+#include
+#endif
+
+/* This file is derived from the GAS 2.1.4 assembler control file.
+ The GAS product is under the GNU Public License, version 2 or later.
+ As such, this file is also under that license.
+
+ If the file format changes in the COFF object, this file should be
+ subsequently updated to reflect the changes.
+
+ The actual loader module only uses a few of these structures. The full
+ set is documented here because I received the full set. If you wish
+ more information about COFF, then O'Reilly has a very excellent book.
+*/
+
+#define E_SYMNMLEN 8 /* Number of characters in a symbol name */
+#define E_FILNMLEN 14 /* Number of characters in a file name */
+#define E_DIMNUM 4 /* Number of array dimensions in auxiliary entry */
+
+/*
+ * These defines are byte order independent. There is no alignment of fields
+ * permitted in the structures. Therefore they are declared as characters
+ * and the values loaded from the character positions. It also makes it
+ * nice to have it "endian" independent.
+ */
+#if !defined(WORDS_BIGENDIAN)
+/* Load a short int from the following tables with little-endian formats */
+#define COFF_SHORT_L SWAP_ENDIAN_SHORT
+/* Load a long int from the following tables with little-endian formats */
+#define COFF_LONG_L SWAP_ENDIAN_LONG
+/* Load a short int from the following tables with big-endian formats */
+#define COFF_SHORT_H KEEP_ENDIAN_SHORT
+/* Load a long int from the following tables with big-endian formats */
+#define COFF_LONG_H KEEP_ENDIAN_LONG
+#else
+#define COFF_SHORT_L KEEP_ENDIAN_SHORT
+#define COFF_LONG_L KEEP_ENDIAN_LONG
+#define COFF_SHORT_H SWAP_ENDIAN_SHORT
+#define COFF_LONG_H SWAP_ENDIAN_LONG
+#endif
+
+#define SWAP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\
+ ((unsigned short)((unsigned char)ps[0]))))
+
+#define SWAP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\
+ ((unsigned long)((unsigned char)ps[2])<<16) |\
+ ((unsigned long)((unsigned char)ps[1])<<8) |\
+ ((unsigned long)((unsigned char)ps[0])))))
+
+#define KEEP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\
+ ((unsigned short)((unsigned char)ps[1]))))
+
+#define KEEP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\
+ ((unsigned long)((unsigned char)ps[1])<<16) |\
+ ((unsigned long)((unsigned char)ps[2])<<8) |\
+ ((unsigned long)((unsigned char)ps[3])))))
+
+/* These may be overridden later by brain dead implementations which generate
+ a big-endian header with little-endian data. In that case, generate a
+ replacement macro which tests a flag and uses either of the two above
+ as appropriate. */
+
+#define COFF_LONG(v) COFF_LONG_L(v)
+#define COFF_SHORT(v) COFF_SHORT_L(v)
+
+/*** coff information for Intel 386/486. */
+
+/********************** FILE HEADER **********************/
+
+struct COFF_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+/*
+ * Bits for f_flags:
+ *
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (i.e. no unresolved external
+ * references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_MINMAL this is a minimal object file (".m") output of fextract
+ * F_UPDATE this is a fully bound update file, output of ogen
+ * F_SWABD this file has had its bytes swabbed (in names)
+ * F_AR16WR this file has the byte ordering of an AR16WR
+ * (e.g. 11/70) machine
+ * F_AR32WR this file has the byte ordering of an AR32WR machine
+ * (e.g. vax and iNTEL 386)
+ * F_AR32W this file has the byte ordering of an AR32W machine
+ * (e.g. 3b,maxi)
+ * F_PATCH file contains "patch" list in optional header
+ * F_NODF (minimal file only) no decision functions for
+ * replaced functions
+ */
+
+#define COFF_F_RELFLG 0000001
+#define COFF_F_EXEC 0000002
+#define COFF_F_LNNO 0000004
+#define COFF_F_LSYMS 0000010
+#define COFF_F_MINMAL 0000020
+#define COFF_F_UPDATE 0000040
+#define COFF_F_SWABD 0000100
+#define COFF_F_AR16WR 0000200
+#define COFF_F_AR32WR 0000400
+#define COFF_F_AR32W 0001000
+#define COFF_F_PATCH 0002000
+#define COFF_F_NODF 0002000
+
+#define COFF_I386MAGIC 0x14c /* Linux's system */
+
+#if 0 /* Perhaps, someday, these formats may be used. */
+#define COFF_I386PTXMAGIC 0x154
+#define COFF_I386AIXMAGIC 0x175 /* IBM's AIX system */
+#define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \
+ && COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \
+ && COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC)
+#else
+#define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC)
+#endif
+
+#define COFF_FILHDR struct COFF_filehdr
+#define COFF_FILHSZ sizeof(COFF_FILHDR)
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+/* Linux COFF must have this "optional" header. Standard COFF has no entry
+ location for the "entry" point. They normally would start with the first
+ location of the .text section. This is not a good idea for linux. So,
+ the use of this "optional" header is not optional. It is required.
+
+ Do not be tempted to assume that the size of the optional header is
+ a constant and simply index the next byte by the size of this structure.
+ Use the 'f_opthdr' field in the main coff header for the size of the
+ structure actually written to the file!!
+*/
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry */
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+COFF_AOUTHDR;
+
+#define COFF_AOUTSZ (sizeof(COFF_AOUTHDR))
+
+#define COFF_STMAGIC 0401
+#define COFF_OMAGIC 0404
+#define COFF_JMAGIC 0407 /* dirty text and data image, can't share */
+#define COFF_DMAGIC 0410 /* dirty text segment, data aligned */
+#define COFF_ZMAGIC 0413 /* The proper magic number for executables */
+#define COFF_SHMAGIC 0443 /* shared library header */
+
+/********************** STORAGE CLASSES **********************/
+
+/* This used to be defined as -1, but now n_sclass is unsigned. */
+#define C_EFCN 0xff /* physical end of function */
+#define C_NULL 0
+#define C_AUTO 1 /* automatic variable */
+#define C_EXT 2 /* external symbol */
+#define C_STAT 3 /* static */
+#define C_REG 4 /* register variable */
+#define C_EXTDEF 5 /* external definition */
+#define C_LABEL 6 /* label */
+#define C_ULABEL 7 /* undefined label */
+#define C_MOS 8 /* member of structure */
+#define C_ARG 9 /* function argument */
+#define C_STRTAG 10 /* structure tag */
+#define C_MOU 11 /* member of union */
+#define C_UNTAG 12 /* union tag */
+#define C_TPDEF 13 /* type definition */
+#define C_USTATIC 14 /* undefined static */
+#define C_ENTAG 15 /* enumeration tag */
+#define C_MOE 16 /* member of enumeration */
+#define C_REGPARM 17 /* register parameter */
+#define C_FIELD 18 /* bit field */
+#define C_AUTOARG 19 /* auto argument */
+#define C_LASTENT 20 /* dummy entry (end of block) */
+#define C_BLOCK 100 /* ".bb" or ".eb" */
+#define C_FCN 101 /* ".bf" or ".ef" */
+#define C_EOS 102 /* end of structure */
+#define C_FILE 103 /* file name */
+#define C_LINE 104 /* line # reformatted as symbol table entry */
+#define C_ALIAS 105 /* duplicate tag */
+#define C_HIDDEN 106 /* ext symbol in dmert public lib */
+
+#define C_WEAKEXT 127 /* weak symbol -- GNU extension */
+
+/* New storage classes for TI COFF */
+#define C_UEXT 19 /* Tentative external definition */
+#define C_STATLAB 20 /* Static load time label */
+#define C_EXTLAB 21 /* External load time label */
+#define C_SYSTEM 23 /* System Wide variable */
+
+/* New storage classes for WINDOWS_NT */
+#define C_SECTION 104 /* section name */
+#define C_NT_WEAK 105 /* weak external */
+
+ /* New storage classes for 80960 */
+
+/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */
+#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */
+
+#define C_SCALL 107 /* Procedure reachable via system call */
+#define C_LEAFEXT 108 /* External leaf */
+#define C_LEAFSTAT 113 /* Static leaf */
+#define C_OPTVAR 109 /* Optimized variable */
+#define C_DEFINE 110 /* Preprocessor #define */
+#define C_PRAGMA 111 /* Advice to compiler or linker */
+#define C_SEGMENT 112 /* 80960 segment name */
+
+ /* Storage classes for m88k */
+#define C_SHADOW 107 /* shadow symbol */
+#define C_VERSION 108 /* coff version symbol */
+
+ /* New storage classes for RS/6000 */
+#define C_HIDEXT 107 /* Un-named external symbol */
+#define C_BINCL 108 /* Marks beginning of include file */
+#define C_EINCL 109 /* Marks ending of include file */
+
+ /* storage classes for stab symbols for RS/6000 */
+#define C_GSYM (0x80)
+#define C_LSYM (0x81)
+#define C_PSYM (0x82)
+#define C_RSYM (0x83)
+#define C_RPSYM (0x84)
+#define C_STSYM (0x85)
+#define C_TCSYM (0x86)
+#define C_BCOMM (0x87)
+#define C_ECOML (0x88)
+#define C_ECOMM (0x89)
+#define C_DECL (0x8c)
+#define C_ENTRY (0x8d)
+#define C_FUN (0x8e)
+#define C_BSTAT (0x8f)
+#define C_ESTAT (0x90)
+
+/* Storage classes for Thumb symbols */
+#define C_THUMBEXT (128 + C_EXT) /* 130 */
+#define C_THUMBSTAT (128 + C_STAT) /* 131 */
+#define C_THUMBLABEL (128 + C_LABEL) /* 134 */
+#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */
+#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */
+
+/********************** SECTION HEADER **********************/
+
+struct COFF_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries */
+ char s_flags[4]; /* flags */
+};
+
+#define COFF_SCNHDR struct COFF_scnhdr
+#define COFF_SCNHSZ sizeof(COFF_SCNHDR)
+
+/*
+ * names of "special" sections
+ */
+
+#define COFF_TEXT ".text"
+#define COFF_DATA ".data"
+#define COFF_BSS ".bss"
+#define COFF_COMMENT ".comment"
+#define COFF_LIB ".lib"
+
+#define COFF_SECT_TEXT 0 /* Section for instruction code */
+#define COFF_SECT_DATA 1 /* Section for initialized globals */
+#define COFF_SECT_BSS 2 /* Section for un-initialized globals */
+#define COFF_SECT_REQD 3 /* Minimum number of sections for good file */
+
+#define COFF_STYP_REG 0x00 /* regular segment */
+#define COFF_STYP_DSECT 0x01 /* dummy segment */
+#define COFF_STYP_NOLOAD 0x02 /* no-load segment */
+#define COFF_STYP_GROUP 0x04 /* group segment */
+#define COFF_STYP_PAD 0x08 /* .pad segment */
+#define COFF_STYP_COPY 0x10 /* copy section */
+#define COFF_STYP_TEXT 0x20 /* .text segment */
+#define COFF_STYP_DATA 0x40 /* .data segment */
+#define COFF_STYP_BSS 0x80 /* .bss segment */
+#define COFF_STYP_INFO 0x200 /* .comment section */
+#define COFF_STYP_OVER 0x400 /* overlay section */
+#define COFF_STYP_LIB 0x800 /* library section */
+
+/*
+ * Shared libraries have the following section header in the data field for
+ * each library.
+ */
+
+struct COFF_slib {
+ char sl_entsz[4]; /* Size of this entry */
+ char sl_pathndx[4]; /* size of the header field */
+};
+
+#define COFF_SLIBHD struct COFF_slib
+#define COFF_SLIBSZ sizeof(COFF_SLIBHD)
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+
+struct COFF_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+#define COFF_LINENO struct COFF_lineno
+#define COFF_LINESZ 6
+
+/********************** SYMBOLS **********************/
+
+#define COFF_E_SYMNMLEN 8 /* # characters in a short symbol name */
+#define COFF_E_FILNMLEN 14 /* # characters in a file name */
+#define COFF_E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+/*
+ * All symbols and sections have the following definition
+ */
+
+struct COFF_syment
+{
+ union {
+ char e_name[E_SYMNMLEN]; /* Symbol name (first 8 characters) */
+ struct {
+ char e_zeroes[4]; /* Leading zeros */
+ char e_offset[4]; /* Offset if this is a header section */
+ } e;
+ } e;
+
+ char e_value[4]; /* Value (address) of the segment */
+ char e_scnum[2]; /* Section number */
+ char e_type[2]; /* Type of section */
+ char e_sclass[1]; /* Loader class */
+ char e_numaux[1]; /* Number of auxiliary entries which follow */
+};
+
+#define COFF_N_BTMASK (0xf) /* Mask for important class bits */
+#define COFF_N_TMASK (0x30) /* Mask for important type bits */
+#define COFF_N_BTSHFT (4) /* # bits to shift class field */
+#define COFF_N_TSHIFT (2) /* # bits to shift type field */
+
+/*
+ * Auxiliary entries because the main table is too limiting.
+ */
+
+union COFF_auxent {
+
+/*
+ * Debugger information
+ */
+
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+/*
+ * Source file names (debugger information)
+ */
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+/*
+ * Section information
+ */
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+/*
+ * Transfer vector (branch table)
+ */
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+};
+
+#define COFF_SYMENT struct COFF_syment
+#define COFF_SYMESZ 18
+#define COFF_AUXENT union COFF_auxent
+#define COFF_AUXESZ 18
+
+#define COFF_ETEXT "etext"
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct COFF_reloc {
+ char r_vaddr[4]; /* Virtual address of item */
+ char r_symndx[4]; /* Symbol index in the symtab */
+ char r_type[2]; /* Relocation type */
+};
+
+#define COFF_RELOC struct COFF_reloc
+#define COFF_RELSZ 10
+
+#define COFF_DEF_DATA_SECTION_ALIGNMENT 4
+#define COFF_DEF_BSS_SECTION_ALIGNMENT 4
+#define COFF_DEF_TEXT_SECTION_ALIGNMENT 4
+
+/* For new sections we haven't heard of before */
+#define COFF_DEF_SECTION_ALIGNMENT 4
Index: common
===================================================================
--- common (nonexistent)
+++ common (revision 1765)
common
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps
Index: or1k/spr-dump.c
===================================================================
--- or1k/spr-dump.c (nonexistent)
+++ or1k/spr-dump.c (revision 1765)
@@ -0,0 +1,542 @@
+/* spr_dump.c -- Dump given spr in human readable form
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "arch.h"
+#include "spr-defs.h"
+#include "debug.h"
+#include "misc.h"
+
+
+struct spr_bit_def {
+ const char *name;
+ uorreg_t mask;
+};
+
+struct spr_def {
+ uint16_t from_spr;
+ uint16_t to_spr;
+ const char *name;
+ const struct spr_bit_def *bits;
+};
+
+/* One value spr */
+static const struct spr_bit_def spr_one_val[] = {
+ { "", 0xffffffff },
+ { NULL, 0 } };
+
+/*---------------------------------------------------------[ System group ]---*/
+/* Supervisor register */
+static const struct spr_bit_def spr_sr[] = {
+ { "SR_SM", SPR_SR_SM },
+ { "SR_TEE", SPR_SR_TEE },
+ { "SR_IEE", SPR_SR_IEE },
+ { "SR_DCE", SPR_SR_DCE },
+ { "SR_ICE", SPR_SR_ICE },
+ { "SR_DME", SPR_SR_DME },
+ { "SR_IME", SPR_SR_IME },
+ { "SR_LEE", SPR_SR_IME },
+ { "SR_CE", SPR_SR_CE },
+ { "SR_F", SPR_SR_F },
+ { "SR_CY", SPR_SR_CY },
+ { "SR_OV", SPR_SR_OV },
+ { "SR_OVE", SPR_SR_OVE },
+ { "SR_DSX", SPR_SR_DSX },
+ { "SR_EPH", SPR_SR_EPH },
+ { "SR_FO", SPR_SR_FO },
+ { "SR_SUMRA", SPR_SR_SUMRA },
+ { "SR_RES", SPR_SR_RES },
+ { "SR_CID", SPR_SR_CID },
+ { NULL, 0 } };
+
+/* Version register */
+static const struct spr_bit_def spr_vr[] = {
+ { "VR_VER", SPR_VR_VER },
+ { "VR_REV", SPR_VR_REV },
+ { NULL, 0 } };
+
+/* upr register */
+static const struct spr_bit_def spr_upr[] = {
+ { "UPR_UP", SPR_UPR_UP },
+ { "UPR_DCP", SPR_UPR_DCP },
+ { "UPR_ICP", SPR_UPR_ICP },
+ { "UPR_DMP", SPR_UPR_DMP },
+ { "UPR_IMP", SPR_UPR_IMP },
+ { "UPR_MP", SPR_UPR_MP },
+ { "UPR_DUP", SPR_UPR_DUP },
+ { "UPR_PCUP", SPR_UPR_PCUP },
+ { "UPR_PMP", SPR_UPR_PMP },
+ { "UPR_PICP", SPR_UPR_PICP },
+ { "UPR_TTP", SPR_UPR_TTP },
+ { "UPR_RES", SPR_UPR_RES },
+ { "UPR_CUP", SPR_UPR_CUP },
+ { NULL, 0 } };
+
+/* CPUCFGR register */
+static const struct spr_bit_def spr_cpucfgr[] = {
+ { "CPUCFGR_OB32S", SPR_CPUCFGR_OB32S },
+ { "CPUCFGR_OB64S", SPR_CPUCFGR_OB64S },
+ { "CPUCFGR_OF32S", SPR_CPUCFGR_OF32S },
+ { "CPUCFGR_OF64S", SPR_CPUCFGR_OF64S },
+ { "CPUCFGR_OV64S", SPR_CPUCFGR_OV64S },
+ { NULL, 0 } };
+
+/* dmmucfgr register */
+static const struct spr_bit_def spr_dmmucfgr[] = {
+ { "DMMUCFGR_NTW", SPR_DMMUCFGR_NTW },
+ { "DMMUCFGR_NTS", SPR_DMMUCFGR_NTS },
+ { "DMMUCFGR_NAE", SPR_DMMUCFGR_NAE },
+ { "DMMUCFGR_CRI", SPR_DMMUCFGR_CRI },
+ { "DMMUCFGR_PRI", SPR_DMMUCFGR_PRI },
+ { "DMMUCFGR_TEIRI", SPR_DMMUCFGR_TEIRI },
+ { "DMMUCFGR_HTR", SPR_DMMUCFGR_HTR },
+ { NULL, 0 } };
+
+/* immucfgr register */
+static const struct spr_bit_def spr_immucfgr[] = {
+ { "IMMUCFGR_NTW", SPR_IMMUCFGR_NTW },
+ { "IMMUCFGR_NTS", SPR_IMMUCFGR_NTS },
+ { "IMMUCFGR_NAE", SPR_IMMUCFGR_NAE },
+ { "IMMUCFGR_CRI", SPR_IMMUCFGR_CRI },
+ { "IMMUCFGR_PRI", SPR_IMMUCFGR_PRI },
+ { "IMMUCFGR_TEIRI", SPR_IMMUCFGR_TEIRI },
+ { "IMMUCFGR_HTR", SPR_IMMUCFGR_HTR },
+ { NULL, 0 } };
+
+/* dccfgr register */
+static const struct spr_bit_def spr_dccfgr[] = {
+ { "DCCFGR_NCW", SPR_DCCFGR_NCW },
+ { "DCCFGR_NCS", SPR_DCCFGR_NCS },
+ { "DCCFGR_CBS", SPR_DCCFGR_CBS },
+ { "DCCFGR_CWS", SPR_DCCFGR_CWS },
+ { "DCCFGR_CCRI", SPR_DCCFGR_CCRI },
+ { "DCCFGR_CBIRI", SPR_DCCFGR_CBIRI },
+ { "DCCFGR_CBPRI", SPR_DCCFGR_CBPRI },
+ { "DCCFGR_CBLRI", SPR_DCCFGR_CBLRI },
+ { "DCCFGR_CBFRI", SPR_DCCFGR_CBFRI },
+ { "DCCFGR_CBWBRI", SPR_DCCFGR_CBWBRI },
+ { NULL, 0 } };
+
+/* iccfgr register */
+static const struct spr_bit_def spr_iccfgr[] = {
+ { "ICCFGR_NCW", SPR_ICCFGR_NCW },
+ { "ICCFGR_NCS", SPR_ICCFGR_NCS },
+ { "ICCFGR_CBS", SPR_ICCFGR_CBS },
+ { "ICCFGR_CCRI", SPR_ICCFGR_CCRI },
+ { "ICCFGR_CBIRI", SPR_ICCFGR_CBIRI },
+ { "ICCFGR_CBPRI", SPR_ICCFGR_CBPRI },
+ { "ICCFGR_CBLRI", SPR_ICCFGR_CBLRI },
+ { NULL, 0 } };
+
+/* DCFGR register */
+static const struct spr_bit_def spr_dcfgr[] = {
+ { "DCFGR_NDP", SPR_DCFGR_NDP },
+ { "DCFGR_WPCI", SPR_DCFGR_WPCI },
+ { NULL, 0 } };
+
+/* System group */
+static const struct spr_def spr_sys_group[] = {
+ /* 000-000 */ { 0x000, 0x000, "SPR_VR", spr_vr },
+ /* 001-001 */ { 0x001, 0x001, "SPR_UPR", spr_upr },
+ /* 002-002 */ { 0x002, 0x002, "SPR_CPUCFGR", spr_cpucfgr }, /* JPB */
+ /* 003-003 */ { 0x003, 0x003, "SPR_DMMUCFGR", spr_dmmucfgr },
+ /* 004-004 */ { 0x004, 0x004, "SPR_IMMUCFGR", spr_immucfgr },
+ /* 005-005 */ { 0x005, 0x005, "SPR_DCCFGR", spr_dccfgr },
+ /* 006-006 */ { 0x006, 0x006, "SPR_ICCFGR", spr_iccfgr },
+ /* 007-007 */ { 0x007, 0x007, "SPR_DCFGR", spr_dcfgr }, /* JPB */
+ /* 010-010 */ { 0x010, 0x010, "SPR_NPC", spr_one_val },
+ /* 011-011 */ { 0x011, 0x011, "SPR_SR", spr_sr },
+ /* 012-012 */ { 0x012, 0x012, "SPR_PPC", spr_one_val },
+ /* 020-02f */ { 0x020, 0x02f, "SPR_EPCR(%i)", spr_one_val },
+ /* 030-03f */ { 0x030, 0x03f, "SPR_EEAR(%i)", spr_one_val },
+ /* 040-04f */ { 0x040, 0x04f, "SPR_ESR(%i)", spr_sr },
+ /* 400-41f */ { 0x400, 0x41f, "GPR(%i)", spr_one_val },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*-----------------------------------------------------------[ DMMU group ]---*/
+/* Data MMU conrtol reg */
+static const struct spr_bit_def spr_dmmucr[] = {
+ { "DMMUCR_P2S", SPR_DMMUCR_P2S },
+ { "DMMUCR_P1S", SPR_DMMUCR_P1S },
+ { "DMMUCR_VADDR_WIDTH", SPR_DMMUCR_VADDR_WIDTH },
+ { "DMMUCR_PADDR_WIDTH", SPR_DMMUCR_PADDR_WIDTH },
+ { NULL, 0 } };
+
+/* dtlbmr register */
+static const struct spr_bit_def spr_dtlbmr[] = {
+ { "DTLBMR_V", SPR_DTLBMR_V },
+ { "DTLBMR_PL1", SPR_DTLBMR_PL1 },
+ { "DTLBMR_CID", SPR_DTLBMR_CID },
+ { "DTLBMR_LRU", SPR_DTLBMR_LRU },
+ { "DTLBMR_VPN", SPR_DTLBMR_VPN },
+ { NULL, 0 } };
+
+/* dtlbtr register */
+static const struct spr_bit_def spr_dtlbtr[] = {
+ { "DTLBTR_CC", SPR_DTLBTR_CC },
+ { "DTLBTR_CI", SPR_DTLBTR_CI },
+ { "DTLBTR_WBC", SPR_DTLBTR_WBC },
+ { "DTLBTR_WOM", SPR_DTLBTR_WOM },
+ { "DTLBTR_A", SPR_DTLBTR_A },
+ { "DTLBTR_D", SPR_DTLBTR_D },
+ { "DTLBTR_URE", SPR_DTLBTR_URE },
+ { "DTLBTR_UWE", SPR_DTLBTR_UWE },
+ { "DTLBTR_SRE", SPR_DTLBTR_SRE },
+ { "DTLBTR_SWE", SPR_DTLBTR_SWE },
+ { "DTLBTR_PPN", SPR_DTLBTR_PPN },
+ { NULL, 0 } };
+
+/* DMMU group */
+static const struct spr_def spr_dmmu_group[] = {
+ /* 000-000 */ { 0, 0, "SPR_DMMUCR", spr_dmmucr },
+ /* 200-27f */ { 0x200, 0x27f, "SPR_DTLBMR way 0 set %i", spr_dtlbmr },
+ /* 280-2ff */ { 0x280, 0x2ff, "SPR_DTLBTR way 0 set %i", spr_dtlbtr },
+ /* 300-37f */ { 0x300, 0x37f, "SPR_DTLBMR way 1 set %i", spr_dtlbmr },
+ /* 380-3ff */ { 0x380, 0x3ff, "SPR_DTLBTR way 1 set %i", spr_dtlbtr },
+ /* 400-47f */ { 0x400, 0x47f, "SPR_DTLBMR way 2 set %i", spr_dtlbmr },
+ /* 480-4ff */ { 0x480, 0x4ff, "SPR_DTLBTR way 2 set %i", spr_dtlbtr },
+ /* 500-57f */ { 0x500, 0x57f, "SPR_DTLBMR way 3 set %i", spr_dtlbmr },
+ /* 580-5ff */ { 0x580, 0x5ff, "SPR_DTLBTR way 3 set %i", spr_dtlbtr },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*-----------------------------------------------------------[ IMMU group ]---*/
+/* Instruction MMU conrtol reg */
+static const struct spr_bit_def spr_immucr[] = {
+ { "IMMUCR_P2S", SPR_IMMUCR_P2S },
+ { "IMMUCR_P1S", SPR_IMMUCR_P1S },
+ { "IMMUCR_VADDR_WIDTH", SPR_IMMUCR_VADDR_WIDTH },
+ { "IMMUCR_PADDR_WIDTH", SPR_IMMUCR_PADDR_WIDTH },
+ { NULL, 0 } };
+
+/* itlbmr register */
+static const struct spr_bit_def spr_itlbmr[] = {
+ { "ITLBMR_V", SPR_ITLBMR_V },
+ { "ITLBMR_PL1", SPR_ITLBMR_PL1 },
+ { "ITLBMR_CID", SPR_ITLBMR_CID },
+ { "ITLBMR_LRU", SPR_ITLBMR_LRU },
+ { "ITLBMR_VPN", SPR_ITLBMR_VPN },
+ { NULL, 0 } };
+
+/* itlbtr register */
+static const struct spr_bit_def spr_itlbtr[] = {
+ { "ITLBTR_CC", SPR_ITLBTR_CC },
+ { "ITLBTR_CI", SPR_ITLBTR_CI },
+ { "ITLBTR_WBC", SPR_ITLBTR_WBC },
+ { "ITLBTR_WOM", SPR_ITLBTR_WOM },
+ { "ITLBTR_A", SPR_ITLBTR_A },
+ { "ITLBTR_D", SPR_ITLBTR_D },
+ { "ITLBTR_URE", SPR_ITLBTR_SXE },
+ { "ITLBTR_UWE", SPR_ITLBTR_UXE },
+ { "ITLBTR_PPN", SPR_ITLBTR_PPN },
+ { NULL, 0 } };
+
+/* IMMU group */
+static const struct spr_def spr_immu_group[] = {
+ /* 000-000 */ { 0, 0, "SPR_IMMUCR", spr_immucr },
+ /* 200-27f */ { 0x200, 0x27f, "SPR_ITLBMR way 0 set %i", spr_itlbmr },
+ /* 280-2ff */ { 0x280, 0x2ff, "SPR_ITLBTR way 0 set %i", spr_itlbtr },
+ /* 300-37f */ { 0x300, 0x37f, "SPR_ITLBMR way 1 set %i", spr_itlbmr },
+ /* 380-3ff */ { 0x380, 0x3ff, "SPR_ITLBTR way 1 set %i", spr_itlbtr },
+ /* 400-47f */ { 0x400, 0x47f, "SPR_ITLBMR way 2 set %i", spr_itlbmr },
+ /* 480-4ff */ { 0x480, 0x4ff, "SPR_ITLBTR way 2 set %i", spr_itlbtr },
+ /* 500-57f */ { 0x500, 0x57f, "SPR_ITLBMR way 3 set %i", spr_itlbmr },
+ /* 580-5ff */ { 0x580, 0x5ff, "SPR_ITLBTR way 3 set %i", spr_itlbtr },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*-----------------------------------------------------[ Data cache group ]---*/
+static const struct spr_bit_def spr_dccr[] = {
+ { "DCCR_EW", SPR_DCCR_EW },
+ { NULL, 0 } };
+
+static const struct spr_def spr_dc_group[] = {
+ /* 000-000 */ { 0x000, 0x000, "SPR_DCCR", spr_dccr },
+ /* 001-001 */ { 0x001, 0x001, "SPR_DCBPR", spr_one_val },
+ /* 002-002 */ { 0x002, 0x002, "SPR_DCBFR", spr_one_val },
+ /* 003-003 */ { 0x003, 0x003, "SPR_DCBIR", spr_one_val },
+ /* 004-004 */ { 0x004, 0x004, "SPR_DCBWR", spr_one_val },
+ /* 005-005 */ { 0x005, 0x005, "SPR_DCBLR", spr_one_val },
+ /* 200-3ff */ { 0x200, 0x3ff, "SPR_DCR way 0 set %i", spr_one_val },
+ /* 400-5ff */ { 0x400, 0x5ff, "SPR_DCR way 1 set %i", spr_one_val },
+ /* 600-7ff */ { 0x600, 0x7ff, "SPR_DCR way 2 set %i", spr_one_val },
+ /* 800-9ff */ { 0x800, 0x9ff, "SPR_DCR way 3 set %i", spr_one_val },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*----------------------------------------------[ Instruction cache group ]---*/
+static const struct spr_bit_def spr_iccr[] = {
+ { "ICCR_EW", SPR_ICCR_EW },
+ { NULL, 0 } };
+
+static const struct spr_def spr_ic_group[] = {
+ /* 000-000 */ { 0x000, 0x000, "SPR_ICCR", spr_iccr },
+ /* 001-001 */ { 0x001, 0x001, "SPR_ICBPR", spr_one_val },
+ /* 002-002 */ { 0x002, 0x002, "SPR_ICBFR", spr_one_val },
+ /* 003-003 */ { 0x003, 0x003, "SPR_ICBIR", spr_one_val },
+ /* 200-3ff */ { 0x200, 0x3ff, "SPR_ICR way 0 set %i", spr_one_val },
+ /* 400-5ff */ { 0x400, 0x5ff, "SPR_ICR way 1 set %i", spr_one_val },
+ /* 600-7ff */ { 0x600, 0x7ff, "SPR_ICR way 2 set %i", spr_one_val },
+ /* 800-9ff */ { 0x800, 0x9ff, "SPR_ICR way 3 set %i", spr_one_val },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*------------------------------------------------------------[ MAC group ]---*/
+static const struct spr_def spr_mac_group[] = {
+ /* 1-1 */ { 0x1, 0x1, "SPR_MACLO", spr_one_val },
+ /* 2-2 */ { 0x2, 0x2, "SPR_MACHI", spr_one_val },
+ /* ------- */ { -1, -1, NULL, NULL } };
+
+/*----------------------------------------------------------[ Debug group ]---*/
+/* dmr1 register */
+static const struct spr_bit_def spr_dmr1[] = {
+ { "DMR1_CW0", SPR_DMR1_CW0 },
+ { "DMR1_CW1", SPR_DMR1_CW1 },
+ { "DMR1_CW2", SPR_DMR1_CW2 },
+ { "DMR1_CW3", SPR_DMR1_CW3 },
+ { "DMR1_CW4", SPR_DMR1_CW4 },
+ { "DMR1_CW5", SPR_DMR1_CW5 },
+ { "DMR1_CW6", SPR_DMR1_CW6 },
+ { "DMR1_CW7", SPR_DMR1_CW7 },
+ { "DMR1_CW8", SPR_DMR1_CW8 },
+ { "DMR1_CW9", SPR_DMR1_CW9 },
+ { "DMR1_RES1", SPR_DMR1_RES1 },
+ { "DMR1_ST", SPR_DMR1_ST },
+ { "DMR1_BT", SPR_DMR1_BT },
+ { "DMR1_RES2", SPR_DMR1_RES2 },
+ { NULL, 0 } };
+
+/* dmr2 register */
+static const struct spr_bit_def spr_dmr2[] = {
+ { "DMR2_WCE0", SPR_DMR2_WCE0 },
+ { "DMR2_WCE1", SPR_DMR2_WCE1 },
+ { "DMR2_AWTC", SPR_DMR2_AWTC },
+ { "DMR2_WGB", SPR_DMR2_WGB },
+ { "DMR2_WBS", SPR_DMR2_WBS }, /* JPB */
+ { NULL, 0 } };
+
+/* dwcr register */
+static const struct spr_bit_def spr_dwcr[] = {
+ { "DWCR_COUNT", SPR_DWCR_COUNT },
+ { "DWCR_MATCH", SPR_DWCR_MATCH },
+ { NULL, 0 } };
+
+/* dsr register */
+static const struct spr_bit_def spr_dsr[] = {
+ { "DSR_RSTE", SPR_DSR_RSTE },
+ { "DSR_BUSE", SPR_DSR_BUSEE },
+ { "DSR_DPFE", SPR_DSR_DPFE },
+ { "DSR_IPFE", SPR_DSR_IPFE },
+ { "DSR_TTE", SPR_DSR_TTE },
+ { "DSR_AE", SPR_DSR_AE },
+ { "DSR_IIE", SPR_DSR_IIE },
+ { "DSR_IE", SPR_DSR_IE },
+ { "DSR_DME", SPR_DSR_DME },
+ { "DSR_IME", SPR_DSR_IME },
+ { "DSR_RE", SPR_DSR_RE },
+ { "DSR_SCE", SPR_DSR_SCE },
+ { "DSR_SSE", SPR_DSR_SSE },
+ { "DSR_TE", SPR_DSR_TE },
+ { NULL, 0 } };
+
+/* drr register */
+static const struct spr_bit_def spr_drr[] = {
+ { "DRR_RSTE", SPR_DRR_RSTE },
+ { "DRR_BUSE", SPR_DRR_BUSEE },
+ { "DRR_DPFE", SPR_DRR_DPFE },
+ { "DRR_IPFE", SPR_DRR_IPFE },
+ { "DRR_TTE", SPR_DRR_TTE },
+ { "DRR_AE", SPR_DRR_AE },
+ { "DRR_IIE", SPR_DRR_IIE },
+ { "DRR_IE", SPR_DRR_IE },
+ { "DRR_DME", SPR_DRR_DME },
+ { "DRR_IME", SPR_DRR_IME },
+ { "DRR_RE", SPR_DRR_RE },
+ { "DRR_SCE", SPR_DRR_SCE },
+ { "DRR_TE", SPR_DRR_TE },
+ { NULL, 0 } };
+
+/* Debug group */
+static const struct spr_def spr_d_group[] = {
+#if 0
+ /* 00-07 */ { 0x00, 0x07, "SPR_DVR(%i)", spr_dvr },
+ /* 08-0f */ { 0x08, 0x0f, "SPR_DCR(%i)", spr_dcr },
+#endif
+ /* 10-10 */ { 0x10, 0x10, "SPR_DMR1", spr_dmr1 },
+ /* 11-11 */ { 0x11, 0x11, "SPR_DMR2", spr_dmr2 },
+ /* 12-12 */ { 0x12, 0x12, "SPR_DWCR0", spr_dwcr },
+ /* 13-13 */ { 0x13, 0x13, "SPR_DWCR1", spr_dwcr },
+ /* 14-14 */ { 0x14, 0x14, "SPR_DSR", spr_dsr },
+ /* 15-15 */ { 0x15, 0x15, "SPR_DRR", spr_drr },
+ /* ----- */ { -1, -1, NULL, NULL } };
+
+/*-------------------------------------------[ Performance counters group ]---*/
+static const struct spr_bit_def spr_pcmr[] = {
+ { "PCMR_CP", SPR_PCMR_CP },
+ { "PCMR_UMRA", SPR_PCMR_UMRA },
+ { "PCMR_CISM", SPR_PCMR_CISM },
+ { "PCMR_CIUM", SPR_PCMR_CIUM },
+ { "PCMR_LA", SPR_PCMR_LA },
+ { "PCMR_SA", SPR_PCMR_SA },
+ { "PCMR_IF", SPR_PCMR_IF },
+ { "PCMR_DCM", SPR_PCMR_DCM },
+ { "PCMR_ICM", SPR_PCMR_ICM },
+ { "PCMR_IFS", SPR_PCMR_IFS },
+ { "PCMR_LSUS", SPR_PCMR_LSUS },
+ { "PCMR_BS", SPR_PCMR_BS },
+ { "PCMR_DTLBM", SPR_PCMR_DTLBM },
+ { "PCMR_ITLBM", SPR_PCMR_ITLBM },
+ { "PCMR_DDS", SPR_PCMR_DDS },
+ { "PCMR_WPE", SPR_PCMR_WPE },
+ { NULL, 0 } };
+
+static const struct spr_def spr_pc_group[] = {
+ /* 00-07 */ { 0x00, 0x07, "PCCR", spr_one_val },
+ /* 08-0f */ { 0x08, 0x0f, "PCMR", spr_pcmr },
+ /* ----- */ { -1, -1, NULL, NULL } };
+
+/*------------------------------------------------[ Power managment group ]---*/
+static const struct spr_bit_def spr_pmr[] = {
+ { "PMR_SDF", SPR_PMR_SDF },
+ { "PMR_DME", SPR_PMR_DME },
+ { "PMR_SME", SPR_PMR_SME },
+ { "PMR_DCGE", SPR_PMR_DCGE },
+ { "PMR_SUME", SPR_PMR_SUME },
+ { NULL, 0 } };
+
+static const struct spr_def spr_pm_group[] = {
+ /* 0-0 */ { 0x0, 0x0, "SPR_PMR", spr_pmr },
+ /* --- */ { -1, -1, NULL, NULL } };
+
+/*------------------------------------------------------------[ PIC group ]---*/
+/* picmr register */
+static const struct spr_bit_def spr_picmr[] = {
+ { "PICMR_IUM", SPR_PICMR_IUM },
+ { NULL, 0 } };
+
+static const struct spr_def spr_pic_group[] = {
+ /* 0-0 */ { 0, 0, "PICMR", spr_picmr },
+ /* 2-2 */ { 2, 2, "PICSR", spr_one_val },
+ /* --- */ { -1, -1, NULL, NULL } };
+
+/*-----------------------------------------------------[ Tick timer group ]---*/
+static const struct spr_bit_def spr_ttmr[] = {
+ { "TTMR_PERIOD", SPR_TTMR_PERIOD },
+ { "TTMR_IP", SPR_TTMR_IP },
+ { "TTMR_IE", SPR_TTMR_IE },
+ { "TTMR_M", SPR_TTMR_M },
+ { NULL, 0 } };
+
+static const struct spr_def spr_tt_group[] = {
+ /* 0-0 */ { 0, 0, "TTMR", spr_ttmr },
+ /* 1-1 */ { 0, 0, "TTCR", spr_one_val },
+ /* --- */ { -1, -1, NULL, NULL } };
+
+/* Spr groups */
+static const struct spr_def *spr_groups[] = {
+ /* 00 */ spr_sys_group,
+ /* 01 */ spr_dmmu_group,
+ /* 02 */ spr_immu_group,
+ /* 03 */ spr_dc_group,
+ /* 04 */ spr_ic_group,
+ /* 05 */ spr_mac_group,
+ /* 06 */ spr_d_group,
+ /* 07 */ spr_pc_group,
+ /* 08 */ spr_pm_group,
+ /* 09 */ spr_pic_group,
+ /* 0a */ spr_tt_group };
+
+/* Should be long enough for everything */
+static char ret_spr[1000];
+
+/* Dumps the given spr in nice, human readable form */
+char *dump_spr(uint16_t spr, uorreg_t spr_val)
+{
+ const struct spr_def *spr_def;
+ uint16_t spr_in_group = spr & (MAX_SPRS_PER_GRP - 1);
+ uint16_t spr_group = spr >> MAX_SPRS_PER_GRP_BITS;
+ const struct spr_bit_def *spr_bit_def;
+
+ int first_bit = 1;
+ int i;
+ uorreg_t tmp;
+
+ spr_def = spr_groups[spr_group];
+
+ /* Find the given spr */
+ for(; spr_def->from_spr != 0xffff; spr_def++) {
+ if((spr_def->from_spr <= spr_in_group) && (spr_def->to_spr >= spr_in_group))
+ break;
+ }
+
+ if(spr_def->from_spr == 0xffff) {
+ sprintf(ret_spr, "Spr %"PRIx16", group %"PRIx16" = 0x%"PRIxREG"\n",
+ spr_in_group, spr_group, spr_val);
+ return ret_spr;
+ }
+
+ /* Decode the spr bits and show them in a pretty format */
+ if(spr_def->from_spr == spr_def->to_spr)
+ sprintf(ret_spr, "%s", spr_def->name);
+ else
+ sprintf(ret_spr, spr_def->name, spr_in_group - spr_def->from_spr);
+ strcat(ret_spr, " = ");
+
+ /* First get all the single-bit bit fields and dump them */
+ for(spr_bit_def = spr_def->bits; spr_bit_def->name; spr_bit_def++) {
+ if(!is_power2(spr_bit_def->mask))
+ continue;
+
+ if(!(spr_bit_def->mask & spr_val))
+ continue;
+
+ if(!first_bit)
+ strcat(ret_spr, " | ");
+ else
+ first_bit = 0;
+ strcat(ret_spr, spr_bit_def->name);
+ }
+
+ /* Now dump all the multi-bit bit fields */
+ for(spr_bit_def = spr_def->bits; spr_bit_def->name; spr_bit_def++) {
+ if(is_power2(spr_bit_def->mask))
+ continue;
+ if(!first_bit)
+ strcat(ret_spr, " | ");
+ else
+ first_bit = 0;
+ for(tmp = spr_bit_def->mask, i = 0; !(tmp & 1); i++)
+ tmp >>= 1;
+
+ sprintf(ret_spr, "%s%s = %" PRIxREG, ret_spr, spr_bit_def->name,
+ (spr_val >> i) & tmp);
+ }
+ return ret_spr;
+}
+
Index: or1k/sprs.c
===================================================================
--- or1k/sprs.c (nonexistent)
+++ or1k/sprs.c (revision 1765)
@@ -0,0 +1,258 @@
+/* sprs.c -- Simulation of OR1K special-purpose registers
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+#include "port.h"
+
+/* System includes */
+#include
+#include
+#include
+
+/* Package includes */
+#include "sprs.h"
+#include "sim-config.h"
+#include "debug.h"
+#include "execute.h"
+#include "spr-defs.h"
+#include "tick.h"
+#include "dcache-model.h"
+#include "icache-model.h"
+#include "dmmu.h"
+#include "immu.h"
+#include "toplevel-support.h"
+#include "pic.h"
+
+
+DECLARE_DEBUG_CHANNEL(immu);
+
+static int audio_cnt = 0;
+
+static FILE *fo = 0;
+
+/* Set a specific SPR with a value. */
+void mtspr(uint16_t regno, const uorreg_t value)
+{
+ uorreg_t prev_val;
+
+ prev_val = cpu_state.sprs[regno];
+ cpu_state.sprs[regno] = value;
+
+ /* MM: Register hooks. */
+ switch (regno) {
+ case SPR_TTCR:
+ spr_write_ttcr (value);
+ break;
+ case SPR_TTMR:
+ spr_write_ttmr (prev_val);
+ break;
+ /* Data cache simulateing stuff */
+ case SPR_DCBPR:
+ /* FIXME: This is not correct. The arch. manual states: "Memory accesses
+ * are not recorded (Unlike load or store instructions) and cannot invoke
+ * any exception". If the physical address is invalid a bus error will be
+ * generated. Also if the effective address is not resident in the mmu
+ * the read will happen from address 0, which is naturally not correct. */
+ dc_simulate_read(peek_into_dtlb(value, 0, 1), value, 4);
+ cpu_state.sprs[SPR_DCBPR] = 0;
+ break;
+ case SPR_DCBFR:
+ dc_inv(value);
+ cpu_state.sprs[SPR_DCBFR] = -1;
+ break;
+ case SPR_DCBIR:
+ dc_inv(value);
+ cpu_state.sprs[SPR_DCBIR] = 0;
+ break;
+ case SPR_DCBWR:
+ cpu_state.sprs[SPR_DCBWR] = 0;
+ break;
+ case SPR_DCBLR:
+ cpu_state.sprs[SPR_DCBLR] = 0;
+ break;
+ /* Instruction cache simulateing stuff */
+ case SPR_ICBPR:
+ /* FIXME: The arch manual does not say what happens when an invalid memory
+ * location is specified. I guess the same as for the DCBPR register */
+ ic_simulate_fetch(peek_into_itlb(value), value);
+ cpu_state.sprs[SPR_ICBPR] = 0;
+ break;
+ case SPR_ICBIR:
+ ic_inv(value);
+ cpu_state.sprs[SPR_ICBIR] = 0;
+ break;
+ case SPR_ICBLR:
+ cpu_state.sprs[SPR_ICBLR] = 0;
+ break;
+ case SPR_SR:
+ cpu_state.sprs[regno] |= SPR_SR_FO;
+ if((value & SPR_SR_IEE) && !(prev_val & SPR_SR_IEE))
+ pic_ints_en();
+#if DYNAMIC_EXECUTION
+ if((value & SPR_SR_IME) && !(prev_val & SPR_SR_IME)) {
+ TRACE_(immu)("IMMU just became enabled (%lli).\n", runtime.sim.cycles);
+ recheck_immu(IMMU_GOT_ENABLED);
+ } else if(!(value & SPR_SR_IME) && (prev_val & SPR_SR_IME)) {
+ TRACE_(immu)("Remove counting of mmu hit delay with cycles (%lli)\n",
+ runtime.sim.cycles);
+ recheck_immu(IMMU_GOT_DISABLED);
+ }
+#endif
+ break;
+ case SPR_NPC:
+ {
+ /* The debugger has redirected us to a new address */
+ /* This is usually done to reissue an instruction
+ which just caused a breakpoint exception. */
+ cpu_state.pc = value;
+
+ if(!value && config.sim.verbose)
+ PRINTF("WARNING: PC just set to 0!\n");
+
+ /* Clear any pending delay slot jumps also */
+ cpu_state.delay_insn = 0;
+ pcnext = value + 4;
+ }
+ break;
+ case SPR_PICSR:
+ if(!config.pic.edge_trigger)
+ cpu_state.sprs[SPR_PICSR] = prev_val;
+ break;
+ case SPR_PICMR:
+ if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
+ pic_ints_en();
+ break;
+ case 0xFFFD:
+ fo = fopen ("audiosim.pcm", "wb+");
+ if (!fo) PRINTF("Cannot open audiosim.pcm\n");
+ PRINTF("Audio opened.\n");
+ break;
+ case 0xFFFE:
+ if (!fo) PRINTF("audiosim.pcm not opened\n");
+ fputc (value & 0xFF, fo);
+ if ((audio_cnt % 1024) == 0)
+ PRINTF("%i\n", audio_cnt);
+ audio_cnt++;
+ break;
+ case 0xFFFF:
+ fclose(fo);
+ PRINTF("Audio closed.\n");
+ sim_done();
+ break;
+ case SPR_PMR:
+ /* PMR[SDF] and PMR[DCGE] are ignored completely. */
+ if (config.pm.enabled && (value & SPR_PMR_SUME)) {
+ PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
+ sim_done();
+ }
+ break;
+ default:
+ /* Mask reserved bits in DTLBMR and DTLBMR registers */
+ if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
+ if((regno & 0xff) < 0x80)
+ cpu_state.sprs[regno] = DADDR_PAGE(value) |
+ (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
+ else
+ cpu_state.sprs[regno] = DADDR_PAGE(value) |
+ (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
+ SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
+ SPR_DTLBTR_SWE));
+ }
+
+ /* Mask reseved bits in ITLBMR and ITLBMR registers */
+ if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
+ if((regno & 0xff) < 0x80)
+ cpu_state.sprs[regno] = IADDR_PAGE(value) |
+ (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
+ else
+ cpu_state.sprs[regno] = IADDR_PAGE(value) |
+ (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
+ SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
+
+#if DYNAMIC_EXECUTION
+ if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
+ /* The immu got reconfigured. Recheck if the current page in execution
+ * is resident in the immu ways. This check would be done during the
+ * instruction fetch but since the dynamic execution model does not do
+ * instruction fetchs, do it now. */
+ recheck_immu(0);
+ }
+#endif
+ }
+
+ /* Links to GPRS */
+ if(regno >= 0x0400 && regno < 0x0420) {
+ cpu_state.reg[regno - 0x0400] = value;
+ }
+ break;
+ }
+}
+
+/* Get a specific SPR. */
+uorreg_t mfspr(const uint16_t regno)
+{
+ uorreg_t ret;
+
+ ret = cpu_state.sprs[regno];
+
+ switch (regno) {
+ case SPR_NPC:
+ ret = cpu_state.pc;
+ break;
+ case SPR_TTCR:
+ ret = spr_read_ttcr();
+ break;
+ default:
+ /* Links to GPRS */
+ if(regno >= 0x0400 && regno < 0x0420)
+ ret = cpu_state.reg[regno - 0x0400];
+ }
+
+ return ret;
+}
+
+/* Show status of important SPRs. */
+void sprs_status(void)
+{
+ PRINTF("VR : 0x%"PRIxREG" UPR : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
+ cpu_state.sprs[SPR_UPR]);
+ PRINTF("SR : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
+ PRINTF("MACLO: 0x%"PRIxREG" MACHI: 0x%"PRIxREG"\n",
+ cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
+ PRINTF("EPCR0: 0x%"PRIxADDR" EPCR1: 0x%"PRIxADDR"\n",
+ cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
+ PRINTF("EEAR0: 0x%"PRIxADDR" EEAR1: 0x%"PRIxADDR"\n",
+ cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
+ PRINTF("ESR0 : 0x%"PRIxREG" ESR1 : 0x%"PRIxREG"\n",
+ cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
+ PRINTF("TTMR : 0x%"PRIxREG" TTCR : 0x%"PRIxREG"\n",
+ cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
+ PRINTF("PICMR: 0x%"PRIxREG" PICSR: 0x%"PRIxREG"\n",
+ cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
+ PRINTF("PPC: 0x%"PRIxADDR" NPC : 0x%"PRIxADDR"\n",
+ cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
+}
Index: or1k/except.c
===================================================================
--- or1k/except.c (nonexistent)
+++ or1k/except.c (revision 1765)
@@ -0,0 +1,161 @@
+/* except.c -- Simulation of OR1K exceptions
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+/* Autoconf and/or portability configuration */
+#include "config.h"
+
+/* Package includes */
+#include "except.h"
+#include "sim-config.h"
+#include "arch.h"
+#include "debug.h"
+#include "spr-defs.h"
+#include "execute.h"
+#include "debug-unit.h"
+
+#if DYNAMIC_EXECUTION
+#include "sched.h"
+#include "op-support.h"
+#endif
+
+extern void op_join_mem_cycles(void);
+
+
+
+int except_pending = 0;
+
+/* Asserts OR1K exception. */
+/* WARNING: Don't expect except_handle to return. Sometimes it _may_ return at
+ * other times it may not. */
+void
+except_handle (oraddr_t except, oraddr_t ea)
+{
+ oraddr_t except_vector;
+
+ if (debug_ignore_exception (except))
+ return;
+
+#if !(DYNAMIC_EXECUTION)
+ /* In the dynamic recompiler, this function never returns, so this is not
+ * needed. Ofcourse we could set it anyway, but then all code that checks
+ * this variable would break, since it is never reset */
+ except_pending = 1;
+#endif
+
+ except_vector =
+ except + (cpu_state.sprs[SPR_SR] & SPR_SR_EPH ? 0xf0000000 : 0x00000000);
+
+#if !(DYNAMIC_EXECUTION)
+ pcnext = except_vector;
+#endif
+
+ cpu_state.sprs[SPR_EEAR_BASE] = ea;
+ cpu_state.sprs[SPR_ESR_BASE] = cpu_state.sprs[SPR_SR];
+
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_OVE; /* Disable overflow flag exception. */
+
+ cpu_state.sprs[SPR_SR] |= SPR_SR_SM; /* SUPV mode */
+ cpu_state.sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE); /* Disable interrupts. */
+
+ /* Address translation is always disabled when starting exception. */
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_DME;
+
+#if DYNAMIC_EXECUTION
+ /* If we were called from do_scheduler and there were more jobs scheduled to
+ * run after this, they won't run unless the following call is made since this
+ * function never returns. (If we weren't called from do_scheduler, then the
+ * job at the head of the queue will still have some time remaining) */
+ if (scheduler.job_queue->time <= 0)
+ do_scheduler ();
+#endif
+
+ switch (except)
+ {
+ /* EPCR is irrelevent */
+ case EXCEPT_RESET:
+ break;
+ /* EPCR is loaded with address of instruction that caused the exception */
+ case EXCEPT_ITLBMISS:
+ case EXCEPT_IPF:
+ cpu_state.sprs[SPR_EPCR_BASE] = ea - (cpu_state.delay_insn ? 4 : 0);
+#if DYNAMIC_EXECUTION
+ op_join_mem_cycles ();
+#endif
+ break;
+ case EXCEPT_BUSERR:
+ case EXCEPT_DPF:
+ case EXCEPT_ALIGN:
+ case EXCEPT_ILLEGAL:
+ case EXCEPT_DTLBMISS:
+ case EXCEPT_RANGE:
+ case EXCEPT_TRAP:
+ /* All these exceptions happen during a simulated instruction */
+#if DYNAMIC_EXECUTION
+ /* Since these exceptions happen during a simulated instruction and this
+ * function jumps out to the exception vector the scheduler would never have
+ * a chance to run, therefore run it now */
+ run_sched_out_of_line ();
+#endif
+ cpu_state.sprs[SPR_EPCR_BASE] =
+ cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
+ break;
+ /* EPCR is loaded with address of next not-yet-executed instruction */
+ case EXCEPT_SYSCALL:
+ cpu_state.sprs[SPR_EPCR_BASE] =
+ (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0);
+ break;
+ /* These exceptions happen AFTER (or before) an instruction has been
+ * simulated, therefore the pc already points to the *next* instruction */
+ case EXCEPT_TICK:
+ case EXCEPT_INT:
+ cpu_state.sprs[SPR_EPCR_BASE] =
+ cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
+#if !(DYNAMIC_EXECUTION)
+ /* If we don't update the pc now, then it will only happen *after* the next
+ * instruction (There would be serious problems if the next instruction just
+ * happens to be a branch), when it should happen NOW. */
+ cpu_state.pc = pcnext;
+ pcnext += 4;
+#endif
+ break;
+ }
+
+ /* Address trnaslation is here because run_sched_out_of_line calls
+ * eval_insn_direct which checks out the immu for the address translation but
+ * if it would be disabled above then there would be not much point... */
+ cpu_state.sprs[SPR_SR] &= ~SPR_SR_IME;
+
+ /* Complex/simple execution strictly don't need this because of the
+ * next_delay_insn thingy but in the dynamic execution modell that doesn't
+ * exist and thus cpu_state.delay_insn would stick in the exception handler
+ * causeing grief if the first instruction of the exception handler is also in
+ * the delay slot of the previous instruction */
+ cpu_state.delay_insn = 0;
+
+#if DYNAMIC_EXECUTION
+ do_jump (except_vector);
+#endif
+}
Index: or1k/opcode/or32.h
===================================================================
--- or1k/opcode/or32.h (nonexistent)
+++ or1k/opcode/or32.h (revision 1765)
@@ -0,0 +1,217 @@
+/* Table of opcodes for the OpenRISC 1000 ISA.
+
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributed by Damjan Lampret (lampret@opencores.org).
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+ This file is also part of or1k_gen_isa, GDB and GAS.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+/* We treat all letters the same in encode/decode routines so
+ we need to assign some characteristics to them like signess etc.*/
+
+#ifndef OR32_H_ISA
+#define OR32_H_ISA
+
+#define NUM_UNSIGNED (0)
+#define NUM_SIGNED (1)
+
+#ifndef PARAMS
+#define PARAMS(x) x
+#endif
+
+#ifndef CONST
+#define CONST const
+#endif
+
+#define MAX_GPRS 32
+#define PAGE_SIZE 8192
+#undef __HALF_WORD_INSN__
+
+#define OPERAND_DELIM (',')
+
+#define OR32_IF_DELAY (1)
+#define OR32_W_FLAG (2)
+#define OR32_R_FLAG (4)
+
+#if defined(HAVE_EXECUTION)
+# if SIMPLE_EXECUTION
+# include "simpl32-defs.h"
+# elif DYNAMIC_EXECUTION
+# include "dyn32-defs.h"
+# else
+extern void l_none PARAMS((void));
+# endif
+#else
+extern void l_none PARAMS((void));
+#endif
+
+
+struct or32_letter {
+ char letter;
+ int sign;
+ /* int reloc; relocation per letter ??*/
+};
+
+enum insn_type {
+ it_unknown,
+ it_exception,
+ it_arith,
+ it_shift,
+ it_compare,
+ it_branch,
+ it_jump,
+ it_load,
+ it_store,
+ it_movimm,
+ it_move,
+ it_extend,
+ it_nop,
+ it_mac,
+ it_float };
+
+/* Main instruction specification array. */
+struct or32_opcode {
+ /* Name of the instruction. */
+ char *name;
+
+ /* A string of characters which describe the operands.
+ Valid characters are:
+ ,() Itself. Characters appears in the assembly code.
+ rA Register operand.
+ rB Register operand.
+ rD Register operand (destination).
+ I An immediate operand, range -32768 to 32767.
+ J An immediate operand, range . (unused)
+ K An immediate operand, range 0 to 65535.
+ L An immediate operand, range 0 to 63.
+ M An immediate operand, range . (unused)
+ N An immediate operand, range -33554432 to 33554431.
+ O An immediate operand, range . (unused) */
+ char *args;
+
+ /* Opcode and operand encoding. */
+ char *encoding;
+
+#ifdef HAVE_EXECUTION
+# if COMPLEX_EXECUTION
+ char *function_name;
+# elif SIMPLE_EXECUTION
+ void (*exec)(struct iqueue_entry *);
+# else /* DYNAMIC_EXECUTION */
+ void (*exec)(struct op_queue *opq, int param_t[3], int);
+# endif
+#else /* HAVE_EXECUTION */
+ void (*exec)(void);
+#endif
+
+ unsigned int flags;
+ enum insn_type func_unit;
+};
+
+/* This operand is the last in the list */
+#define OPTYPE_LAST (0x80000000)
+/* This operand marks the end of the operand sequence (for things like I(rD)) */
+#define OPTYPE_OP (0x40000000)
+/* The operand specifies a register index */
+#define OPTYPE_REG (0x20000000)
+/* The operand must be sign extended */
+#define OPTYPE_SIG (0x10000000)
+/* Operand is a relative address, the `I' in `I(rD)' */
+#define OPTYPE_DIS (0x08000000)
+/* The operand is a destination */
+#define OPTYPE_DST (0x04000000)
+/* Which bit of the operand is the sign bit */
+#define OPTYPE_SBIT (0x00001F00)
+/* Amount to shift the instruction word right to get the operand */
+#define OPTYPE_SHR (0x0000001F)
+#define OPTYPE_SBIT_SHR (8)
+
+/* MM: Data how to decode operands. */
+extern struct insn_op_struct {
+ unsigned long type;
+ unsigned long data;
+} **op_start;
+
+/* Leaf flag used in automata building */
+#define LEAF_FLAG (0x80000000)
+
+struct temp_insn_struct
+{
+ unsigned long insn;
+ unsigned long insn_mask;
+ int in_pass;
+};
+
+extern unsigned long *automata;
+extern struct temp_insn_struct *ti;
+
+extern CONST struct or32_letter or32_letters[];
+
+extern CONST struct or32_opcode or32_opcodes[];
+
+extern CONST int num_opcodes;
+
+extern char *disassembled;
+
+/* Calculates instruction length in bytes. Always 4 for OR32. */
+extern int insn_len PARAMS((int insn_index));
+
+/* Is individual insn's operand signed or unsigned? */
+extern int letter_signed PARAMS((char l));
+
+/* Number of letters in the individual lettered operand. */
+extern int letter_range PARAMS((char l));
+
+/* MM: Returns index of given instruction name. */
+extern int insn_index PARAMS((char *insn));
+
+/* MM: Returns instruction name from index. */
+extern CONST char *insn_name PARAMS ((int index));
+
+/* MM: Constructs new FSM, based on or32_opcodes. */
+extern void build_automata PARAMS ((void));
+
+/* MM: Destructs FSM. */
+extern void destruct_automata PARAMS ((void));
+
+/* MM: Decodes instruction using FSM. Call build_automata first. */
+extern int insn_decode PARAMS((unsigned int insn));
+
+/* Disassemble one instruction from insn to disassemble.
+ Return the size of the instruction. */
+int disassemble_insn (unsigned long insn);
+
+/* Disassemble one instruction from insn index.
+ Return the size of the instruction. */
+int disassemble_index (unsigned long insn, int index);
+
+/* FOR INTERNAL USE ONLY */
+/* Automatically does zero- or sign- extension and also finds correct
+ sign bit position if sign extension is correct extension. Which extension
+ is proper is figured out from letter description. */
+unsigned long extend_imm(unsigned long imm, char l);
+
+/* Extracts value from opcode */
+unsigned long or32_extract(char param_ch, char *enc_initial, unsigned long insn);
+
+#endif
+
Index: or1k/except.h
===================================================================
--- or1k/except.h (nonexistent)
+++ or1k/except.h (revision 1765)
@@ -0,0 +1,55 @@
+/* except.h -- OR1K architecture specific exceptions
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef EXCEPT__H
+#define EXCEPT__H
+
+
+/* Package includes */
+#include "arch.h"
+
+/* Definition of OR1K exceptions */
+#define EXCEPT_NONE 0x0000
+#define EXCEPT_RESET 0x0100
+#define EXCEPT_BUSERR 0x0200
+#define EXCEPT_DPF 0x0300
+#define EXCEPT_IPF 0x0400
+#define EXCEPT_TICK 0x0500
+#define EXCEPT_ALIGN 0x0600
+#define EXCEPT_ILLEGAL 0x0700
+#define EXCEPT_INT 0x0800
+#define EXCEPT_DTLBMISS 0x0900
+#define EXCEPT_ITLBMISS 0x0a00
+#define EXCEPT_RANGE 0x0b00
+#define EXCEPT_SYSCALL 0x0c00
+#define EXCEPT_FPE 0x0d00
+#define EXCEPT_TRAP 0x0e00
+
+/* Function prototypes for external use */
+extern void except_handle (oraddr_t except, oraddr_t ea);
+extern int except_pending;
+
+#endif /* EXCEPT__H */
Index: or1k/Makefile.in
===================================================================
--- or1k/Makefile.in (nonexistent)
+++ or1k/Makefile.in (revision 1765)
@@ -0,0 +1,480 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile -- Makefile for OR1K architecture dependent simulation
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = cpu/or1k
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libor1k_la_LIBADD =
+am_libor1k_la_OBJECTS = sprs.lo except.lo spr-dump.lo
+libor1k_la_OBJECTS = $(am_libor1k_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libor1k_la_SOURCES)
+DIST_SOURCES = $(libor1k_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_ARCH = @CPU_ARCH@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUGFLAGS = @DEBUGFLAGS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INCLUDES = @INCLUDES@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_SHELL = @MAKE_SHELL@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libor1k.la
+libor1k_la_SOURCES = sprs.c \
+ except.c \
+ spr-dump.c \
+ sprs.h \
+ except.h \
+ spr-dump.h \
+ arch.h \
+ spr-defs.h \
+ opcode/or32.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/or1k/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/or1k/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libor1k.la: $(libor1k_la_OBJECTS) $(libor1k_la_DEPENDENCIES)
+ $(LINK) $(libor1k_la_OBJECTS) $(libor1k_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spr-dump.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprs.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: or1k/arch.h
===================================================================
--- or1k/arch.h (nonexistent)
+++ or1k/arch.h (revision 1765)
@@ -0,0 +1,50 @@
+/* arch.h -- OR1K architecture specific macros
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef ARCH__H
+#define ARCH__H
+
+/* Autoconf and/or portability configuration */
+#include "port.h"
+
+/*! Index of the link register */
+#define LINK_REGNO 9
+
+/* Conversion macros */
+#define ADDR_C(c) UINT32_C(c)
+#define REG_C(c) UINT32_C(c)
+
+/* Strings for printing OpenRISC types */
+#define PRIxADDR "08" PRIx32 /*!< print an openrisc address in hex */
+#define PRIxREG "08" PRIx32 /*!< print an openrisc register in hex */
+#define PRIdREG PRId32 /*!< print an openrisc register in decimals */
+
+/* Basic types for openrisc */
+typedef uint32_t oraddr_t; /*!< Address as addressed by openrisc */
+typedef uint32_t uorreg_t; /*!< An unsigned register of openrisc */
+typedef int32_t orreg_t; /*!< A signed register of openrisc */
+
+#endif /* ARCH__H */
Index: or1k/Makefile.am
===================================================================
--- or1k/Makefile.am (nonexistent)
+++ or1k/Makefile.am (revision 1765)
@@ -0,0 +1,33 @@
+# Makefile -- Makefile for OR1K architecture dependent simulation
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+
+noinst_LTLIBRARIES = libor1k.la
+libor1k_la_SOURCES = sprs.c \
+ except.c \
+ spr-dump.c \
+ sprs.h \
+ except.h \
+ spr-dump.h \
+ arch.h \
+ spr-defs.h \
+ opcode/or32.h
Index: or1k/spr-defs.h
===================================================================
--- or1k/spr-defs.h (nonexistent)
+++ or1k/spr-defs.h (revision 1765)
@@ -0,0 +1,577 @@
+/* spr-defs.h -- Defines OR1K architecture specific special-purpose registers
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef SPR_DEFS__H
+#define SPR_DEFS__H
+
+/* Definition of special-purpose registers (SPRs). */
+
+#define MAX_GRPS (32)
+#define MAX_SPRS_PER_GRP_BITS (11)
+#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS)
+#define MAX_SPRS (0x10000)
+
+/* Base addresses for the groups */
+#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS)
+
+/* System control and status group */
+#define SPR_VR (SPRGROUP_SYS + 0)
+#define SPR_UPR (SPRGROUP_SYS + 1)
+#define SPR_CPUCFGR (SPRGROUP_SYS + 2)
+#define SPR_DMMUCFGR (SPRGROUP_SYS + 3)
+#define SPR_IMMUCFGR (SPRGROUP_SYS + 4)
+#define SPR_DCCFGR (SPRGROUP_SYS + 5)
+#define SPR_ICCFGR (SPRGROUP_SYS + 6)
+#define SPR_DCFGR (SPRGROUP_SYS + 7)
+#define SPR_PCCFGR (SPRGROUP_SYS + 8)
+#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */
+#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */
+#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */
+#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */
+#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */
+#define SPR_EEAR_BASE (SPRGROUP_SYS + 48)
+#define SPR_EEAR_LAST (SPRGROUP_SYS + 63)
+#define SPR_ESR_BASE (SPRGROUP_SYS + 64)
+#define SPR_ESR_LAST (SPRGROUP_SYS + 79)
+
+/* Data MMU group */
+#define SPR_DMMUCR (SPRGROUP_DMMU + 0)
+#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100)
+#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100)
+#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100)
+#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100)
+
+/* Instruction MMU group */
+#define SPR_IMMUCR (SPRGROUP_IMMU + 0)
+#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100)
+#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100)
+#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100)
+#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100)
+
+/* Data cache group */
+#define SPR_DCCR (SPRGROUP_DC + 0)
+#define SPR_DCBPR (SPRGROUP_DC + 1)
+#define SPR_DCBFR (SPRGROUP_DC + 2)
+#define SPR_DCBIR (SPRGROUP_DC + 3)
+#define SPR_DCBWR (SPRGROUP_DC + 4)
+#define SPR_DCBLR (SPRGROUP_DC + 5)
+#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200)
+#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200)
+
+/* Instruction cache group */
+#define SPR_ICCR (SPRGROUP_IC + 0)
+#define SPR_ICBPR (SPRGROUP_IC + 1)
+#define SPR_ICBIR (SPRGROUP_IC + 2)
+#define SPR_ICBLR (SPRGROUP_IC + 3)
+#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200)
+#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200)
+
+/* MAC group */
+#define SPR_MACLO (SPRGROUP_MAC + 1)
+#define SPR_MACHI (SPRGROUP_MAC + 2)
+
+/* Debug group */
+#define SPR_DVR(N) (SPRGROUP_D + (N))
+#define SPR_DCR(N) (SPRGROUP_D + 8 + (N))
+#define SPR_DMR1 (SPRGROUP_D + 16)
+#define SPR_DMR2 (SPRGROUP_D + 17)
+#define SPR_DWCR0 (SPRGROUP_D + 18)
+#define SPR_DWCR1 (SPRGROUP_D + 19)
+#define SPR_DSR (SPRGROUP_D + 20)
+#define SPR_DRR (SPRGROUP_D + 21)
+
+/* Performance counters group */
+#define SPR_PCCR(N) (SPRGROUP_PC + (N))
+#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N))
+
+/* Power management group */
+#define SPR_PMR (SPRGROUP_PM + 0)
+
+/* PIC group */
+#define SPR_PICMR (SPRGROUP_PIC + 0)
+#define SPR_PICPR (SPRGROUP_PIC + 1)
+#define SPR_PICSR (SPRGROUP_PIC + 2)
+
+/* Tick Timer group */
+#define SPR_TTMR (SPRGROUP_TT + 0)
+#define SPR_TTCR (SPRGROUP_TT + 1)
+
+/*
+ * Bit definitions for the Version Register
+ *
+ */
+#define SPR_VR_VER 0xff000000 /* Processor version */
+#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */
+#define SPR_VR_RES 0x00ff0000 /* Reserved */
+#define SPR_VR_REV 0x0000003f /* Processor revision */
+
+#define SPR_VR_VER_OFF 24
+#define SPR_VR_CFG_OFF 16
+#define SPR_VR_REV_OFF 0
+
+/*
+ * Bit definitions for the Unit Present Register
+ *
+ */
+#define SPR_UPR_UP 0x00000001 /* UPR present */
+#define SPR_UPR_DCP 0x00000002 /* Data cache present */
+#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */
+#define SPR_UPR_DMP 0x00000008 /* Data MMU present */
+#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */
+#define SPR_UPR_MP 0x00000020 /* MAC present */
+#define SPR_UPR_DUP 0x00000040 /* Debug unit present */
+#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */
+#define SPR_UPR_PMP 0x00000100 /* Power management present */
+#define SPR_UPR_PICP 0x00000200 /* PIC present */
+#define SPR_UPR_TTP 0x00000400 /* Tick timer present */
+#define SPR_UPR_RES 0x00fe0000 /* Reserved */
+#define SPR_UPR_CUP 0xff000000 /* Context units present */
+
+/*
+ * JPB: Bit definitions for the CPU configuration register
+ *
+ */
+#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */
+#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */
+#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */
+#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */
+#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */
+#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */
+#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */
+#define SPR_CPUCFGR_RES 0xfffffc00 /* Reserved */
+
+/*
+ * JPB: Bit definitions for the Debug configuration register and other
+ * constants.
+ *
+ */
+
+#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */
+#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */
+#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */
+#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */
+#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */
+#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */
+#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */
+#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */
+#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */
+#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */
+
+#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \
+ 2 == n ? SPR_DCFGR_NDP2 : \
+ 3 == n ? SPR_DCFGR_NDP3 : \
+ 4 == n ? SPR_DCFGR_NDP4 : \
+ 5 == n ? SPR_DCFGR_NDP5 : \
+ 6 == n ? SPR_DCFGR_NDP6 : \
+ 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8)
+#define MAX_MATCHPOINTS 8
+#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2)
+
+/*
+ * Bit definitions for the Supervision Register
+ *
+ */
+#define SPR_SR_SM 0x00000001 /* Supervisor Mode */
+#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */
+#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */
+#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */
+#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */
+#define SPR_SR_DME 0x00000020 /* Data MMU Enable */
+#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */
+#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */
+#define SPR_SR_CE 0x00000100 /* CID Enable */
+#define SPR_SR_F 0x00000200 /* Condition Flag */
+#define SPR_SR_CY 0x00000400 /* Carry flag */
+#define SPR_SR_OV 0x00000800 /* Overflow flag */
+#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */
+#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */
+#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */
+#define SPR_SR_FO 0x00008000 /* Fixed one */
+#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */
+#define SPR_SR_RES 0x0ffe0000 /* Reserved */
+#define SPR_SR_CID 0xf0000000 /* Context ID */
+
+/*
+ * Bit definitions for the Data MMU Control Register
+ *
+ */
+#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */
+#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
+#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
+#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Instruction MMU Control Register
+ *
+ */
+#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */
+#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
+#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
+#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Data TLB Match Register
+ *
+ */
+#define SPR_DTLBMR_V 0x00000001 /* Valid */
+#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
+#define SPR_DTLBMR_CID 0x0000003c /* Context ID */
+#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */
+#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Data TLB Translate Register
+ *
+ */
+#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */
+#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */
+#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */
+#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
+#define SPR_DTLBTR_A 0x00000010 /* Accessed */
+#define SPR_DTLBTR_D 0x00000020 /* Dirty */
+#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */
+#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */
+#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */
+#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */
+#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */
+
+/*
+ * Bit definitions for the Instruction TLB Match Register
+ *
+ */
+#define SPR_ITLBMR_V 0x00000001 /* Valid */
+#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
+#define SPR_ITLBMR_CID 0x0000003c /* Context ID */
+#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */
+#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Instruction TLB Translate Register
+ *
+ */
+#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */
+#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */
+#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */
+#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
+#define SPR_ITLBTR_A 0x00000010 /* Accessed */
+#define SPR_ITLBTR_D 0x00000020 /* Dirty */
+#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */
+#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */
+#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */
+
+/*
+ * Bit definitions for Data Cache Control register
+ *
+ */
+#define SPR_DCCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Insn Cache Control register
+ *
+ */
+#define SPR_ICCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Data Cache Configuration Register
+ *
+ */
+
+#define SPR_DCCFGR_NCW 0x00000007
+#define SPR_DCCFGR_NCS 0x00000078
+#define SPR_DCCFGR_CBS 0x00000080
+#define SPR_DCCFGR_CWS 0x00000100
+#define SPR_DCCFGR_CCRI 0x00000200
+#define SPR_DCCFGR_CBIRI 0x00000400
+#define SPR_DCCFGR_CBPRI 0x00000800
+#define SPR_DCCFGR_CBLRI 0x00001000
+#define SPR_DCCFGR_CBFRI 0x00002000
+#define SPR_DCCFGR_CBWBRI 0x00004000
+
+#define SPR_DCCFGR_NCW_OFF 0
+#define SPR_DCCFGR_NCS_OFF 3
+#define SPR_DCCFGR_CBS_OFF 7
+
+/*
+ * Bit definitions for Instruction Cache Configuration Register
+ *
+ */
+#define SPR_ICCFGR_NCW 0x00000007
+#define SPR_ICCFGR_NCS 0x00000078
+#define SPR_ICCFGR_CBS 0x00000080
+#define SPR_ICCFGR_CCRI 0x00000200
+#define SPR_ICCFGR_CBIRI 0x00000400
+#define SPR_ICCFGR_CBPRI 0x00000800
+#define SPR_ICCFGR_CBLRI 0x00001000
+
+#define SPR_ICCFGR_NCW_OFF 0
+#define SPR_ICCFGR_NCS_OFF 3
+#define SPR_ICCFGR_CBS_OFF 7
+
+/*
+ * Bit definitions for Data MMU Configuration Register
+ *
+ */
+
+#define SPR_DMMUCFGR_NTW 0x00000003
+#define SPR_DMMUCFGR_NTS 0x0000001C
+#define SPR_DMMUCFGR_NAE 0x000000E0
+#define SPR_DMMUCFGR_CRI 0x00000100
+#define SPR_DMMUCFGR_PRI 0x00000200
+#define SPR_DMMUCFGR_TEIRI 0x00000400
+#define SPR_DMMUCFGR_HTR 0x00000800
+
+#define SPR_DMMUCFGR_NTW_OFF 0
+#define SPR_DMMUCFGR_NTS_OFF 2
+
+/*
+ * Bit definitions for Instruction MMU Configuration Register
+ *
+ */
+
+#define SPR_IMMUCFGR_NTW 0x00000003
+#define SPR_IMMUCFGR_NTS 0x0000001C
+#define SPR_IMMUCFGR_NAE 0x000000E0
+#define SPR_IMMUCFGR_CRI 0x00000100
+#define SPR_IMMUCFGR_PRI 0x00000200
+#define SPR_IMMUCFGR_TEIRI 0x00000400
+#define SPR_IMMUCFGR_HTR 0x00000800
+
+#define SPR_IMMUCFGR_NTW_OFF 0
+#define SPR_IMMUCFGR_NTS_OFF 2
+
+/*
+ * Bit definitions for Debug Control registers
+ *
+ */
+#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */
+#define SPR_DCR_CC 0x0000000e /* Compare condition */
+#define SPR_DCR_SC 0x00000010 /* Signed compare */
+#define SPR_DCR_CT 0x000000e0 /* Compare to */
+
+/* Bit results with SPR_DCR_CC mask */
+#define SPR_DCR_CC_MASKED 0x00000000
+#define SPR_DCR_CC_EQUAL 0x00000002
+#define SPR_DCR_CC_LESS 0x00000004
+#define SPR_DCR_CC_LESSE 0x00000006
+#define SPR_DCR_CC_GREAT 0x00000008
+#define SPR_DCR_CC_GREATE 0x0000000a
+#define SPR_DCR_CC_NEQUAL 0x0000000c
+
+/* Bit results with SPR_DCR_CT mask */
+#define SPR_DCR_CT_DISABLED 0x00000000
+#define SPR_DCR_CT_IFEA 0x00000020
+#define SPR_DCR_CT_LEA 0x00000040
+#define SPR_DCR_CT_SEA 0x00000060
+#define SPR_DCR_CT_LD 0x00000080
+#define SPR_DCR_CT_SD 0x000000a0
+#define SPR_DCR_CT_LSEA 0x000000c0
+#define SPR_DCR_CT_LSD 0x000000e0
+/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */
+
+/*
+ * Bit definitions for Debug Mode 1 register
+ *
+ */
+#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */
+#define SPR_DMR1_CW0_AND 0x00000001
+#define SPR_DMR1_CW0_OR 0x00000002
+#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR)
+#define SPR_DMR1_CW1_AND 0x00000004
+#define SPR_DMR1_CW1_OR 0x00000008
+#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR)
+#define SPR_DMR1_CW2_AND 0x00000010
+#define SPR_DMR1_CW2_OR 0x00000020
+#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR)
+#define SPR_DMR1_CW3_AND 0x00000040
+#define SPR_DMR1_CW3_OR 0x00000080
+#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR)
+#define SPR_DMR1_CW4_AND 0x00000100
+#define SPR_DMR1_CW4_OR 0x00000200
+#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR)
+#define SPR_DMR1_CW5_AND 0x00000400
+#define SPR_DMR1_CW5_OR 0x00000800
+#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR)
+#define SPR_DMR1_CW6_AND 0x00001000
+#define SPR_DMR1_CW6_OR 0x00002000
+#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR)
+#define SPR_DMR1_CW7_AND 0x00004000
+#define SPR_DMR1_CW7_OR 0x00008000
+#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR)
+#define SPR_DMR1_CW8_AND 0x00010000
+#define SPR_DMR1_CW8_OR 0x00020000
+#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR)
+#define SPR_DMR1_CW9_AND 0x00040000
+#define SPR_DMR1_CW9_OR 0x00080000
+#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR)
+#define SPR_DMR1_RES1 0x00300000 /* Reserved */
+#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/
+#define SPR_DMR1_BT 0x00800000 /* Branch trace */
+#define SPR_DMR1_RES2 0xff000000 /* Reserved */
+
+/*
+ * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB
+ *
+ */
+#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */
+#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */
+#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */
+#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */
+#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */
+#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */
+
+/*
+ * Bit definitions for Debug watchpoint counter registers
+ *
+ */
+#define SPR_DWCR_COUNT 0x0000ffff /* Count */
+#define SPR_DWCR_MATCH 0xffff0000 /* Match */
+#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */
+
+/*
+ * Bit definitions for Debug stop register
+ *
+ */
+#define SPR_DSR_RSTE 0x00000001 /* Reset exception */
+#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */
+#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */
+#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */
+#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */
+#define SPR_DSR_AE 0x00000020 /* Alignment exception */
+#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */
+#define SPR_DSR_IE 0x00000080 /* Interrupt exception */
+#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */
+#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */
+#define SPR_DSR_RE 0x00000400 /* Range exception */
+#define SPR_DSR_SCE 0x00000800 /* System call exception */
+#define SPR_DSR_SSE 0x00001000 /* Single Step Exception */
+#define SPR_DSR_TE 0x00002000 /* Trap exception */
+
+/*
+ * Bit definitions for Debug reason register
+ *
+ */
+#define SPR_DRR_RSTE 0x00000001 /* Reset exception */
+#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */
+#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */
+#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */
+#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */
+#define SPR_DRR_AE 0x00000020 /* Alignment exception */
+#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */
+#define SPR_DRR_IE 0x00000080 /* Interrupt exception */
+#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */
+#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */
+#define SPR_DRR_RE 0x00000400 /* Range exception */
+#define SPR_DRR_SCE 0x00000800 /* System call exception */
+#define SPR_DRR_TE 0x00001000 /* Trap exception */
+
+/*
+ * Bit definitions for Performance counters mode registers
+ *
+ */
+#define SPR_PCMR_CP 0x00000001 /* Counter present */
+#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */
+#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */
+#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */
+#define SPR_PCMR_LA 0x00000010 /* Load access event */
+#define SPR_PCMR_SA 0x00000020 /* Store access event */
+#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/
+#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */
+#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */
+#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */
+#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */
+#define SPR_PCMR_BS 0x00000800 /* Branch stall event */
+#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */
+#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */
+#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */
+#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */
+
+/*
+ * Bit definitions for the Power management register
+ *
+ */
+#define SPR_PMR_SDF 0x0000000f /* Slow down factor */
+#define SPR_PMR_DME 0x00000010 /* Doze mode enable */
+#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */
+#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */
+#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */
+
+/*
+ * Bit definitions for PICMR
+ *
+ */
+#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */
+
+/*
+ * Bit definitions for PICPR
+ *
+ */
+#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */
+
+/*
+ * Bit definitions for PICSR
+ *
+ */
+#define SPR_PICSR_IS 0xffffffff /* Interrupt status */
+
+/*
+ * Bit definitions for Tick Timer Control Register
+ *
+ */
+#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */
+#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD
+#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */
+#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */
+#define SPR_TTMR_RT 0x40000000 /* Restart tick */
+#define SPR_TTMR_SR 0x80000000 /* Single run */
+#define SPR_TTMR_CR 0xc0000000 /* Continuous run */
+#define SPR_TTMR_M 0xc0000000 /* Tick mode */
+
+/*
+ * l.nop constants
+ *
+ */
+#define NOP_NOP 0x0000 /* Normal nop instruction */
+#define NOP_EXIT 0x0001 /* End of simulation */
+#define NOP_REPORT 0x0002 /* Simple report */
+#define NOP_PRINTF 0x0003 /* Simprintf instruction */
+#define NOP_PUTC 0x0004 /* JPB: Simputc instruction */
+#define NOP_CNT_RESET 0x0005 /* Reset statistics counters */
+#define NOP_REPORT_FIRST 0x0400 /* Report with number */
+#define NOP_REPORT_LAST 0x03ff /* Report with number */
+
+#endif /* SPR_DEFS__H */
Index: or1k/sprs.h
===================================================================
--- or1k/sprs.h (nonexistent)
+++ or1k/sprs.h (revision 1765)
@@ -0,0 +1,44 @@
+/* sprs.h -- OR1K architecture specific special-purpose registers
+
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef SPRS__H
+#define SPRS__H
+
+/* Autoconf and/or portability configuration */
+#include "port.h"
+
+/* Package includes */
+#include "arch.h"
+
+/* Function prototypes for external use */
+extern void mtspr (uint16_t regno,
+ const uorreg_t value);
+extern uorreg_t mfspr (const uint16_t regno);
+extern void sprs_status ();
+extern char *dump_spr (uint16_t spr,
+ uorreg_t spr_val);
+
+#endif /* SPRS__H */
Index: or1k/spr-dump.h
===================================================================
--- or1k/spr-dump.h (nonexistent)
+++ or1k/spr-dump.h (revision 1765)
@@ -0,0 +1,41 @@
+/* spr_dump.h -- Dump given spr in human readable form header
+
+ Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
+ Copyright (C) 2008 Embecosm Limited
+
+ Contributor Jeremy Bennett
+
+ This file is part of OpenRISC 1000 Architectural Simulator.
+
+ 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 3 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, see . */
+
+/* This program is commented throughout in a fashion suitable for processing
+ with Doxygen. */
+
+
+#ifndef SPR_DUMP__H
+#define SPR_DUMP__H
+
+/* System includes */
+#include
+
+/* Package includes */
+#include "arch.h"
+
+
+/* Function prototypes for external use */
+extern char *dump_spr (uint16_t spr,
+ uorreg_t spr_val);
+
+#endif /* SPR_DUMP__H */
Index: or1k
===================================================================
--- or1k (nonexistent)
+++ or1k (revision 1765)
or1k
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps
Index: Makefile.in
===================================================================
--- Makefile.in (nonexistent)
+++ Makefile.in (revision 1765)
@@ -0,0 +1,518 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile -- Makefile for all cpu simulations
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = cpu
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_ARCH = @CPU_ARCH@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEBUGFLAGS = @DEBUGFLAGS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INCLUDES = @INCLUDES@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_SHELL = @MAKE_SHELL@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = common or1k $(CPU_ARCH)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ ctags ctags-recursive distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: Makefile.am
===================================================================
--- Makefile.am (nonexistent)
+++ Makefile.am (revision 1765)
@@ -0,0 +1,23 @@
+# Makefile -- Makefile for all cpu simulations
+#
+# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+# Copyright (C) 2008 Embecosm Limited
+#
+# Contributor Jeremy Bennett
+#
+# This file is part of OpenRISC 1000 Architectural Simulator.
+#
+# 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 3 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, see .
+
+SUBDIRS = common or1k $(CPU_ARCH)
Index: or16
===================================================================
--- or16 (nonexistent)
+++ or16 (revision 1765)
or16
Property changes :
Added: svn:ignore
## -0,0 +1 ##
+Makefile
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 1765)
.
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps