New stuff for SH.
authorSteve Chamberlain <sac@cygnus>
Tue, 27 Apr 1993 01:02:38 +0000 (01:02 +0000)
committerSteve Chamberlain <sac@cygnus>
Tue, 27 Apr 1993 01:02:38 +0000 (01:02 +0000)
sim/.Sanitize
sim/sh/.Sanitize [new file with mode: 0644]
sim/sh/ChangeLog [new file with mode: 0644]
sim/sh/Makefile.in [new file with mode: 0644]
sim/sh/configure.in [new file with mode: 0644]
sim/sh/gencode.c [new file with mode: 0644]
sim/sh/interp.c [new file with mode: 0644]
sim/sh/run.c [new file with mode: 0644]

index 41df081b34c9011f30b3ec1e3d4e268403c26f71..b455fbd69d30e586aff8f601f79d645e35a49cad 100644 (file)
@@ -29,6 +29,7 @@ configure.in
 endian.c
 h8300
 h8500
+sh
 z8k
 
 Do-last:
diff --git a/sim/sh/.Sanitize b/sim/sh/.Sanitize
new file mode 100644 (file)
index 0000000..a76a514
--- /dev/null
@@ -0,0 +1,38 @@
+# Sanitize.in for devo.
+# $Id$
+#
+
+# Each directory to survive it's way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this 
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+ChangeLog
+Makefile.in
+configure.in
+interp.c
+gencode.c
+run.c
+
+
+Do-last:
+
+# End of file.
diff --git a/sim/sh/ChangeLog b/sim/sh/ChangeLog
new file mode 100644 (file)
index 0000000..4c59bf5
--- /dev/null
@@ -0,0 +1,4 @@
+Mon Apr 26 18:01:10 1993  Steve Chamberlain  (sac@thepub.cygnus.com)
+
+       * created
+
diff --git a/sim/sh/Makefile.in b/sim/sh/Makefile.in
new file mode 100644 (file)
index 0000000..8e542de
--- /dev/null
@@ -0,0 +1,176 @@
+#    Makefile template for Configure for the h8300sim library.
+#    Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+#    Written by Cygnus Support.
+# 
+# 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.
+
+srcdir = .
+
+prefix = /usr/local
+program_transform_name =
+exec_prefix = $(prefix)
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+
+datadir = $(prefix)/lib
+mandir = $(prefix)/man
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = $(prefix)/info
+includedir = $(prefix)/include
+oldincludedir =
+docdir = $(srcdir)/doc
+
+SHELL = /bin/sh
+
+INSTALL = install -c
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL)
+
+AR = ar
+AR_FLAGS = qc
+CFLAGS = -g
+BISON = bison
+MAKEINFO = makeinfo
+RANLIB = ranlib
+
+INCDIR = $(srcdir)/../../include 
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR) -I$(srcdir)/../../bfd
+DEP = mkdep
+
+#### host, target, and site specific Makefile frags come in here.
+
+all:   run
+
+
+run:   interp.o run.o table.o
+       $(CC) -o run interp.o table.o run.o ../../bfd/libbfd.a ../../libiberty/libiberty.a
+
+interp.o:interp.c code.c table.c
+run.o:run.c 
+
+code.c:gencode
+       ./gencode -x >code.c
+       indent code.c
+
+table.c:gencode
+       ./gencode -s >table.c
+       indent table.c
+
+gencode:gencode.c
+       cc -o gencode -g gencode.c
+
+#### host and target dependent Makefile fragments come in here.
+###
+
+FLAGS_TO_PASS = \
+       "against=$(against)" \
+       "AR=$(AR)" \
+       "AR_FLAGS=$(AR_FLAGS)" \
+       "CC=$(CC)" \
+       "CFLAGS=$(CFLAGS)" \
+       "RANLIB=$(RANLIB)" \
+       "MAKEINFO=$(MAKEINFO)" \
+       "INSTALL=$(INSTALL)" \
+       "INSTALL_DATA=$(INSTALL_DATA)" \
+       "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+       "BISON=$(BISON)"
+
+.c.o:
+       $(CC) -c $(CFLAGS) $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) $<
+
+
+
+.NOEXPORT:
+
+check:
+
+info:
+clean-info:
+install-info:
+
+# HDEPFILES comes from the host config; TDEPFILES from the target config.
+
+
+
+tags etags: TAGS
+
+TAGS: force
+       etags $(INCDIR)/*.h $(srcdir)/*.h $(srcdir)/*.c
+
+clean:
+       rm -f *.[oa] *~ core *.E *.p *.ip aout-params.h gen-aout
+
+clobber realclean: clean
+       rm -f libbfd.a TAGS
+
+# Mark everything as depending on config.status, since the timestamp on
+# sysdep.h might actually move backwards if we reconfig and relink it
+# to a different hosts/h-xxx.h file.  This will force a recompile anyway.
+RECONFIG = config.status
+
+
+
+# This target should be invoked before building a new release.
+# 'VERSION' file must be present and contain a string of the form "x.y"
+#
+roll:
+       @V=`cat VERSION`                ; \
+       MAJ=`sed 's/\..*//' VERSION`    ; \
+       MIN=`sed 's/.*\.//' VERSION`    ; \
+       V=$$MAJ.`expr $$MIN + 1`        ; \
+       rm -f VERSION                   ; \
+       echo $$V >VERSION               ; \
+       echo Version $$V
+
+# Dummy target to force execution of dependent targets.
+#
+force:
+
+install:
+       -parent=`echo $(bindir)|sed -e 's@/[^/]*$$@@'`; \
+       if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
+       -if [ -d $(bindir) ] ; then true ; else mkdir $(bindir) ; fi
+       -parent=`echo $(man1dir)|sed -e 's@/[^/]*$$@@'`; \
+       if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
+       -if [ -d $(man1dir) ] ; then true ; else mkdir $(man1dir) ; fi
+       -n=`t='$(program_transform_name)'; echo run | sed -e "" $$t`; \
+       $(INSTALL_PROGRAM) run $(bindir)/$$n; \
+       $(M_INSTALL)
+
+
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+       $(SHELL) ./config.status
+
+dep: $(CFILES)
+       mkdep $(CFLAGS) $?
+
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
diff --git a/sim/sh/configure.in b/sim/sh/configure.in
new file mode 100644 (file)
index 0000000..22bc10a
--- /dev/null
@@ -0,0 +1,33 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory.  For more information, check any
+# existing configure script.
+
+srctrigger=compile.c
+srcname="shsim"
+
+# per-host:
+
+. ${srcdir}/../../bfd/configure.host
+
+# Set up to make a link between the host's include file and "sysdep.h".
+files="../../bfd/hosts/${my_host}.h"
+
+links="sysdep.h"
+
+if [ ! -f ${srcdir}/${files} ] ; then
+       if [ -n "${my_host}" ] ; then
+               echo '***' No file ${srcdir}/${files} 1>&2
+       fi
+       echo '***' ${srcname} does not support host ${host} 1>&2
+       exit 1
+fi
+
+host_makefile_frag=
+if [ -f ${srcdir}/../../bfd/config/${my_host}.mh ] ; then
+       host_makefile_frag=../../bfd/config/${my_host}.mh
+fi
+
+# per-target:
+
+
diff --git a/sim/sh/gencode.c b/sim/sh/gencode.c
new file mode 100644 (file)
index 0000000..8b495e5
--- /dev/null
@@ -0,0 +1,703 @@
+/* Simulator/Opcode generator for the Hitachi Super-H architecture.
+
+   Written by Steve Chamberlain of Cygnus Support.
+   sac@cygnus.com
+
+   This file is part of SH sim
+
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   Cygnus offers the following for use in the public domain.  Cygnus
+   makes no warranty with regard to the software or it's performance
+   and the user accepts the software "AS IS" with all faults.
+
+   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
+   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+*/
+
+/* This program generates the opcode table for the assembler and
+   the simulator code
+
+   -t          prints a pretty table for the assembler manual
+   -s          generates the simulator code jump table
+   -x          generates the simulator code switch statement
+   default     generates the opcode tables
+
+*/
+
+typedef struct
+{
+  char *name;
+  char *code;
+  char *stuff[10];
+  int index;
+}
+
+op;
+
+
+op tab[] =
+{
+
+  {"add #<imm>,<REG_N>", "0111nnnni8*1....", "R[n] += SEXT(i);"},
+  {"add <REG_M>,<REG_N>", "0011nnnnmmmm1100", "R[n] += R[m];"},
+  {"addc <REG_M>,<REG_N>", "0011nnnnmmmm1110", "ult = R[n]; R[n] += (R[m]+T); T = ult>R[n];"},
+  {"addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
+   "long ans;",
+   "ans = R[n] + R[m];",
+   "T = ((~R[n] & R[m] & ans) | (R[n] & R[m] & ~ans)) >>31;",
+   "R[n] = ans;"},
+
+  {"and #<imm>,R0", "11001001i8*1....", "R0&=i;"},
+  {"and <REG_M>,<REG_N>", "0010nnnnmmmm1001", "R[n]&=R[m];"},
+  {"and.b #<imm>,@(R0,GBR)", "11001101i8*1....", "WBAT(GBR+R0, RBAT(GBR+R0) & i);"},
+
+  {"bf <bdisp8>", "10001011i8p1....", "if(T==0) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
+  {"bra <bdisp12>", "1010i12.........", "ult = PC; PC=PC+(i<<1)+2;SL(ult+2);"},
+  {"bsr <bdisp12>", "1011i12.........", "PR = PC; PC=PC+(i<<1)+2;SL(PR+2);"},
+  {"bt <bdisp8>", "10001001i8p1....", "if(T==1) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
+  {"clrmac", "0000000000101000", "MACH = MACL = 0;"},
+  {"clrt", "0000000000001000", "T= 0;"},
+  {"cmp/eq #<imm>,R0", "10001000i8*1....", "T = R0 == SEXT(i);"},
+  {"cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000", "T=R[n]==R[m];"},
+  {"cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011", "T=R[n]>=R[m];"},
+  {"cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111", "T=R[n]>R[m];"},
+  {"cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110", "T=UR[n]>UR[m];"},
+  {"cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010", "T=UR[n]>=UR[m];"},
+  {"cmp/pl <REG_N>", "0100nnnn00010101", "T = R[n]>0;"},
+  {"cmp/pz <REG_N>", "0100nnnn00010001", "T = R[n]>=0;"},
+  {"cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100", "ult = R[n] ^ R[m]; T=((ult&0xff000000)==0) |((ult&0xff0000)==0) |((ult&0xff00)==0) |((ult&0xff)==0); "},
+  {"div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111", "Q=R[n]<0; M=R[m]<0; T=M!=Q;;"},
+  {"div0u", "0000000000011001", "M=Q=T=0;"},
+  {"div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", "T=div1(R,n,m,T);"},
+  {"exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110", "R[n] = SEXT(R[m]);"},
+  {"exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111", "R[n] = SEXTW(R[m]);"},
+  {"extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100", "R[n] = R[m] & 0xff;"},
+  {"extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101", "R[n] = R[m] & 0xffff;"},
+  {"jmp @<REG_N>", "0100nnnn00101011", "ult = PC; PC=R[n]-2; SL(ult+2);"},
+  {"jsr @<REG_N>", "0100nnnn00001011", "PR = PC; PC=R[n]-2; SL(PR+2);"},
+  {"ldc <REG_N>,GBR", "0100nnnn00011110", "GBR=R[n];"},
+  {"ldc <REG_N>,SR", "0100nnnn00001110", "SET_SR(R[n]);"},
+  {"ldc <REG_N>,VBR", "0100nnnn00101110", "VBR=R[n];"},
+  {"ldc.l @<REG_N>+,GBR", "0100nnnn00010111", "GBR=RLAT(R[n]);R[n]+=4;;"},
+  {"ldc.l @<REG_N>+,SR", "0100nnnn00000111", "SET_SR(RLAT(R[n]));R[n]+=4;;"},
+  {"ldc.l @<REG_N>+,VBR", "0100nnnn00100111", "VBR=RLAT(R[n]);R[n]+=4;;"},
+  {"lds <REG_N>,MACH", "0100nnnn00001010", "MACH = SEXT(R[n]);"},
+  {"lds <REG_N>,MACL", "0100nnnn00011010", "MACL= R[n];"},
+  {"lds <REG_N>,PR", "0100nnnn00101010", "PR = R[n];"},
+  {"lds.l @<REG_N>+,MACH", "0100nnnn00000110", "MACH = SEXT(RLAT(R[n]));R[n]+=4;"},
+  {"lds.l @<REG_N>+,MACL", "0100nnnn00010110", "MACL = RLAT(R[n]);R[n]+=4;"},
+  {"lds.l @<REG_N>+,PR", "0100nnnn00100110", "PR = RLAT(R[n]);R[n]+=4;;"},
+  {"mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111", "abort();"},
+  {"mov #<imm>,<REG_N>", "1110nnnni8*1....", "R[n] = SEXT(i);"},
+  {"mov <REG_M>,<REG_N>", "0110nnnnmmmm0011", "R[n] = R[m];"},
+{"mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100", "WBAT(R[n]+R0, R[m]);"},
+{"mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100", "R[n]--; WBAT(R[n], R[m]);"},
+  {"mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000", "WBAT(R[n], R[m]);"},
+  {"mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1", "R0=RBAT(i+R[m]);"},
+  {"mov.b @(<disp>,GBR),R0", "11000100i8*1....", "R0=RBAT(i+GBR);"},
+  {"mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100", "R[n]=RBAT(R0+R[m]);"},
+{"mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100", "R[n] = RBAT(R[m]);R[m]++;"},
+  {"mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000", "R[n]=RBAT(R[m]);"},
+  {"mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1", "R0=RBAT(i+R[m]);"},
+  {"mov.b R0,@(<disp>,GBR)", "11000000i8*1....", "R0 = RBAT(i+GBR);"},
+  {"mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4", "WLAT(i+R[n],R[m]);"},
+  {"mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110", "WLAT(R0+R[n],R[m]);"},
+{"mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110", "R[n]-=4;WLAT(R[n],R[m]);"},
+  {"mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010", "WLAT(R[n], R[m]);"},
+  {"mov.l @(<disp>,<REG_N>),<REG_M>", "0101nnnnmmmmi4*4", "R[m]=RLAT(i+R[n]);"},
+  {"mov.l @(<disp>,GBR),R0", "11000110i4*4", "R0=RLAT(i+GBR);"},
+  {"mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....", "R[n]=RLAT(i+4+PC);"},
+  {"mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110", "R[n]=RLAT(R0+R[m]);"},
+{"mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110", "R[n]=RLAT(R[m]);R[m]+=4;"},
+  {"mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010", "R[n]=RLAT(R[m]);"},
+  {"mov.l R0,@(<disp>,GBR)", "11000010i8*4....", "R0=RLAT(R0+GBR);"},
+  {"mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101", "WWAT(R0+R[n],R[m]);"},
+{"mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101", "R[n]-=2;WWAT(R[n],R[m]);"},
+  {"mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001", "WWAT(R[n],R[m]);"},
+  {"mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2", "R0=RSWAT(i+R[m]);"},
+  {"mov.w @(<disp>,GBR),R0", "11000101i8*2....", "R0=RSWAT(i+GBR);"},
+  {"mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....", "R[n]=RSWAT(PC+i+4);"},
+{"mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101", "R[n]=RSWAT(R0+R[m]);"},
+{"mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101", "R[n]=RSWAT(R[m]);R[m]+=2;"},
+  {"mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001", "R[n]=RSWAT(R[m]);"},
+  {"mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2", "R0=RSWAT(i+R[m]);"},
+  {"mov.w R0,@(<disp>,GBR)", "11000001i8*2....", "R0=RSWAT(i+GBR);"},
+  {"mova @(<disp>,PC),R0", "11000111i8p4....", "R0=i+4+PC;"},
+  {"movt <REG_N>", "0000nnnn00101001", "R[n]=T;"},
+  {"muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
+   "MACL=((long)(short)R[n])*((long)(short)R[m]);"},
+{"mulu <REG_M>,<REG_N>","0010nnnnmmmm1110", "MACL=((unsigned long)(unsigned short)R[n])*((unsigned long)(unsigned short)R[m]);"},  
+  {"neg <REG_M>,<REG_N>", "0110nnnnmmmm1011", "R[n] = - R[m];"},
+  {"negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",  "ult=0-R[m];R[n]=ult-T;T=SBIT(R[n])!=SBIT(ult);"},
+  {"nop", "0000000000001001", ""},
+  {"not <REG_M>,<REG_N>", "0110nnnnmmmm0111", "R[n]=~R[m];"},
+  {"or #<imm>,R0", "11001011i8*1....", "R0|=i;"},
+  {"or <REG_M>,<REG_N>", "0010nnnnmmmm1011", "R[n]|=R[m];"},
+  {"or.b #<imm>,@(R0,GBR)", "11001111i8*1....", "WBAT(R0+GBR,RBAT(R0+GBR)|i);"},
+  {"rotcl <REG_N>", "0100nnnn00100100", "ult = R[n] <0;R[n] = (R[n]<<1)|T;T=ult;"},
+  {"rotcr <REG_N>", "0100nnnn00100101", "ult = R[n]&1;R[n]=(UR[n]>>1)|(T<<31);T=ult;"},
+  {"rotl <REG_N>", "0100nnnn00000100", "T=R[n]<0;R[n]<<=1;R[n]|=T;"},
+  {"rotr <REG_N>", "0100nnnn00000101", "T=R[n]&1;UR[n]>>=1;R[n]|=(T<<31);"},
+  {"rte", "0000000000101011", "abort();"},
+  {"rts", "0000000000001011", "ult=PC;PC=PR+2;SL(ult+2);"},
+  {"sett", "0000000000011000", "T=1;"},
+  {"shal <REG_N>", "0100nnnn00100000", "T=R[n]<0; R[n]<<=1;"},
+  {"shar <REG_N>", "0100nnnn00100001", "T=R[n]&1; R[n]>>=1;"},
+  {"shll <REG_N>", "0100nnnn00000000", "T=R[n]<0; R[n]<<=1;"},
+  {"shll16 <REG_N>", "0100nnnn00101000", "R[n]<<=16;"},
+  {"shll2 <REG_N>", "0100nnnn00001000", "R[n]<<=2;"},
+  {"shll8 <REG_N>", "0100nnnn00011000", "R[n]<<=8;"},
+  {"shlr <REG_N>", "0100nnnn00000001", "T=R[n]&1;R[n]=UR[n]>>1;"},
+  {"shlr16 <REG_N>", "0100nnnn00101001", "R[n]=UR[n]>>16;"},
+  {"shlr2 <REG_N>", "0100nnnn00001001", "R[n]=UR[n]>>2;"},
+  {"shlr8 <REG_N>", "0100nnnn00011001", "R[n]=UR[n]>>8;"},
+  {"sleep", "0000000000011011", "abort();"},
+  {"stc GBR,<REG_N>", "0000nnnn00010010", "R[n]=GBR;"},
+  {"stc SR,<REG_N>", "0000nnnn00000010", "R[n]=GET_SR();"},
+  {"stc VBR,<REG_N>", "0000nnnn00100010", "R[n]=VBR;"},
+  {"stc.l GBR,@-<REG_N>", "0100nnnn00010011", "R[n]-=4;WLAT(R[n],GBR);;"},
+  {"stc.l SR,@-<REG_N>", "0100nnnn00000011", "R[n]-=4;WLAT(R[n],GET_SR());"},
+  {"stc.l VBR,@-<REG_N>", "0100nnnn00100011", "R[n]-=4;WLAT(R[n],VBR);"},
+  {"sts MACH,<REG_N>", "0000nnnn00001010", "R[n]=MACH;"},
+  {"sts MACL,<REG_N>", "0000nnnn00011010", "R[n]=MACL;"},
+  {"sts PR,<REG_N>", "0000nnnn00101010", "R[n]=PR;"},
+  {"sts.l MACH,@-<REG_N>", "0100nnnn00000010", "R[n]-=4;WLAT(R[n],MACH);"},
+  {"sts.l MACL,@-<REG_N>", "0100nnnn00010010", "R[n]-=4;WLAT(R[n],MACL);"},
+  {"sts.l PR,@-<REG_N>", "0100nnnn00100010", "R[n]-=4;WLAT(R[n],PR);"},
+  {"sub <REG_M>,<REG_N>", "0011nnnnmmmm1000", "R[n]-=R[m];"},
+  {"subc <REG_M>,<REG_N>", "0011nnnnmmmm1010", "ult = R[n];R[n]-=R[m]+T;T=ult<UR[n];"},
+  {"subv <REG_M>,<REG_N>", "0011nnnnmmmm1011", "abort();"},
+  {"swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000", "R[n]=((R[m]<<8)&0xff00)|((R[m]>>8)&0x00ff);"},
+  {"swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001", "R[n]=((R[m]<<16)&0xffff0000)|((R[m]>>16)&0x00ffff);"},
+  {"tas.b @<REG_N>", "0100nnnn00011011", "ult=RBAT(R[n]);T=ult==0;WBAT(R[n],ult|0x80);"},
+  {"trapa #<imm>", "11000011i8*1....", "trap(i,R);"},
+  {"tst #<imm>,R0", "11001000i8*1....", "T=(R0&i)==0;"},
+  {"tst <REG_M>,<REG_N>", "0010nnnnmmmm1000", "T=(R[n]&R[m])==0;"},
+  {"tst.b #<imm>,@(R0,GBR)", "11001100i8*1....", "T=(RBAT(GBR+R0)&i)==0;"},
+  {"xor #<imm>,R0", "11001010i8*1....", "R0^=i;"},
+  {"xor <REG_M>,<REG_N>", "0010nnnnmmmm1010", "R[n]^=R[m];"},
+  {"xor.b #<imm>,@(R0,GBR)", "11001110i8*1....", "ult=RBAT(GBR+R0);ult^=i;WBAT(GBR+R0,ult);"},
+  {"xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101", "R[n]=((R[n]>>16)&0xffff)|((R[m]<<16)&0xffff0000);"},
+
+#if 0
+{"mul.l <REG_M>,<REG_N>","0000nnnnmmmm0111","/* mull */"},
+{"dmuls.l <REG_M>,<REG_N>","0011nnnnmmmm1101","/* dmuls.l */"},
+{"dmulu.l <REG_M>,<REG_N>","0011nnnnmmmm0101",""},
+{"mac.l @<REG_M>+,@<REG_N>+","0000nnnnmmmm1111",""},
+{"bt/s <bdisp8>","10001101i8p1....",""},
+{"bf/s <bdisp8>","10001111i8p1....",""},
+{"dt <REG_N>","0100nnnn00010000",""},
+{"braf @<REG_N>","0000nnnn00100011",""},
+{"bsrf @<REG_N>","0000nnnn00000011",""},
+{"mulu <REG_M>,<REG_N>","0010nnnnmmmm1110",""},
+{"muls <REG_M>,<REG_N>","0010nnnnmmmm1111",""},     
+#endif
+
+  {0, 0}};
+
+/* Tables of things to put into enums for sh-opc.h */
+static char *nibble_type_list[] =
+{
+  "HEX_0",
+  "HEX_1",
+  "HEX_2",
+  "HEX_3",
+  "HEX_4",
+  "HEX_5",
+  "HEX_6",
+  "HEX_7",
+  "HEX_8",
+  "HEX_9",
+  "HEX_A",
+  "HEX_B",
+  "HEX_C",
+  "HEX_D",
+  "HEX_E",
+  "HEX_F",
+  "REG_N",
+  "REG_M",
+  "BRANCH_12",
+  "BRANCH_8",
+  "DISP_8",
+  "DISP_4",
+  "IMM_4",
+  "IMM_4BY2",
+  "IMM_4BY4",
+  "PCRELIMM_8BY2",
+  "PCRELIMM_8BY4",
+  "IMM_8",
+  "IMM_8BY2",
+  "IMM_8BY4",
+  0
+};
+static
+char *arg_type_list[] =
+{
+  "A_END",
+  "A_BDISP12",
+  "A_BDISP8",
+  "A_DEC_M",
+  "A_DEC_N",
+  "A_DISP_GBR",
+  "A_DISP_PC",
+  "A_DISP_REG_M",
+  "A_DISP_REG_N",
+  "A_GBR",
+  "A_IMM",
+  "A_INC_M",
+  "A_INC_N",
+  "A_IND_M",
+  "A_IND_N",
+  "A_IND_R0_REG_M",
+  "A_IND_R0_REG_N",
+  "A_MACH",
+  "A_MACL",
+  "A_PR",
+  "A_R0",
+  "A_R0_GBR",
+  "A_REG_M",
+  "A_REG_N",
+  "A_SR",
+  "A_VBR",
+  0,
+};
+
+static void
+make_enum_list (name, s)
+     char *name;
+     char **s;
+{
+  int i = 1;
+  printf ("typedef enum {\n");
+  while (*s)
+    {
+      printf ("\t%s,\n", *s, i);
+      s++;
+      i++;
+    }
+  printf ("} %s;\n", name);
+}
+
+static void
+gengastab ()
+{
+  op *p;
+  sorttab ();
+  for (p = tab; p->name; p++)
+    {
+      printf ("%s %-30s\n", p->code, p->name);
+    }
+
+
+}
+
+
+static void 
+genopc ()
+{
+  op *p;
+  make_enum_list ("sh_nibble_type", nibble_type_list);
+  make_enum_list ("sh_arg_type", arg_type_list);
+
+  printf ("typedef struct {\n");
+  printf ("char *name;\n");
+  printf ("sh_arg_type arg[3];\n");
+  printf ("sh_nibble_type nibbles[4];\n");
+  printf ("} sh_opcode_info;\n");
+  printf ("#ifdef DEFINE_TABLE\n");
+  printf ("sh_opcode_info sh_table[]={\n");
+  for (p = tab; p->name; p++)
+    {
+      printf ("\n\/\* %s %-20s*/", p->code, p->name);
+      think (p);
+    }
+  printf ("0};\n");
+  printf ("#endif\n");
+}
+
+
+m (ptr, a, rep)
+     char **ptr;
+     char *a;
+     char *rep;
+{
+  int l = strlen (a);
+  if (strncmp (*ptr, a, l) == 0)
+    {
+      printf ("%s", rep);
+      *ptr += l;
+      if (**ptr)
+       printf (",");
+    }
+}
+
+think (o)
+     op *o;
+{
+  int t;
+  char *n;
+  char *p;
+
+  printf ("{\"");
+  n = o->name;
+  while (*n && *n != ' ')
+    {
+      printf ("%c", *n);
+      n++;
+    }
+  printf ("\",{");
+
+  p = n;
+
+  if (!*p)
+    {
+      printf ("0");
+    }
+  while (*p)
+    {
+      while (*p == ',' || *p == ' ')
+       p++;
+      m (&p, "#<imm>", "A_IMM");
+      m (&p, "R0", "A_R0");
+      m (&p, "<REG_N>", "A_REG_N");
+      m (&p, "@<REG_N>+", "A_INC_N");
+      m (&p, "@<REG_N>", "A_IND_N");
+      m (&p, "@-<REG_N>", "A_DEC_N");
+      m (&p, "<REG_M>", " A_REG_M");
+      m (&p, "@<REG_M>+", "A_INC_M");
+      m (&p, "@<REG_M>", "A_IND_M");
+      m (&p, "@-<REG_M>", "A_DEC_M");
+      m (&p, "@(<disp>,PC)", "A_DISP_PC");
+      m (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
+      m (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
+      m (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
+      m (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
+      m (&p, "@(<disp>,GBR)", "A_DISP_GBR");
+      m (&p, "@(R0,GBR)", "A_R0_GBR");
+      m (&p, "<bdisp8>", "A_BDISP8");
+      m (&p, "<bdisp12>", "A_BDISP12");
+      m (&p, "SR", "A_SR");
+      m (&p, "GBR", "A_GBR");
+      m (&p, "VBR", "A_VBR");
+      m (&p, "MACH", "A_MACH");
+      m (&p, "MACL", "A_MACL");
+      m (&p, "PR", "A_PR");
+
+    }
+  printf ("},{");
+
+  p = o->code;
+  while (*p)
+    {
+      m (&p, "0000", "HEX_0");
+      m (&p, "0001", "HEX_1");
+      m (&p, "0010", "HEX_2");
+      m (&p, "0011", "HEX_3");
+      m (&p, "0100", "HEX_4");
+      m (&p, "0101", "HEX_5");
+      m (&p, "0110", "HEX_6");
+      m (&p, "0111", "HEX_7");
+
+      m (&p, "1000", "HEX_8");
+      m (&p, "1001", "HEX_9");
+      m (&p, "1010", "HEX_A");
+      m (&p, "1011", "HEX_B");
+      m (&p, "1100", "HEX_C");
+      m (&p, "1101", "HEX_D");
+      m (&p, "1110", "HEX_E");
+      m (&p, "1111", "HEX_F");
+      m (&p, "i8*1....", "IMM_8");
+      m (&p, "i4*1", "IMM_4");
+      m (&p, "i8p4....", "PCRELIMM_8BY4");
+      m (&p, "i8p2....", "PCRELIMM_8BY2");
+      m (&p, "i8*2....", "IMM_8BY2");
+      m (&p, "i4*2", "IMM_4BY2");
+      m (&p, "i8*4....", "IMM_8BY4");
+      m (&p, "i4*4", "IMM_4BY4");
+      m (&p, "i12.........", "BRANCH_12");
+      m (&p, "i8p1....", "BRANCH_8");
+      m (&p, "nnnn", "REG_N");
+      m (&p, "mmmm", "REG_M");
+
+    }
+  printf ("}},\n");
+}
+
+qfunc (a, b)
+     op *a;
+     op *b;
+{
+  char bufa[9];
+  char bufb[9];
+  memcpy (bufa, a->code, 4);
+  memcpy (bufa + 4, a->code + 12, 4);
+  bufa[8] = 0;
+
+  memcpy (bufb, b->code, 4);
+  memcpy (bufb + 4, b->code + 12, 4);
+  bufb[8] = 0;
+  return (strcmp (bufa, bufb));
+}
+
+
+sorttab ()
+{
+  op *p = tab;
+
+  int len = 0;
+
+  while (p->name)
+    {
+      p++;
+      len++;
+    }
+
+  qsort (tab, len, sizeof (*p), qfunc);
+
+}
+
+/* Convert a string of 4 binary digits into an int */
+
+static
+int
+bton (s)
+     char *s;
+
+{
+  int n = 0;
+  int v = 8;
+  while (v)
+    {
+      if (*s == '1')
+       n |= v;
+      v >>= 1;
+      s++;
+    }
+  return n;
+}
+
+static char table[1 << 16];
+
+/* Take an opcode expand all varying fields in it out and fill all the 
+  right entries in 'table' with the opcode index*/
+    
+expand_opcode (shift, val, i, s)
+     char *s;
+{
+  int j;
+
+  if (*s == 0)
+    {
+      table[val] = i;
+    }
+  else
+    {
+      switch (s[0])
+       {
+
+       case '0':
+       case '1':
+         {
+
+           int n = bton (s);
+           if (n >= 0)
+             {
+               expand_opcode (shift - 4, val | (n << shift), i, s + 4);
+             }
+           break;
+         }
+       case 'n':
+       case 'm':
+         for (j = 0; j < 16; j++)
+           {
+             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
+
+           }
+         break;
+
+       default:
+         for (j = 0; j < (1 << (shift + 4)); j++)
+           {
+             table[val | j] = i;
+           }
+       }
+    }
+}
+
+/* Print the jump table used to index an opcode into a switch
+  statement entry */
+static void
+
+dumptable ()
+{
+  int lump = 256;
+  int online = 16;
+
+  int i = 0;
+
+  while (i < 1 << 16)
+    {
+      int j = 0;
+      int nc = 0;
+
+      printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
+
+      while (j < lump)
+       {
+         int k = 0;
+         while (k < online)
+           {
+             printf ("%2d", table[i + j + k]);
+             if (j + k < lump)
+               printf (",");
+
+             k++;
+           }
+         j += k;
+         printf ("\n");
+       }
+      i += j;
+      printf ("};\n");
+    }
+
+}
+
+
+static void
+filltable ()
+{
+  op *p;
+  int index = 1;
+
+  sorttab ();
+  for (p = tab; p->name; p++)
+    {
+      p->index = index++;
+      expand_opcode (12, 0, p->index, p->code);
+    }
+}
+
+static void 
+gensim ()
+{
+  op *p;
+  int j;
+
+  printf ("{\n");
+  printf ("switch (jump_table[iword]) {\n");
+
+  for (p = tab; p->name; p++)
+    {
+      int sextbit = -1;
+   
+      char *s = p->code;
+
+      printf ("\/\* %s %s *\/\n", p->name, p->code);
+      printf ("case %d:      \n", p->index);
+
+      printf ("{\n");
+      while (*s)
+       {
+         switch (*s)
+           {
+           case '0':
+           case '1':
+           case '.':
+             s += 4;
+             break;
+           case 'n':
+             printf ("int n =  (iword >>8) & 0xf;\n");
+             s += 4;
+             break;
+           case 'm':
+             printf ("int m =  (iword >>4) & 0xf;\n");
+             s += 4;
+
+             break;
+
+           case 'i':
+             printf ("int i = (iword & 0x");
+
+             switch (s[1])
+               {
+               case '4':
+                 printf ("f");
+                 break;
+               case '8':
+                 printf ("ff");
+                 break;
+               case '1':
+                 sextbit = 12;
+                 
+                 printf ("fff");
+                 break;
+               }
+             printf (")");
+
+             switch (s[3])
+               {
+               case '1':
+                 break;
+               case '2':
+                 printf ("<<1");
+                 break;
+               case '4':
+                 printf ("<<2");
+                 break;
+               }
+             printf (";\n");
+             s += 4;
+           }
+       }
+      if (sextbit>0) 
+       {
+         printf("i = (i ^ (1<<%d))-(1<<%d);\n",sextbit-1,sextbit-1);
+       }
+      
+      for (j = 0; j < 10; j++)
+       {
+         if (p->stuff[j])
+           {
+             printf ("%s\n", p->stuff[j]);
+           }
+       }
+      printf ("break;\n", p->stuff);
+      printf ("}\n");
+    }
+  printf ("}\n}\n");
+}
+
+
+int
+main (ac, av)
+     char **av;
+
+{
+  if (ac > 1)
+    {
+      if (strcmp (av[1], "-t") == 0)
+       {
+         gengastab ();
+       }
+      else if (strcmp (av[1], "-s") == 0)
+       {
+         filltable ();
+         dumptable ();
+
+       }
+      else if (strcmp (av[1], "-x") == 0)
+       {
+         filltable ();
+         gensim ();
+       }
+    }
+  else
+    {
+      genopc ();
+    }
+  return 0;
+}
diff --git a/sim/sh/interp.c b/sim/sh/interp.c
new file mode 100644 (file)
index 0000000..152ab05
--- /dev/null
@@ -0,0 +1,392 @@
+#define MSIZE (256*1024)
+#define MMASKL ((MSIZE -1) & ~3)
+#define MMASKW ((MSIZE -1) & ~1)
+#define MMASKB ((MSIZE -1) & ~0)
+/* Simulator for the Hitachi SH architecture.
+
+   Written by Steve Chamberlain of Cygnus Support.
+   sac@cygnus.com
+
+   This file is part of SH sim
+
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   Cygnus offers the following for use in the public domain.  Cygnus
+   makes no warranty with regard to the software or it's performance
+   and the user accepts the software "AS IS" with all faults.
+
+   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
+   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+*/
+
+#include <signal.h>
+#include <sys/times.h>
+#include <sys/param.h>
+
+#define O_RECOMPILE 85
+#define DEFINE_TABLE
+
+#define DISASSEMBLER_TABLE
+
+#define SBIT(x) ((x)&sbit)
+#define R0 saved_state.asregs.regs[0]
+#define Rn saved_state.asregs.regs[n]
+#define Rm saved_state.asregs.regs[m]
+
+#define UR0 (unsigned long)(saved_state.asregs.regs[0])
+#define UR (unsigned long)R
+#define UR (unsigned long)R
+
+#define SR0 saved_state.asregs.regs[0]
+
+#define GBR saved_state.asregs.gbr
+#define VBR saved_state.asregs.vbr
+#define MACH saved_state.asregs.mach
+#define MACL saved_state.asregs.macl
+#define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
+#define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
+
+#define PC pc
+#define C cycles
+
+#define LMEM(x) *((long *)(memory+(x&maskl)))
+#define BMEM(x) *((char *)(memory+(x&maskb)))
+#define UWMEM(x) *((unsigned short *)(memory+(x&maskw)))
+#define SWMEM(x) *((short *)(memory+(x&maskw)))
+#define WLAT(x,value)  (LMEM(x) = value)
+#define RLAT(x)  (LMEM(x))
+
+#define WWAT(x,value)  (UWMEM(x) = value)
+#define RSWAT(x)  (SWMEM(x))
+#define RUWAT(x)  (UWMEM(x))
+
+#define WBAT(x,value)  (BMEM(x) = value)
+#define RBAT(x)  (BMEM(x))
+
+#define SEXT(x)     ((int)((char)x))
+#define SEXTW(y)    ((int)((short)y))
+#define M saved_state.asregs.sr.bits.m
+#define Q saved_state.asregs.sr.bits.q
+#define SL(TEMPPC)  iword= RUWAT(TEMPPC); goto top;
+int debug;
+typedef union
+{
+
+  struct
+    {
+
+      int regs[16];
+      int pc;
+      int pr;
+
+      int gbr;
+      int vbr;
+      int mach;
+      int macl;
+
+
+      union
+       {
+         struct
+           {
+             int d0:22;
+             int m:1;
+             int q:1;
+             int i:4;
+             int d1:2;
+             int s:1;
+             int t:1;
+           }
+         bits;
+         int word;
+       }
+      sr;
+      int ticks;
+      int cycles;
+      int insts;
+      unsigned char *memory;
+      int exception;
+
+    }
+  asregs;
+  int asints[25];
+
+}
+
+saved_state_type;
+
+
+
+saved_state_type saved_state;
+
+
+
+/*#include "../opcodes/sh-opc.h"*/
+
+
+static int
+get_now ()
+{
+  struct tms b;
+  times (&b);
+  return b.tms_utime + b.tms_stime;
+}
+
+static int
+now_persec ()
+{
+  return HZ;
+}
+
+/* simulate a monitor trap */
+trap (i, regs)
+     int *regs;
+{
+  switch (i)
+    {
+    case 1:
+      printf ("%c", regs[0]);
+      break;
+    case 2:
+      saved_state.asregs.exception = SIGQUIT;
+      break;
+    case 255:
+      saved_state.asregs.exception = SIGILL;
+      break;
+    }
+
+}
+void
+control_c (sig, code, scp, addr)
+     int sig;
+     int code;
+     char *scp;
+     char *addr;
+{
+  saved_state.asregs.exception = SIGINT;
+}
+
+
+int div1(R,m,n,T)
+     int *R;
+     int m;
+     int n;
+     int T;
+{
+  unsigned long tmp0;
+  unsigned char old_q, tmp1;
+  
+  old_q = Q;
+  Q= R[n] <0;
+  
+  R[n] <<=1;
+  R[n] |= T;
+  
+  switch (old_q) 
+    {
+    case 0:
+      switch (M) 
+       {
+       case 0:
+         tmp0 = R[n];
+         R[n] -= R[m];
+         tmp1 = (R[n] > tmp0) != Q;
+         break;
+       case 1:
+         tmp0 = R[n];
+         R[n] += R[m];
+         tmp1 = (R[n] < tmp0) == Q;
+         break;
+       }
+      break;
+    case 1:
+      switch (M)
+       {
+       case 0:
+         tmp0 = R[n];
+         R[n] += R[m];
+         tmp1 = (R[n] < tmp0) != Q;
+         break;
+       case 1:
+         tmp0 = R[n];
+         R[n] -= R[m];
+         tmp1 = (R[n] > tmp0) == Q;
+         break;
+       }
+      break;
+
+    }
+
+  T=(Q==M);  
+return T;  
+
+}
+
+     
+int
+sim_resume (step)
+{
+  static int init1;
+  int pc;
+register  int cycles = 0;
+register  int insts = 0;
+  int tick_start = get_now ();
+  void (*prev) ();
+  extern unsigned char sh_jump_table0[];
+
+  register unsigned char *jump_table = sh_jump_table0;
+
+  register int *R = &(saved_state.asregs.regs[0]);
+  register int T;
+  register int PR;
+
+  register int maskb = MMASKB;
+  register int maskw = MMASKW;
+  register int maskl = MMASKL;
+  register unsigned char *memory = saved_state.asregs.memory;
+  register int sbit = (1<<31);
+  
+  prev = signal (SIGINT, control_c);
+
+  if (step)
+    {
+      saved_state.asregs.exception = SIGTRAP;
+    }
+  else
+    {
+      saved_state.asregs.exception = 0;
+    }
+
+  pc = saved_state.asregs.pc;
+  PR = saved_state.asregs.pr;
+  T = saved_state.asregs.sr.bits.t;
+
+  do
+    {
+      unsigned int iword = RUWAT (pc);
+      unsigned long ult;
+
+      insts++;
+    top:
+
+#include "code.c"
+
+      pc += 2;
+      cycles++;
+    }
+  while (!saved_state.asregs.exception);
+
+  if (saved_state.asregs.exception == SIGILL) 
+    {
+      pc-=2;
+    }
+  
+  saved_state.asregs.ticks += get_now () - tick_start;
+  saved_state.asregs.cycles += cycles;
+  saved_state.asregs.insts += insts;
+  saved_state.asregs.pc = pc;
+  saved_state.asregs.sr.bits.t = T;
+  saved_state.asregs.pr = PR;
+
+  signal (SIGINT, prev);
+}
+
+
+
+void
+sim_write (addr, buffer, size)
+     long int addr;
+     unsigned char *buffer;
+     int size;
+{
+  int i;
+  init_pointers ();
+
+  for (i = 0; i < size; i++)
+    {
+      saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
+    }
+}
+
+void
+sim_read (addr, buffer, size)
+     long int addr;
+     char *buffer;
+     int size;
+{
+  int i;
+
+  init_pointers ();
+
+  for (i = 0; i < size; i++)
+    {
+      buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
+    }
+}
+
+
+sim_store_register (rn, value)
+     int rn;
+     int value;
+{
+  saved_state.asregs.regs[rn] = value;
+}
+
+sim_fetch_register (rn, buf)
+     int rn;
+     char *buf;
+{
+
+  int value = ((int *) (&saved_state))[rn];
+
+  buf[0] = value >> 24;
+  buf[1] = value >> 16;
+  buf[2] = value >> 8;
+  buf[3] = value >> 0;
+
+}
+
+int
+sim_trace ()
+{
+
+  int i;
+  return 0;
+
+}
+
+sim_stop_signal ()
+{
+  return saved_state.asregs.exception;
+}
+
+sim_set_pc (x)
+{
+  saved_state.asregs.pc = x;
+}
+
+
+
+sim_info ()
+{
+  double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
+  double virttime = saved_state.asregs.cycles / 10.0e6;
+
+  printf ("\n\ninstructions executed  %10d\n", saved_state.asregs.insts);
+  printf ("cycles                  %10d\n", saved_state.asregs.cycles);
+  printf ("real time taken        %10.4f\n", timetaken);
+  printf ("cycles/second           %10d\n", (int)(saved_state.asregs.cycles/timetaken));
+  printf ("virtual time taked     %10.4f\n", virttime);
+  printf ("simulation ratio       %10.4f\n", virttime / timetaken);
+}
+
+init_pointers ()
+{
+  if (!saved_state.asregs.memory)
+    {
+      saved_state.asregs.memory = (unsigned char *) (calloc (64, MSIZE / 64));
+    }
+}
diff --git a/sim/sh/run.c b/sim/sh/run.c
new file mode 100644 (file)
index 0000000..f7d987f
--- /dev/null
@@ -0,0 +1,98 @@
+/* run front end support for H8/500
+   Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+
+This file is part of H8300 SIM
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* Steve Chamberlain
+   sac@cygnus.com */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+int
+main (ac, av)
+     int ac;
+     char **av;
+{
+  bfd *abfd;
+  bfd_vma start_address;
+  asection *s;
+  int i;
+  int verbose = 0;
+  int trace = 0;
+  char *name = "";
+  for (i = 1; i < ac; i++)
+    {
+      if (strcmp (av[i], "-v") == 0)
+       {
+         verbose = 1;
+       }
+      else if (strcmp (av[i], "-t") == 0)
+       {
+         trace = 1;
+       }
+      else
+       {
+         name = av[i];
+       }
+    }
+  if (verbose)
+    {
+      printf ("run %s\n", name);
+    }
+  abfd = bfd_openr (name, "coff-sh");
+  if (abfd)
+    {
+
+      if (bfd_check_format (abfd, bfd_object))
+       {
+
+         for (s = abfd->sections; s; s = s->next)
+           {
+             unsigned char *buffer = malloc (bfd_section_size (abfd, s));
+             bfd_get_section_contents (abfd,
+                                       s,
+                                       buffer,
+                                       0,
+                                       bfd_section_size (abfd, s));
+             sim_write (s->vma, buffer, bfd_section_size (abfd, s));
+           }
+
+         start_address = bfd_get_start_address (abfd);
+         sim_set_pc (start_address);
+         if (trace)
+           {
+             int done = 0;
+             while (!done)
+               {
+                 done = sim_trace ();
+               }
+           }
+         else
+           {
+             sim_resume (0, 0);
+           }
+         if (verbose)
+           sim_info ();
+
+         return 0;
+       }
+    }
+
+  return 1;
+}