URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/tags/nog_patch_55/or1ksim/cpu
- from Rev 1435 to Rev 1765
- ↔ Reverse comparison
Rev 1435 → 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,331
# Makefile.in generated by automake 1.6.3 from Makefile.am. |
# @configure_input@ |
|
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
# 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 |
# |
# 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. |
# |
SHELL = @SHELL@ |
|
srcdir = @srcdir@ |
top_srcdir = @top_srcdir@ |
VPATH = @srcdir@ |
prefix = @prefix@ |
exec_prefix = @exec_prefix@ |
|
bindir = @bindir@ |
sbindir = @sbindir@ |
libexecdir = @libexecdir@ |
datadir = @datadir@ |
sysconfdir = @sysconfdir@ |
sharedstatedir = @sharedstatedir@ |
localstatedir = @localstatedir@ |
libdir = @libdir@ |
infodir = @infodir@ |
mandir = @mandir@ |
includedir = @includedir@ |
oldincludedir = /usr/include |
pkgdatadir = $(datadir)/@PACKAGE@ |
pkglibdir = $(libdir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
top_builddir = ../.. |
|
ACLOCAL = @ACLOCAL@ |
AUTOCONF = @AUTOCONF@ |
AUTOMAKE = @AUTOMAKE@ |
AUTOHEADER = @AUTOHEADER@ |
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd |
INSTALL = @INSTALL@ |
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
INSTALL_DATA = @INSTALL_DATA@ |
install_sh_DATA = $(install_sh) -c -m 644 |
install_sh_PROGRAM = $(install_sh) -c |
install_sh_SCRIPT = $(install_sh) -c |
INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
INSTALL_HEADER = $(INSTALL_DATA) |
transform = @program_transform_name@ |
NORMAL_INSTALL = : |
PRE_INSTALL = : |
POST_INSTALL = : |
NORMAL_UNINSTALL = : |
PRE_UNINSTALL = : |
POST_UNINSTALL = : |
build_alias = @build_alias@ |
build_triplet = @build@ |
host_alias = @host_alias@ |
host_triplet = @host@ |
target_alias = @target_alias@ |
target_triplet = @target@ |
|
EXEEXT = @EXEEXT@ |
OBJEXT = @OBJEXT@ |
PATH_SEPARATOR = @PATH_SEPARATOR@ |
AMTAR = @AMTAR@ |
AR = @AR@ |
ARFLAGS = @ARFLAGS@ |
AWK = @AWK@ |
BUILD_DIR = @BUILD_DIR@ |
CC = @CC@ |
CFLAGS = @CFLAGS@ |
CPU_ARCH = @CPU_ARCH@ |
DEPDIR = @DEPDIR@ |
INCLUDES = @INCLUDES@ |
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
LOCAL_CFLAGS = @LOCAL_CFLAGS@ |
LOCAL_DEFS = @LOCAL_DEFS@ |
MAKE_SHELL = @MAKE_SHELL@ |
PACKAGE = @PACKAGE@ |
RANLIB = @RANLIB@ |
STRIP = @STRIP@ |
SUMVERSION = @SUMVERSION@ |
TERMCAP_LIB = @TERMCAP_LIB@ |
VERSION = @VERSION@ |
am__include = @am__include@ |
am__quote = @am__quote@ |
host = @host@ |
host_cpu = @host_cpu@ |
host_os = @host_os@ |
install_sh = @install_sh@ |
|
noinst_LIBRARIES = libarch.a |
libarch_a_SOURCES = execute.c |
subdir = cpu/dlx |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = $(top_builddir)/config.h |
CONFIG_CLEAN_FILES = |
LIBRARIES = $(noinst_LIBRARIES) |
|
libarch_a_AR = $(AR) cru |
libarch_a_LIBADD = |
am_libarch_a_OBJECTS = execute.$(OBJEXT) |
libarch_a_OBJECTS = $(am_libarch_a_OBJECTS) |
|
DEFS = @DEFS@ |
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) |
CPPFLAGS = @CPPFLAGS@ |
LDFLAGS = @LDFLAGS@ |
LIBS = @LIBS@ |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
am__depfiles_maybe = depfiles |
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/execute.Po |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ |
DIST_SOURCES = $(libarch_a_SOURCES) |
DIST_COMMON = Makefile.am Makefile.in |
SOURCES = $(libarch_a_SOURCES) |
|
all: all-am |
|
.SUFFIXES: |
.SUFFIXES: .c .o .obj |
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) |
cd $(top_srcdir) && \ |
$(AUTOMAKE) --gnu cpu/dlx/Makefile |
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) |
|
clean-noinstLIBRARIES: |
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) |
libarch.a: $(libarch_a_OBJECTS) $(libarch_a_DEPENDENCIES) |
-rm -f libarch.a |
$(libarch_a_AR) libarch.a $(libarch_a_OBJECTS) $(libarch_a_LIBADD) |
$(RANLIB) libarch.a |
|
mostlyclean-compile: |
-rm -f *.$(OBJEXT) core *.core |
|
distclean-compile: |
-rm -f *.tab.c |
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Po@am__quote@ |
|
distclean-depend: |
-rm -rf ./$(DEPDIR) |
|
.c.o: |
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< |
|
.c.obj: |
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ |
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
$(COMPILE) -c `cygpath -w $<` |
CCDEPMODE = @CCDEPMODE@ |
uninstall-info-am: |
|
ETAGS = etags |
ETAGSFLAGS = |
|
tags: TAGS |
|
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; } \ |
END { for (i in files) print i; }'`; \ |
mkid -fID $$unique |
|
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; } \ |
END { for (i in files) print i; }'`; \ |
test -z "$(ETAGS_ARGS)$$tags$$unique" \ |
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_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 |
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) |
|
top_distdir = ../.. |
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) |
|
distdir: $(DISTFILES) |
@list='$(DISTFILES)'; for file in $$list; do \ |
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ |
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ |
if test "$$dir" != "$$file" && test "$$dir" != "."; then \ |
dir="/$$dir"; \ |
$(mkinstalldirs) "$(distdir)$$dir"; \ |
else \ |
dir=''; \ |
fi; \ |
if test -d $$d/$$file; then \ |
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 $(LIBRARIES) |
|
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_STRIP_FLAG=-s \ |
`test -z '$(STRIP)' || \ |
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install |
mostlyclean-generic: |
|
clean-generic: |
|
distclean-generic: |
-rm -f Makefile $(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-noinstLIBRARIES mostlyclean-am |
|
distclean: distclean-am |
|
distclean-am: clean-am distclean-compile distclean-depend \ |
distclean-generic distclean-tags |
|
dvi: dvi-am |
|
dvi-am: |
|
info: info-am |
|
info-am: |
|
install-data-am: |
|
install-exec-am: |
|
install-info: install-info-am |
|
install-man: |
|
installcheck-am: |
|
maintainer-clean: maintainer-clean-am |
|
maintainer-clean-am: distclean-am maintainer-clean-generic |
|
mostlyclean: mostlyclean-am |
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic |
|
uninstall-am: uninstall-info-am |
|
.PHONY: GTAGS all all-am check check-am clean clean-generic \ |
clean-noinstLIBRARIES distclean distclean-compile \ |
distclean-depend distclean-generic distclean-tags distdir dvi \ |
dvi-am info info-am install install-am install-data \ |
install-data-am install-exec install-exec-am install-info \ |
install-info-am install-man install-strip installcheck \ |
installcheck-am installdirs maintainer-clean \ |
maintainer-clean-generic mostlyclean mostlyclean-compile \ |
mostlyclean-generic tags uninstall uninstall-am \ |
uninstall-info-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/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/Makefile.am
0,0 → 1,22
# Makefile -- Makefile for DLX architecture 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. |
# |
|
noinst_LIBRARIES = libarch.a |
libarch_a_SOURCES = execute.c |
dlx
Property changes :
Added: svn:ignore
## -0,0 +1 ##
+Makefile
Index: common/execute.h
===================================================================
--- common/execute.h (nonexistent)
+++ common/execute.h (revision 1765)
@@ -0,0 +1,62 @@
+/* execute.h -- Header file for architecture dependent execute.c
+ 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. */
+
+struct cpu_state {
+ /* General purpose registers. */
+ uorreg_t reg[MAX_GPRS];
+
+ /* Sprs */
+ uorreg_t sprs[MAX_SPRS];
+
+ /* Effective address of instructions that have an effective address. This is
+ * only used to get dump_exe_log correct */
+ oraddr_t insn_ea;
+
+ /* Is current instruction in execution in a delay slot? */
+ int delay_insn;
+
+ /* Program counter (and translated PC) */
+ oraddr_t pc;
+
+ /* Delay instruction effective address register */
+ oraddr_t pc_delay;
+
+ /* Decoding of the just executed instruction. Only used in analysis(). */
+ struct iqueue_entry iqueue;
+
+ /* decoding of the instruction that was executed before this one. Only used
+ * in analysis(). */
+ struct iqueue_entry icomplet;
+};
+
+extern struct cpu_state cpu_state;
+
+#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0)
+
+/*extern machword eval_operand(char *srcoperand,int* breakpoint);
+extern void set_operand(char *dstoperand, unsigned long value,int* breakpoint);*/
+void dumpreg();
+inline void dump_exe_log();
+inline int cpu_clock ();
+void cpu_reset ();
+uorreg_t evalsim_reg(unsigned int regno);
+void setsim_reg(unsigned int regno, uorreg_t value);
+
+extern oraddr_t pcnext;
+int depend_operands(struct iqueue_entry *prev, struct iqueue_entry *next);
Index: common/stats.c
===================================================================
--- common/stats.c (nonexistent)
+++ common/stats.c (revision 1765)
@@ -0,0 +1,293 @@
+/* stats.c -- Various statistics about instruction scheduling etc.
+ 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. */
+
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "abstract.h"
+#include "sim-config.h"
+#include "spr_defs.h"
+#include "opcode/or32.h"
+#include "execute.h"
+#include "sprs.h"
+#include "debug.h"
+#include "stats.h"
+
+struct branchstat {
+ int taken;
+ int nottaken;
+ int forward;
+ int backward;
+};
+
+/* See also enum insn_type in abstract.h */
+const char func_unit_str[30][30] = { "unknown", "exception", "arith", "shift", "compare",
+ "branch", "jump", "load", "store", "movimm", "move", "extend", "nop", "mac" };
+
+struct dstats_entry dstats[DSTATS_LEN]; /* dependency stats */
+struct sstats_entry sstats[SSTATS_LEN]; /* single stats */
+struct fstats_entry fstats[FSTATS_LEN]; /* functional units stats */
+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 = {0}; /* RAW hazard 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;
+
+ debug(7,"adddstats start\n");
+
+ 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));
+}
+
+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 (config.ic.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 (testsprbits(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 (testsprbits(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 < MAX_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;
+ }
+ #if 0
+ PRINTF("Byte ADD: %d instructions\n", or1k_mstats.byteadd);
+ #endif
+}
Index: common/abstract.c
===================================================================
--- common/abstract.c (nonexistent)
+++ common/abstract.c (revision 1765)
@@ -0,0 +1,1145 @@
+/* abstract.c -- Abstract entities
+ 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. */
+
+/* Abstract memory and routines that go with this. I need to
+add all sorts of other abstract entities. Currently we have
+only memory. */
+
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+
+#include "arch.h"
+#include "parse.h"
+#include "abstract.h"
+#include "sim-config.h"
+#include "labels.h"
+#include "except.h"
+#include "debug_unit.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
+#include "support/profile.h"
+#include "dmmu.h"
+#include "dcache_model.h"
+#include "icache_model.h"
+#include "debug.h"
+#include "stats.h"
+
+extern char *disassembled;
+
+/* Pointer to memory area descriptions that are assigned to individual
+ peripheral devices. */
+struct dev_memarea *dev_list;
+
+/* Temporary variable to increase speed. */
+struct dev_memarea *cur_area;
+
+/* Pointer to memory controller device descriptor. */
+struct dev_memarea *mc_area = (struct dev_memarea *)0;
+
+/* These are set by mmu if cache inhibit bit is set for current acces. */
+int data_ci, insn_ci;
+
+/* Virtual address of current access. */
+oraddr_t cur_vadd;
+
+/* Calculates bit mask to fit the data */
+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.) */
+void register_memoryarea_mask(oraddr_t addr_mask, oraddr_t addr_compare,
+ uint32_t size, unsigned granularity, unsigned mc_dev,
+ uint32_t (readfunc)(oraddr_t, void *),
+ void (writefunc)(oraddr_t, uint32_t, void *),
+ void *dat)
+{
+ struct dev_memarea **pptmp;
+ unsigned int size_mask = bit_mask (size);
+ int found_error = 0;
+ addr_compare &= addr_mask;
+
+ debug(5, "addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %08"PRIx32", gran %iB\n",
+ addr_mask, addr_compare, addr_compare | bit_mask (size), size,
+ granularity);
+ /* 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", gran %iB\n",
+ addr_mask, addr_compare, addr_compare | bit_mask (size), size,
+ granularity);
+ }
+ found_error = 1;
+ fprintf (stderr, "and\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
+ ", size %08"PRIx32", gran %iB\n",
+ (*pptmp)->addr_mask, (*pptmp)->addr_compare,
+ (*pptmp)->addr_compare | (*pptmp)->size_mask,
+ (*pptmp)->size, (*pptmp)->granularity);
+ }
+
+ 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)->granularity = granularity;
+ (*pptmp)->readfunc = readfunc;
+ (*pptmp)->writefunc = writefunc;
+ (*pptmp)->log = 0;
+ (*pptmp)->delayr = 2;
+ (*pptmp)->delayw = 2;
+ (*pptmp)->priv_dat = dat;
+ (*pptmp)->chip_select = -1;
+ (*pptmp)->next = NULL;
+}
+
+/* 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 means that this device will be checked first for match
+ and will be accessed in case of overlaping memory spaces.
+ Only one device can have this set to 1 (used for memory controller) */
+void register_memoryarea(oraddr_t addr, uint32_t size, unsigned granularity,
+ unsigned mc_dev,
+ uint32_t (readfunc)(oraddr_t, void *),
+ void (writefunc)(oraddr_t, uint32_t, void *),
+ void *dat)
+{
+ unsigned int size_mask = bit_mask (size);
+ unsigned int addr_mask = ~size_mask;
+ register_memoryarea_mask (addr_mask, addr & addr_mask,
+ size_mask + 1, granularity, mc_dev,
+ readfunc, writefunc, dat);
+}
+
+
+/* Check if access is to registered area of memory. */
+inline 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;
+}
+
+/* Finds the memory area for the address and adjust the read and write delays for it. */
+void adjust_rw_delay(oraddr_t memaddr, unsigned int delayr, unsigned int delayw)
+{
+ if (verify_memoryarea(memaddr)) {
+ cur_area->delayr = delayr;
+ cur_area->delayw = delayw;
+ }
+}
+
+/* for cpu accesses
+ *
+ * STATISTICS: check cpu/common/parse.c
+ */
+inline uint32_t evalsim_mem32(oraddr_t memaddr)
+{
+ return(evalsim_mem32_atomic(memaddr, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline uint32_t evalsim_mem32_void(oraddr_t memaddr)
+{
+ return(evalsim_mem32_atomic(memaddr, 0));
+}
+
+uint32_t evalsim_mem32_atomic(oraddr_t memaddr, int cpu_access)
+{
+ uint32_t temp = 0;
+
+ if (verify_memoryarea(memaddr)) {
+ switch(cur_area->granularity) {
+ case 4:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat);
+ break;
+ case 1:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat) << 24;
+ temp |= cur_area->readfunc(memaddr + 1, cur_area->priv_dat) << 16;
+ temp |= cur_area->readfunc(memaddr + 2, cur_area->priv_dat) << 8;
+ temp |= cur_area->readfunc(memaddr + 3, cur_area->priv_dat);
+ break;
+ case 2:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat) << 16;
+ temp |= cur_area->readfunc(memaddr + 2, cur_area->priv_dat);
+ break;
+ default:
+ /* if you add new memory granularity be sure to check the formula
+ * below for the read delay and fix it if necessery
+ */
+ PRINTF("unknown/unhandled memory granularuty\n");
+ exit(-1);
+ }
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayr * (4 / cur_area->granularity);
+ }
+ return temp;
+}
+
+/* for cpu accesses */
+inline uint16_t evalsim_mem16(oraddr_t memaddr)
+{
+ return(evalsim_mem16_atomic(memaddr, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline uint16_t evalsim_mem16_void(oraddr_t memaddr)
+{
+ return(evalsim_mem16_atomic(memaddr, 0));
+}
+
+uint16_t evalsim_mem16_atomic(oraddr_t memaddr, int cpu_access)
+{
+ uint32_t temp = 0;
+
+ if (verify_memoryarea(memaddr)) {
+ switch(cur_area->granularity) {
+ case 1:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat) << 8;
+ temp |= cur_area->readfunc(memaddr + 1, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayr * 2;
+ break;
+ case 2:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayr;
+ break;
+ case 4:
+ temp = evalsim_mem32_atomic (memaddr & ~UINT32_C(3), cpu_access);
+ if (memaddr & 2)
+ temp &= 0xffff;
+ else
+ temp >>= 16;
+ break;
+ default:
+ /* if you add new memory granularity be sure to check the formula
+ * below for the read delay and fix it if necessery
+ */
+ PRINTF("unknown/unhandled memory granularuty\n");
+ exit(-1);
+ }
+ }
+ return temp;
+}
+
+/* for cpu accesses */
+inline uint8_t evalsim_mem8(oraddr_t memaddr)
+{
+ return(evalsim_mem8_atomic(memaddr, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline uint8_t evalsim_mem8_void(oraddr_t memaddr)
+{
+ return(evalsim_mem8_atomic(memaddr, 0));
+}
+
+uint8_t evalsim_mem8_atomic(oraddr_t memaddr, int cpu_access)
+{
+ uint32_t temp = 0;
+
+ if (verify_memoryarea(memaddr)) {
+ switch(cur_area->granularity) {
+ case 1:
+ temp = cur_area->readfunc(memaddr, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayr;
+ break;
+ case 2:
+ temp = evalsim_mem16_atomic (memaddr & ~ADDR_C(1), cpu_access);
+ if (memaddr & 1)
+ temp &= 0xff;
+ else
+ temp >>= 8;
+ break;
+ case 4:
+ temp = evalsim_mem32_atomic (memaddr & ~ADDR_C(3), cpu_access);
+ temp >>= 8 * (3 - (memaddr & 3));
+ temp &= 0xff;
+ break;
+ default:
+ /* if you add new memory granularity be sure to check the formula
+ * below for the read delay and fix it if necessery
+ */
+ PRINTF("unknown/unhandled memory granularuty\n");
+ exit(-1);
+ }
+ }
+ return temp;
+}
+
+/* Returns 32-bit values from mem array. Big endian version.
+ *
+ * this function is only used in dumpmemory() below, so it's
+ * safe to asume it's for simulator purposes access only,
+ * hence the use of eval_mem32_void()
+ *
+ * STATISTICS OK.
+ */
+static uint32_t read_mem(oraddr_t memaddr, int* breakpoint)
+{
+ uint32_t temp;
+
+ cur_vadd = memaddr;
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
+ temp = evalsim_mem32_void(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ } else if (cur_area->log)
+ fprintf (cur_area->log, "[%"PRIxADDR"] -> read %08"PRIx32"\n", memaddr, temp);
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
+ return temp;
+}
+
+/* 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;
+
+ 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 += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
+
+ cur_vadd = memaddr;
+
+ memaddr = dmmu_translate(memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = dc_simulate_read(memaddr, 4);
+ else {
+ temp = evalsim_mem32(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(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 *breakpoint, int through_mmu,
+ int through_dc)
+{
+ uint32_t temp;
+
+ if (memaddr & 3) {
+ PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
+ return 0;
+ }
+
+ cur_vadd = memaddr;
+
+ if (through_mmu)
+ memaddr = peek_into_dtlb(memaddr, 0, through_dc);
+
+ if (through_dc)
+ temp = dc_simulate_read(memaddr, 4);
+ else {
+ temp = evalsim_mem32_void(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR
+ ") in eval_direct32()\n", memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ return temp;
+}
+
+
+/* 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;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_32 | MPROF_FETCH);
+// memaddr = simulate_ic_mmu_fetch(memaddr);
+
+ cur_vadd = memaddr;
+
+ memaddr = immu_translate(memaddr);
+
+ if (except_pending)
+ return 0;
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);
+
+ if (config.ic.enabled)
+ temp = ic_simulate_fetch(memaddr);
+ else {
+ temp = evalsim_mem32(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(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;
+
+ 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 += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
+
+ cur_vadd = memaddr;
+
+ memaddr = dmmu_translate(memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = (uint16_t)dc_simulate_read(memaddr, 2);
+ else {
+ temp = evalsim_mem16(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(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 *breakpoint, int through_mmu,
+ int through_dc)
+{
+ uint32_t temp;
+
+ if (memaddr & 1) {
+ PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
+ return 0;
+ }
+
+ cur_vadd = memaddr;
+
+ if (through_mmu)
+ memaddr = peek_into_dtlb(memaddr, 0, through_dc);
+
+ if (through_dc)
+ temp = dc_simulate_read(memaddr, 2);
+ else {
+ temp = evalsim_mem16_void(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR
+ ") in eval_direct16()\n", memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ return temp;
+}
+
+
+/* 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;
+
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_8 | MPROF_READ);
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
+
+ cur_vadd = memaddr;
+
+ memaddr = dmmu_translate(memaddr, 0);
+ if (except_pending)
+ return 0;
+
+ if (config.dc.enabled)
+ temp = (uint8_t)dc_simulate_read(memaddr, 1);
+ else {
+ temp = evalsim_mem8(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+
+ if (config.debug.enabled)
+ *breakpoint += CheckDebugUnit(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 *breakpoint, int through_mmu,
+ int through_dc)
+{
+ uint8_t temp;
+
+ cur_vadd = memaddr;
+
+ if (through_mmu)
+ memaddr = peek_into_dtlb(memaddr, 0, through_dc);
+
+ if (through_dc)
+ temp = (unsigned char)dc_simulate_read(memaddr, 1);
+ else {
+ temp = evalsim_mem8_void(memaddr);
+ if (!cur_area) {
+ PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR
+ ") in eval_direct8()\n", memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ temp = 0;
+ }
+ }
+ return temp;
+}
+
+/* for cpu accesses */
+inline void setsim_mem32(oraddr_t memaddr, uint32_t value)
+{
+ return(setsim_mem32_atomic(memaddr, value, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline void setsim_mem32_void(oraddr_t memaddr, uint32_t value)
+{
+ return(setsim_mem32_atomic(memaddr, value, 0));
+}
+
+void setsim_mem32_atomic(oraddr_t memaddr, uint32_t value, int cpu_access)
+{
+ if (verify_memoryarea(memaddr)) {
+ switch(cur_area->granularity) {
+ case 4:
+ cur_area->writefunc(memaddr, value, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw;
+ break;
+ case 1:
+ cur_area->writefunc(memaddr , (value >> 24) & 0xFF, cur_area->priv_dat);
+ cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF, cur_area->priv_dat);
+ cur_area->writefunc(memaddr + 2, (value >> 8) & 0xFF, cur_area->priv_dat);
+ cur_area->writefunc(memaddr + 3, (value ) & 0xFF, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw * 4;
+ break;
+ case 2:
+ cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF, cur_area->priv_dat);
+ cur_area->writefunc(memaddr + 2, value & 0xFFFF, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw * 2;
+ break;
+ default:
+ /* if you add new memory granularity be sure to check the formula
+ * below for the read delay and fix it if necessery
+ */
+ PRINTF("unknown/unhandled memory granularuty\n");
+ exit(-1);
+ }
+ } else {
+ PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ }
+}
+
+/* for cpu accesses */
+inline void setsim_mem16(oraddr_t memaddr, uint16_t value)
+{
+ return(setsim_mem16_atomic(memaddr, value, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline void setsim_mem16_void(oraddr_t memaddr, uint16_t value)
+{
+ return(setsim_mem16_atomic(memaddr, value, 0));
+}
+
+void setsim_mem16_atomic(oraddr_t memaddr, uint16_t value, int cpu_access)
+{
+ uint32_t temp;
+ if (verify_memoryarea(memaddr)) {
+ switch(cur_area->granularity) {
+ case 1:
+ cur_area->writefunc(memaddr, (value >> 8) & 0xFF, cur_area->priv_dat);
+ cur_area->writefunc(memaddr + 1, value & 0xFF, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw * 2;
+ break;
+ case 2:
+ cur_area->writefunc(memaddr, value & 0xFFFF, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw;
+ break;
+ case 4:
+ temp = evalsim_mem32_void(memaddr & ~ADDR_C(3));
+ temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
+ temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
+ setsim_mem32_atomic(memaddr & ~ADDR_C(3), temp, cpu_access);
+ break;
+ default:
+ /* if you add new memory granularity be sure to check the formula
+ * below for the read delay and fix it if necessery
+ */
+ PRINTF("unknown/unhandled memory granularuty\n");
+ exit(-1);
+ }
+ } else {
+ PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ }
+}
+
+/* for cpu accesses */
+inline void setsim_mem8(oraddr_t memaddr, uint8_t value)
+{
+ return(setsim_mem8_atomic(memaddr, value, 1));
+}
+
+/* for simulator accesses, the ones that cpu wouldn't do */
+inline void setsim_mem8_void(oraddr_t memaddr, uint8_t value)
+{
+ return(setsim_mem8_atomic(memaddr, value, 0));
+}
+
+void setsim_mem8_atomic(oraddr_t memaddr, uint8_t value, int cpu_access)
+{
+ uint32_t temp;
+ if (verify_memoryarea(memaddr)) {
+ switch (cur_area->granularity) {
+ case 1:
+ cur_area->writefunc(memaddr, value, cur_area->priv_dat);
+ if (cpu_access)
+ runtime.sim.mem_cycles += cur_area->delayw;
+ break;
+ case 2:
+ temp = evalsim_mem16_void (memaddr & ~ADDR_C(1));
+ temp &= 0xff << ((memaddr & 1) ? 8 : 0);
+ temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
+ setsim_mem16_atomic (memaddr & ~ADDR_C(1), temp, cpu_access);
+ break;
+ case 4:
+ temp = evalsim_mem32_void (memaddr & ~ADDR_C(3));
+ temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
+ temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
+ setsim_mem32_atomic (memaddr & ~ADDR_C(3), temp, cpu_access);
+ break;
+ }
+ } else {
+ PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
+ memaddr);
+ except_handle(EXCEPT_BUSERR, cur_vadd);
+ }
+}
+
+/* Set mem, 32-bit. Big endian version.
+ *
+ * STATISTICS OK. (the only suspicious usage is in toplevel.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)
+{
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_32 | MPROF_WRITE);
+
+ if (memaddr & 3) {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return;
+ }
+
+ cur_vadd = memaddr;
+ memaddr = dmmu_translate(memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending)
+ return;
+
+ if (config.debug.enabled) {
+ *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
+ *breakpoint += CheckDebugUnit(DebugStoreData,value);
+ }
+
+ dc_simulate_write(memaddr, value, 4);
+
+ 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* breakpoint,
+ int through_mmu, int through_dc)
+{
+
+ if (memaddr & 3) {
+ PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
+ return;
+ }
+
+ cur_vadd = memaddr;
+
+ if (through_mmu) {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ memaddr = peek_into_dtlb(memaddr, 1, through_dc);
+ }
+
+
+ /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
+ * and possibly also memory access times.
+ */
+ if (!through_dc)
+ PRINTF("WARNING: statistics might not be OK\n");
+ dc_simulate_write(memaddr, value, 4);
+
+ 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)
+{
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_16 | MPROF_WRITE);
+
+ if (memaddr & 1) {
+ except_handle (EXCEPT_ALIGN, memaddr);
+ return;
+ }
+
+ cur_vadd = memaddr;
+ memaddr = dmmu_translate(memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending)
+ return;
+
+ if (config.debug.enabled) {
+ *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
+ *breakpoint += CheckDebugUnit(DebugStoreData,value);
+ }
+
+ dc_simulate_write(memaddr, (unsigned long)value, 2);
+
+ 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* breakpoint,
+ int through_mmu, int through_dc)
+{
+
+ if (memaddr & 1) {
+ PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
+ return;
+ }
+
+ cur_vadd = memaddr;
+
+ if (through_mmu) {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ memaddr = peek_into_dtlb(memaddr, 0, through_dc);
+ }
+
+ /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
+ * and possibly also memory access times.
+ */
+ if (!through_dc)
+ PRINTF("WARNING: statistics might not be OK\n");
+ dc_simulate_write(memaddr, value, 2);
+
+ 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)
+{
+ if (config.sim.mprofile)
+ mprofile (memaddr, MPROF_8 | MPROF_WRITE);
+
+ cur_vadd = memaddr;
+ memaddr = dmmu_translate(memaddr, 1);;
+ /* If we produced exception don't set anything */
+ if (except_pending) return;
+
+ if (config.debug.enabled) {
+ *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
+ *breakpoint += CheckDebugUnit(DebugStoreData,value);
+ }
+
+ dc_simulate_write(memaddr, value, 1);
+
+ 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* breakpoint,
+ int through_mmu, int through_dc)
+{
+
+ cur_vadd = memaddr;
+
+ if (through_mmu) {
+ /* 0 - no write access, we do not want a DPF exception do we ;)
+ */
+ memaddr = peek_into_dtlb(memaddr, 0, through_dc);
+ }
+
+ /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
+ * and possibly also memory access times.
+ */
+ if (!through_dc)
+ PRINTF("WARNING: statistics might not be OK\n");
+ dc_simulate_write(memaddr, value, 1);
+
+ if (cur_area && cur_area->log)
+ fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
+ memaddr, value);
+}
+
+
+void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
+{
+ oraddr_t i, j;
+ struct label_entry *tmp;
+ int ilen = disasm ? 4 : 16;
+
+ for(i = from; i < to; i += ilen) {
+ PRINTF("%"PRIxADDR": ", i);
+ for (j = 0; j < ilen;) {
+ if (!disasm) {
+ tmp = NULL;
+ if (verify_memoryarea(i + j)) {
+ struct label_entry *entry;
+ entry = get_label(i + j);
+ if (entry)
+ PRINTF("(%s)", entry->name);
+ PRINTF("%02"PRIx8" ", evalsim_mem8(i + j));
+ } else PRINTF("XX ");
+ j++;
+ } else {
+ int breakpoint;
+ uint32_t _insn = read_mem(i, &breakpoint);
+ int index = insn_decode (_insn);
+ int len = insn_len (index);
+
+ tmp = NULL;
+ if (verify_memoryarea(i + j)) {
+ struct label_entry *entry;
+ entry = get_label(i + j);
+ if (entry)
+ PRINTF("(%s)", entry->name);
+
+ PRINTF(": %08"PRIx32" ", _insn);
+ if (index >= 0) {
+ disassemble_insn (_insn);
+ PRINTF(" %s", disassembled);
+ } else
+ PRINTF("");
+ } else PRINTF("XXXXXXXX");
+ j += len;
+ }
+ }
+ if (nl)
+ PRINTF ("\n");
+ }
+}
+
+uint32_t simmem_read_word(oraddr_t addr, void *priv_dat) {
+ return *(uint32_t *)(priv_dat + (addr & cur_area->size_mask));
+}
+
+void simmem_write_word(oraddr_t addr, uint32_t value, void *priv_dat) {
+ *(uint32_t *)(priv_dat + (addr & cur_area->size_mask)) = value;
+}
+
+uint32_t simmem_read_zero(oraddr_t addr, void *dat) {
+ if (config.sim.verbose)
+ fprintf (stderr, "WARNING: memory read from non-read memory area 0x%"
+ PRIxADDR".\n", addr);
+ return 0;
+}
+
+void simmem_write_null(oraddr_t addr, uint32_t value, void *dat) {
+ if (config.sim.verbose)
+ fprintf (stderr, "WARNING: memory write to 0x%"PRIxADDR", non-write memory area (value 0x%08"PRIx32").\n", addr, value);
+}
+
+/* Initialize memory table from a config struct */
+
+void init_memory_table ()
+{
+ /* If nothing was defined, use default memory block */
+ if (config.memory.nmemories) {
+ int i;
+ for (i = 0; i < config.memory.nmemories; i++) {
+ oraddr_t start = config.memory.table[i].baseaddr;
+ uint32_t length = config.memory.table[i].size;
+ char *type = config.memory.table[i].name;
+ int rd = config.memory.table[i].delayr;
+ int wd = config.memory.table[i].delayw;
+ int ce = config.memory.table[i].ce;
+ void *mem = malloc (length);
+
+ if (config.sim.verbose)
+ debug (1, "%"PRIxADDR" %08"PRIx32" (%"PRIi32" KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
+ start, length, length >> 10, type, ce, rd, wd);
+
+ if (!mem) {
+ fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
+ exit (-1);
+ }
+
+ register_memoryarea(start, length, 4, 0, &simmem_read_word,
+ &simmem_write_word, mem);
+ cur_area->chip_select = ce;
+ cur_area->valid = 1;
+ cur_area->delayw = wd;
+ cur_area->delayr = rd;
+ if (config.memory.table[i].log[0] != '\0') {
+ if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
+ fprintf (stderr, "WARNING: Cannot open '%s'.\n",
+ config.memory.table[i].log);
+ } else
+ cur_area->log = NULL;
+ }
+ PRINTF ("\n");
+ } else {
+ void *mem = malloc (DEFAULT_MEMORY_LEN);
+ if (config.sim.verbose)
+ fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
+
+ if (!mem) {
+ fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
+ exit (-1);
+ }
+
+ register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0,
+ &simmem_read_word, &simmem_write_word, mem);
+ cur_area->chip_select = 0;
+ cur_area->valid = 1;
+ cur_area->delayw = 1;
+ cur_area->delayr = 1;
+ cur_area->log = NULL;
+ }
+}
+
+/* Changes read/write memory in read/write only */
+
+void lock_memory_table ()
+{
+ struct dev_memarea *ptmp;
+
+ /* Check list of registered devices. */
+ for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
+ if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
+ ptmp->readfunc = &simmem_read_zero;
+ if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
+ ptmp->writefunc = &simmem_write_null;
+
+ /* If this mem area is not for memory chip under MC control
+ then this area is valid all the time */
+ if (ptmp->readfunc != &simmem_read_word) {
+ ptmp->valid = 1;
+ ptmp->chip_select = -1;
+ }
+ }
+}
+
+/* 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 ()
+{
+ 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
+ ", gran %iB\n",
+ ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
+ ptmp->size, ptmp->granularity);
+ PRINTF ("\t");
+ if (ptmp->delayr >= 0)
+ PRINTF ("read delay = %i cycles, ", ptmp->delayr);
+ else
+ PRINTF ("reads not possible, ");
+
+ if (ptmp->delayw >= 0)
+ PRINTF ("write delay = %i cycles", ptmp->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,109 @@
+/* stats.h -- Header file for stats.c
+ 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 DSTATS_LEN 3000
+#define SSTATS_LEN 300
+#define FSTATS_LEN 200
+#define RAW_RANGE 1000
+
+/* Used by safe division - increment divisor by one if it is zero */
+#define SD(X) (X != 0 ? X : 1)
+
+struct dstats_entry {
+ int insn1;
+ int insn2;
+ int cnt_dynamic;
+ int depend;
+};
+
+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 */
+
+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 */
+
+/* Renamed mstats to or1k_mstats because Mac OS X has a lib function called mstats */
+extern struct mstats_entry or1k_mstats;
+extern struct sstats_entry sstats[SSTATS_LEN];
+extern struct dstats_entry dstats[DSTATS_LEN];
+extern struct fstats_entry fstats[FSTATS_LEN];
+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;
+
+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();
Index: common/abstract.h
===================================================================
--- common/abstract.h (nonexistent)
+++ common/abstract.h (revision 1765)
@@ -0,0 +1,175 @@
+/* abstract.c -- Abstract entities header file
+ 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. */
+
+#include
+
+#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
+
+/* Instruction queue */
+struct iqueue_entry {
+ int insn_index;
+ uint32_t insn;
+ oraddr_t insn_addr;
+};
+
+/* Memory regions assigned to devices */
+struct dev_memarea {
+ struct dev_memarea *next;
+ /*unsigned long start;
+ unsigned long end;*/ /* if start + size > end, this block is disabled; to enable it recalculate end addr. */
+ oraddr_t addr_mask;
+ oraddr_t addr_compare;
+ uint32_t size;
+ uint32_t size_mask; /* Address mask, calculated out of size */
+ unsigned int granularity; /* how many bytes read/write accepts: 1/2/4 */
+ int delayr; /* Read delay */
+ int delayw; /* Write delay */
+
+ int chip_select; /* Needed by memory controller; specifies chip
+ * select number for this memory area. */
+ int valid; /* This bit reflect the memory controler valid bit */
+ FILE *log; /* log file if this device is to be logged, NULL otherwise */
+
+ uint32_t (*readfunc)(oraddr_t, void *);
+ void (*writefunc)(oraddr_t, uint32_t, void *);
+ /* private data */
+ void *priv_dat;
+};
+
+extern struct iqueue_entry iqueue[20];
+extern struct iqueue_entry icomplet[20];
+extern oraddr_t pc;
+extern int mem_cycles; /* Number of memory cycles in during this instruction execution */
+extern int cycles; /* Total number of cycles executed so far */
+
+extern void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl);
+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*);
+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*);
+
+uint32_t evalsim_mem32(oraddr_t);
+uint16_t evalsim_mem16(oraddr_t);
+uint8_t evalsim_mem8(oraddr_t);
+
+uint32_t evalsim_mem32_atomic(oraddr_t, int);
+uint16_t evalsim_mem16_atomic(oraddr_t, int);
+uint8_t evalsim_mem8_atomic(oraddr_t, int);
+
+void setsim_mem32(oraddr_t, uint32_t);
+void setsim_mem16(oraddr_t, uint16_t);
+void setsim_mem8(oraddr_t, uint8_t);
+
+void setsim_mem32_atomic(oraddr_t, uint32_t, int);
+void setsim_mem16_atomic(oraddr_t, uint16_t, int);
+void setsim_mem8_atomic(oraddr_t, uint8_t, int);
+
+void init_memory_table ();
+
+/* Changes read/write memory in read/write only */
+void lock_memory_table ();
+
+/* Closes files, etc. */
+void done_memory_table ();
+
+/* Displays current memory configuration */
+void memory_table_status ();
+
+/* 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.) */
+void register_memoryarea_mask(oraddr_t addr_mask, oraddr_t addr_compare,
+ uint32_t size, unsigned granularity, unsigned mc_dev,
+ uint32_t (readfunc)(oraddr_t, void *),
+ void (writefunc)(oraddr_t, uint32_t, void *),
+ void *dat);
+
+/* 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 means that this device will be checked first for match
+ and will be accessed in case in overlaping memory spaces.
+ Only one device can have this set to 1 (used for memory controller) */
+void register_memoryarea(oraddr_t addr, uint32_t size, unsigned granularity,
+ unsigned mc_dev, uint32_t (readfunc)(oraddr_t, void *),
+ void (writefunc)(oraddr_t, uint32_t, void *),
+ void *dat);
+
+/* Finds the memory area for the address and adjust the read and write delays for it. */
+void adjust_rw_delay(oraddr_t memaddr, unsigned int delayr, unsigned int delayw);
+
+/* Check if access is to registered area of memory. */
+struct dev_memarea *verify_memoryarea(oraddr_t addr);
+
+/* Outputs time in pretty form to dest string. */
+char *generate_time_pretty (char *dest, long time_ps);
+
+/* Returns 32-bit values from mem array. */
+uint32_t eval_insn(oraddr_t, int *);
+
+uint8_t eval_direct8(oraddr_t memaddr, int *breakpoint, int through_mmu, int through_dc);
+uint16_t eval_direct16(oraddr_t memaddr, int *breakpoint, int through_mmu, int through_dc);
+uint32_t eval_direct32(oraddr_t addr, int *breakpoint, int through_mmu, int through_dc);
+
+void set_direct32(uint32_t addr, uint32_t value, int *breakpoint, int through_mmu, int through_dc);
+
+/* Temporary variable to increase speed. */
+extern struct dev_memarea *cur_area;
+
+/* Virtual address of current access. */
+extern oraddr_t cur_vadd;
+
+/* These are set by mmu if cache inhibit bit is set for current acces. */
+extern int data_ci, insn_ci;
+
+/* Added by MM */
+#ifndef LONGEST
+#define LONGEST long long
+#define ULONGEST unsigned long long
+#endif /* ! LONGEST */
+
+/* Instructions left to execute */
+extern int cont_run;
+
+/* History of execution */
+#define HISTEXEC_LEN 200
+struct hist_exec {
+ oraddr_t addr;
+ struct hist_exec *prev;
+ struct hist_exec *next;
+};
+
+extern struct hist_exec *hist_exec_tail;
Index: common/Makefile.in
===================================================================
--- common/Makefile.in (nonexistent)
+++ common/Makefile.in (revision 1765)
@@ -0,0 +1,338 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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
+#
+# 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.
+#
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPU_ARCH = @CPU_ARCH@
+DEPDIR = @DEPDIR@
+INCLUDES = @INCLUDES@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+MAKE_SHELL = @MAKE_SHELL@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+am__include = @am__include@
+am__quote = @am__quote@
+host = @host@
+host_cpu = @host_cpu@
+host_os = @host_os@
+install_sh = @install_sh@
+
+noinst_LIBRARIES = libcommon.a
+libcommon_a_SOURCES = abstract.c parse.c stats.c trace.c labels.c
+subdir = cpu/common
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libcommon_a_AR = $(AR) cru
+libcommon_a_LIBADD =
+am_libcommon_a_OBJECTS = abstract.$(OBJEXT) parse.$(OBJEXT) \
+ stats.$(OBJEXT) trace.$(OBJEXT) labels.$(OBJEXT)
+libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/abstract.Po ./$(DEPDIR)/labels.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/parse.Po ./$(DEPDIR)/stats.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/trace.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libcommon_a_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libcommon_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/common/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
+ -rm -f libcommon.a
+ $(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
+ $(RANLIB) libcommon.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/labels.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @list='$(DISTFILES)'; for file in $$list; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ 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 $(LIBRARIES)
+
+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_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(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-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic tags uninstall uninstall-am \
+ uninstall-info-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,153 @@
+/* abstract.c -- Abstract entities, handling labels
+ Copyright (C) 2001 Marko Mlinar, markom@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. */
+
+/* Abstract memory and routines that go with this. I need to
+add all sorts of other abstract entities. Currently we have
+only memory. */
+
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "config.h"
+
+#include "arch.h"
+#include "sim-config.h"
+#include "labels.h"
+
+static struct label_entry *label_hash[LABELS_HASH_SIZE];
+struct breakpoint_entry *breakpoints;
+
+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");
+}
+
+inline 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/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
+
+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. */
+
+/* Here we define some often used caharcters in assembly files.
+This wil probably go into architecture dependent directory. */
+
+#define COMMENT_CHAR '#'
+#define DIRECTIVE_CHAR '.'
+#define LABELEND_CHAR ":"
+/*#define OPERAND_DELIM ","*/
+
+/* Strip whitespace from the start and end of STRING. Return a pointer
+ into STRING. */
+#ifndef whitespace
+#define whitespace(a) ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0))
+#endif
+
+/* Strips white spaces at beginning and at the end of the string */
+char *stripwhite (char *string);
+
+/* This function is very similar to strncpy, except it null terminates the string */
+char *strstrip (char *dst, const char *src, int n);
+
+/* Loads file to memory starting at address startaddr and returns freemem. */
+unsigned long loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl);
Index: common/parse.c
===================================================================
--- common/parse.c (nonexistent)
+++ common/parse.c (revision 1765)
@@ -0,0 +1,697 @@
+/* parce.c -- Architecture independent load
+ 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. */
+
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "abstract.h"
+#include "dmmu.h"
+#include "coff.h"
+#include "elf.h"
+#include "debug_unit.h"
+#include "opcode/or32.h"
+#include "parse.h"
+#include "sim-config.h"
+#include "labels.h"
+#include "debug.h"
+
+#define MEMORY_LEN 0x100000000
+#define MAXLINE_LEN 18000
+
+/* Whether to do immediate statistics */
+#define IMM_STATS 0
+
+extern char *disassembled;
+
+/* Unused mem memory marker. It is used when allocating program and data memory
+ during parsing */
+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 unsigned long transl_error;
+
+char *
+stripwhite (string)
+ char *string;
+{
+ register char *s, *t;
+
+ for (s = string; whitespace (*s); s++)
+ ;
+
+ if (*s == 0)
+ return (s);
+
+ t = s + strlen (s) - 1;
+ while (t > s && whitespace (*t))
+ t--;
+ *++t = '\0';
+
+ return s;
+}
+
+/* This function is very similar to strncpy, except it null terminates the string */
+char *strstrip (char *dst, const char *src, int n)
+{
+ strncpy (dst, src, n);
+ *(dst + n) = '\0';
+ return dst;
+}
+
+/* Used only by the simulator loader to translate logical addresses into physical.
+ If loadcode() is called with valid virtphy_transl pointer to a table of
+ translations then translate() performs translation otherwise phy address is
+ equal to logical. */
+static oraddr_t translate(oraddr_t laddr,int* breakpoint)
+{
+ int i;
+
+ /* No translation (i.e. when loading kernel into simulator) */
+/* PRINTF("transl_table=%x laddr=%x\n", transl_table, laddr);
+ PRINTF("laddr=%x\n", laddr);*/
+ 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)) == evalsim_mem32(transl_table + i)) {
+ setsim_mem32(transl_table + i + 8, -2); /* Page modified */
+ PRINTF("found paddr=%"PRIx32"\n",
+ evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
+ return (oraddr_t)evalsim_mem32(transl_table + i + 4) | (laddr & (oraddr_t)(PAGE_SIZE - 1));
+ }
+
+ /* Allocate new phy page for us. */
+ for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
+ if (evalsim_mem32(transl_table + i + 8) == 0) {
+ setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
+ setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
+ setsim_mem32(transl_table + i + 8, -2); /* Page modified */
+ PRINTF("newly allocated ppn=%"PRIx32"\n",
+ evalsim_mem32(transl_table + i + 4));
+ 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",
+ evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
+ return (oraddr_t)evalsim_mem32(transl_table + i + 4) | (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;
+}
+
+#if IMM_STATS
+int bcnt[33][3] = {0};
+int bsum[3] = {0};
+unsigned long movhi = 0;
+
+int bits (unsigned long val) {
+ int i = 1;
+ if (!val) return 0;
+ while (val != 0 && (signed long)val != -1) {i++; val = (signed long)val >> 1;}
+ return i;
+}
+
+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
+
+/* Replaced several calls to translate(freemem) with vaddr */
+/* Added new mode execution code */
+/* Changed parameters so address can be passed as argument */
+void addprogram(oraddr_t address, uint32_t insn, int* breakpoint)
+{
+ int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
+
+ setsim_mem32 (vaddr, insn);
+#if IMM_STATS
+ check_insn (insn);
+#endif
+ if(runtime.sim.filename)
+ freemem += insn_len (insn_decode (insn));
+}
+
+/* Load big-endian COFF file. */
+
+void readfile_coff(char *filename, short sections)
+{
+ FILE *inputfs;
+ char inputbuf[4];
+ uint32_t insn;
+ signed long 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--) {
+ long 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);
+#if 0
+ /* A couple of sanity checks. */
+ if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
+ PRINTF("Section %s starts out of ", coffscnhdr.s_name);
+ PRINTF("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
+ exit(1);
+ }
+ if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) >
+ MEMORY_START + MEMORY_LEN) {
+ PRINTF("Section %s ends out of ", coffscnhdr.s_name);
+ PRINTF("memory.\n");
+ exit(1);
+ }
+#endif
+#if 0
+ if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
+ PRINTF("First section should be .text (%s instead)\n", coffscnhdr.s_name);
+ exit(1);
+ }
+ if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
+ PRINTF("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
+ exit(1);
+ }
+ if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
+ PRINTF("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
+ exit(1);
+ }
+#else
+ ++firstthree;
+#endif
+
+ /* loading section */
+ freemem = COFF_LONG_H(coffscnhdr.s_paddr);
+ debug(2,"Starting to load at 0x%x\n", freemem);
+ 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);
+ debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn >> 16);
+ }
+ else
+ debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn);
+ 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;
+}
+
+/* Load symbols from big-endian COFF file. */
+
+void readsyms_coff(char *filename, unsigned long symptr, long syms)
+{
+ FILE *inputfs;
+ struct COFF_syment coffsymhdr;
+ int count = 0;
+ long 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 0
+ /* If not important or not in text, skip. */
+ if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
+#endif
+
+ if (*((unsigned long *)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);
+ debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
+ } else {
+ long 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]);
+ debug(8, "[%i] Symbol: %s,", count++, &tmp[0]);
+ }
+ fseek(inputfs, fpos, SEEK_SET);
+ }
+
+ debug(9, " val: 0x%.8lx,", COFF_LONG_H(coffsymhdr.e_value));
+ debug(9, " type: %x, %x, auxs: %i\n", COFF_SHORT_H(coffsymhdr.e_type), *((unsigned short *)coffsymhdr.e_type), n);
+ }
+
+ 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;
+}
+
+void readfile_elf(char *filename)
+{
+
+ FILE *inputfs;
+ struct elf32_hdr elfhdr;
+ struct elf32_phdr *elf_phdata;
+ struct elf32_shdr *elf_spnt, *elf_shdata;
+ struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
+ unsigned long syms = 0;
+ char *str_tbl = (char *)0;
+ char *s_str = (char *)0;
+ int breakpoint = 0;
+ unsigned long inputbuf;
+ unsigned long 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((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((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%.8lx,", 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");
+ exit(1);
+ }
+
+ while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
+ insn = ELF_LONG_H(inputbuf);
+ len = insn_len (insn_decode (insn));
+ if (len == 2)
+ {
+ fseek(inputfs, -2, SEEK_CUR);
+ debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn >> 16);
+ }
+ else
+ debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn);
+ addprogram (freemem, insn, &breakpoint);
+ sectsize -= len;
+ }
+ }
+ }
+
+ 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)]);
+ debug (8, "%08lx(%s): %x %x %x\n", ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)], sym_tbl[i].st_info, sym_tbl[i].st_other, ELF_SHORT_H(sym_tbl[i].st_shndx));
+ }
+ i++;
+ }
+ }
+}
+
+/* Identify file type and call appropriate readfile_X routine. It only
+handles orX-coff-big executables at the moment. */
+
+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) {
+ unsigned long 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%.2lx\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;
+}
+
+
+/* Loads file to memory starting at address startaddr and returns freemem. */
+unsigned long 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,54 @@
+/* trace.c -- Simulator breakpoints
+ 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. */
+
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "abstract.h"
+#include "labels.h"
+#include "sim-config.h"
+#include "trace.h"
+
+/* Set instruction execution breakpoint. */
+
+void set_insnbrkpoint(oraddr_t addr)
+{
+ addr &= 0xfffffffc; /* 32-bit aligned */
+
+ if (verify_memoryarea(addr))
+ 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);
+ }
+ else
+ PRINTF("ERROR: Can't set this breakpoint out of memory.\n");
+
+ return;
+}
+
Index: common/trace.h
===================================================================
--- common/trace.h (nonexistent)
+++ common/trace.h (revision 1765)
@@ -0,0 +1,2 @@
+
+void set_insnbrkpoint(oraddr_t addr);
Index: common/labels.h
===================================================================
--- common/labels.h (nonexistent)
+++ common/labels.h (revision 1765)
@@ -0,0 +1,58 @@
+/* labels.h -- Abstract entities header file handling labels
+ Copyright (C) 2001 Marko Mlinar, markom@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. */
+
+#ifndef _LABELS_H_
+#define _LABELS_H_
+
+#define LABELS_HASH_SIZE 119
+
+/* Structure for holding one label per particular memory location */
+struct label_entry {
+ char *name;
+ oraddr_t addr;
+ struct label_entry *next;
+};
+
+struct breakpoint_entry {
+ oraddr_t addr;
+ struct breakpoint_entry *next;
+};
+
+/* Label handling */
+void init_labels();
+void add_label (oraddr_t addr, char *name);
+struct label_entry *get_label (oraddr_t addr);
+struct label_entry *find_label (char *name);
+
+/* 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);
+
+/* Breakpoint handling */
+void breakpoints_init ();
+void add_breakpoint (oraddr_t addr);
+void remove_breakpoint (oraddr_t addr);
+void print_breakpoints ();
+int has_breakpoint (oraddr_t addr);
+void init_breakpoints ();
+
+extern struct breakpoint_entry *breakpoints;
+#define CHECK_BREAKPOINTS (breakpoints)
+
+#endif /* _LABELS_H_ */
common/labels.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
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/elf.h
===================================================================
--- common/elf.h (nonexistent)
+++ common/elf.h (revision 1765)
@@ -0,0 +1,439 @@
+#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
+
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+
+/* 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/Makefile.am
===================================================================
--- common/Makefile.am (nonexistent)
+++ common/Makefile.am (revision 1765)
@@ -0,0 +1,22 @@
+# Makefile -- Makefile for cpu architecture independent 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.
+#
+
+noinst_LIBRARIES = libcommon.a
+libcommon_a_SOURCES = abstract.c parse.c stats.c trace.c labels.c
Index: common
===================================================================
--- common (nonexistent)
+++ common (revision 1765)
common
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps
Index: or32/execute.c
===================================================================
--- or32/execute.c (nonexistent)
+++ or32/execute.c (revision 1765)
@@ -0,0 +1,802 @@
+/* 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
+
+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 OR1K simulation is done in here.
+
+ When SIMPLE_EXECUTION is defined below a file insnset.c is included!
+*/
+
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "branch_predict.h"
+#include "abstract.h"
+#include "labels.h"
+#include "parse.h"
+#include "except.h"
+#include "sim-config.h"
+#include "debug_unit.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
+#include "immu.h"
+#include "dmmu.h"
+#include "debug.h"
+#include "stats.h"
+
+/* Current cpu state */
+struct cpu_state cpu_state;
+
+/* Benchmark multi issue execution */
+int multissue[20];
+int issued_per_cycle = 4;
+
+/* Previous program counter */
+oraddr_t pcprev = 0;
+
+/* Temporary program counter */
+oraddr_t pcnext;
+
+/* CCR */
+int flag;
+
+/* Store buffer analysis - stores are accumulated and commited when IO is idle */
+static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
+static int sbuf_buf[MAX_SBUF_LEN] = {0};
+static int sbuf_prev_cycles = 0;
+
+/* Num cycles waiting for stores to complete */
+int sbuf_wait_cyc = 0;
+
+/* Number of total store cycles */
+int sbuf_total_cyc = 0;
+
+/* Whether we are doing statistical analysis */
+int do_stats = 0;
+
+/* Local data needed for execution. */
+static int next_delay_insn;
+static int breakpoint;
+
+
+/* History of execution */
+struct hist_exec *hist_exec_tail = NULL;
+
+/* Implementation specific.
+ Get an actual value of a specific register. */
+
+uorreg_t evalsim_reg(unsigned int regno)
+{
+ if (regno < MAX_GPRS) {
+ return cpu_state.reg[regno];
+ } else {
+ PRINTF("\nABORT: read out of registers\n");
+ runtime.sim.cont_run = 0;
+ return 0;
+ }
+}
+
+/* Implementation specific.
+ Set a specific register with value. */
+
+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");
+ runtime.sim.cont_run = 0;
+ }
+}
+
+/* Implementation specific.
+ Set a specific register with value. */
+
+inline static void set_reg(int regno, uorreg_t value)
+{
+#if 0
+ if (strcmp(regstr, FRAME_REG) == 0) {
+ PRINTF("FP (%s) modified by insn at %x. ", FRAME_REG, cpu_state.pc);
+ PRINTF("Old:%.8lx New:%.8lx\n", eval_reg(regno), value);
+ }
+
+ if (strcmp(regstr, STACK_REG) == 0) {
+ PRINTF("SP (%s) modified by insn at %x. ", STACK_REG, cpu_state.pc);
+ PRINTF("Old:%.8lx New:%.8lx\n", eval_reg(regno), value);
+ }
+#endif
+
+ if (regno < MAX_GPRS) {
+ cpu_state.reg[regno] = value;
+#if RAW_RANGE_STATS
+ raw_stats.reg[regno] = runtime.sim.cycles;
+#endif /* RAW_RANGE */
+ } else {
+ PRINTF("\nABORT: write out of registers\n");
+ runtime.sim.cont_run = 0;
+ }
+}
+
+/* Implementation specific.
+ Evaluates source operand opd. */
+
+static 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;
+}
+
+/* Does source operand 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)
+dst: flag src: flag always 1
+*/
+
+static int check_depend(prev, next)
+ struct iqueue_entry *prev;
+ struct iqueue_entry *next;
+{
+ /* Find destination type. */
+ unsigned long type = 0;
+ int prev_dis, 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;
+}
+
+/* Sets a new SPR_SR_OV value, based on next register value */
+
+#if SET_OV_FLAG
+#define set_ov_flag(value) if((value) & 0x80000000) setsprbits (SPR_SR, SPR_SR_OV, 1); else setsprbits (SPR_SR, SPR_SR_OV, 0)
+#else
+#define set_ov_flag(value)
+#endif
+
+/* Modified by CZ 26/05/01 for new mode execution */
+/* Fetch returns nonzero if instruction should NOT be executed. */
+static inline int fetch()
+{
+ static int break_just_hit = 0;
+
+ if (CHECK_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;
+ /* Fetch instruction. */
+ if (!except_pending)
+ runtime.cpu.instructions++;
+ cpu_state.iqueue.insn_addr = cpu_state.pc;
+ cpu_state.iqueue.insn = eval_insn (cpu_state.pc, &breakpoint);
+
+ /* update_pc will be called after execution */
+
+ return 0;
+}
+
+/* This code actually updates the PC value. */
+static inline void update_pc ()
+{
+ cpu_state.delay_insn = next_delay_insn;
+ pcprev = cpu_state.pc; /* Store value for later */
+ cpu_state.pc = pcnext;
+ pcnext = cpu_state.delay_insn ? cpu_state.pc_delay : pcnext + 4;
+}
+
+#if SIMPLE_EXECUTION
+static inline
+#endif
+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;
+#if 0
+ if ((cpu_state.icomplet.func_unit == it_load) &&
+ check_depend(&cpu_state.icomplet, current))
+ runtime.sim.loadcycles++;
+#endif
+
+ /* 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();
+}
+
+/* Store buffer analysis - stores are accumulated and commited when IO is idle */
+static inline void sbuf_store (int cyc) {
+ int delta = runtime.sim.cycles - sbuf_prev_cycles;
+ sbuf_total_cyc += cyc;
+ sbuf_prev_cycles = runtime.sim.cycles;
+
+ //PRINTF (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
+ //PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
+ /* 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++;
+ //PRINTF ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
+}
+
+/* Store buffer analysis - previous stores should commit, before any load */
+static inline void sbuf_load () {
+ int delta = runtime.sim.cycles - sbuf_prev_cycles;
+ sbuf_prev_cycles = runtime.sim.cycles;
+
+ //PRINTF (">LOAD %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
+ //PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
+ /* 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--;
+ }
+ //PRINTF ("|LOAD %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
+}
+
+/* Outputs dissasembled instruction */
+void dump_exe_log ()
+{
+ oraddr_t insn_addr = cpu_state.iqueue.insn_addr;
+ unsigned int i, 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))) {
+ 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", evalsim_mem8_void(insn_addr),
+ evalsim_mem8_void(insn_addr + 1));
+ fprintf (runtime.sim.fexe_log, "%.2x%.2x",
+ evalsim_mem8_void(insn_addr + 2),
+ evalsim_mem8_void(insn_addr + 3));
+ 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 : %.8lx ", mfspr(SPR_SR));
+ fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx ", mfspr(SPR_EPCR_BASE));
+ fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx ", mfspr(SPR_EEAR_BASE));
+ fprintf (runtime.sim.fexe_log, "ESR0 : %.8lx\n", mfspr(SPR_ESR_BASE));
+ break;
+ case EXE_LOG_SIMPLE:
+ case EXE_LOG_SOFTWARE:
+ {
+ extern char *disassembled;
+ disassemble_index (cpu_state.iqueue.insn, cpu_state.iqueue.insn_index);
+ {
+ struct label_entry *entry;
+ 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 =%08x",
+ 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 registers - 'r' or 't' command */
+void dumpreg()
+{
+ int i;
+ oraddr_t physical_pc;
+
+ if ((physical_pc = peek_into_itlb(cpu_state.iqueue.insn_addr))) {
+ /*
+ * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", cpu_state.iqueue.insn_addr, physical_pc);
+ */
+ dumpmemory(physical_pc, physical_pc + 4, 1, 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))) {
+ /*
+ * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", cpu_state.pc, physical_pc);
+ */
+ dumpmemory(physical_pc, physical_pc + 4, 1, 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", flag);
+}
+
+/* Generated/built in decoding/executing function */
+static inline void decode_execute (struct iqueue_entry *current);
+
+/* Wrapper around real decode_execute function -- some statistics here only */
+static inline void decode_execute_wrapper (struct iqueue_entry *current)
+{
+ breakpoint = 0;
+
+#ifndef HAS_EXECUTION
+#error HAS_EXECUTION has to be defined in order to execute programs.
+#endif
+
+ decode_execute (current);
+
+#if SET_OV_FLAG
+ /* Check for range exception */
+ if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
+ except_handle (EXCEPT_RANGE, mfspr(SPR_EEAR_BASE));
+#endif
+
+ if(breakpoint)
+ except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
+}
+
+/* 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++)
+ set_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;
+
+ /* Cpu configuration */
+ mtspr(SPR_UPR, config.cpu.upr);
+ setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
+ setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
+ mtspr(SPR_SR, config.cpu.sr);
+
+ pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */
+ if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);
+ cpu_state.pc = pcnext;
+ pcnext += 4;
+ debug(1, "reset ...\n");
+
+ /* MM1409: All programs should set their stack pointer! */
+ except_handle(EXCEPT_RESET, 0);
+ update_pc();
+ except_pending = 0;
+}
+
+/* Simulates one CPU clock cycle */
+inline int cpu_clock ()
+{
+ except_pending = 0;
+ next_delay_insn = 0;
+ if(fetch()) {
+ PRINTF ("Breakpoint hit.\n");
+ runtime.sim.cont_run = 0; /* memory breakpoint encountered */
+ return 1;
+ }
+
+ if(except_pending) {
+ update_pc();
+ except_pending = 0;
+ return 0;
+ }
+
+ if(breakpoint) {
+ except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
+ update_pc();
+ except_pending = 0;
+ return 0;
+ }
+
+ decode_execute_wrapper (&cpu_state.iqueue);
+ update_pc();
+ return 0;
+}
+
+/* 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);
+}
+
+#if !SIMPLE_EXECUTION
+
+/* Include decode_execute function */
+#include "execgen.c"
+
+#else /* SIMPLE_EXECUTION */
+
+
+#define INSTRUCTION(name) void name (struct iqueue_entry *current)
+
+/* Implementation specific.
+ Get an actual value of a specific register. */
+
+static uorreg_t eval_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)MAX_RAW_RANGE)
+ raw_stats.range[delta]++;
+#endif /* RAW_RANGE */
+ return cpu_state.reg[regno];
+ } else {
+ PRINTF("\nABORT: read out of registers\n");
+ runtime.sim.cont_run = 0;
+ return 0;
+ }
+}
+
+/* Implementation specific.
+ Evaluates source operand op_no. */
+
+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 += eval_reg (eval_operand_val (insn, opd));
+ cpu_state.insn_ea = ret;
+ return ret;
+ }
+ if (opd->type & OPTYPE_REG)
+ return eval_reg (eval_operand_val (insn, opd));
+
+ return eval_operand_val (insn, opd);
+}
+
+/* Implementation specific.
+ Set destination operand (reister direct) with value. */
+
+inline 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);
+ }
+ set_reg (eval_operand_val (insn, opd), value);
+}
+
+/* Simple and rather slow decoding function based on built automata. */
+static inline 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);
+}
+
+#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)
+
+#include "insnset.c"
+
+#endif /* !SIMPLE_EXECUTION */
Index: or32/insnset.c
===================================================================
--- or32/insnset.c (nonexistent)
+++ or32/insnset.c (revision 1765)
@@ -0,0 +1,567 @@
+/* execute.c -- Instruction specific functions.
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ 2000-2002 Marko Mlinar, markom@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. */
+
+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 (temp1);
+ if (ARITH_SET_FLAG) {
+ flag = temp1 == 0;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+ }
+ if ((uorreg_t) temp1 < (uorreg_t) temp2)
+ setsprbits(SPR_SR, SPR_SR_CY, 1);
+ else
+ setsprbits(SPR_SR, SPR_SR_CY, 0);
+
+ 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 + getsprbits(SPR_SR, SPR_SR_CY);
+ SET_PARAM0(temp1);
+ set_ov_flag (temp1);
+ if (ARITH_SET_FLAG) {
+ flag = temp1 == 0;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+ }
+ if ((uorreg_t) temp1 < (uorreg_t) temp2)
+ setsprbits(SPR_SR, SPR_SR_CY, 1);
+ else
+ setsprbits(SPR_SR, SPR_SR_CY, 0);
+
+ 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 */
+ if (!except_pending)
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lbs) {
+ int8_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem8(PARAM1, &breakpoint);
+ /* If eval opreand produced exception don't set anything */
+ if (!except_pending)
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lbz) {
+ uint8_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem8(PARAM1, &breakpoint);
+ /* If eval opreand produced exception don't set anything */
+ if (!except_pending)
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lhs) {
+ int16_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem16(PARAM1, &breakpoint);
+ /* If eval opreand produced exception don't set anything */
+ if (!except_pending)
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_lhz) {
+ uint16_t val;
+ if (config.cpu.sbuf_len) sbuf_load ();
+ val = eval_mem16(PARAM1, &breakpoint);
+ /* If eval opreand produced exception don't set anything */
+ if (!except_pending)
+ SET_PARAM0(val);
+}
+INSTRUCTION (l_movhi) {
+ SET_PARAM0(PARAM1 << 16);
+}
+INSTRUCTION (l_and) {
+ uorreg_t temp1;
+ temp1 = PARAM1 & PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+ if (ARITH_SET_FLAG) {
+ flag = temp1 == 0;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+ }
+}
+INSTRUCTION (l_or) {
+ uorreg_t temp1;
+ temp1 = PARAM1 | PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+}
+INSTRUCTION (l_xor) {
+ uorreg_t temp1;
+ temp1 = PARAM1 ^ PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+}
+INSTRUCTION (l_sub) {
+ orreg_t temp1;
+ temp1 = (orreg_t)PARAM1 - (orreg_t)PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+}
+/*int mcount = 0;*/
+INSTRUCTION (l_mul) {
+ orreg_t temp1;
+
+ temp1 = (orreg_t)PARAM1 * (orreg_t)PARAM2;
+ set_ov_flag (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 (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 (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 16; */
+}
+INSTRUCTION (l_sll) {
+ uorreg_t temp1;
+
+ temp1 = PARAM1 << PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 2; */
+}
+INSTRUCTION (l_sra) {
+ orreg_t temp1;
+
+ temp1 = (orreg_t)PARAM1 >> PARAM2;
+ set_ov_flag (temp1);
+ SET_PARAM0(temp1);
+ /* runtime.sim.cycles += 2; */
+}
+INSTRUCTION (l_srl) {
+ uorreg_t temp1;
+ temp1 = PARAM1 >> PARAM2;
+ set_ov_flag (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[flag][fwd]++;
+ bpb_update(current->insn_addr, flag);
+ }
+ if (flag) {
+ 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[!flag][fwd]++;
+ bpb_update(current->insn_addr, flag == 0);
+ }
+ if (flag == 0) {
+ 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;
+
+ set_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;
+ set_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 = mfspr(SPR_EPCR_BASE);
+ mtspr(SPR_SR, mfspr(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
+ runtime.sim.cont_run = 0;
+ 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));
+ debug(5, "simprintf %x\n", stackaddr);
+ break;
+ case NOP_REPORT:
+ PRINTF("report(0x%"PRIdREG");\n", evalsim_reg(3));
+ default:
+ if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
+ PRINTF("report %i (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
+ evalsim_reg(3));
+ break;
+ }
+}
+INSTRUCTION (l_sfeq) {
+ flag = PARAM0 == PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfne) {
+ flag = PARAM0 != PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfgts) {
+ flag = (orreg_t)PARAM0 > (orreg_t)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfges) {
+ flag = (orreg_t)PARAM0 >= (orreg_t)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sflts) {
+ flag = (orreg_t)PARAM0 < (orreg_t)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfles) {
+ flag = (orreg_t)PARAM0 <= (orreg_t)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfgtu) {
+ flag = PARAM0 > PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfgeu) {
+ flag = PARAM0 >= PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfltu) {
+ flag = PARAM0 < PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (l_sfleu) {
+ flag = PARAM0 <= PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+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 (runtime.sim.fspr_log) {
+ fprintf(runtime.sim.fspr_log, "Write to SPR : [%08"PRIx16"] <- [%08"PRIx32"]\n", regno, value);
+ }
+
+ if (mfspr(SPR_SR) & SPR_SR_SM)
+ mtspr(regno, value);
+ else {
+ PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
+ runtime.sim.cont_run = 0;
+ }
+}
+INSTRUCTION (l_mfspr) {
+ uint16_t regno = PARAM1 + PARAM2;
+ uorreg_t value = mfspr(regno);
+
+ if (runtime.sim.fspr_log) {
+ fprintf(runtime.sim.fspr_log, "Read from SPR : [%08"PRIx16"] -> [%08"PRIx32"]\n", regno, value);
+ }
+
+ if (mfspr(SPR_SR) & SPR_SR_SM)
+ SET_PARAM0(value);
+ else {
+ SET_PARAM0(0);
+ PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
+ runtime.sim.cont_run = 0;
+ }
+}
+INSTRUCTION (l_sys) {
+ except_handle(EXCEPT_SYSCALL, mfspr(SPR_EEAR_BASE));
+}
+INSTRUCTION (l_trap) {
+ /* TODO: some SR related code here! */
+ except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
+}
+INSTRUCTION (l_mac) {
+ sprword lo, hi;
+ LONGEST l;
+ orreg_t x, y;
+
+ lo = mfspr (SPR_MACLO);
+ hi = mfspr (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;
+ mtspr (SPR_MACLO, lo);
+ mtspr (SPR_MACHI, hi);
+ PRINTF ("(%08lx,%08lx)\n", hi, lo);
+}
+INSTRUCTION (l_msb) {
+ sprword lo, hi;
+ LONGEST l;
+ orreg_t x, y;
+
+ lo = mfspr (SPR_MACLO);
+ hi = mfspr (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;
+ mtspr (SPR_MACLO, lo);
+ mtspr (SPR_MACHI, hi);
+ PRINTF ("(%08lx,%08lx)\n", hi, lo);
+}
+INSTRUCTION (l_macrc) {
+ sprword lo, hi;
+ LONGEST l;
+ /* No need for synchronization here -- all MAC instructions are 1 cycle long. */
+ lo = mfspr (SPR_MACLO);
+ hi = mfspr (SPR_MACHI);
+ l = (ULONGEST) lo | ((LONGEST)hi << 32);
+ l >>= 28;
+ //PRINTF ("<%08x>\n", (unsigned long)l);
+ SET_PARAM0((orreg_t)l);
+ mtspr (SPR_MACLO, 0);
+ mtspr (SPR_MACHI, 0);
+}
+INSTRUCTION (l_cmov) {
+ SET_PARAM0(flag ? 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) {
+ flag = (float)PARAM0 == (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (lf_sfge_s) {
+ flag = (float)PARAM0 >= (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (lf_sfgt_s) {
+ flag = (float)PARAM0 > (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (lf_sfle_s) {
+ flag = (float)PARAM0 <= (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (lf_sflt_s) {
+ flag = (float)PARAM0 < (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+INSTRUCTION (lf_sfne_s) {
+ flag = (float)PARAM0 != (float)PARAM1;
+ setsprbits(SPR_SR, SPR_SR_F, flag);
+}
+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/generate.c
===================================================================
--- or32/generate.c (nonexistent)
+++ or32/generate.c (revision 1765)
@@ -0,0 +1,392 @@
+/* generate.c -- generates file execgen.c from instruction set
+ Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
+ 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 "config.h"
+#include "opcode/or32.h"
+
+static char *in_file;
+static char *out_file;
+
+/* Whether this instruction stores something in register */
+static int write_to_reg;
+
+static int out_lines = 0;
+
+void debug(int level, const char *format, ...)
+{
+#if DEBUG
+ char *p;
+ va_list ap;
+
+ if ((p = malloc(1000)) == NULL)
+ return;
+ va_start(ap, format);
+ (void) vsnprintf(p, 1000, format, ap);
+ va_end(ap);
+ printf("%s\n", p);
+ fflush(stdout);
+ free(p);
+#endif
+}
+
+static int shift_fprintf(int level, FILE *f, const char *fmt, ...)
+{
+ va_list ap;
+ int i;
+
+ va_start(ap, fmt);
+ for(i = 0; i < level; i++)
+ fprintf(f, " ");
+
+ i = vfprintf(f, fmt, ap);
+ va_end(ap);
+
+ out_lines++;
+ return i + (level * 2);
+}
+
+/* Generates a execute sequence for one instruction */
+int output_function (FILE *fo, const char *func_name, int level)
+{
+ FILE *fi;
+ int olevel;
+ int line_num = 0;
+
+ if ((fi = fopen (in_file, "rt")) == NULL) {
+ printf("could not open file\n");
+ return 1;
+ }
+
+ while (!feof (fi)) {
+ char line[10000], *str = line;
+ fgets (str, sizeof (line), fi);
+ line[sizeof (line) - 1] = 0;
+ line_num++;
+ if (strncmp (str, "INSTRUCTION (", 13) == 0) {
+ char *s;
+ str += 13;
+ while (isspace (*str)) str++;
+ s = str;
+ while (*s && *s != ')') s++;
+ *s = 0;
+ while (isspace(*(s - 1))) s--;
+ *s = 0;
+ if (strcmp (str, func_name) == 0) {
+ olevel = 1;
+ str += strlen (str) + 1;
+ while (isspace (*str)) str++;
+ s = str;
+ while (*s && *s != '\n' && *s != '\r') s++;
+ *s = 0;
+ while (isspace(*(s - 1))) s--;
+ *s = 0;
+ /*shift_fprintf (level, fo, "#line %i \"%s\"\n", line_num, in_file);*/
+ shift_fprintf (level, fo, "%s", str);
+ shift_fprintf (level, fo, " /* \"%s\" */\n", func_name);
+ do {
+ fgets (line, sizeof (line), fi);
+ line[sizeof(line) - 1] = 0;
+ for (str = line; *str; str++) {
+ if (*str == '{') olevel++;
+ else if (*str == '}') olevel--;
+ }
+ shift_fprintf (level, fo, "%s", line);
+ } while (olevel);
+ fclose(fi);
+ /*shift_fprintf (level, fo, "#line %i \"%s\"\n", out_lines, out_file);*/
+ return 0;
+ }
+ }
+ }
+ shift_fprintf (level, fo, "%s ();\n", func_name);
+
+ fclose(fi);
+ return 0;
+}
+
+/* Parses operands. */
+
+static int
+gen_eval_operands (FILE *fo, int insn_index, int level)
+{
+ struct insn_op_struct *opd = op_start[insn_index];
+ int i;
+ int num_ops;
+ int nbits = 0;
+ int set_param = 0;
+ int dis = 0;
+ int sbit;
+ int dis_op = -1;
+
+ write_to_reg = 0;
+
+ shift_fprintf (level, fo, "uorreg_t ");
+
+ /* Count number of operands */
+ for (i = 0, num_ops = 0;; i++) {
+ if (!(opd[i].type & OPTYPE_OP))
+ continue;
+ if (opd[i].type & OPTYPE_DIS)
+ continue;
+ if (num_ops)
+ fprintf(fo, ", ");
+ fprintf(fo, "%c", 'a' + num_ops);
+ num_ops++;
+ if (opd[i].type & OPTYPE_LAST)
+ break;
+ }
+
+ fprintf (fo, ";\n");
+
+ shift_fprintf (level, fo, "/* Number of operands: %i */\n", num_ops);
+
+ i = 0;
+ num_ops = 0;
+ do {
+/*
+ printf("opd[%i].type = %c\n", i, opd->type & OPTYPE_LAST ? '1' : '0'); printf("opd[%i].type = %c\n", i, opd->type & OPTYPE_OP ? '1' : '0');
+ printf("opd[%i].type = %c\n", i, opd->type & OPTYPE_REG ? '1' : '0');
+ printf("opd[%i].type = %c\n", i, opd->type & OPTYPE_SIG ? '1' : '0');
+ printf("opd[%i].type = %c\n", i, opd->type & OPTYPE_DIS ? '1' : '0');
+ printf("opd[%i].type = %i\n", i, opd->type & OPTYPE_SHR);
+ printf("opd[%i].type = %i\n", i, (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR);
+ printf("opd[%i].data = %i\n", i, opd->data);
+*/
+
+ if (!nbits)
+ shift_fprintf (level, fo, "%c = (insn >> %i) & 0x%x;\n", 'a' + num_ops,
+ opd->type & OPTYPE_SHR, (1 << opd->data) - 1);
+ else
+ shift_fprintf (level, fo, "%c |= ((insn >> %i) & 0x%x) << %i;\n",
+ 'a' + num_ops, opd->type & OPTYPE_SHR,
+ (1 << opd->data) - 1, nbits);
+
+ nbits += opd->data;
+
+ if ((opd->type & OPTYPE_DIS) && (opd->type & OPTYPE_OP)) {
+ sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
+ if (opd->type & OPTYPE_SIG)
+ shift_fprintf (level, fo, "if(%c & 0x%08x) %c |= 0x%x;\n",
+ 'a' + num_ops, 1 << sbit, 'a' + num_ops,
+ 0xffffffff << sbit);
+ opd++;
+ shift_fprintf (level, fo, "(signed)%c += (signed)cpu_state.reg[(insn >> %i) & 0x%x];\n",
+ 'a' + num_ops, opd->type & OPTYPE_SHR,
+ (1 << opd->data) - 1);
+ dis = 1;
+ dis_op = num_ops;
+ }
+
+ if (opd->type & OPTYPE_OP) {
+ sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
+ if (opd->type & OPTYPE_SIG)
+ shift_fprintf (level, fo, "if(%c & 0x%08x) %c |= 0x%x;\n",
+ 'a' + num_ops, 1 << sbit, 'a' + num_ops,
+ 0xffffffff << sbit);
+ if ((opd->type & OPTYPE_REG) && !dis) {
+ if(!i) {
+ shift_fprintf (level, fo, "#define SET_PARAM0(val) cpu_state.reg[a] = val\n");
+ set_param = 1;
+ }
+ shift_fprintf (level, fo, "#define PARAM%i cpu_state.reg[%c]\n", num_ops,
+ 'a' + num_ops);
+ if(opd->type & OPTYPE_DST)
+ write_to_reg = 1;
+ } else {
+ shift_fprintf (level, fo, "#define PARAM%i %c\n", num_ops,
+ 'a' + num_ops);
+ }
+ num_ops++;
+ nbits = 0;
+ dis = 0;
+ }
+
+ if ((opd->type & OPTYPE_LAST))
+ break;
+ opd++;
+ i++;
+ } while (1);
+
+ output_function (fo, or32_opcodes[insn_index].function_name, level);
+
+ if (set_param)
+ shift_fprintf (level, fo, "#undef SET_PARAM\n");
+
+ for (i = 0; i < num_ops; i++)
+ shift_fprintf (level, fo, "#undef PARAM%i\n", i);
+
+ return dis_op;
+}
+
+/* Generates decode and execute for one instruction instance */
+static int output_call (FILE *fo, int index, int level)
+{
+ int dis_op = -1;
+
+ /*printf ("%i:%s\n", index, insn_name (index));*/
+
+ shift_fprintf (level++, fo, "{\n");
+
+ if (index >= 0)
+ dis_op = gen_eval_operands (fo, index, level);
+
+ if (index < 0) output_function (fo, "l_invalid", level);
+
+ fprintf (fo, "\n");
+
+ shift_fprintf (level++, fo, "if (do_stats) {\n");
+
+ if (dis_op >= 0)
+ shift_fprintf (level, fo, "cpu_state.insn_ea = %c;\n", 'a' + dis_op);
+
+ shift_fprintf (level, fo, "current->insn_index = %i; /* \"%s\" */\n", index,
+ insn_name (index));
+
+ shift_fprintf (level, fo, "analysis(current);\n");
+ shift_fprintf (--level, fo, "}\n");
+
+ if (write_to_reg)
+ shift_fprintf (level, fo, "cpu_state.reg[0] = 0; /* Repair in case we changed it */\n");
+ shift_fprintf (--level, fo, "}\n");
+ return 0;
+}
+
+/* Generates .c file header */
+static int generate_header (FILE *fo)
+{
+ fprintf (fo, "/* This file was automatically generated by generate (see cpu/or32/generate.c) */\n\n");
+ fprintf (fo, "static inline void decode_execute (struct iqueue_entry *current)\n{\n");
+ fprintf (fo, " uint32_t insn = current->insn;\n");
+ out_lines = 5;
+ return 0;
+}
+
+/* Generates .c file footer */
+static int generate_footer (FILE *fo)
+{
+ fprintf (fo, "}\n");
+ return 0;
+}
+
+/* Decodes all instructions and generates code for that. This function
+ is similar to insn_decode, except it decodes all instructions. */
+static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
+{
+ unsigned long shift = *a;
+ unsigned long mask;
+ int i;
+ int prev_inv = 0;
+
+ if (!(*a & LEAF_FLAG)) {
+ shift = *a++;
+ mask = *a++;
+ shift_fprintf (level, fo, "switch((insn >> %i) & 0x%x) {\n", shift,
+ mask);
+ for (i = 0; i <= mask; i++, a++) {
+ if (!*a) {
+ shift_fprintf (level, fo, "case 0x%x:\n", i);
+ prev_inv = 1;
+ } else {
+ if(prev_inv) {
+ shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
+ shift_fprintf (level--, fo, "break;\n");
+ }
+ shift_fprintf (level, fo, "case 0x%x:\n", i);
+ generate_body (fo, automata + *a, cur_mask | (mask << shift), ++level);
+ shift_fprintf (level--, fo, "break;\n");
+ prev_inv = 0;
+ }
+ }
+ if (prev_inv) {
+ shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
+ shift_fprintf (level--, fo, "break;\n");
+ }
+ shift_fprintf (level, fo, "}\n");
+ } else {
+ i = *a & ~LEAF_FLAG;
+
+ /* Final check - do we have direct match?
+ (based on or32_opcodes this should be the only possibility,
+ but in case of invalid/missing instruction we must perform a check) */
+
+ if (ti[i].insn_mask != cur_mask) {
+ shift_fprintf (level, fo, "/* Not unique: real mask %08lx and current mask %08lx differ - do final check */\n", ti[i].insn_mask, cur_mask);
+ shift_fprintf (level++, fo, "if((insn & 0x%x) == 0x%x) {\n",
+ ti[i].insn_mask, ti[i].insn);
+ }
+ shift_fprintf (level, fo, "/* Instruction: %s */\n", or32_opcodes[i].name);
+
+ output_call (fo, i, level);
+
+ if (ti[i].insn_mask != cur_mask) {
+ shift_fprintf (--level, fo, "} else {\n");
+ shift_fprintf (++level, fo, "/* Invalid insn */\n");
+ output_call (fo, -1, level);
+ shift_fprintf (--level, fo, "}\n");
+ }
+ }
+ return 0;
+}
+
+/* Main function; it takes two parameters:
+ input_file(possibly insnset.c) output_file(possibly execgen.c)*/
+int main (int argc, char *argv[])
+{
+ FILE *fo;
+
+ if (argc != 3) {
+ fprintf (stderr, "USAGE: generate input_file(possibly insnset.c) output_file(possibly execgen.c)\n");
+ exit (-1);
+ }
+
+ in_file = argv[1];
+ out_file = argv[2];
+ if (!(fo = fopen (argv[2], "wt+"))) {
+ fprintf (stderr, "Cannot create '%s'.\n", argv[2]);
+ exit (1);
+ }
+
+ build_automata ();
+ if (generate_header (fo)) {
+ fprintf (stderr, "generate_header\n");
+ return 1;
+ }
+
+ if (generate_body (fo, automata, 0, 1)) {
+ fprintf (stderr, "generate_body\n");
+ return 1;
+ }
+
+ if (generate_footer (fo)) {
+ fprintf (stderr, "generate_footer\n");
+ return 1;
+ }
+
+ fclose (fo);
+ destruct_automata ();
+ return 0;
+}
+
or32/generate.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: or32/or32.c
===================================================================
--- or32/or32.c (nonexistent)
+++ or32/or32.c (revision 1765)
@@ -0,0 +1,1295 @@
+/* Table of opcodes for the OpenRISC 1000 ISA.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Contributed by Damjan Lampret (lampret@opencores.org).
+
+This file is part of gen_or1k_isa, or1ksim, 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 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * $Log: not supported by cvs2svn $
+ * Revision 1.41 2005/02/09 17:41:03 nogj
+ * Mark a simulated cpu address as such, by introducing the new oraddr_t type
+ *
+ * Revision 1.40 2005/01/27 14:14:13 nogj
+ * Remove the global op structure
+ *
+ * Revision 1.39 2005/01/27 13:35:40 nogj
+ * * Fix generate.c to produce a execgen.c with less warnings.
+ * * Fix the --enable-simple configure option.
+ *
+ * Revision 1.38 2005/01/27 13:15:50 nogj
+ * Mark wich operand is the destination operand in the architechture definition
+ *
+ * Revision 1.37 2005/01/11 15:41:58 andreje
+ * l.ff1 instruction added
+ *
+ * Revision 1.36 2004/07/22 20:17:23 phoenix
+ * removed includes
+ *
+ * Revision 1.35 2004/07/19 23:07:37 phoenix
+ * Gyorgy Jeney: extensive cleanup
+ *
+ * Revision 1.34 2004/06/27 22:56:48 lampret
+ * Updated instruction set descriptions. Changed FP instructions encoding.
+ *
+ * Revision 1.33 2004/05/09 19:52:31 lampret
+ * Changed desciption of the l.cust5 insns
+ *
+ * Revision 1.31 2003/07/01 19:34:49 csanchez
+ * Added support for l.addc instruction.
+ *
+ * Revision 1.30 2003/01/28 03:49:24 lampret
+ * Added cvs log keywords
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#ifdef HAS_EXECUTION
+# ifdef HAVE_INTTYPES_H
+# include /* ...but to get arch.h we need uint{8,16,32}_t... */
+# endif
+# include "port.h"
+# include "arch.h" /* ...but to get abstract.h, we need oraddr_t... */
+# include "abstract.h" /* To get struct iqueue_entry... */
+#endif
+#include "opcode/or32.h"
+
+/* **INDENT-OFF** */
+
+/* We treat all letters the same in encode/decode routines so
+ we need to assign some characteristics to them like signess etc.*/
+CONST struct or32_letter or32_letters[] =
+{
+{ 'A', NUM_UNSIGNED },
+{ 'B', NUM_UNSIGNED },
+{ 'D', NUM_UNSIGNED },
+{ 'I', NUM_SIGNED },
+{ 'K', NUM_UNSIGNED },
+{ 'L', NUM_UNSIGNED },
+{ 'N', NUM_SIGNED },
+{ '0', NUM_UNSIGNED },
+{ '\0', 0 } /* dummy entry */
+};
+
+/* Opcode encoding:
+ machine[31:30]: first two bits of opcode
+ 00 - neither of source operands is GPR
+ 01 - second source operand is GPR (rB)
+ 10 - first source operand is GPR (rA)
+ 11 - both source operands are GPRs (rA and rB)
+ machine[29:26]: next four bits of opcode
+ machine[25:00]: instruction operands (specific to individual instruction)
+
+ Recommendation: irrelevant instruction bits should be set with a value of
+ bits in same positions of instruction preceding current instruction in the
+ code (when assembling).
+*/
+
+#ifdef HAS_EXECUTION
+# if SIMPLE_EXECUTION
+# define EFN &l_none
+# define EF(func) &(func)
+# define EFI &l_invalid
+# else /* SIMPLE_EXECUTION */
+# define EFN "l_none"
+# define EFI "l_invalid"
+# ifdef __GNUC__
+# define EF(func) #func
+# else
+# define EF(func) "func"
+# endif
+# endif /* SIMPLE_EXECUTION */
+#else /* HAS_EXECUTION */
+# define EFN &l_none
+# define EF(func) EFN
+# define EFI EFN
+#endif /* HAS_EXECUTION */
+
+CONST struct or32_opcode or32_opcodes[] =
+{
+
+{ "l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN",
+ EF(l_j), OR32_IF_DELAY, it_jump },
+{ "l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN",
+ EF(l_jal), OR32_IF_DELAY, it_jump },
+{ "l.bnf", "N", "00 0x3 NNNNN NNNNN NNNN NNNN NNNN NNNN",
+ EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG, it_branch },
+{ "l.bf", "N", "00 0x4 NNNNN NNNNN NNNN NNNN NNNN NNNN",
+ EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG, it_branch },
+{ "l.nop", "K", "00 0x5 01--- ----- KKKK KKKK KKKK KKKK",
+ EF(l_nop), 0, it_nop },
+{ "l.movhi", "rD,K", "00 0x6 DDDDD ----0 KKKK KKKK KKKK KKKK",
+ EF(l_movhi), 0, it_movimm },
+{ "l.macrc", "rD", "00 0x6 DDDDD ----1 0000 0000 0000 0000",
+ EF(l_macrc), 0, it_mac },
+{ "l.sys", "K", "00 0x8 00000 00000 KKKK KKKK KKKK KKKK",
+ EF(l_sys), 0, it_unknown },
+{ "l.trap", "K", "00 0x8 01000 00000 KKKK KKKK KKKK KKKK",
+ EF(l_trap), 0, it_unknown },
+{ "l.msync", "", "00 0x8 10000 00000 0000 0000 0000 0000", EFN,
+ 0, it_unknown },
+{ "l.psync", "", "00 0x8 10100 00000 0000 0000 0000 0000", EFN,
+ 0, it_unknown },
+{ "l.csync", "", "00 0x8 11000 00000 0000 0000 0000 0000", EFN,
+ 0, it_unknown },
+{ "l.rfe", "", "00 0x9 ----- ----- ---- ---- ---- ----",
+ EF(l_rfe), OR32_IF_DELAY, it_exception },
+{ "lv.all_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0,
+ it_unknown },
+{ "lv.all_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0,
+ it_unknown },
+{ "lv.all_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0,
+ it_unknown },
+{ "lv.all_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0,
+ it_unknown },
+{ "lv.all_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0,
+ it_unknown },
+{ "lv.all_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0,
+ it_unknown },
+{ "lv.all_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0,
+ it_unknown },
+{ "lv.all_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0,
+ it_unknown },
+{ "lv.all_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0,
+ it_unknown },
+{ "lv.all_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0,
+ it_unknown },
+{ "lv.all_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0,
+ it_unknown },
+{ "lv.all_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0,
+ it_unknown },
+{ "lv.any_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0,
+ it_unknown },
+{ "lv.any_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0,
+ it_unknown },
+{ "lv.any_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0,
+ it_unknown },
+{ "lv.any_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0,
+ it_unknown },
+{ "lv.any_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0,
+ it_unknown },
+{ "lv.any_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0,
+ it_unknown },
+{ "lv.any_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0,
+ it_unknown },
+{ "lv.any_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0,
+ it_unknown },
+{ "lv.any_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0,
+ it_unknown },
+{ "lv.any_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0,
+ it_unknown },
+{ "lv.any_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0,
+ it_unknown },
+{ "lv.any_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0,
+ it_unknown },
+{ "lv.add.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0,
+ it_unknown },
+{ "lv.add.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0,
+ it_unknown },
+{ "lv.adds.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0,
+ it_unknown },
+{ "lv.adds.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0,
+ it_unknown },
+{ "lv.addu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0,
+ it_unknown },
+{ "lv.addu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0,
+ it_unknown },
+{ "lv.addus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0,
+ it_unknown },
+{ "lv.addus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0,
+ it_unknown },
+{ "lv.and", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0,
+ it_unknown },
+{ "lv.avg.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0,
+ it_unknown },
+{ "lv.avg.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0,
+ it_unknown },
+{ "lv.cmp_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0,
+ it_unknown },
+{ "lv.cmp_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0,
+ it_unknown },
+{ "lv.cmp_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0,
+ it_unknown },
+{ "lv.cmp_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0,
+ it_unknown },
+{ "lv.cmp_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0,
+ it_unknown },
+{ "lv.cmp_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0,
+ it_unknown },
+{ "lv.cmp_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0,
+ it_unknown },
+{ "lv.cmp_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0,
+ it_unknown },
+{ "lv.cmp_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0,
+ it_unknown },
+{ "lv.cmp_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0,
+ it_unknown },
+{ "lv.cmp_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0,
+ it_unknown },
+{ "lv.cmp_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0,
+ it_unknown },
+{ "lv.madds.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0,
+ it_unknown },
+{ "lv.max.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0,
+ it_unknown },
+{ "lv.max.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0,
+ it_unknown },
+{ "lv.merge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0,
+ it_unknown },
+{ "lv.merge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0,
+ it_unknown },
+{ "lv.min.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0,
+ it_unknown },
+{ "lv.min.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0,
+ it_unknown },
+{ "lv.msubs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0,
+ it_unknown },
+{ "lv.muls.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0,
+ it_unknown },
+{ "lv.nand", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0,
+ it_unknown },
+{ "lv.nor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0,
+ it_unknown },
+{ "lv.or", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0,
+ it_unknown },
+{ "lv.pack.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0,
+ it_unknown },
+{ "lv.pack.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0,
+ it_unknown },
+{ "lv.packs.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0,
+ it_unknown },
+{ "lv.packs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0,
+ it_unknown },
+{ "lv.packus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0,
+ it_unknown },
+{ "lv.packus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0,
+ it_unknown },
+{ "lv.perm.n", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0,
+ it_unknown },
+{ "lv.rl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0,
+ it_unknown },
+{ "lv.rl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0,
+ it_unknown },
+{ "lv.sll.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0,
+ it_unknown },
+{ "lv.sll.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0,
+ it_unknown },
+{ "lv.sll", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0,
+ it_unknown },
+{ "lv.srl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0,
+ it_unknown },
+{ "lv.srl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0,
+ it_unknown },
+{ "lv.sra.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0,
+ it_unknown },
+{ "lv.sra.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0,
+ it_unknown },
+{ "lv.srl", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0,
+ it_unknown },
+{ "lv.sub.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0,
+ it_unknown },
+{ "lv.sub.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0,
+ it_unknown },
+{ "lv.subs.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0,
+ it_unknown },
+{ "lv.subs.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0,
+ it_unknown },
+{ "lv.subu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0,
+ it_unknown },
+{ "lv.subu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0,
+ it_unknown },
+{ "lv.subus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0,
+ it_unknown },
+{ "lv.subus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0,
+ it_unknown },
+{ "lv.unpack.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0,
+ it_unknown },
+{ "lv.unpack.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0,
+ it_unknown },
+{ "lv.xor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0,
+ it_unknown },
+{ "lv.cust1", "", "00 0xA ----- ----- ---- ---- 0xC ----", EFI, 0,
+ it_unknown },
+{ "lv.cust2", "", "00 0xA ----- ----- ---- ---- 0xD ----", EFI, 0,
+ it_unknown },
+{ "lv.cust3", "", "00 0xA ----- ----- ---- ---- 0xE ----", EFI, 0,
+ it_unknown },
+{ "lv.cust4", "", "00 0xA ----- ----- ---- ---- 0xF ----", EFI, 0,
+ it_unknown },
+
+{ "l.jr", "rB", "01 0x1 ----- ----- BBBB B--- ---- ----",
+ EF(l_jr), OR32_IF_DELAY, it_jump },
+{ "l.jalr", "rB", "01 0x2 ----- ----- BBBB B--- ---- ----",
+ EF(l_jalr), OR32_IF_DELAY, it_jump },
+{ "l.maci", "rA,I", "01 0x3 IIIII ----- AAAA AIII IIII IIII",
+ EF(l_mac), 0, it_mac },
+{ "l.cust1", "", "01 0xC ----- ----- ---- ---- ---- ----",
+ EF(l_cust1), 0, it_unknown },
+{ "l.cust2", "", "01 0xD ----- ----- ---- ---- ---- ----",
+ EF(l_cust2), 0, it_unknown },
+{ "l.cust3", "", "01 0xE ----- ----- ---- ---- ---- ----",
+ EF(l_cust3), 0, it_unknown },
+{ "l.cust4", "", "01 0xF ----- ----- ---- ---- ---- ----",
+ EF(l_cust4), 0, it_unknown },
+
+{ "l.ld", "rD,I(rA)", "10 0x0 DDDDD AAAAA IIII IIII IIII IIII", EFI,
+ 0, it_load },
+{ "l.lwz", "rD,I(rA)", "10 0x1 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_lwz), 0, it_load },
+{ "l.lws", "rD,I(rA)", "10 0x2 DDDDD AAAAA IIII IIII IIII IIII", EFI,
+ 0, it_load },
+{ "l.lbz", "rD,I(rA)", "10 0x3 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_lbz), 0, it_load },
+{ "l.lbs", "rD,I(rA)", "10 0x4 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_lbs), 0, it_load },
+{ "l.lhz", "rD,I(rA)", "10 0x5 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_lhz), 0, it_load },
+{ "l.lhs", "rD,I(rA)", "10 0x6 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_lhs), 0, it_load },
+
+{ "l.addi", "rD,rA,I", "10 0x7 DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_add), OR32_W_FLAG, it_arith },
+{ "l.addic", "rD,rA,I", "10 0x8 DDDDD AAAAA IIII IIII IIII IIII", EFI,
+ 0, it_arith },
+{ "l.andi", "rD,rA,K", "10 0x9 DDDDD AAAAA KKKK KKKK KKKK KKKK",
+ EF(l_and), OR32_W_FLAG, it_arith },
+{ "l.ori", "rD,rA,K", "10 0xA DDDDD AAAAA KKKK KKKK KKKK KKKK",
+ EF(l_or), 0, it_arith },
+{ "l.xori", "rD,rA,I", "10 0xB DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_xor), 0, it_arith },
+{ "l.muli", "rD,rA,I", "10 0xC DDDDD AAAAA IIII IIII IIII IIII",
+ EF(l_mul), 0, it_arith },
+{ "l.mfspr", "rD,rA,K", "10 0xD DDDDD AAAAA KKKK KKKK KKKK KKKK",
+ EF(l_mfspr), 0, it_move },
+{ "l.slli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 00LL LLLL",
+ EF(l_sll), 0, it_shift },
+{ "l.srli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 01LL LLLL",
+ EF(l_srl), 0, it_shift },
+{ "l.srai", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 10LL LLLL",
+ EF(l_sra), 0, it_shift },
+{ "l.rori", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 11LL LLLL", EFI,
+ 0, it_shift },
+
+{ "l.sfeqi", "rA,I", "10 0xF 00000 AAAAA IIII IIII IIII IIII",
+ EF(l_sfeq), OR32_W_FLAG, it_compare },
+{ "l.sfnei", "rA,I", "10 0xF 00001 AAAAA IIII IIII IIII IIII",
+ EF(l_sfne), OR32_W_FLAG, it_compare },
+{ "l.sfgtui", "rA,I", "10 0xF 00010 AAAAA IIII IIII IIII IIII",
+ EF(l_sfgtu), OR32_W_FLAG, it_compare },
+{ "l.sfgeui", "rA,I", "10 0xF 00011 AAAAA IIII IIII IIII IIII",
+ EF(l_sfgeu), OR32_W_FLAG, it_compare },
+{ "l.sfltui", "rA,I", "10 0xF 00100 AAAAA IIII IIII IIII IIII",
+ EF(l_sfltu), OR32_W_FLAG, it_compare },
+{ "l.sfleui", "rA,I", "10 0xF 00101 AAAAA IIII IIII IIII IIII",
+ EF(l_sfleu), OR32_W_FLAG, it_compare },
+{ "l.sfgtsi", "rA,I", "10 0xF 01010 AAAAA IIII IIII IIII IIII",
+ EF(l_sfgts), OR32_W_FLAG, it_compare },
+{ "l.sfgesi", "rA,I", "10 0xF 01011 AAAAA IIII IIII IIII IIII",
+ EF(l_sfges), OR32_W_FLAG, it_compare },
+{ "l.sfltsi", "rA,I", "10 0xF 01100 AAAAA IIII IIII IIII IIII",
+ EF(l_sflts), OR32_W_FLAG, it_compare },
+{ "l.sflesi", "rA,I", "10 0xF 01101 AAAAA IIII IIII IIII IIII",
+ EF(l_sfles), OR32_W_FLAG, it_compare },
+
+{ "l.mtspr", "rA,rB,K", "11 0x0 KKKKK AAAAA BBBB BKKK KKKK KKKK",
+ EF(l_mtspr), 0, it_move },
+{ "l.mac", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x1",
+ EF(l_mac), 0, it_mac },
+{ "l.msb", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x2",
+ EF(l_msb), 0, it_mac },
+
+{ "lf.add.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x0",
+ EF(lf_add_s), 0, it_float },
+{ "lf.sub.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x1",
+ EF(lf_sub_s), 0, it_float },
+{ "lf.mul.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x2",
+ EF(lf_mul_s), 0, it_float },
+{ "lf.div.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x3",
+ EF(lf_div_s), 0, it_float },
+{ "lf.itof.s", "rD,rA", "11 0x2 DDDDD AAAAA 0000 0--- 0x0 0x4",
+ EF(lf_itof_s), 0, it_float },
+{ "lf.ftoi.s", "rD,rA", "11 0x2 DDDDD AAAAA 0000 0--- 0x0 0x5",
+ EF(lf_ftoi_s), 0, it_float },
+{ "lf.rem.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x6",
+ EF(lf_rem_s), 0, it_float },
+{ "lf.madd.s", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x0 0x7",
+ EF(lf_madd_s), 0, it_float },
+{ "lf.sfeq.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0x8",
+ EF(lf_sfeq_s), 0, it_float },
+{ "lf.sfne.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0x9",
+ EF(lf_sfne_s), 0, it_float },
+{ "lf.sfgt.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0xA",
+ EF(lf_sfgt_s), 0, it_float },
+{ "lf.sfge.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0xB",
+ EF(lf_sfge_s), 0, it_float },
+{ "lf.sflt.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0xC",
+ EF(lf_sflt_s), 0, it_float },
+{ "lf.sfle.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x0 0xD",
+ EF(lf_sfle_s), 0, it_float },
+{ "lf.cust1.s", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0xD ----", EFI,
+ 0, it_float },
+
+{ "lf.add.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0,
+ it_float },
+{ "lf.sub.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0,
+ it_float },
+{ "lf.mul.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0,
+ it_float },
+{ "lf.div.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0,
+ it_float },
+{ "lf.itof.d", "rD,rA", "11 0x2 DDDDD AAAAA 0000 0--- 0x1 0x4", EFI, 0,
+ it_float },
+{ "lf.ftoi.d", "rD,rA", "11 0x2 DDDDD AAAAA 0000 0--- 0x1 0x5", EFI, 0,
+ it_float },
+{ "lf.rem.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0,
+ it_float },
+{ "lf.madd.d", "rD,rA,rB", "11 0x2 DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0,
+ it_float },
+{ "lf.sfeq.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0,
+ it_float },
+{ "lf.sfne.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0,
+ it_float },
+{ "lf.sfgt.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0,
+ it_float },
+{ "lf.sfge.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0,
+ it_float },
+{ "lf.sflt.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0,
+ it_float },
+{ "lf.sfle.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0,
+ it_float },
+{ "lf.cust1.d", "rA,rB", "11 0x2 ----- AAAAA BBBB B--- 0xE ----", EFI, 0,
+ it_float },
+
+{ "l.sd", "I(rD),rB", "11 0x4 IIIII DDDDD BBBB BIII IIII IIII", EFI,
+ 0, it_store },
+{ "l.sw", "I(rD),rB", "11 0x5 IIIII DDDDD BBBB BIII IIII IIII",
+ EF(l_sw), 0, it_store },
+{ "l.sb", "I(rD),rB", "11 0x6 IIIII DDDDD BBBB BIII IIII IIII",
+ EF(l_sb), 0, it_store },
+{ "l.sh", "I(rD),rB", "11 0x7 IIIII DDDDD BBBB BIII IIII IIII",
+ EF(l_sh), 0, it_store },
+
+{ "l.add", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x0",
+ EF(l_add), OR32_W_FLAG, it_arith },
+{ "l.addc", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x1",
+ EF(l_addc), OR32_W_FLAG, it_arith },
+{ "l.sub", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x2",
+ EF(l_sub), 0, it_arith },
+{ "l.and", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x3",
+ EF(l_and), OR32_W_FLAG, it_arith },
+{ "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4",
+ EF(l_or), 0, it_arith },
+{ "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5",
+ EF(l_xor), 0, it_arith },
+{ "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6",
+ EF(l_mul), 0, it_arith },
+
+{ "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8",
+ EF(l_sll), 0, it_shift },
+{ "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8",
+ EF(l_srl), 0, it_shift },
+{ "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8",
+ EF(l_sra), 0, it_shift },
+{ "l.ror", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0x8", EFI,
+ 0, it_shift },
+{ "l.div", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x9",
+ EF(l_div), 0, it_arith },
+{ "l.divu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0xA",
+ EF(l_divu), 0, it_arith },
+{ "l.mulu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0xB", EFI,
+ 0, it_arith },
+{ "l.extbs", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 01-- 0xC",
+ EF(l_extbs), 0, it_move },
+{ "l.exths", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 00-- 0xC",
+ EF(l_exths), 0, it_move },
+{ "l.extws", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 00-- 0xD",
+ EF(l_extws), 0, it_move },
+{ "l.extbz", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 11-- 0xC",
+ EF(l_extbz), 0, it_move },
+{ "l.exthz", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 10-- 0xC",
+ EF(l_exthz), 0, it_move },
+{ "l.extwz", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 01-- 0xD",
+ EF(l_extwz), 0, it_move },
+{ "l.cmov", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xE",
+ EF(l_cmov), OR32_R_FLAG, it_move },
+{ "l.ff1", "rD,rA", "11 0x8 DDDDD AAAAA ---- --00 ---- 0xF", EFI, 0,
+ it_arith },
+
+{ "l.sfeq", "rA,rB", "11 0x9 00000 AAAAA BBBB B--- ---- ----",
+ EF(l_sfeq), OR32_W_FLAG, it_compare },
+{ "l.sfne", "rA,rB", "11 0x9 00001 AAAAA BBBB B--- ---- ----",
+ EF(l_sfne), OR32_W_FLAG, it_compare },
+{ "l.sfgtu", "rA,rB", "11 0x9 00010 AAAAA BBBB B--- ---- ----",
+ EF(l_sfgtu), OR32_W_FLAG, it_compare },
+{ "l.sfgeu", "rA,rB", "11 0x9 00011 AAAAA BBBB B--- ---- ----",
+ EF(l_sfgeu), OR32_W_FLAG, it_compare },
+{ "l.sfltu", "rA,rB", "11 0x9 00100 AAAAA BBBB B--- ---- ----",
+ EF(l_sfltu), OR32_W_FLAG, it_compare },
+{ "l.sfleu", "rA,rB", "11 0x9 00101 AAAAA BBBB B--- ---- ----",
+ EF(l_sfleu), OR32_W_FLAG, it_compare },
+{ "l.sfgts", "rA,rB", "11 0x9 01010 AAAAA BBBB B--- ---- ----",
+ EF(l_sfgts), OR32_W_FLAG, it_compare },
+{ "l.sfges", "rA,rB", "11 0x9 01011 AAAAA BBBB B--- ---- ----",
+ EF(l_sfges), OR32_W_FLAG, it_compare },
+{ "l.sflts", "rA,rB", "11 0x9 01100 AAAAA BBBB B--- ---- ----",
+ EF(l_sflts), OR32_W_FLAG, it_compare },
+{ "l.sfles", "rA,rB", "11 0x9 01101 AAAAA BBBB B--- ---- ----",
+ EF(l_sfles), OR32_W_FLAG, it_compare },
+
+{ "l.cust5", "rD,rA,rB,L,K", "11 0xC DDDDD AAAAA BBBB BLLL LLLK KKKK", EFI,
+ 0, it_unknown },
+{ "l.cust6", "", "11 0xD ----- ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+
+/* This section should not be defined in or1ksim, since it contains duplicates,
+ which would cause machine builder to complain. */
+#ifdef HAS_CUST
+{ "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI,
+ 0, it_unknown },
+
+{ "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI,
+ 0, it_unknown },
+
+{ "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI,
+ 0, it_unknown },
+
+{ "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI,
+ 0, it_unknown },
+{ "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI,
+ 0, it_unknown },
+#endif
+
+{ "", "", "", EFI, 0, 0 } /* Dummy entry, not included in num_opcodes. This
+ * lets code examine entry i+1 without checking
+ * if we've run off the end of the table. */
+};
+
+#undef EFI
+#undef EFN
+#undef EF
+
+/* **INDENT-ON** */
+
+/* Define dummy, if debug is not defined. */
+#ifndef HAS_DEBUG
+#define debug(l, fmt...) ;
+#endif
+
+CONST int num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
+
+/* Calculates instruction length in bytes. Always 4 for OR32. */
+int
+insn_len(int insn_index)
+{
+ insn_index = 0; /* Just to get rid that warning. */
+ return 4;
+}
+
+/* Is individual insn's operand signed or unsigned? */
+int
+letter_signed(char l)
+{
+ CONST struct or32_letter *pletter;
+
+ for(pletter = or32_letters; pletter->letter != '\0'; pletter++)
+ if (pletter->letter == l)
+ return pletter->sign;
+
+ printf("letter_signed(%c): Unknown letter.\n", l);
+ return 0;
+}
+
+/* Simple cache for letter ranges */
+static int range_cache[256] = {0};
+
+/* Number of letters in the individual lettered operand. */
+int
+letter_range(char l)
+{
+ CONST struct or32_opcode *pinsn;
+ char *enc;
+ int range = 0;
+
+ /* Is value cached? */
+ if ((range = range_cache[(unsigned char)l])) return range;
+
+ for(pinsn = or32_opcodes; strlen(pinsn->name); pinsn++)
+ {
+ if (strchr(pinsn->encoding,l))
+ {
+ for (enc = pinsn->encoding; *enc != '\0'; enc++)
+ if ((*enc == '0') && (*(enc+1) == 'x'))
+ enc += 2;
+ else if (*enc == l)
+ range++;
+ return range_cache[(unsigned char)l] = range;
+ }
+ }
+
+ printf("\nABORT: letter_range(%c): Never used letter.\n", l);
+ exit(1);
+}
+
+/* MM: Returns index of given instruction name. */
+int
+insn_index (char *insn)
+{
+ int i, found = -1;
+ for (i = 0; i < num_opcodes; i++)
+ if (!strcmp (or32_opcodes[i].name, insn))
+ {
+ found = i;
+ break;
+ }
+ return found;
+}
+
+/* Returns name of the specified instruction index */
+CONST char *
+insn_name(int index)
+{
+ if (index >= 0 && index < num_opcodes)
+ return or32_opcodes[index].name;
+ else
+ return "???";
+}
+
+#if defined(HAS_EXECUTION) && SIMPLE_EXECUTION
+void
+l_none(struct iqueue_entry *current)
+{
+}
+#else
+void
+l_none()
+{
+}
+#endif
+
+/*** Finite automata for instruction decoding building code ***/
+
+/* Find symbols in encoding. */
+unsigned long
+insn_extract(param_ch, enc_initial)
+ char param_ch;
+ char *enc_initial;
+{
+ char *enc;
+ unsigned long ret = 0;
+ unsigned opc_pos = 32;
+ for (enc = enc_initial; *enc != '\0'; )
+ if ((*enc == '0') && (*(enc+1) == 'x'))
+ {
+ unsigned long tmp = strtol(enc+2, NULL, 16);
+ opc_pos -= 4;
+ if (param_ch == '0' || param_ch == '1')
+ {
+ if (param_ch == '0')
+ tmp = 15 - tmp;
+ ret |= tmp << opc_pos;
+ }
+ enc += 3;
+ }
+ else
+ {
+ if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha(*enc) )
+ {
+ opc_pos--;
+ if (param_ch == *enc)
+ ret |= 1 << opc_pos;
+ }
+ enc++;
+ }
+ return ret;
+}
+
+#define MAX_AUTOMATA_SIZE (1200)
+#define MAX_OP_TABLE_SIZE (1200)
+#define MAX_LEN (8)
+
+#ifndef MIN
+# define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+unsigned long *automata;
+int nuncovered;
+int curpass = 0;
+
+/* MM: Struct that holds runtime build information about instructions. */
+struct temp_insn_struct *ti;
+
+struct insn_op_struct *op_data, **op_start;
+
+/* Recursive utility function used to find best match and to build automata. */
+
+static unsigned long *
+cover_insn (unsigned long *cur, int pass, unsigned int mask)
+{
+ int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
+ unsigned long cur_mask = mask;
+ unsigned long *next;
+
+ for (i = 0; i < num_opcodes; i++)
+ if (ti[i].in_pass == pass)
+ {
+ cur_mask &= ti[i].insn_mask;
+ ninstr++;
+ last_match = i;
+ }
+
+ debug(8, "%08X %08X\n", mask, cur_mask);
+ if (ninstr == 0)
+ return 0;
+ if (ninstr == 1)
+ {
+ /* Leaf holds instruction index. */
+ debug(8, "%i>I%i %s\n", cur - automata, last_match, or32_opcodes[last_match].name);
+ *cur = LEAF_FLAG | last_match;
+ cur++;
+ nuncovered--;
+ } else {
+ /* Find longest match. */
+ for (i = 0; i < 32; i++)
+ {
+ int len;
+ for (len = best_len + 1; len < MIN(MAX_LEN, 33 - i); len++)
+ {
+ unsigned long m = (1UL << ((unsigned long)len)) - 1;
+ debug(9, " (%i(%08X & %08X>>%i = %08X, %08X)",len,m, cur_mask, i, (cur_mask >> (unsigned)i), (cur_mask >> (unsigned)i) & m);
+ if ((m & (cur_mask >> (unsigned)i)) == m)
+ {
+ best_len = len;
+ best_first = i;
+ debug(9, "!");
+ }
+ else
+ break;
+ }
+ }
+ debug(9, "\n");
+ if (!best_len)
+ {
+ fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask);
+ for (i = 0; i < num_opcodes; i++)
+ if (ti[i].in_pass == pass)
+ fprintf (stderr, "%s ", or32_opcodes[i].name);
+
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+ debug(8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len, best_first, ninstr);
+ *cur = best_first;
+ cur++;
+ *cur = (1 << best_len) - 1;
+ cur++;
+ next = cur;
+ /* Allocate space for pointers. */
+ cur += 1 << best_len;
+ cur_mask = (1 << (unsigned long)best_len) - 1;
+
+ for (i = 0; i < (1 << (unsigned long)best_len); i++)
+ {
+ int j;
+ unsigned long *c;
+ curpass++;
+ for (j = 0; j < num_opcodes; j++)
+ if (ti[j].in_pass == pass
+ && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i
+ && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
+ ti[j].in_pass = curpass;
+
+ debug(9, "%08X %08X %i\n", mask, cur_mask, best_first);
+ c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
+ if (c)
+ {
+ debug(8, "%i> #%X -> %u\n", next - automata, i, cur - automata);
+ *next = cur - automata;
+ cur = c;
+ }
+ else
+ {
+ debug(8, "%i> N/A\n", next - automata);
+ *next = 0;
+ }
+ next++;
+ }
+ }
+ return cur;
+}
+
+/* Returns number of nonzero bits. */
+static int
+num_ones (unsigned long value)
+{
+ int c = 0;
+ while (value)
+ {
+ if (value & 1)
+ c++;
+ value >>= 1;
+ }
+ return c;
+}
+
+/* Utility function, which converts parameters from or32_opcode format to more binary form.
+ Parameters are stored in ti struct. */
+
+static struct insn_op_struct *
+parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
+{
+ char *args = opcode->args;
+ int i, type;
+ int num_cur_op = 0;;
+
+ i = 0;
+ type = 0;
+ /* In case we don't have any parameters, we add dummy read from r0. */
+ if (!(*args)) {
+ cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
+ cur->data = 0;
+ debug(9, "#%08X %08X\n", cur->type, cur->data);
+ cur++;
+ return cur;
+ }
+
+ while (*args != '\0')
+ {
+ if (*args == 'r')
+ {
+ args++;
+ type |= OPTYPE_REG;
+ if(args[1] == 'D')
+ type |= OPTYPE_DST;
+ }
+ else if (isalpha (*args))
+ {
+ unsigned long arg;
+ arg = insn_extract(*args, opcode->encoding);
+ debug(9, "%s : %08X ------\n", opcode->name, arg);
+ if (letter_signed (*args))
+ {
+ type |= OPTYPE_SIG;
+ type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
+ }
+
+ num_cur_op = 0;
+ /* Split argument to sequences of consecutive ones. */
+ while (arg)
+ {
+ int shr = 0;
+ unsigned long tmp = arg, mask = 0;
+ while ((tmp & 1) == 0)
+ {
+ shr++;
+ tmp >>= 1;
+ }
+ while (tmp & 1)
+ {
+ mask++;
+ tmp >>= 1;
+ }
+ cur->type = type | shr;
+ cur->data = mask;
+ arg &= ~(((1 << mask) - 1) << shr);
+ debug(6, "|%08X %08X\n", cur->type, cur->data);
+ cur++;
+ num_cur_op++;
+ }
+ args++;
+ }
+ else if (*args == '(')
+ {
+ /* Next param is displacement. Later we will treat them as one operand. */
+ /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
+ * operand */
+ while(num_cur_op > 0) {
+ cur[-num_cur_op].type |= type | OPTYPE_DIS;
+ num_cur_op--;
+ }
+ cur[-1].type |= OPTYPE_OP;
+ debug(9, ">%08X %08X\n", cur->type, cur->data);
+ type = 0;
+ i++;
+ args++;
+ }
+ else if (*args == OPERAND_DELIM)
+ {
+ cur--;
+ cur->type = type | cur->type | OPTYPE_OP;
+ debug(9, ">%08X %08X\n", cur->type, cur->data);
+ cur++;
+ type = 0;
+ i++;
+ args++;
+ }
+ else if (*args == '0')
+ {
+ cur->type = type;
+ cur->data = 0;
+ debug(9, ">%08X %08X\n", cur->type, cur->data);
+ cur++;
+ type = 0;
+ i++;
+ args++;
+ }
+ else if (*args == ')')
+ args++;
+ else
+ {
+ fprintf (stderr, "%s : parse error in args.\n", opcode->name);
+ exit (1);
+ }
+ }
+ cur--;
+ cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
+ debug(9, "#%08X %08X\n", cur->type, cur->data);
+ cur++;
+ return cur;
+}
+
+/* Constructs new automata based on or32_opcodes array. */
+
+void
+build_automata()
+{
+ int i;
+ unsigned long *end;
+ struct insn_op_struct *cur;
+
+ automata = (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
+ ti = (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) * num_opcodes);
+
+ nuncovered = num_opcodes;
+
+#ifdef HAS_EXECUTION
+ printf("Building automata... ");
+#endif
+
+ /* Build temporary information about instructions. */
+ for (i = 0; i < num_opcodes; i++)
+ {
+ unsigned long ones, zeros;
+ char *encoding = or32_opcodes[i].encoding;
+ ones = insn_extract('1', encoding);
+ zeros = insn_extract('0', encoding);
+ ti[i].insn_mask = ones | zeros;
+ ti[i].insn = ones;
+ ti[i].in_pass = curpass = 0;
+ /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
+ or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
+ }
+
+ /* Until all are covered search for best criteria to separate them. */
+ end = cover_insn (automata, curpass, 0xFFFFFFFF);
+ if (end - automata > MAX_AUTOMATA_SIZE)
+ {
+ fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
+ exit (1);
+ }
+#ifdef HAS_EXECUTION
+ printf("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
+#endif
+
+#ifdef HAS_EXECUTION
+ printf("Parsing operands data... ");
+#endif
+ op_data = (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct));
+ op_start = (struct insn_op_struct **) malloc (num_opcodes * sizeof (struct insn_op_struct *));
+ cur = op_data;
+ for (i = 0; i < num_opcodes; i++)
+ {
+ op_start[i] = cur;
+ cur = parse_params (&or32_opcodes[i], cur);
+ if (cur - op_data > MAX_OP_TABLE_SIZE)
+ {
+ fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
+ exit (1);
+ }
+ }
+#ifdef HAS_EXECUTION
+ printf("done.\n");
+#endif
+}
+
+void destruct_automata ()
+{
+ free (ti);
+ free (automata);
+ free (op_data);
+ free (op_start);
+}
+
+/* Decodes instruction and returns instruction index. */
+int insn_decode (unsigned int insn)
+{
+ unsigned long *a = automata;
+ int i;
+ while (!(*a & LEAF_FLAG))
+ {
+ unsigned int first = *a;
+ //debug(9, "%i ", a - automata);
+ a++;
+ i = (insn >> first) & *a;
+ a++;
+ if (!*(a + i))
+ { /* Invalid instruction found? */
+ //debug(9, "XXX\n", i);
+ return -1;
+ }
+ a = automata + *(a + i);
+ }
+ i = *a & ~LEAF_FLAG;
+ //debug(9, "%i\n", i);
+ /* Final check - do we have direct match?
+ (based on or32_opcodes this should be the only possibility,
+ but in case of invalid/missing instruction we must perform a check) */
+ if ((ti[i].insn_mask & insn) == ti[i].insn)
+ return i;
+ else
+ return -1;
+}
+
+static char disassembled_str[50];
+char *disassembled = &disassembled_str[0];
+
+/* Automagically 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)
+{
+ unsigned long mask;
+ int letter_bits;
+
+ /* First truncate all bits above valid range for this letter
+ in case it is zero extend. */
+ letter_bits = letter_range(l);
+ mask = (1 << letter_bits) - 1;
+ imm &= mask;
+
+ /* Do sign extend if this is the right one. */
+ if (letter_signed(l) && (imm >> (letter_bits - 1)))
+ imm |= (~mask);
+
+ return imm;
+}
+
+unsigned long
+or32_extract(param_ch, enc_initial, insn)
+ char param_ch;
+ char *enc_initial;
+ unsigned long insn;
+{
+ char *enc;
+ unsigned long ret = 0;
+ int opc_pos = 0;
+ int param_pos = 0;
+
+ for (enc = enc_initial; *enc != '\0'; enc++)
+ if (*enc == param_ch)
+ {
+ if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
+ continue;
+ else
+ param_pos++;
+ }
+
+#if DEBUG
+ printf("or32_extract: %x ", param_pos);
+#endif
+ opc_pos = 32;
+ for (enc = enc_initial; *enc != '\0'; )
+ if ((*enc == '0') && (*(enc+1) == 'x'))
+ {
+ opc_pos -= 4;
+ if ((param_ch == '0') || (param_ch == '1'))
+ {
+ unsigned long tmp = strtol(enc, NULL, 16);
+#if DEBUG
+ printf(" enc=%s, tmp=%x ", enc, tmp);
+#endif
+ if (param_ch == '0')
+ tmp = 15 - tmp;
+ ret |= tmp << opc_pos;
+ }
+ enc += 3;
+ }
+ else if ((*enc == '0') || (*enc == '1'))
+ {
+ opc_pos--;
+ if (param_ch == *enc)
+ ret |= 1 << opc_pos;
+ enc++;
+ }
+ else if (*enc == param_ch)
+ {
+ opc_pos--;
+ param_pos--;
+#if DEBUG
+ printf("\n ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
+#endif
+ if (islower(param_ch))
+ ret -= ((insn >> opc_pos) & 0x1) << param_pos;
+ else
+ ret += ((insn >> opc_pos) & 0x1) << param_pos;
+ enc++;
+ }
+ else if (isalpha(*enc))
+ {
+ opc_pos--;
+ enc++;
+ }
+ else if (*enc == '-')
+ {
+ opc_pos--;
+ enc++;
+ }
+ else
+ enc++;
+
+#if DEBUG
+ printf ("ret=%x\n", ret);
+#endif
+ return ret;
+}
+
+/* Print register. Used only by print_insn. */
+
+static char *
+or32_print_register (dest, param_ch, encoding, insn)
+ char *dest;
+ char param_ch;
+ char *encoding;
+ unsigned long insn;
+{
+ int regnum = or32_extract(param_ch, encoding, insn);
+
+ sprintf (dest, "r%d", regnum);
+ while (*dest) dest++;
+ return dest;
+}
+
+/* Print immediate. Used only by print_insn. */
+
+static char *
+or32_print_immediate (dest, param_ch, encoding, insn)
+ char *dest;
+ char param_ch;
+ char *encoding;
+ unsigned long insn;
+{
+ int imm = or32_extract (param_ch, encoding, insn);
+
+ imm = extend_imm(imm, param_ch);
+
+ if (letter_signed(param_ch))
+ {
+ if (imm < 0)
+ sprintf (dest, "%d", imm);
+ else
+ sprintf (dest, "0x%x", imm);
+ }
+ else
+ sprintf (dest, "%#x", imm);
+ while (*dest) dest++;
+ return dest;
+}
+
+/* Disassemble one instruction from insn to disassemble.
+ Return the size of the instruction. */
+
+int
+disassemble_insn (insn)
+ unsigned long insn;
+{
+ return disassemble_index (insn, insn_decode (insn));
+}
+
+/* Disassemble one instruction from insn index.
+ Return the size of the instruction. */
+
+int
+disassemble_index (insn, index)
+ unsigned long insn;
+ int index;
+{
+ char *dest = disassembled;
+ if (index >= 0)
+ {
+ struct or32_opcode const *opcode = &or32_opcodes[index];
+ char *s;
+
+ strcpy (dest, opcode->name);
+ while (*dest) dest++;
+ *dest++ = ' ';
+ *dest = 0;
+
+ for (s = opcode->args; *s != '\0'; ++s)
+ {
+ switch (*s)
+ {
+ case '\0':
+ return insn_len (insn);
+
+ case 'r':
+ dest = or32_print_register(dest, *++s, opcode->encoding, insn);
+ break;
+
+ default:
+ if (strchr (opcode->encoding, *s))
+ dest = or32_print_immediate (dest, *s, opcode->encoding, insn);
+ else {
+ *dest++ = *s;
+ *dest = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* This used to be %8x for binutils. */
+ sprintf(dest, ".word 0x%08lx", insn);
+ while (*dest) dest++;
+ }
+ return insn_len (insn);
+}
Index: or32/Makefile.in
===================================================================
--- or32/Makefile.in (nonexistent)
+++ or32/Makefile.in (revision 1765)
@@ -0,0 +1,368 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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
+#
+# 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.
+#
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPU_ARCH = @CPU_ARCH@
+DEPDIR = @DEPDIR@
+INCLUDES = @INCLUDES@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+MAKE_SHELL = @MAKE_SHELL@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+am__include = @am__include@
+am__quote = @am__quote@
+host = @host@
+host_cpu = @host_cpu@
+host_os = @host_os@
+install_sh = @install_sh@
+
+noinst_LIBRARIES = libarch.a
+libarch_a_SOURCES = execute.c or32.c
+
+@SIMPLE_EXECUTION_TRUE@noinst_PROGRAMS =
+@SIMPLE_EXECUTION_FALSE@noinst_PROGRAMS = generate
+@SIMPLE_EXECUTION_TRUE@generate_SOURCES =
+@SIMPLE_EXECUTION_FALSE@generate_SOURCES = or32.c generate.c
+@SIMPLE_EXECUTION_FALSE@BUILT_SOURCES = execgen.c
+
+# If the simulator was first built without --enable-simple and then with it,
+# then also remove these two files
+CLEANFILES = execgen.c generate
+subdir = cpu/or32
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libarch_a_AR = $(AR) cru
+libarch_a_LIBADD =
+am_libarch_a_OBJECTS = execute.$(OBJEXT) or32.$(OBJEXT)
+libarch_a_OBJECTS = $(am_libarch_a_OBJECTS)
+@SIMPLE_EXECUTION_TRUE@noinst_PROGRAMS =
+@SIMPLE_EXECUTION_FALSE@noinst_PROGRAMS = generate$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+@SIMPLE_EXECUTION_TRUE@am_generate_OBJECTS =
+@SIMPLE_EXECUTION_FALSE@am_generate_OBJECTS = or32.$(OBJEXT) \
+@SIMPLE_EXECUTION_FALSE@ generate.$(OBJEXT)
+generate_OBJECTS = $(am_generate_OBJECTS)
+generate_LDADD = $(LDADD)
+generate_DEPENDENCIES =
+generate_LDFLAGS =
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/execute.Po ./$(DEPDIR)/generate.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/or32.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libarch_a_SOURCES) $(generate_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libarch_a_SOURCES) $(generate_SOURCES)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/or32/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libarch.a: $(libarch_a_OBJECTS) $(libarch_a_DEPENDENCIES)
+ -rm -f libarch.a
+ $(libarch_a_AR) libarch.a $(libarch_a_OBJECTS) $(libarch_a_LIBADD)
+ $(RANLIB) libarch.a
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+generate$(EXEEXT): $(generate_OBJECTS) $(generate_DEPENDENCIES)
+ @rm -f generate$(EXEEXT)
+ $(LINK) $(generate_LDFLAGS) $(generate_OBJECTS) $(generate_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/or32.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @list='$(DISTFILES)'; for file in $$list; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ 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 $(LIBRARIES) $(PROGRAMS)
+
+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_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:
+ -rm -f Makefile $(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-noinstLIBRARIES clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES clean-noinstPROGRAMS distclean \
+ distclean-compile distclean-depend distclean-generic \
+ distclean-tags distdir dvi dvi-am info info-am install \
+ install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic tags uninstall \
+ uninstall-am uninstall-info-am
+
+
+@SIMPLE_EXECUTION_FALSE@execgen.c: generate $(srcdir)/insnset.c
+@SIMPLE_EXECUTION_FALSE@ ./generate $(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/Makefile.am
===================================================================
--- or32/Makefile.am (nonexistent)
+++ or32/Makefile.am (revision 1765)
@@ -0,0 +1,40 @@
+# Makefile -- Makefile for OR32 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.
+#
+
+noinst_LIBRARIES = libarch.a
+libarch_a_SOURCES = execute.c or32.c
+
+if SIMPLE_EXECUTION
+noinst_PROGRAMS =
+generate_SOURCES =
+
+else
+noinst_PROGRAMS = generate
+generate_SOURCES = or32.c generate.c
+BUILT_SOURCES = execgen.c
+
+execgen.c: generate $(srcdir)/insnset.c
+ ./generate $(srcdir)/insnset.c execgen.c
+
+endif
+
+# If the simulator was first built without --enable-simple and then with it,
+# then also remove these two files
+CLEANFILES=execgen.c generate
Index: or32
===================================================================
--- or32 (nonexistent)
+++ or32 (revision 1765)
or32
Property changes :
Added: svn:ignore
## -0,0 +1,3 ##
+Makefile
+.deps
+generate
Index: or1k/sprs.c
===================================================================
--- or1k/sprs.c (nonexistent)
+++ or1k/sprs.c (revision 1765)
@@ -0,0 +1,194 @@
+/* sprs.c -- Simulation of OR1K special-purpose registers
+ 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. */
+
+#include
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "abstract.h"
+#include "sim-config.h"
+#include "except.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
+#include "dcache_model.h"
+#include "icache_model.h"
+
+
+extern int flag;
+
+int audio_cnt = 0;
+
+static FILE *fo = 0;
+/* Set a specific SPR with a value. */
+inline void
+mtspr(uint16_t regno, const sprword value)
+{
+ regno %= MAX_SPRS;
+ cpu_state.sprs[regno] = value;
+
+ /* MM: Register hooks. */
+ switch (regno) {
+ case SPR_TTCR:
+ spr_write_ttcr (value);
+ break;
+ case SPR_TTMR:
+ spr_write_ttmr (value);
+ break;
+ /* Data cache simulateing stuff */
+ case SPR_DCBPR:
+ if(value) {
+ dc_simulate_read(value, 4);
+ cpu_state.sprs[SPR_DCBPR] = 0;
+ }
+ break;
+ case SPR_DCBFR:
+ if(value != -1) {
+ dc_inv(value);
+ cpu_state.sprs[SPR_DCBFR] = -1;
+ }
+ break;
+ case SPR_DCBIR:
+ if(value != 0) {
+ 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:
+ if(value) {
+ ic_simulate_fetch(value);
+ cpu_state.sprs[SPR_ICBPR] = 0;
+ }
+ break;
+ case SPR_ICBIR:
+ if(value) {
+ ic_inv(value);
+ cpu_state.sprs[SPR_ICBIR] = 0;
+ }
+ break;
+ case SPR_ICBLR:
+ cpu_state.sprs[SPR_ICBLR] = 0;
+ break;
+ case SPR_SR:
+ /* Set internal flag also */
+ if(value & SPR_SR_F) flag = 1;
+ else flag = 0;
+ cpu_state.sprs[regno] |= SPR_SR_FO;
+ 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 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");
+ runtime.sim.cont_run = 0;
+ break;
+ case SPR_PMR:
+ /* PMR[SDF] and PMR[DCGE] are ignored completely. */
+ if (value & SPR_PMR_SUME) {
+ PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
+ runtime.sim.cont_run = 0;
+ }
+ break;
+ default:
+ /* Mask reseved 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] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
+ (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
+ else
+ cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
+ (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] = ((value / config.immu.pagesize) * config.immu.pagesize) |
+ (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
+ else
+ cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
+ (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));
+ }
+
+ /* Links to GPRS */
+ if(regno >= 0x0400 && regno < 0x0420) {
+ cpu_state.reg[regno - 0x0400] = value;
+ }
+ break;
+ }
+}
+
+/* Show status of important SPRs. */
+void sprs_status()
+{
+ PRINTF("VR : 0x%.8lx UPR : 0x%.8lx\n", mfspr(SPR_VR), mfspr(SPR_UPR));
+ PRINTF("SR : 0x%.8lx\n", mfspr(SPR_SR));
+ PRINTF("MACLO: 0x%.8lx MACHI: 0x%.8lx\n", mfspr(SPR_MACLO), mfspr(SPR_MACHI));
+ PRINTF("EPCR0: 0x%.8lx EPCR1: 0x%.8lx\n", mfspr(SPR_EPCR_BASE), mfspr(SPR_EPCR_BASE+1));
+ PRINTF("EEAR0: 0x%.8lx EEAR1: 0x%.8lx\n", mfspr(SPR_EEAR_BASE), mfspr(SPR_EEAR_BASE+1));
+ PRINTF("ESR0 : 0x%.8lx ESR1 : 0x%.8lx\n", mfspr(SPR_ESR_BASE), mfspr(SPR_ESR_BASE+1));
+ PRINTF("TTMR : 0x%.8lx TTCR : 0x%.8lx\n", mfspr(SPR_TTMR), mfspr(SPR_TTCR));
+ PRINTF("PICMR: 0x%.8lx PICSR: 0x%.8lx\n", mfspr(SPR_PICMR), mfspr(SPR_PICSR));
+ PRINTF("PPC: 0x%.8lx NPC : 0x%.8lx\n", mfspr(SPR_PPC), mfspr(SPR_NPC));
+}
Index: or1k/except.c
===================================================================
--- or1k/except.c (nonexistent)
+++ or1k/except.c (revision 1765)
@@ -0,0 +1,130 @@
+/* except.c -- Simulation of OR1K exceptions
+ 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. */
+
+#include
+#include
+#include
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+#include
+#endif
+
+#include "port.h"
+#include "arch.h"
+#include "abstract.h"
+#include "except.h"
+#include "sim-config.h"
+#include "debug_unit.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
+
+extern oraddr_t pcprev;
+
+int except_pending = 0;
+
+static const char *except_names[] = {
+ NULL,
+ "Reset",
+ "Bus Error",
+ "Data Page Fault",
+ "Insn Page Fault",
+ "Tick timer",
+ "Alignment",
+ "Illegal instruction",
+ "Interrupt",
+ "Data TLB Miss",
+ "Insn TLB Miss",
+ "Range",
+ "System Call",
+ "Trap" };
+
+static const char *except_name(oraddr_t except)
+{
+ return except_names[except >> 8];
+}
+
+/* Asserts OR1K exception. */
+void except_handle(oraddr_t except, oraddr_t ea)
+{
+ if(debug_ignore_exception (except))
+ return;
+
+ except_pending = 1;
+
+ if (config.sim.verbose)
+ PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
+ ", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
+ ", cycles %lld, #%lld\n",
+ except, except_name(except), pcprev, ea, cpu_state.pc, pcnext,
+ cpu_state.pc_delay, runtime.sim.cycles, runtime.cpu.instructions);
+
+ pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
+
+ switch(except) {
+ /* EPCR is irrelevent */
+ case EXCEPT_RESET:
+ break;
+ /* EPCR is loaded with address of instruction that caused the exception */
+ /* All these exceptions happen during a simulated instruction */
+ case EXCEPT_BUSERR:
+ case EXCEPT_DPF:
+ case EXCEPT_IPF:
+ case EXCEPT_ALIGN:
+ case EXCEPT_ILLEGAL:
+ case EXCEPT_DTLBMISS:
+ case EXCEPT_ITLBMISS:
+ case EXCEPT_RANGE:
+ case EXCEPT_TRAP:
+ mtspr(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:
+ mtspr(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:
+ mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
+ /* 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;
+ break;
+ }
+
+ mtspr(SPR_EEAR_BASE, ea);
+ mtspr(SPR_ESR_BASE, mfspr(SPR_SR));
+
+ /* Address translation is always disabled when starting exception. */
+ mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_DME));
+ mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IME));
+
+ mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE); /* Disable overflow flag exception. */
+
+ mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */
+ mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */
+
+ cpu_state.delay_insn = 0;
+}
Index: or1k/sprs.h
===================================================================
--- or1k/sprs.h (nonexistent)
+++ or1k/sprs.h (revision 1765)
@@ -0,0 +1,132 @@
+/* sprs.h -- OR1K architecture specific special-purpose registers
+ 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. */
+
+#include "spr_defs.h"
+
+typedef unsigned long sprword;
+
+/* Prototypes */
+inline void mtspr(uint16_t regno, const sprword value);
+static inline sprword mfspr_(const uint16_t regno);
+extern sprword sprs[MAX_SPRS];
+#define mfspr(regno) mfspr_(regno)
+
+static inline void setsprbit(const int regno, const int bitnum, const unsigned long bitvalue);
+static inline int getsprbit(const int regno, const int bitnum);
+void sprs_status();
+
+#include "sim-config.h"
+#include "tick.h"
+
+/* Ugly, but fast */
+/* Get a specific SPR. */
+static inline sprword
+mfspr_(const uint16_t regno)
+{
+ extern oraddr_t pcprev;
+
+ switch (regno) {
+ case SPR_NPC:
+ return cpu_state.pc;
+ case SPR_PPC:
+ return pcprev;
+ case SPR_TTCR:
+ return spr_read_ttcr();
+ default:
+ /* Links to GPRS */
+ if(regno >= 0x0400 && regno < 0x0420)
+ return cpu_state.reg[regno - 0x0400];
+ else if (regno < MAX_SPRS)
+ return cpu_state.sprs[regno];
+ }
+ if (config.sim.verbose)
+ PRINTF ("WARNING: read out of SPR range %08X\n", regno);
+ return 0;
+}
+
+/* Set specific SPR bit(s) identified by mask. */
+static inline void
+setsprbits(const int regno, const unsigned long mask, const unsigned long value)
+{
+ sprword regvalue = mfspr(regno);
+ sprword shifted = 0x0;
+ int m, v = 0;
+
+ /* m counts bits in valuemask */
+ /* v counts bits in value */
+ for (m = 0; m < 32; m++)
+ if ((mask >> m) & 0x1) {
+ shifted |= ((value >> v) & 0x1) << m;
+ v++;
+ }
+
+ /* PRINTF("oldvalue %x setsprbits(%x, %x, %x) shifted %x", regvalue, regno, mask, value, shifted); */
+ mtspr(regno, (regvalue & ~mask) | shifted);
+}
+
+/* Get specific SPR bit(s) identified by mask. */
+static inline unsigned long
+getsprbits(const int regno, const unsigned long mask)
+{
+ sprword regvalue = mfspr(regno);
+ sprword shifted = 0x0;
+ int m, v = 0;
+
+ /* m counts bits in valuemask */
+ /* v counts bits in regvalue */
+ for (m = 0; m < 32; m++)
+ if ((mask >> m) & 0x1) {
+ shifted |= ((regvalue >> m) & 0x1) << v;
+ v++;
+ }
+
+ return shifted;
+}
+
+/* Set a specific bit from SPR. LSB in a word is numbered zero. */
+static inline void
+setsprbit(const int regno, const int bitnum, const unsigned long bitvalue)
+{
+ sprword mask;
+ sprword regvalue = mfspr(regno);
+
+ mask = ~(1 << bitnum);
+
+ mtspr(regno, (regvalue & mask) | ((bitvalue & 0x1) << bitnum));
+
+ return;
+}
+
+/* Get a specific bit from SPR. */
+static inline int
+getsprbit(const int regno, const int bitnum)
+{
+ sprword regvalue = mfspr(regno);
+
+ return (regvalue >> bitnum) & 0x1;
+}
+
+/* Get specific SPR bit(s) identified by mask. */
+static inline unsigned long
+testsprbits(const int regno, const unsigned long mask)
+{
+ sprword regvalue = mfspr(regno);
+ return regvalue & mask;
+}
+
Index: or1k/except.h
===================================================================
--- or1k/except.h (nonexistent)
+++ or1k/except.h (revision 1765)
@@ -0,0 +1,51 @@
+/* except.h -- OR1K architecture specific exceptions
+ 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. */
+
+#ifndef _EXCEPT_H_
+#define _EXCEPT_H_
+
+/* Define if you want pure virtual machine simulation (no exceptions etc.) */
+#define ONLY_VIRTUAL_MACHINE 0
+
+/* Definition of OR1K exceptions */
+
+#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_TRAP 0x0e00
+
+/* Non maskable exceptions */
+#define IS_NME(E) ((E) == EXCEPT_RESET)
+
+/* Prototypes */
+void except_handle(oraddr_t except, oraddr_t ea);
+
+/* Has an exception been raised in this cycle ? */
+extern int except_pending;
+
+#endif
Index: or1k/spr_defs.h
===================================================================
--- or1k/spr_defs.h (nonexistent)
+++ or1k/spr_defs.h (revision 1765)
@@ -0,0 +1,486 @@
+/* spr_defs.h -- Defines OR1K architecture specific special-purpose registers
+ 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. */
+
+/* This file is also used by microkernel test bench. Among
+others it is also used in assembly file(s). */
+
+/* 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 0xffff0000 /* Processor version */
+#define SPR_VR_REV 0x0000003f /* Processor revision */
+
+/*
+ * 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_OB32P 0x00000020 /* ORBIS32 present */
+#define SPR_UPR_OB64P 0x00000040 /* ORBIS64 present */
+#define SPR_UPR_OF32P 0x00000080 /* ORFPX32 present */
+#define SPR_UPR_OF64P 0x00000100 /* ORFPX64 present */
+#define SPR_UPR_OV32P 0x00000200 /* ORVDX32 present */
+#define SPR_UPR_OV64P 0x00000400 /* ORVDX64 present */
+#define SPR_UPR_DUP 0x00000800 /* Debug unit present */
+#define SPR_UPR_PCUP 0x00001000 /* Performance counters unit present */
+#define SPR_UPR_PMP 0x00002000 /* Power management present */
+#define SPR_UPR_PICP 0x00004000 /* PIC present */
+#define SPR_UPR_TTP 0x00008000 /* Tick timer present */
+#define SPR_UPR_SRP 0x00010000 /* Shadow registers present */
+#define SPR_UPR_RES 0x00fe0000 /* ORVDX32 present */
+#define SPR_UPR_CUST 0xff000000 /* Custom units */
+
+/*
+ * Bit definitions for the Supervision Register
+ *
+ */
+#define SPR_SR_CID 0xf0000000 /* Context ID */
+#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */
+#define SPR_SR_FO 0x00008000 /* Fixed one */
+#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */
+#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */
+#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */
+#define SPR_SR_OV 0x00000800 /* Overflow flag */
+#define SPR_SR_CY 0x00000400 /* Carry flag */
+#define SPR_SR_F 0x00000200 /* Condition Flag */
+#define SPR_SR_CE 0x00000100 /* CID Enable */
+#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */
+#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */
+#define SPR_SR_DME 0x00000020 /* Data MMU Enable */
+#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */
+#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */
+#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */
+#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */
+#define SPR_SR_SM 0x00000001 /* Supervisor Mode */
+
+/*
+ * 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
+
+/*
+ * 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
+
+/*
+ * 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
+
+/*
+ * 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
+
+/*
+ * 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_CW0 0x00000003 /* Chain watchpoint 0 */
+#define SPR_DMR1_CW1 0x0000000c /* Chain watchpoint 1 */
+#define SPR_DMR1_CW2 0x00000030 /* Chain watchpoint 2 */
+#define SPR_DMR1_CW3 0x000000c0 /* Chain watchpoint 3 */
+#define SPR_DMR1_CW4 0x00000300 /* Chain watchpoint 4 */
+#define SPR_DMR1_CW5 0x00000c00 /* Chain watchpoint 5 */
+#define SPR_DMR1_CW6 0x00003000 /* Chain watchpoint 6 */
+#define SPR_DMR1_CW7 0x0000c000 /* Chain watchpoint 7 */
+#define SPR_DMR1_CW8 0x00030000 /* Chain watchpoint 8 */
+#define SPR_DMR1_CW9 0x000c0000 /* Chain watchpoint 9 */
+#define SPR_DMR1_CW10 0x00300000 /* Chain watchpoint 10 */
+#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/
+#define SPR_DMR1_BT 0x00800000 /* Branch trace */
+#define SPR_DMR1_DXFW 0x01000000 /* Disable external force watchpoint */
+
+/*
+ * Bit definitions for Debug Mode 2 register
+ *
+ */
+#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_AWTC 0x00001ffc /* Assign watchpoints to counters */
+#define SPR_DMR2_WGB 0x00ffe000 /* Watchpoints generating breakpoint */
+
+/*
+ * Bit definitions for Debug watchpoint counter registers
+ *
+ */
+#define SPR_DWCR_COUNT 0x0000ffff /* Count */
+#define SPR_DWCR_MATCH 0xffff0000 /* Match */
+
+/*
+ * 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 /* iTick 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_CNT_RESET 0x0005 /* Reset statistics counters */
+#define NOP_REPORT_FIRST 0x0400 /* Report with number */
+#define NOP_REPORT_LAST 0x03ff /* Report with number */
Index: or1k/Makefile.in
===================================================================
--- or1k/Makefile.in (nonexistent)
+++ or1k/Makefile.in (revision 1765)
@@ -0,0 +1,332 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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
+#
+# 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.
+#
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPU_ARCH = @CPU_ARCH@
+DEPDIR = @DEPDIR@
+INCLUDES = @INCLUDES@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+MAKE_SHELL = @MAKE_SHELL@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+am__include = @am__include@
+am__quote = @am__quote@
+host = @host@
+host_cpu = @host_cpu@
+host_os = @host_os@
+install_sh = @install_sh@
+
+noinst_LIBRARIES = libor1k.a
+libor1k_a_SOURCES = sprs.c except.c
+subdir = cpu/or1k
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libor1k_a_AR = $(AR) cru
+libor1k_a_LIBADD =
+am_libor1k_a_OBJECTS = sprs.$(OBJEXT) except.$(OBJEXT)
+libor1k_a_OBJECTS = $(am_libor1k_a_OBJECTS)
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/except.Po ./$(DEPDIR)/sprs.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libor1k_a_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libor1k_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/or1k/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libor1k.a: $(libor1k_a_OBJECTS) $(libor1k_a_DEPENDENCIES)
+ -rm -f libor1k.a
+ $(libor1k_a_AR) libor1k.a $(libor1k_a_OBJECTS) $(libor1k_a_LIBADD)
+ $(RANLIB) libor1k.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprs.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @list='$(DISTFILES)'; for file in $$list; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ 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 $(LIBRARIES)
+
+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_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(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-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic tags uninstall uninstall-am \
+ uninstall-info-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,61 @@
+/* arch.h -- OR1K 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 "r9"
+#define LINK_REGNO (9)
+#define STACK_REG "r1"
+#define STACK_REGNO (1)
+#define FRAME_REG "r2"
+#define FRAME_REGNO (2)
+#define RETURNV_REG "r11"
+#define RETURNV_REGNO (11)
+
+/* 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 */
+
+#define PRIxADDR "08" PRIx32 /* How to print an openrisc address in hex */
+#define PRIxREG "08" PRIx32 /* How to print an openrisc register in hex */
+#define PRIdREG "08" PRId32 /* How to print an openrisc register in decimals */
+
+#define ADDR_C(c) UINT32_C(c)
+#define REG_C(c) UINT32_C(c)
+
+/* Should args be passed on stack for simprintf
+ *
+ * FIXME: do not enable this since it causes problems
+ * in some cases (an example beeing cbasic test
+ * from orp testbench). the problems is in
+ *
+ * or1k/support/simprintf.c
+ *
+ * #if STACK_ARGS
+ * arg = eval_mem32(argaddr,&breakpoint);
+ * argaddr += 4;
+ * #else
+ * sprintf(regstr, "r%u", ++argaddr);
+ * arg = evalsim_reg(atoi(regstr));
+ * #endif
+ *
+ * the access to memory should be without any
+ * checks (ie not like or32 application accessed it)
+ *
+ */
+#define STACK_ARGS 0
Index: or1k/opcode/or32.h
===================================================================
--- or1k/opcode/or32.h (nonexistent)
+++ or1k/opcode/or32.h (revision 1765)
@@ -0,0 +1,273 @@
+/* Table of opcodes for the OpenRISC 1000 ISA.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Contributed by Damjan Lampret (lampret@opencores.org).
+
+This file is part of or1k_gen_isa, or1ksim, 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 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* 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)
+
+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 HAS_EXECUTION
+# if !SIMPLE_EXECUTION
+ char *function_name;
+# else /* !SIMPLE_EXECUTION */
+ void (*exec)(struct iqueue_entry *);
+# endif
+#else /* HAS_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;
+
+#if defined(HAS_EXECUTION) && SIMPLE_EXECUTION
+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 *));
+#else
+extern void l_none PARAMS((void));
+#endif
+
+extern CONST struct or32_letter or32_letters[];
+
+extern CONST struct or32_opcode or32_opcodes[];
+
+extern CONST int num_opcodes;
+
+/* 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/Makefile.am
===================================================================
--- or1k/Makefile.am (nonexistent)
+++ or1k/Makefile.am (revision 1765)
@@ -0,0 +1,23 @@
+# Makefile -- Makefile for OR1K architecture 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.
+#
+
+noinst_LIBRARIES = libor1k.a
+libor1k_a_SOURCES = sprs.c except.c
+
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,345 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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@
+
+#
+#
+#
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+AMTAR = @AMTAR@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+BUILD_DIR = @BUILD_DIR@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPU_ARCH = @CPU_ARCH@
+DEPDIR = @DEPDIR@
+INCLUDES = @INCLUDES@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LOCAL_CFLAGS = @LOCAL_CFLAGS@
+LOCAL_DEFS = @LOCAL_DEFS@
+MAKE_SHELL = @MAKE_SHELL@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+SUMVERSION = @SUMVERSION@
+TERMCAP_LIB = @TERMCAP_LIB@
+VERSION = @VERSION@
+am__include = @am__include@
+am__quote = @am__quote@
+host = @host@
+host_cpu = @host_cpu@
+host_os = @host_os@
+install_sh = @install_sh@
+
+SUBDIRS = common or1k $(CPU_ARCH)
+subdir = cpu
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
+ uninstall-info-recursive all-recursive install-data-recursive \
+ install-exec-recursive installdirs-recursive install-recursive \
+ uninstall-recursive check-recursive installcheck-recursive
+DIST_COMMON = Makefile.am Makefile.in
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cpu/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+uninstall-info-am:
+
+# 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):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ 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) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ 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) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @list='$(DISTFILES)'; for file in $$list; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ 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='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ 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_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(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 mostlyclean-am
+
+distclean: distclean-recursive
+
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
+ clean-generic clean-recursive distclean distclean-generic \
+ distclean-recursive distclean-tags distdir dvi dvi-am \
+ dvi-recursive info info-am info-recursive install install-am \
+ install-data install-data-am install-data-recursive \
+ install-exec install-exec-am install-exec-recursive \
+ install-info install-info-am install-info-recursive install-man \
+ install-recursive install-strip installcheck installcheck-am \
+ installdirs installdirs-am installdirs-recursive \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-generic \
+ mostlyclean-recursive tags tags-recursive uninstall \
+ uninstall-am uninstall-info-am uninstall-info-recursive \
+ uninstall-recursive
+
+# 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: or16
===================================================================
--- or16 (nonexistent)
+++ or16 (revision 1765)
or16
Property changes :
Added: svn:ignore
## -0,0 +1 ##
+Makefile
Index: Makefile.am
===================================================================
--- Makefile.am (nonexistent)
+++ Makefile.am (revision 1765)
@@ -0,0 +1,5 @@
+#
+#
+#
+
+SUBDIRS = common or1k $(CPU_ARCH)
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 1765)
.
Property changes :
Added: svn:ignore
## -0,0 +1,2 ##
+Makefile
+.deps