OpenCores
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_47/or1ksim/cpu/dlx
    from Rev 1419 to Rev 1765
    Reverse comparison

Rev 1419 → Rev 1765

/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
/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:
/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]);
}
}
/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
/.
. Property changes : Added: svn:ignore ## -0,0 +1 ## +Makefile

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.