New stuff for SH.

This commit is contained in:
Steve Chamberlain 1993-04-27 01:02:38 +00:00
parent 31568a6f41
commit 594266fc8a
8 changed files with 1445 additions and 0 deletions

View file

@ -29,6 +29,7 @@ configure.in
endian.c
h8300
h8500
sh
z8k
Do-last:

38
sim/sh/.Sanitize Normal file
View file

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

4
sim/sh/ChangeLog Normal file
View file

@ -0,0 +1,4 @@
Mon Apr 26 18:01:10 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* created

176
sim/sh/Makefile.in Normal file
View file

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

33
sim/sh/configure.in Normal file
View file

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

703
sim/sh/gencode.c Normal file
View file

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

392
sim/sh/interp.c Normal file
View file

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

98
sim/sh/run.c Normal file
View file

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