From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 37164 invoked by alias); 23 Sep 2019 08:59:54 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 37156 invoked by uid 89); 23 Sep 2019 08:59:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=H*RU:sk:host86-, HX-Spam-Relays-External:sk:host86-, addressed, H*r:sk:host86- X-HELO: mail-wm1-f68.google.com Received: from mail-wm1-f68.google.com (HELO mail-wm1-f68.google.com) (209.85.128.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Sep 2019 08:59:46 +0000 Received: by mail-wm1-f68.google.com with SMTP id i16so8913868wmd.3 for ; Mon, 23 Sep 2019 01:59:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=nnHd7tbNDRt1z4+6agaFTq5erX5DOyDkgy/WI/wBVoA=; b=L6Tgsf1kEOdgyGl9JvJgmFqzk7MmMQ0rLLBiiVwEv5+/YQwr61BboxyjYrIYSE/coW AYZnme5YAUhWMCOlaMhHjJ5dNig3K8EeQ66DO4yWvbL5iM8oQMFDdGZc+YAgq2nSI9Kn vraNamFwBolsSyZhaRonW+nWDAOSVVeFmpnA8JRM6Mc4fukHiN0eT4AN+BSlxbIOAMf5 QvrQp3VBtdHrA/iu/UmEVx0thbOi63//VD0Xim5sCIV1ocXJJUbXDVk11ub/zfRkwJkr XA9wNVL11KxgepPRutkgIL5g0cnyaQMzMxAM3huo70pLaUnQcCh7C6DVZABlKgeHQh/x nfFg== Return-Path: Received: from localhost (host86-161-16-231.range86-161.btcentralplus.com. [86.161.16.231]) by smtp.gmail.com with ESMTPSA id q192sm15972117wme.23.2019.09.23.01.59.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Sep 2019 01:59:41 -0700 (PDT) Date: Mon, 23 Sep 2019 08:59:00 -0000 From: Andrew Burgess To: Dimitar Dimitrov Cc: gdb-patches@sourceware.org Subject: Re: [PATCH v6 1/3] PRU Simulator port Message-ID: <20190923085940.GG4962@embecosm.com> References: <20190904194031.30525-1-dimitar@dinux.eu> <11920096.ZOrQXH10OB@tpdeb> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <11920096.ZOrQXH10OB@tpdeb> X-Fortune: Did I SELL OUT yet?? X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] User-Agent: Mutt/1.9.2 (2017-12-15) X-IsSubscribed: yes X-SW-Source: 2019-09/txt/msg00444.txt.bz2 * Dimitar Dimitrov [2019-09-22 11:08:41 +0300]: > Ping. Sorry for the delay in reviewing this. I plan to review this in the first half of this week. Thanks, Andrew > > On Wednesday, 4 Sep 2019, 22:40:29 EEST Dimitar Dimitrov wrote: > > I'd like to contribute a sim port for the TI PRU I/O processor. This > > is the sixth version of the patch series. > > > > Changes since patch series v5: > > - Added copyright headers to test cases. > > - Regenerated using autoconf-2.69 and automake-1.5.1 > > - Added more comments to functions and MAC register enum. > > - Updated copyright years. > > > > v1: https://sourceware.org/ml/gdb-patches/2016-12/msg00143.html > > v2: https://sourceware.org/ml/gdb-patches/2017-02/msg00397.html > > v3: https://sourceware.org/ml/gdb-patches/2017-02/msg00516.html > > v4: https://sourceware.org/ml/gdb-patches/2018-06/msg00484.html > > v5: https://sourceware.org/ml/gdb-patches/2019-08/msg00584.html > > > > gdb/ChangeLog: > > > > 2019-09-04 Dimitar Dimitrov > > > > * NEWS: Mention new simulator port for PRU. > > > > sim/ > > 2019-09-04 Dimitar Dimitrov > > > > * MAINTAINERS: Add myself as PRU maintainer. > > * configure: Regenerated. > > * configure.tgt: Add PRU. > > > > sim/common/ > > 2019-09-04 Dimitar Dimitrov > > > > * gennltvals.sh: Add PRU libgloss target. > > * nltvals.def: Regenerate from the latest libgloss sources. > > > > sim/pru/ > > 2019-09-04 Dimitar Dimitrov > > > > * Makefile.in: New file. > > * aclocal.m4: Regenerated. > > * config.in: Regenerated. > > * configure: Regenerated. > > * configure.ac: New file. > > * interp.c: New file. > > * pru.h: New file. > > * pru.isa: New file. > > * sim-main.h: New file. > > > > Signed-off-by: Dimitar Dimitrov > > --- > > gdb/NEWS | 4 + > > sim/MAINTAINERS | 1 + > > sim/common/gennltvals.sh | 4 + > > sim/common/nltvals.def | 31 ++ > > sim/configure | 8 + > > sim/configure.tgt | 3 + > > sim/pru/Makefile.in | 29 ++ > > sim/pru/aclocal.m4 | 119 ++++++ > > sim/pru/config.in | 248 ++++++++++++ > > sim/pru/configure.ac | 31 ++ > > sim/pru/interp.c | 848 +++++++++++++++++++++++++++++++++++++++ > > sim/pru/pru.h | 110 +++++ > > sim/pru/pru.isa | 249 ++++++++++++ > > sim/pru/sim-main.h | 91 +++++ > > 14 files changed, 1776 insertions(+) > > create mode 100644 sim/pru/Makefile.in > > create mode 100644 sim/pru/aclocal.m4 > > create mode 100644 sim/pru/config.in > > create mode 100644 sim/pru/configure.ac > > create mode 100644 sim/pru/interp.c > > create mode 100644 sim/pru/pru.h > > create mode 100644 sim/pru/pru.isa > > create mode 100644 sim/pru/sim-main.h > > > > diff --git a/gdb/NEWS b/gdb/NEWS > > index f382e887c0..f4b5c9239c 100644 > > --- a/gdb/NEWS > > +++ b/gdb/NEWS > > @@ -318,6 +318,10 @@ maint show test-options-completion-result > > GDB now bundles GNU readline 8.0, but if you choose to use > > --with-system-readline, only readline >= 7.0 can be used. > > > > +* New Simulators > > + > > +TI PRU pru-*-elf > > + > > *** Changes in GDB 8.3 > > > > * GDB and GDBserver now support access to additional registers on > > diff --git a/sim/MAINTAINERS b/sim/MAINTAINERS > > index 3b9b08c40d..4ca67cfd1d 100644 > > --- a/sim/MAINTAINERS > > +++ b/sim/MAINTAINERS > > @@ -29,6 +29,7 @@ mips I-IV Maciej W. Rozycki > > moxie Anthony Green > > msp430 Nick Clifton > > or1k Stafford Horne > > +pru Dimitar Dimitrov > > sh (global maintainers) > > sh64 Dave Brolley > > common Frank Ch. Eigler > > diff --git a/sim/common/gennltvals.sh b/sim/common/gennltvals.sh > > index 7027c35ad4..79180335b6 100755 > > --- a/sim/common/gennltvals.sh > > +++ b/sim/common/gennltvals.sh > > @@ -95,3 +95,7 @@ $shell ${srccom}/gentvals.sh $target sys > > ${newlibroot}/$dir \ dir=libgloss target=lm32 > > $shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \ > > "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}" > > + > > +dir=libgloss target=pru > > +$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \ > > + "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}" > > diff --git a/sim/common/nltvals.def b/sim/common/nltvals.def > > index 3f82d47b6b..92ccc9aded 100644 > > --- a/sim/common/nltvals.def > > +++ b/sim/common/nltvals.def > > @@ -574,3 +574,34 @@ > > /* end lm32 sys target macros */ > > #endif > > #endif > > +#ifdef NL_TARGET_pru > > +#ifdef sys_defs > > +/* from syscall.h */ > > +/* begin pru sys target macros */ > > + { "SYS_argc", 22 }, > > + { "SYS_argn", 24 }, > > + { "SYS_argnlen", 23 }, > > + { "SYS_argv", 13 }, > > + { "SYS_argvlen", 12 }, > > + { "SYS_chdir", 14 }, > > + { "SYS_chmod", 16 }, > > + { "SYS_close", 3 }, > > + { "SYS_exit", 1 }, > > + { "SYS_fstat", 10 }, > > + { "SYS_getpid", 8 }, > > + { "SYS_gettimeofday", 19 }, > > + { "SYS_kill", 9 }, > > + { "SYS_link", 21 }, > > + { "SYS_lseek", 6 }, > > + { "SYS_open", 2 }, > > + { "SYS_read", 4 }, > > + { "SYS_reconfig", 25 }, > > + { "SYS_stat", 15 }, > > + { "SYS_time", 18 }, > > + { "SYS_times", 20 }, > > + { "SYS_unlink", 7 }, > > + { "SYS_utime", 17 }, > > + { "SYS_write", 5 }, > > +/* end pru sys target macros */ > > +#endif > > +#endif > > diff --git a/sim/configure b/sim/configure > > index ca3fd673ab..72f95cd5c7 100755 > > --- a/sim/configure > > +++ b/sim/configure > > @@ -686,6 +686,7 @@ mn10300 > > moxie > > msp430 > > or1k > > +pru > > rl78 > > rx > > sh64 > > @@ -3837,6 +3838,13 @@ subdirs="$subdirs aarch64" > > subdirs="$subdirs or1k" > > > > > > + ;; > > + pru*-*-*) > > + > > + sim_arch=pru > > + subdirs="$subdirs pru" > > + > > + > > ;; > > rl78-*-*) > > > > diff --git a/sim/configure.tgt b/sim/configure.tgt > > index a6dbd1af83..8a8e03d96f 100644 > > --- a/sim/configure.tgt > > +++ b/sim/configure.tgt > > @@ -79,6 +79,9 @@ case "${target}" in > > or1k-*-* | or1knd-*-*) > > SIM_ARCH(or1k) > > ;; > > + pru*-*-*) > > + SIM_ARCH(pru) > > + ;; > > rl78-*-*) > > SIM_ARCH(rl78) > > ;; > > diff --git a/sim/pru/Makefile.in b/sim/pru/Makefile.in > > new file mode 100644 > > index 0000000000..5235a5ff07 > > --- /dev/null > > +++ b/sim/pru/Makefile.in > > @@ -0,0 +1,29 @@ > > +# Makefile template for Configure for the PRU sim library. > > +# Copyright (C) 1990-2019 Free Software Foundation, Inc. > > +# Written by Dimitar Dimitrov > > +# > > +# Based on the MCore sim library > > +# > > +# This program is free software; you can redistribute it and/or modify > > +# it under the terms of the GNU General Public License as published by > > +# the Free Software Foundation; either version 3 of the License, or > > +# (at your option) any later version. > > +# > > +# This program is distributed in the hope that it will be useful, > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +# GNU General Public License for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with this program. If not, see . > > + > > +## COMMON_PRE_CONFIG_FRAG > > + > > +SIM_OBJS = \ > > + $(SIM_NEW_COMMON_OBJS) \ > > + interp.o \ > > + sim-resume.o > > + > > +NL_TARGET = -DNL_TARGET_pru > > + > > +## COMMON_POST_CONFIG_FRAG > > diff --git a/sim/pru/aclocal.m4 b/sim/pru/aclocal.m4 > > new file mode 100644 > > index 0000000000..e9f11c775c > > --- /dev/null > > +++ b/sim/pru/aclocal.m4 > > @@ -0,0 +1,119 @@ > > +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- > > + > > +# Copyright (C) 1996-2017 Free Software Foundation, Inc. > > + > > +# This file 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. > > + > > +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], > > [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +# > > AM_CONDITIONAL -*- Autoconf -*- > > + > > +# Copyright (C) 1997-2017 Free Software Foundation, Inc. > > +# > > +# This file 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. > > + > > +# AM_CONDITIONAL(NAME, SHELL-CONDITION) > > +# ------------------------------------- > > +# Define a conditional. > > +AC_DEFUN([AM_CONDITIONAL], > > +[AC_PREREQ([2.52])dnl > > + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], > > + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl > > +AC_SUBST([$1_TRUE])dnl > > +AC_SUBST([$1_FALSE])dnl > > +_AM_SUBST_NOTMAKE([$1_TRUE])dnl > > +_AM_SUBST_NOTMAKE([$1_FALSE])dnl > > +m4_define([_AM_COND_VALUE_$1], [$2])dnl > > +if $2; then > > + $1_TRUE= > > + $1_FALSE='#' > > +else > > + $1_TRUE='#' > > + $1_FALSE= > > +fi > > +AC_CONFIG_COMMANDS_PRE( > > +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then > > + AC_MSG_ERROR([[conditional "$1" was never defined. > > +Usually this means the macro was only invoked conditionally.]]) > > +fi])]) > > + > > +# Copyright (C) 2003-2017 Free Software Foundation, Inc. > > +# > > +# This file 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. > > + > > +# Check whether the underlying file-system supports filenames > > +# with a leading dot. For instance MS-DOS doesn't. > > +AC_DEFUN([AM_SET_LEADING_DOT], > > +[rm -rf .tst 2>/dev/null > > +mkdir .tst 2>/dev/null > > +if test -d .tst; then > > + am__leading_dot=. > > +else > > + am__leading_dot=_ > > +fi > > +rmdir .tst 2>/dev/null > > +AC_SUBST([am__leading_dot])]) > > + > > +# Add --enable-maintainer-mode option to configure. -*- Autoconf > > -*- +# From Jim Meyering > > + > > +# Copyright (C) 1996-2017 Free Software Foundation, Inc. > > +# > > +# This file 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. > > + > > +# AM_MAINTAINER_MODE([DEFAULT-MODE]) > > +# ---------------------------------- > > +# Control maintainer-specific portions of Makefiles. > > +# Default is to disable them, unless 'enable' is passed literally. > > +# For symmetry, 'disable' may be passed as well. Anyway, the user > > +# can override the default with the --enable/--disable switch. > > +AC_DEFUN([AM_MAINTAINER_MODE], > > +[m4_case(m4_default([$1], [disable]), > > + [enable], [m4_define([am_maintainer_other], [disable])], > > + [disable], [m4_define([am_maintainer_other], [enable])], > > + [m4_define([am_maintainer_other], [enable]) > > + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: > > $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of > > Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' > > is passed + AC_ARG_ENABLE([maintainer-mode], > > + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], > > + am_maintainer_other[ make rules and dependencies not useful > > + (and sometimes confusing) to the casual installer])], > > + [USE_MAINTAINER_MODE=$enableval], > > + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], > > [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) > > + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) > > + MAINT=$MAINTAINER_MODE_TRUE > > + AC_SUBST([MAINT])dnl > > +] > > +) > > + > > +# Copyright (C) 2006-2017 Free Software Foundation, Inc. > > +# > > +# This file 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. > > + > > +# _AM_SUBST_NOTMAKE(VARIABLE) > > +# --------------------------- > > +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. > > +# This macro is traced by Automake. > > +AC_DEFUN([_AM_SUBST_NOTMAKE]) > > + > > +# AM_SUBST_NOTMAKE(VARIABLE) > > +# -------------------------- > > +# Public sister of _AM_SUBST_NOTMAKE. > > +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) > > + > > diff --git a/sim/pru/config.in b/sim/pru/config.in > > new file mode 100644 > > index 0000000000..7c667a1c0d > > --- /dev/null > > +++ b/sim/pru/config.in > > @@ -0,0 +1,248 @@ > > +/* config.in. Generated from configure.ac by autoheader. */ > > + > > +/* Define if building universal (internal helper macro) */ > > +#undef AC_APPLE_UNIVERSAL_BUILD > > + > > +/* Sim debug setting */ > > +#undef DEBUG > > + > > +/* Define to 1 if translation of program messages to the user's native > > + language is requested. */ > > +#undef ENABLE_NLS > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_DLFCN_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_ERRNO_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_FCNTL_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_FPU_CONTROL_H > > + > > +/* Define to 1 if you have the `ftruncate' function. */ > > +#undef HAVE_FTRUNCATE > > + > > +/* Define to 1 if you have the `getrusage' function. */ > > +#undef HAVE_GETRUSAGE > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_INTTYPES_H > > + > > +/* Define to 1 if you have the `nsl' library (-lnsl). */ > > +#undef HAVE_LIBNSL > > + > > +/* Define to 1 if you have the `socket' library (-lsocket). */ > > +#undef HAVE_LIBSOCKET > > + > > +/* Define to 1 if you have the `lstat' function. */ > > +#undef HAVE_LSTAT > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_MEMORY_H > > + > > +/* Define to 1 if you have the `mmap' function. */ > > +#undef HAVE_MMAP > > + > > +/* Define to 1 if you have the `munmap' function. */ > > +#undef HAVE_MUNMAP > > + > > +/* Define to 1 if you have the `posix_fallocate' function. */ > > +#undef HAVE_POSIX_FALLOCATE > > + > > +/* Define to 1 if you have the `sigaction' function. */ > > +#undef HAVE_SIGACTION > > + > > +/* Define to 1 if the system has the type `socklen_t'. */ > > +#undef HAVE_SOCKLEN_T > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_STDINT_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_STDLIB_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_STRINGS_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_STRING_H > > + > > +/* Define to 1 if `st_atime' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_ATIME > > + > > +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_BLKSIZE > > + > > +/* Define to 1 if `st_blocks' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_BLOCKS > > + > > +/* Define to 1 if `st_ctime' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_CTIME > > + > > +/* Define to 1 if `st_dev' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_DEV > > + > > +/* Define to 1 if `st_gid' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_GID > > + > > +/* Define to 1 if `st_ino' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_INO > > + > > +/* Define to 1 if `st_mode' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_MODE > > + > > +/* Define to 1 if `st_mtime' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_MTIME > > + > > +/* Define to 1 if `st_nlink' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_NLINK > > + > > +/* Define to 1 if `st_rdev' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_RDEV > > + > > +/* Define to 1 if `st_size' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_SIZE > > + > > +/* Define to 1 if `st_uid' is a member of `struct stat'. */ > > +#undef HAVE_STRUCT_STAT_ST_UID > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_MMAN_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_RESOURCE_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_STAT_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_TIMES_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_TIME_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_SYS_TYPES_H > > + > > +/* Define to 1 if you have the `time' function. */ > > +#undef HAVE_TIME > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_TIME_H > > + > > +/* Define to 1 if you have the `truncate' function. */ > > +#undef HAVE_TRUNCATE > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_UNISTD_H > > + > > +/* Define to 1 if you have the header file. */ > > +#undef HAVE_WINDOWS_H > > + > > +/* Define to 1 if you have the `__setfpucw' function. */ > > +#undef HAVE___SETFPUCW > > + > > +/* Define to the sub-directory in which libtool stores uninstalled > > libraries. + */ > > +#undef LT_OBJDIR > > + > > +/* Name of this package. */ > > +#undef PACKAGE > > + > > +/* Define to the address where bug reports for this package should be sent. > > */ +#undef PACKAGE_BUGREPORT > > + > > +/* Define to the full name of this package. */ > > +#undef PACKAGE_NAME > > + > > +/* Define to the full name and version of this package. */ > > +#undef PACKAGE_STRING > > + > > +/* Define to the one symbol short name of this package. */ > > +#undef PACKAGE_TARNAME > > + > > +/* Define to the home page for this package. */ > > +#undef PACKAGE_URL > > + > > +/* Define to the version of this package. */ > > +#undef PACKAGE_VERSION > > + > > +/* Additional package description */ > > +#undef PKGVERSION > > + > > +/* Sim profile settings */ > > +#undef PROFILE > > + > > +/* Bug reporting address */ > > +#undef REPORT_BUGS_TO > > + > > +/* Define as the return type of signal handlers (`int' or `void'). */ > > +#undef RETSIGTYPE > > + > > +/* Define to 1 if you have the ANSI C header files. */ > > +#undef STDC_HEADERS > > + > > +/* Enable extensions on AIX 3, Interix. */ > > +#ifndef _ALL_SOURCE > > +# undef _ALL_SOURCE > > +#endif > > +/* Enable GNU extensions on systems that have them. */ > > +#ifndef _GNU_SOURCE > > +# undef _GNU_SOURCE > > +#endif > > +/* Enable threading extensions on Solaris. */ > > +#ifndef _POSIX_PTHREAD_SEMANTICS > > +# undef _POSIX_PTHREAD_SEMANTICS > > +#endif > > +/* Enable extensions on HP NonStop. */ > > +#ifndef _TANDEM_SOURCE > > +# undef _TANDEM_SOURCE > > +#endif > > +/* Enable general extensions on Solaris. */ > > +#ifndef __EXTENSIONS__ > > +# undef __EXTENSIONS__ > > +#endif > > + > > + > > +/* Sim assert settings */ > > +#undef WITH_ASSERT > > + > > +/* Sim debug setting */ > > +#undef WITH_DEBUG > > + > > +/* Sim default environment */ > > +#undef WITH_ENVIRONMENT > > + > > +/* Sim profile settings */ > > +#undef WITH_PROFILE > > + > > +/* How to route I/O */ > > +#undef WITH_STDIO > > + > > +/* Sim trace settings */ > > +#undef WITH_TRACE > > + > > +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most > > + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if > > defined AC_APPLE_UNIVERSAL_BUILD > > +# if defined __BIG_ENDIAN__ > > +# define WORDS_BIGENDIAN 1 > > +# endif > > +#else > > +# ifndef WORDS_BIGENDIAN > > +# undef WORDS_BIGENDIAN > > +# endif > > +#endif > > + > > +/* Define to 1 if on MINIX. */ > > +#undef _MINIX > > + > > +/* Define to 2 if the system does not provide POSIX.1 features except with > > + this defined. */ > > +#undef _POSIX_1_SOURCE > > + > > +/* Define to 1 if you need to in order for `stat' and other things to work. > > */ +#undef _POSIX_SOURCE > > diff --git a/sim/pru/configure.ac b/sim/pru/configure.ac > > new file mode 100644 > > index 0000000000..e7132b4493 > > --- /dev/null > > +++ b/sim/pru/configure.ac > > @@ -0,0 +1,31 @@ > > +dnl Process this file with autoconf to produce a configure script. > > + > > +dnl Copyright (C) 2016-2019 Free Software Foundation, Inc. > > +dnl Contributed by Dimitar Dimitrov > > +dnl > > +dnl This file is part of the GNU simulators. > > +dnl > > +dnl This program is free software; you can redistribute it and/or modify > > +dnl it under the terms of the GNU General Public License as published by > > +dnl the Free Software Foundation; either version 3 of the License, or > > +dnl (at your option) any later version. > > +dnl > > +dnl This program is distributed in the hope that it will be useful, > > +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of > > +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +dnl GNU General Public License for more details. > > +dnl > > +dnl You should have received a copy of the GNU General Public License > > +dnl along with this program. If not, see . > > +dnl > > +AC_PREREQ(2.64)dnl > > +AC_INIT(Makefile.in) > > +sinclude(../common/acinclude.m4) > > + > > +SIM_AC_COMMON > > + > > +SIM_AC_OPTION_ENDIAN(LITTLE) > > +SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT) > > +SIM_AC_OPTION_WARNINGS > > + > > +SIM_AC_OUTPUT > > diff --git a/sim/pru/interp.c b/sim/pru/interp.c > > new file mode 100644 > > index 0000000000..0e783c121c > > --- /dev/null > > +++ b/sim/pru/interp.c > > @@ -0,0 +1,848 @@ > > +/* Simulator for the Texas Instruments PRU processor > > + Copyright 2009-2019 Free Software Foundation, Inc. > > + Inspired by the Microblaze simulator > > + Contributed by Dimitar Dimitrov > > + > > + This file is part of the simulators. > > + > > + This program is free software; you can redistribute it and/or modify > > + it under the terms of the GNU General Public License as published by > > + the Free Software Foundation; either version 3 of the License, or > > + (at your option) any later version. > > + > > + This program is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + GNU General Public License for more details. > > + > > + You should have received a copy of the GNU General Public License > > + along with this program; if not, see . */ > > + > > +#include "config.h" > > +#include > > +#include > > +#include > > +#include "bfd.h" > > +#include "gdb/callback.h" > > +#include "libiberty.h" > > +#include "gdb/remote-sim.h" > > +#include "sim-main.h" > > +#include "sim-assert.h" > > +#include "sim-options.h" > > +#include "sim-syscall.h" > > +#include "pru.h" > > + > > +/* DMEM zero address is perfectly valid. But if CRT leaves the first word > > + alone, we can use it as a trap to catch NULL pointer access. */ > > +static bfd_boolean abort_on_dmem_zero_access; > > + > > +enum { > > + OPTION_ERROR_NULL_DEREF = OPTION_START, > > +}; > > + > > +/* Extract (from PRU endianess) and return an integer in HOST's endianness. > > */ +static uint32_t > > +pru_extract_unsigned_integer (uint8_t *addr, size_t len) > > +{ > > + uint32_t retval; > > + uint8_t *p; > > + uint8_t *startaddr = addr; > > + uint8_t *endaddr = startaddr + len; > > + > > + /* Start at the most significant end of the integer, and work towards > > + the least significant. */ > > + retval = 0; > > + > > + for (p = endaddr; p > startaddr;) > > + retval = (retval << 8) | * -- p; > > + return retval; > > +} > > + > > +/* Store "val" (which is in HOST's endianess) into "addr" > > + (using PRU's endianness). */ > > +static void > > +pru_store_unsigned_integer (uint8_t *addr, size_t len, uint32_t val) > > +{ > > + uint8_t *p; > > + uint8_t *startaddr = (uint8_t *)addr; > > + uint8_t *endaddr = startaddr + len; > > + > > + for (p = startaddr; p < endaddr;) > > + { > > + *p++ = val & 0xff; > > + val >>= 8; > > + } > > +} > > + > > +/* Extract a field value from CPU register using the given REGSEL selector. > > + > > + Byte number maps directly to first values of RSEL, so we can > > + safely use "regsel" as a register byte number (0..3). */ > > +static inline uint32_t > > +extract_regval (uint32_t val, uint32_t regsel) > > +{ > > + ASSERT (RSEL_7_0 == 0); > > + ASSERT (RSEL_15_8 == 1); > > + ASSERT (RSEL_23_16 == 2); > > + ASSERT (RSEL_31_24 == 3); > > + > > + switch (regsel) > > + { > > + case RSEL_7_0: return (val >> 0) & 0xff; > > + case RSEL_15_8: return (val >> 8) & 0xff; > > + case RSEL_23_16: return (val >> 16) & 0xff; > > + case RSEL_31_24: return (val >> 24) & 0xff; > > + case RSEL_15_0: return (val >> 0) & 0xffff; > > + case RSEL_23_8: return (val >> 8) & 0xffff; > > + case RSEL_31_16: return (val >> 16) & 0xffff; > > + case RSEL_31_0: return val; > > + default: sim_io_error (NULL, "invalid regsel"); > > + } > > +} > > + > > +/* Write a value into CPU subregister pointed by reg and regsel. */ > > +static inline void > > +write_regval (uint32_t val, uint32_t *reg, uint32_t regsel) > > +{ > > + uint32_t mask, sh; > > + > > + switch (regsel) > > + { > > + case RSEL_7_0: mask = (0xffu << 0); sh = 0; break; > > + case RSEL_15_8: mask = (0xffu << 8); sh = 8; break; > > + case RSEL_23_16: mask = (0xffu << 16); sh = 16; break; > > + case RSEL_31_24: mask = (0xffu << 24); sh = 24; break; > > + case RSEL_15_0: mask = (0xffffu << 0); sh = 0; break; > > + case RSEL_23_8: mask = (0xffffu << 8); sh = 8; break; > > + case RSEL_31_16: mask = (0xffffu << 16); sh = 16; break; > > + case RSEL_31_0: mask = 0xffffffffu; sh = 0; break; > > + default: sim_io_error (NULL, "invalid regsel"); > > + } > > + > > + *reg = (*reg & ~mask) | ((val << sh) & mask); > > +} > > + > > +/* Convert the given IMEM word address to a regular byte address used by > > the + GNU ELF container. */ > > +static uint32_t > > +imem_wordaddr_to_byteaddr (SIM_CPU *cpu, uint16_t wa) > > +{ > > + return (((uint32_t) wa << 2) & IMEM_ADDR_MASK) | PC_ADDR_SPACE_MARKER; > > +} > > + > > +/* Convert the given ELF text byte address to IMEM word address. */ > > +static uint16_t > > +imem_byteaddr_to_wordaddr (SIM_CPU *cpu, uint32_t ba) > > +{ > > + return (ba >> 2) & 0xffff; > > +} > > + > > + > > +/* Store "nbytes" into DMEM "addr" from CPU register file, starting with > > + register "regn", and byte "regb" within it. */ > > +static inline void > > +pru_reg2dmem (SIM_CPU *cpu, uint32_t addr, unsigned int nbytes, > > + int regn, int regb) > > +{ > > + /* GDB assumes unconditional access to all memories, so enable additional > > + checks only in standalone mode. */ > > + bool standalone = (STATE_OPEN_KIND (CPU_STATE (cpu)) == > > SIM_OPEN_STANDALONE); + > > + if (abort_on_dmem_zero_access && addr < 4) > > + { > > + sim_core_signal (CPU_STATE (cpu), cpu, PC_byteaddr, write_map, > > + nbytes, addr, write_transfer, > > + sim_core_unmapped_signal); > > + } > > + else if (standalone && ((addr >= PC_ADDR_SPACE_MARKER) > > + || (addr + nbytes > PC_ADDR_SPACE_MARKER))) > > + { > > + sim_core_signal (CPU_STATE (cpu), cpu, PC_byteaddr, write_map, > > + nbytes, addr, write_transfer, > > + sim_core_unmapped_signal); > > + } > > + else if ((regn * 4 + regb + nbytes) > (32 * 4)) > > + { > > + sim_io_eprintf (CPU_STATE (cpu), > > + "SBBO/SBCO with invalid store data length\n"); > > + RAISE_SIGILL (CPU_STATE (cpu)); > > + } > > + else > > + { > > + TRACE_MEMORY (cpu, "write of %d bytes to %08x", nbytes, addr); > > + while (nbytes--) > > + { > > + sim_core_write_1 (cpu, > > + PC_byteaddr, > > + write_map, > > + addr++, > > + extract_regval (CPU.regs[regn], regb)); > > + > > + if (++regb >= 4) > > + { > > + regb = 0; > > + regn++; > > + } > > + } > > + } > > +} > > + > > +/* Load "nbytes" from DMEM "addr" into CPU register file, starting with > > + register "regn", and byte "regb" within it. */ > > +static inline void > > +pru_dmem2reg (SIM_CPU *cpu, uint32_t addr, unsigned int nbytes, > > + int regn, int regb) > > +{ > > + /* GDB assumes unconditional access to all memories, so enable additional > > + checks only in standalone mode. */ > > + bool standalone = (STATE_OPEN_KIND (CPU_STATE (cpu)) == > > SIM_OPEN_STANDALONE); + > > + if (abort_on_dmem_zero_access && addr < 4) > > + { > > + sim_core_signal (CPU_STATE (cpu), cpu, PC_byteaddr, read_map, > > + nbytes, addr, read_transfer, > > + sim_core_unmapped_signal); > > + } > > + else if (standalone && ((addr >= PC_ADDR_SPACE_MARKER) > > + || (addr + nbytes > PC_ADDR_SPACE_MARKER))) > > + { > > + /* This check is necessary because our IMEM "address space" > > + is not really accessible, yet we have mapped it as a generic > > + memory space. */ > > + sim_core_signal (CPU_STATE (cpu), cpu, PC_byteaddr, read_map, > > + nbytes, addr, read_transfer, > > + sim_core_unmapped_signal); > > + } > > + else if ((regn * 4 + regb + nbytes) > (32 * 4)) > > + { > > + sim_io_eprintf (CPU_STATE (cpu), > > + "LBBO/LBCO with invalid load data length\n"); > > + RAISE_SIGILL (CPU_STATE (cpu)); > > + } > > + else > > + { > > + unsigned int b; > > + TRACE_MEMORY (cpu, "read of %d bytes from %08x", nbytes, addr); > > + while (nbytes--) > > + { > > + b = sim_core_read_1 (cpu, PC_byteaddr, read_map, addr++); > > + > > + /* Reuse the fact the Register Byte Number maps directly to RSEL. */ > > + ASSERT (RSEL_7_0 == 0); > > + write_regval (b, &CPU.regs[regn], regb); > > + > > + if (++regb >= 4) > > + { > > + regb = 0; > > + regn++; > > + } > > + } > > + } > > +} > > + > > +/* Set reset values of general-purpose registers. */ > > +static void > > +set_initial_gprs (SIM_CPU *cpu) > > +{ > > + int i; > > + > > + /* Set up machine just out of reset. */ > > + CPU_PC_SET (cpu, 0); > > + PC_ADDR_SPACE_MARKER = IMEM_ADDR_DEFAULT; /* from default linker script? > > */ + > > + /* Clean out the GPRs. */ > > + for (i = 0; i < ARRAY_SIZE (CPU.regs); i++) > > + CPU.regs[i] = 0; > > + for (i = 0; i < ARRAY_SIZE (CPU.macregs); i++) > > + CPU.macregs[i] = 0; > > + > > + CPU.loop.looptop = CPU.loop.loopend = 0; > > + CPU.loop.loop_in_progress = 0; > > + CPU.loop.loop_counter = 0; > > + > > + CPU.carry = 0; > > + CPU.insts = 0; > > + CPU.cycles = 0; > > + > > + /* AM335x should provide sane defaults. */ > > + CPU.ctable[0] = 0x00020000; > > + CPU.ctable[1] = 0x48040000; > > + CPU.ctable[2] = 0x4802a000; > > + CPU.ctable[3] = 0x00030000; > > + CPU.ctable[4] = 0x00026000; > > + CPU.ctable[5] = 0x48060000; > > + CPU.ctable[6] = 0x48030000; > > + CPU.ctable[7] = 0x00028000; > > + CPU.ctable[8] = 0x46000000; > > + CPU.ctable[9] = 0x4a100000; > > + CPU.ctable[10] = 0x48318000; > > + CPU.ctable[11] = 0x48022000; > > + CPU.ctable[12] = 0x48024000; > > + CPU.ctable[13] = 0x48310000; > > + CPU.ctable[14] = 0x481cc000; > > + CPU.ctable[15] = 0x481d0000; > > + CPU.ctable[16] = 0x481a0000; > > + CPU.ctable[17] = 0x4819c000; > > + CPU.ctable[18] = 0x48300000; > > + CPU.ctable[19] = 0x48302000; > > + CPU.ctable[20] = 0x48304000; > > + CPU.ctable[21] = 0x00032400; > > + CPU.ctable[22] = 0x480c8000; > > + CPU.ctable[23] = 0x480ca000; > > + CPU.ctable[24] = 0x00000000; > > + CPU.ctable[25] = 0x00002000; > > + CPU.ctable[26] = 0x0002e000; > > + CPU.ctable[27] = 0x00032000; > > + CPU.ctable[28] = 0x00000000; > > + CPU.ctable[29] = 0x49000000; > > + CPU.ctable[30] = 0x40000000; > > + CPU.ctable[31] = 0x80000000; > > +} > > + > > +/* Map regsel selector to subregister field width. */ > > +static inline unsigned int > > +regsel_width (uint32_t regsel) > > +{ > > + switch (regsel) > > + { > > + case RSEL_7_0: return 8; > > + case RSEL_15_8: return 8; > > + case RSEL_23_16: return 8; > > + case RSEL_31_24: return 8; > > + case RSEL_15_0: return 16; > > + case RSEL_23_8: return 16; > > + case RSEL_31_16: return 16; > > + case RSEL_31_0: return 32; > > + default: sim_io_error (NULL, "invalid regsel"); > > + } > > +} > > + > > +/* Handle XIN instruction addressing the MAC peripheral. */ > > +static void > > +pru_sim_xin_mac (SIM_DESC sd, SIM_CPU *cpu, unsigned int rd_regn, > > + unsigned int rdb, unsigned int length) > > +{ > > + if (rd_regn < 25 || (rd_regn * 4 + rdb + length) > (27 + 1) * 4) > > + sim_io_error (sd, "XIN MAC: invalid transfer regn=%u.%u, length=%u\n", > > + rd_regn, rdb, length); > > + > > + /* Copy from MAC to PRU regs. Ranges have been validated above. */ > > + while (length--) > > + { > > + write_regval (CPU.macregs[rd_regn - 25] >> (rdb * 8), > > + &CPU.regs[rd_regn], > > + rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > +} > > + > > +/* Handle XIN instruction. */ > > +static void > > +pru_sim_xin (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba, > > + unsigned int rd_regn, unsigned int rdb, unsigned int length) > > +{ > > + if (wba == 0) > > + { > > + pru_sim_xin_mac (sd, cpu, rd_regn, rdb, length); > > + } > > + else if (wba == XFRID_SCRATCH_BANK_0 || wba == XFRID_SCRATCH_BANK_1 > > + || wba == XFRID_SCRATCH_BANK_2 || wba == XFRID_SCRATCH_BANK_PEER) > > + { > > + while (length--) > > + { > > + unsigned int val; > > + > > + val = extract_regval (CPU.scratchpads[wba][rd_regn], rdb); > > + write_regval (val, &CPU.regs[rd_regn], rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > + } > > + else if (wba == 254 || wba == 255) > > + { > > + /* FILL/ZERO pseudos implemented via XIN. */ > > + unsigned int fillbyte = (wba == 254) ? 0xff : 0x00; > > + while (length--) > > + { > > + write_regval (fillbyte, &CPU.regs[rd_regn], rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > + } > > + else > > + { > > + sim_io_error (sd, "XIN: XFR device %d not supported.\n", wba); > > + } > > +} > > + > > +/* Handle XOUT instruction addressing the MAC peripheral. */ > > +static void > > +pru_sim_xout_mac (SIM_DESC sd, SIM_CPU *cpu, unsigned int rd_regn, > > + unsigned int rdb, unsigned int length) > > +{ > > + const int modereg_accessed = (rd_regn == 25); > > + > > + /* Multiple Accumulate. */ > > + if (rd_regn < 25 || (rd_regn * 4 + rdb + length) > (27 + 1) * 4) > > + sim_io_error (sd, "XOUT MAC: invalid transfer regn=%u.%u, length=%u\n", > > + rd_regn, rdb, length); > > + > > + /* Copy from PRU to MAC regs. Ranges have been validated above. */ > > + while (length--) > > + { > > + write_regval (CPU.regs[rd_regn] >> (rdb * 8), > > + &CPU.macregs[rd_regn - 25], > > + rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > + > > + if (modereg_accessed > > + && (CPU.macregs[PRU_MACREG_MODE] & MAC_R25_MAC_MODE_MASK)) > > + { > > + /* MUL/MAC operands are sampled every XOUT in multiply and > > + accumulate mode. */ > > + uint64_t prod, oldsum, sum; > > + CPU.macregs[PRU_MACREG_OP_0] = CPU.regs[28]; > > + CPU.macregs[PRU_MACREG_OP_1] = CPU.regs[29]; > > + > > + prod = CPU.macregs[PRU_MACREG_OP_0]; > > + prod *= (uint64_t)CPU.macregs[PRU_MACREG_OP_1]; > > + > > + oldsum = CPU.macregs[PRU_MACREG_ACC_L]; > > + oldsum += (uint64_t)CPU.macregs[PRU_MACREG_ACC_H] << 32; > > + sum = oldsum + prod; > > + > > + CPU.macregs[PRU_MACREG_PROD_L] = sum & 0xfffffffful; > > + CPU.macregs[PRU_MACREG_PROD_H] = sum >> 32; > > + CPU.macregs[PRU_MACREG_ACC_L] = CPU.macregs[PRU_MACREG_PROD_L]; > > + CPU.macregs[PRU_MACREG_ACC_H] = CPU.macregs[PRU_MACREG_PROD_H]; > > + > > + if (oldsum > sum) > > + CPU.macregs[PRU_MACREG_MODE] |= MAC_R25_ACC_CARRY_MASK; > > + } > > + if (modereg_accessed > > + && (CPU.macregs[PRU_MACREG_MODE] & MAC_R25_ACC_CARRY_MASK)) > > + { > > + /* store 1 to clear. */ > > + CPU.macregs[PRU_MACREG_MODE] &= ~MAC_R25_ACC_CARRY_MASK; > > + CPU.macregs[PRU_MACREG_ACC_L] = 0; > > + CPU.macregs[PRU_MACREG_ACC_H] = 0; > > + } > > + > > +} > > + > > +/* Handle XOUT instruction. */ > > +static void > > +pru_sim_xout (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba, > > + unsigned int rd_regn, unsigned int rdb, unsigned int length) > > +{ > > + if (wba == 0) > > + { > > + pru_sim_xout_mac (sd, cpu, rd_regn, rdb, length); > > + } > > + else if (wba == XFRID_SCRATCH_BANK_0 || wba == XFRID_SCRATCH_BANK_1 > > + || wba == XFRID_SCRATCH_BANK_2 || wba == XFRID_SCRATCH_BANK_PEER) > > + { > > + while (length--) > > + { > > + unsigned int val; > > + > > + val = extract_regval (CPU.regs[rd_regn], rdb); > > + write_regval (val, &CPU.scratchpads[wba][rd_regn], rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > + } > > + else > > + sim_io_error (sd, "XOUT: XFR device %d not supported.\n", wba); > > +} > > + > > +/* Handle XCHG instruction. */ > > +static void > > +pru_sim_xchg (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba, > > + unsigned int rd_regn, unsigned int rdb, unsigned int length) > > +{ > > + if (wba == XFRID_SCRATCH_BANK_0 || wba == XFRID_SCRATCH_BANK_1 > > + || wba == XFRID_SCRATCH_BANK_2 || wba == XFRID_SCRATCH_BANK_PEER) > > + { > > + while (length--) > > + { > > + unsigned int valr, vals; > > + > > + valr = extract_regval (CPU.regs[rd_regn], rdb); > > + vals = extract_regval (CPU.scratchpads[wba][rd_regn], rdb); > > + write_regval (valr, &CPU.scratchpads[wba][rd_regn], rdb); > > + write_regval (vals, &CPU.regs[rd_regn], rdb); > > + if (++rdb == 4) > > + { > > + rdb = 0; > > + rd_regn++; > > + } > > + } > > + } > > + else > > + sim_io_error (sd, "XOUT: XFR device %d not supported.\n", wba); > > +} > > + > > +/* Handle syscall simulation. Its ABI is specific to the GNU simulator. > > */ +static void > > +pru_sim_syscall (SIM_DESC sd, SIM_CPU *cpu) > > +{ > > + /* If someday TI confirms that the "reserved" HALT opcode fields > > + can be used for extra arguments, then maybe we can embed > > + the syscall number there. Until then, let's use R1. */ > > + const uint32_t syscall_num = CPU.regs[1]; > > + long ret; > > + > > + ret = sim_syscall (cpu, syscall_num, > > + CPU.regs[14], CPU.regs[15], > > + CPU.regs[16], CPU.regs[17]); > > + CPU.regs[14] = ret; > > +} > > + > > +/* Simulate one instruction. */ > > +static void > > +sim_step_once (SIM_DESC sd) > > +{ > > + SIM_CPU *cpu = STATE_CPU (sd, 0); > > + const struct pru_opcode *op; > > + uint32_t inst; > > + uint32_t _RDVAL, OP2; /* intermediate values. */ > > + int rd_is_modified = 0; /* RD modified and must be stored back. */ > > + > > + /* Fetch the initial instruction that we'll decode. */ > > + inst = sim_core_read_4 (cpu, PC_byteaddr, exec_map, PC_byteaddr); > > + TRACE_MEMORY (cpu, "read of insn 0x%08x from %08x", inst, PC_byteaddr); > > + > > + op = pru_find_opcode (inst); > > + > > + if (!op) > > + { > > + sim_io_eprintf (sd, "Unknown instruction 0x%04x\n", inst); > > + RAISE_SIGILL (sd); > > + } > > + else > > + { > > + TRACE_DISASM (cpu, PC_byteaddr); > > + > > + /* In multiply-only mode, R28/R29 operands are sampled on every clock > > + cycle. */ > > + if ((CPU.macregs[PRU_MACREG_MODE] & MAC_R25_MAC_MODE_MASK) == 0) > > + { > > + CPU.macregs[PRU_MACREG_OP_0] = CPU.regs[28]; > > + CPU.macregs[PRU_MACREG_OP_1] = CPU.regs[29]; > > + } > > + > > + switch (op->type) > > + { > > +/* Helper macro to improve clarity of pru.isa. The empty while is a > > + guard against using RD as a left-hand side value. */ > > +#define RD do { } while (0); rd_is_modified = 1; _RDVAL > > +#define INSTRUCTION(NAME, ACTION) \ > > + case prui_ ## NAME: \ > > + ACTION; \ > > + break; > > +#include "pru.isa" > > +#undef INSTRUCTION > > +#undef RD > > + > > + default: > > + RAISE_SIGILL (sd); > > + } > > + > > + if (rd_is_modified) > > + write_regval (_RDVAL, &CPU.regs[RD_REGN], RDSEL); > > + > > + /* Don't treat r30 and r31 as regular registers, they are I/O! */ > > + CPU.regs[30] = 0; > > + CPU.regs[31] = 0; > > + > > + /* Handle PC match of loop end. */ > > + if (LOOP_IN_PROGRESS && (PC == LOOPEND)) > > + { > > + SIM_ASSERT (LOOPCNT > 0); > > + if (--LOOPCNT == 0) > > + LOOP_IN_PROGRESS = 0; > > + else > > + PC = LOOPTOP; > > + } > > + > > + /* In multiply-only mode, MAC does multiplication every cycle. */ > > + if ((CPU.macregs[PRU_MACREG_MODE] & MAC_R25_MAC_MODE_MASK) == 0) > > + { > > + uint64_t prod; > > + prod = CPU.macregs[PRU_MACREG_OP_0]; > > + prod *= (uint64_t)CPU.macregs[PRU_MACREG_OP_1]; > > + CPU.macregs[PRU_MACREG_PROD_L] = prod & 0xfffffffful; > > + CPU.macregs[PRU_MACREG_PROD_H] = prod >> 32; > > + > > + /* Clear the MAC accumulator when in normal mode. */ > > + CPU.macregs[PRU_MACREG_ACC_L] = 0; > > + CPU.macregs[PRU_MACREG_ACC_H] = 0; > > + } > > + > > + /* Update cycle counts. */ > > + CPU.insts += 1; /* One instruction completed ... */ > > + CPU.cycles += 1; /* ... and it takes a single cycle. */ > > + > > + /* Account for memory access latency with a reasonable estimate. > > + No distinction is currently made between SRAM, DRAM and generic > > + L3 slaves. */ > > + if (op->type == prui_lbbo || op->type == prui_sbbo > > + || op->type == prui_lbco || op->type == prui_sbco) > > + CPU.cycles += 2; > > + > > + } > > +} > > + > > +/* Implement standard sim_engine_run function. */ > > +void > > +sim_engine_run (SIM_DESC sd, > > + int next_cpu_nr, /* ignore */ > > + int nr_cpus, /* ignore */ > > + int siggnal) /* ignore */ > > +{ > > + while (1) > > + { > > + sim_step_once (sd); > > + if (sim_events_tick (sd)) > > + sim_events_process (sd); > > + } > > +} > > + > > + > > +/* Implement callback for standard CPU_PC_FETCH routine. */ > > +static sim_cia > > +pru_pc_get (sim_cpu *cpu) > > +{ > > + /* Present PC as byte address. */ > > + return imem_wordaddr_to_byteaddr (cpu, cpu->pru_cpu.pc); > > +} > > + > > +/* Implement callback for standard CPU_PC_STORE routine. */ > > +static void > > +pru_pc_set (sim_cpu *cpu, sim_cia pc) > > +{ > > + /* PC given as byte address. */ > > + cpu->pru_cpu.pc = imem_byteaddr_to_wordaddr (cpu, pc); > > +} > > + > > + > > +/* Implement callback for standard CPU_REG_STORE routine. */ > > +static int > > +pru_store_register (SIM_CPU *cpu, int rn, unsigned char *memory, int > > length) +{ > > + if (rn < NUM_REGS && rn >= 0) > > + { > > + if (length == 4) > > + { > > + /* Misalignment safe. */ > > + long ival = pru_extract_unsigned_integer (memory, 4); > > + if (rn < 32) > > + CPU.regs[rn] = ival; > > + else > > + pru_pc_set (cpu, ival); > > + return 4; > > + } > > + else > > + return 0; > > + } > > + else > > + return 0; > > +} > > + > > +/* Implement callback for standard CPU_REG_FETCH routine. */ > > +static int > > +pru_fetch_register (SIM_CPU *cpu, int rn, unsigned char *memory, int > > length) +{ > > + long ival; > > + > > + if (rn < NUM_REGS && rn >= 0) > > + { > > + if (length == 4) > > + { > > + if (rn < 32) > > + ival = CPU.regs[rn]; > > + else > > + ival = pru_pc_get (cpu); > > + > > + /* Misalignment-safe. */ > > + pru_store_unsigned_integer (memory, 4, ival); > > + return 4; > > + } > > + else > > + return 0; > > + } > > + else > > + return 0; > > +} > > + > > +static void > > +free_state (SIM_DESC sd) > > +{ > > + if (STATE_MODULES (sd) != NULL) > > + sim_module_uninstall (sd); > > + sim_cpu_free_all (sd); > > + sim_state_free (sd); > > +} > > + > > +/* Declare the PRU option handler. */ > > +static DECLARE_OPTION_HANDLER (pru_option_handler); > > + > > +/* Implement the PRU option handler. */ > > +static SIM_RC > > +pru_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg, > > + int is_command) > > +{ > > + switch (opt) > > + { > > + case OPTION_ERROR_NULL_DEREF: > > + abort_on_dmem_zero_access = TRUE; > > + return SIM_RC_OK; > > + > > + default: > > + sim_io_eprintf (sd, "Unknown PRU option %d\n", opt); > > + return SIM_RC_FAIL; > > + } > > +} > > + > > +/* List of PRU-specific options. */ > > +static const OPTION pru_options[] = > > +{ > > + { {"error-null-deref", no_argument, NULL, OPTION_ERROR_NULL_DEREF}, > > + '\0', NULL, "Trap any access to DMEM address zero", > > + pru_option_handler, NULL }, > > + > > + { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL } > > +}; > > + > > +/* Implement standard sim_open function. */ > > +SIM_DESC > > +sim_open (SIM_OPEN_KIND kind, host_callback *cb, > > + struct bfd *abfd, char * const *argv) > > +{ > > + int i; > > + char c; > > + SIM_DESC sd = sim_state_alloc (kind, cb); > > + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); > > + > > + /* The cpu data is kept in a separately allocated chunk of memory. */ > > + if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != > > SIM_RC_OK) + { > > + free_state (sd); > > + return 0; > > + } > > + > > + if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) > > + { > > + free_state (sd); > > + return 0; > > + } > > + sim_add_option_table (sd, NULL, pru_options); > > + > > + /* The parser will print an error message for us, so we silently return. > > */ + if (sim_parse_args (sd, argv) != SIM_RC_OK) > > + { > > + free_state (sd); > > + return 0; > > + } > > + > > + /* Check for/establish a reference program image. */ > > + if (sim_analyze_program (sd, > > + (STATE_PROG_ARGV (sd) != NULL > > + ? *STATE_PROG_ARGV (sd) > > + : NULL), abfd) != SIM_RC_OK) > > + { > > + free_state (sd); > > + return 0; > > + } > > + > > + /* Configure/verify the target byte order and other runtime > > + configuration options. */ > > + if (sim_config (sd) != SIM_RC_OK) > > + { > > + sim_module_uninstall (sd); > > + return 0; > > + } > > + > > + if (sim_post_argv_init (sd) != SIM_RC_OK) > > + { > > + /* Uninstall the modules to avoid memory leaks, > > + file descriptor leaks, etc. */ > > + sim_module_uninstall (sd); > > + return 0; > > + } > > + > > + /* CPU specific initialization. */ > > + for (i = 0; i < MAX_NR_PROCESSORS; ++i) > > + { > > + SIM_CPU *cpu = STATE_CPU (sd, i); > > + > > + CPU_REG_STORE (cpu) = pru_store_register; > > + CPU_REG_FETCH (cpu) = pru_fetch_register; > > + CPU_PC_FETCH (cpu) = pru_pc_get; > > + CPU_PC_STORE (cpu) = pru_pc_set; > > + > > + set_initial_gprs (cpu); > > + } > > + > > + /* Allocate external memory if none specified by user. > > + Use address 4 here in case the user wanted address 0 unmapped. */ > > + if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) > > + { > > + sim_do_commandf (sd, "memory-region 0x%x,0x%x", > > + 0, > > + DMEM_DEFAULT_SIZE); > > + } > > + if (sim_core_read_buffer (sd, NULL, read_map, &c, IMEM_ADDR_DEFAULT, 1) > > == 0) + { > > + sim_do_commandf (sd, "memory-region 0x%x,0x%x", > > + IMEM_ADDR_DEFAULT, > > + IMEM_DEFAULT_SIZE); > > + } > > + > > + return sd; > > +} > > + > > +/* Implement standard sim_create_inferior function. */ > > +SIM_RC > > +sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, > > + char * const *argv, char * const *env) > > +{ > > + SIM_CPU *cpu = STATE_CPU (sd, 0); > > + SIM_ADDR addr; > > + > > + addr = bfd_get_start_address (prog_bfd); > > + > > + sim_pc_set (cpu, addr); > > + PC_ADDR_SPACE_MARKER = addr & ~IMEM_ADDR_MASK; > > + > > + /* Standalone mode (i.e. `run`) will take care of the argv for us in > > + sim_open () -> sim_parse_args (). But in debug mode (i.e. 'target > > sim' + with `gdb`), we need to handle it because the user can change > > the + argv on the fly via gdb's 'run'. */ > > + if (STATE_PROG_ARGV (sd) != argv) > > + { > > + freeargv (STATE_PROG_ARGV (sd)); > > + STATE_PROG_ARGV (sd) = dupargv (argv); > > + } > > + > > + return SIM_RC_OK; > > +} > > diff --git a/sim/pru/pru.h b/sim/pru/pru.h > > new file mode 100644 > > index 0000000000..8b005ef0b5 > > --- /dev/null > > +++ b/sim/pru/pru.h > > @@ -0,0 +1,110 @@ > > +/* Copyright 2016-2019 Free Software Foundation, Inc. > > + Contributed by Dimitar Dimitrov > > + > > + This file is part of the PRU simulator. > > + > > + This library is free software; you can redistribute it and/or modify > > + it under the terms of the GNU General Public License as published by > > + the Free Software Foundation; either version 3 of the License, or > > + (at your option) any later version. > > + > > + This program is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + GNU General Public License for more details. > > + > > + You should have received a copy of the GNU General Public License > > + along with this program; if not, see . */ > > + > > +#ifndef PRU_H > > +#define PRU_H > > + > > +#include "config.h" > > +#include "opcode/pru.h" > > + > > +/* NOTE: Needed for handling the dual PRU address space. */ > > +#define IMEM_ADDR_MASK ((1u << 23) - 1) > > + > > +#define IMEM_ADDR_DEFAULT 0x20000000 > > + > > +/* Define memory sizes to allocate for simulated target. Sizes are > > + artificially large to accommodate execution of compiler test suite. > > + Please synchronize with the linker script for prusim target. */ > > +#define DMEM_DEFAULT_SIZE (64 * 1024 * 1024) > > + > > +/* 16-bit word addressable space. */ > > +#define IMEM_DEFAULT_SIZE (64 * 4 * 1024) > > + > > +/* For AM335x SoCs. */ > > +#define XFRID_SCRATCH_BANK_0 10 > > +#define XFRID_SCRATCH_BANK_1 11 > > +#define XFRID_SCRATCH_BANK_2 12 > > +#define XFRID_SCRATCH_BANK_PEER 14 > > +#define XFRID_MAX 255 > > + > > +#define CPU (cpu->pru_cpu) > > + > > +#define PC (CPU.pc) > > +#define PC_byteaddr ((PC << 2) | PC_ADDR_SPACE_MARKER) > > + > > +/* Various opcode fields. */ > > +#define RS1 extract_regval (CPU.regs[GET_INSN_FIELD (RS1, inst)], \ > > + GET_INSN_FIELD (RS1SEL, inst)) > > +#define RS2 extract_regval (CPU.regs[GET_INSN_FIELD (RS2, inst)], \ > > + GET_INSN_FIELD (RS2SEL, inst)) > > + > > +#define RS2_w0 extract_regval (CPU.regs[GET_INSN_FIELD (RS2, inst)], \ > > + RSEL_15_0) > > + > > +#define XBBO_BASEREG (CPU.regs[GET_INSN_FIELD (RS1, inst)]) > > + > > +#define RDSEL GET_INSN_FIELD (RDSEL, inst) > > +#define RD_WIDTH regsel_width (RDSEL) > > +#define RD_REGN GET_INSN_FIELD (RD, inst) > > +#define IO GET_INSN_FIELD (IO, inst) > > +#define IMM8 GET_INSN_FIELD (IMM8, inst) > > +#define IMM16 GET_INSN_FIELD (IMM16, inst) > > +#define WAKEONSTATUS GET_INSN_FIELD (WAKEONSTATUS, inst) > > +#define CB GET_INSN_FIELD (CB, inst) > > +#define RDB GET_INSN_FIELD (RDB, inst) > > +#define XFR_WBA GET_INSN_FIELD (XFR_WBA, inst) > > +#define LOOP_JMPOFFS GET_INSN_FIELD (LOOP_JMPOFFS, inst) > > +#define BROFF ((uint32_t) GET_BROFF_SIGNED (inst)) > > + > > +#define _BURSTLEN_CALCULATE(BITFIELD) \ > > + ((BITFIELD) >= LSSBBO_BYTECOUNT_R0_BITS7_0 ? \ > > + (CPU.regs[0] >> ((BITFIELD) - LSSBBO_BYTECOUNT_R0_BITS7_0) * 8) & 0xff > > \ + : (BITFIELD) + 1) > > + > > +#define BURSTLEN _BURSTLEN_CALCULATE (GET_BURSTLEN (inst)) > > +#define XFR_LENGTH _BURSTLEN_CALCULATE (GET_INSN_FIELD (XFR_LENGTH, inst)) > > + > > +#define DO_XIN(wba,regn,rdb,l) \ > > + pru_sim_xin (sd, cpu, (wba), (regn), (rdb), (l)) > > +#define DO_XOUT(wba,regn,rdb,l) \ > > + pru_sim_xout (sd, cpu, (wba), (regn), (rdb), (l)) > > +#define DO_XCHG(wba,regn,rdb,l) \ > > + pru_sim_xchg (sd, cpu, (wba), (regn), (rdb), (l)) > > + > > +#define RAISE_SIGILL(sd) sim_engine_halt ((sd), NULL, NULL, PC_byteaddr, \ > > + sim_stopped, SIM_SIGILL) > > +#define RAISE_SIGINT(sd) sim_engine_halt ((sd), NULL, NULL, PC_byteaddr, \ > > + sim_stopped, SIM_SIGINT) > > + > > +#define MAC_R25_MAC_MODE_MASK (1u << 0) > > +#define MAC_R25_ACC_CARRY_MASK (1u << 1) > > + > > +#define CARRY CPU.carry > > +#define CTABLE CPU.ctable > > + > > +#define PC_ADDR_SPACE_MARKER CPU.pc_addr_space_marker > > + > > +#define LOOPTOP CPU.loop.looptop > > +#define LOOPEND CPU.loop.loopend > > +#define LOOP_IN_PROGRESS CPU.loop.loop_in_progress > > +#define LOOPCNT CPU.loop.loop_counter > > + > > +/* 32 GP registers plus PC. */ > > +#define NUM_REGS 33 > > + > > +#endif /* PRU_H */ > > diff --git a/sim/pru/pru.isa b/sim/pru/pru.isa > > new file mode 100644 > > index 0000000000..c906b2a169 > > --- /dev/null > > +++ b/sim/pru/pru.isa > > @@ -0,0 +1,249 @@ > > +/* Copyright 2016-2019 Free Software Foundation, Inc. > > + Contributed by Dimitar Dimitrov > > + > > + This file is part of the PRU simulator. > > + > > + This library is free software; you can redistribute it and/or modify > > + it under the terms of the GNU General Public License as published by > > + the Free Software Foundation; either version 3 of the License, or > > + (at your option) any later version. > > + > > + This program is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + GNU General Public License for more details. > > + > > + You should have received a copy of the GNU General Public License > > + along with this program; if not, see . */ > > + > > +/* > > + PRU Instruction Set Architecture > > + > > + INSTRUCTION (NAME, > > + SEMANTICS) > > + */ > > + > > +INSTRUCTION (add, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 + OP2; > > + CARRY = (((uint64_t) RS1 + (uint64_t) OP2) >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (adc, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 + OP2 + CARRY; > > + CARRY = (((uint64_t) RS1 + (uint64_t) OP2 + (uint64_t) CARRY) > > + >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (sub, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 - OP2; > > + CARRY = (((uint64_t) RS1 - (uint64_t) OP2) >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (suc, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 - OP2 - CARRY; > > + CARRY = (((uint64_t) RS1 - (uint64_t) OP2 - (uint64_t) CARRY) > > + >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (rsb, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = OP2 - RS1; > > + CARRY = (((uint64_t) OP2 - (uint64_t) RS1) >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (rsc, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = OP2 - RS1 - CARRY; > > + CARRY = (((uint64_t) OP2 - (uint64_t) RS1 - (uint64_t) CARRY) > > + >> RD_WIDTH) & 1; > > + PC++) > > + > > +INSTRUCTION (lsl, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 << (OP2 & 0x1f); > > + PC++) > > + > > +INSTRUCTION (lsr, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 >> (OP2 & 0x1f); > > + PC++) > > + > > +INSTRUCTION (and, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 & OP2; > > + PC++) > > + > > +INSTRUCTION (or, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 | OP2; > > + PC++) > > + > > +INSTRUCTION (xor, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 ^ OP2; > > + PC++) > > + > > +INSTRUCTION (not, > > + RD = ~RS1; > > + PC++) > > + > > +INSTRUCTION (min, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 < OP2 ? RS1 : OP2; > > + PC++) > > + > > +INSTRUCTION (max, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 > OP2 ? RS1 : OP2; > > + PC++) > > + > > +INSTRUCTION (clr, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 & ~(1u << (OP2 & 0x1f)); > > + PC++) > > + > > +INSTRUCTION (set, > > + OP2 = (IO ? IMM8 : RS2); > > + RD = RS1 | (1u << (OP2 & 0x1f)); > > + PC++) > > + > > +INSTRUCTION (jmp, > > + OP2 = (IO ? IMM16 : RS2); > > + PC = OP2) > > + > > +INSTRUCTION (jal, > > + OP2 = (IO ? IMM16 : RS2); > > + RD = PC + 1; > > + PC = OP2) > > + > > +INSTRUCTION (ldi, > > + RD = IMM16; > > + PC++) > > + > > +INSTRUCTION (halt, > > + pru_sim_syscall (sd, cpu); > > + PC++) > > + > > +INSTRUCTION (slp, > > + if (!WAKEONSTATUS) > > + { > > + RAISE_SIGINT (sd); > > + } > > + else > > + { > > + PC++; > > + }) > > + > > +INSTRUCTION (qbgt, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 > RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qbge, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 >= RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qblt, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 < RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qble, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 <= RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qbeq, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 == RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qbne, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (OP2 != RS1) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qba, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = PC + BROFF) > > + > > +INSTRUCTION (qbbs, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = (RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (qbbc, > > + OP2 = (IO ? IMM8 : RS2); > > + PC = !(RS1 & (1u << (OP2 & 0x1f))) ? (PC + BROFF) : (PC + 1)) > > + > > +INSTRUCTION (lbbo, > > + pru_dmem2reg (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2), > > + BURSTLEN, RD_REGN, RDB); > > + PC++) > > + > > +INSTRUCTION (sbbo, > > + pru_reg2dmem (cpu, XBBO_BASEREG + (IO ? IMM8 : RS2), > > + BURSTLEN, RD_REGN, RDB); > > + PC++) > > + > > +INSTRUCTION (lbco, > > + pru_dmem2reg (cpu, CTABLE[CB] + (IO ? IMM8 : RS2), > > + BURSTLEN, RD_REGN, RDB); > > + PC++) > > + > > +INSTRUCTION (sbco, > > + pru_reg2dmem (cpu, CTABLE[CB] + (IO ? IMM8 : RS2), > > + BURSTLEN, RD_REGN, RDB); > > + PC++) > > + > > +INSTRUCTION (xin, > > + DO_XIN (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); > > + PC++) > > + > > +INSTRUCTION (xout, > > + DO_XOUT (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); > > + PC++) > > + > > +INSTRUCTION (xchg, > > + DO_XCHG (XFR_WBA, RD_REGN, RDB, XFR_LENGTH); > > + PC++) > > + > > +INSTRUCTION (sxin, > > + sim_io_eprintf (sd, "SXIN instruction not supported by sim\n"); > > + RAISE_SIGILL (sd)) > > + > > +INSTRUCTION (sxout, > > + sim_io_eprintf (sd, "SXOUT instruction not supported by sim\n"); > > + RAISE_SIGILL (sd)) > > + > > +INSTRUCTION (sxchg, > > + sim_io_eprintf (sd, "SXCHG instruction not supported by sim\n"); > > + RAISE_SIGILL (sd)) > > + > > +INSTRUCTION (loop, > > + OP2 = (IO ? IMM8 + 1 : RS2_w0); > > + if (OP2 == 0) > > + { > > + PC = LOOPEND; > > + } > > + else > > + { > > + LOOPTOP = PC + 1; > > + LOOPEND = PC + LOOP_JMPOFFS; > > + LOOPCNT = OP2; > > + LOOP_IN_PROGRESS = 1; > > + PC++; > > + }) > > + > > +INSTRUCTION (iloop, > > + OP2 = (IO ? IMM8 + 1 : RS2_w0); > > + if (OP2 == 0) > > + { > > + PC = LOOPEND; > > + } > > + else > > + { > > + LOOPTOP = PC + 1; > > + LOOPEND = PC + LOOP_JMPOFFS; > > + LOOPCNT = OP2; > > + LOOP_IN_PROGRESS = 1; > > + PC++; > > + }) > > diff --git a/sim/pru/sim-main.h b/sim/pru/sim-main.h > > new file mode 100644 > > index 0000000000..b8a2c20ea8 > > --- /dev/null > > +++ b/sim/pru/sim-main.h > > @@ -0,0 +1,91 @@ > > +/* Copyright 2016-2019 Free Software Foundation, Inc. > > + Contributed by Dimitar Dimitrov > > + > > + This file is part of the PRU simulator. > > + > > + This library is free software; you can redistribute it and/or modify > > + it under the terms of the GNU General Public License as published by > > + the Free Software Foundation; either version 3 of the License, or > > + (at your option) any later version. > > + > > + This program is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + GNU General Public License for more details. > > + > > + You should have received a copy of the GNU General Public License > > + along with this program; if not, see . */ > > + > > +#ifndef PRU_SIM_MAIN > > +#define PRU_SIM_MAIN > > + > > +#include > > +#include > > +#include "pru.h" > > +#include "sim-basics.h" > > + > > +#include "sim-base.h" > > + > > +/* The machine state. > > + This state is maintained in host byte order. The > > + fetch/store register functions must translate between host > > + byte order and the target processor byte order. > > + Keeping this data in target byte order simplifies the register > > + read/write functions. Keeping this data in host order improves > > + the performance of the simulator. Simulation speed is deemed more > > + important. */ > > + > > +/* For clarity, please keep the same relative order in this enum as in the > > + corresponding group of GP registers. > > + > > + In PRU ISA, Multiplier-Accumulator-Unit's registers are like "shadows" > > of + the GP registers. MAC registers are implicitly addressed when > > executing + the XIN/XOUT instructions to access them. Transfer to/from a > > MAC register + can happen only from/to its corresponding GP peer > > register. */ + > > +enum pru_macreg_id { > > + /* MAC register CPU GP register Description. */ > > + PRU_MACREG_MODE, /* r25 */ /* Mode (MUL/MAC). */ > > + PRU_MACREG_PROD_L, /* r26 */ /* Lower 32 bits of product. > */ > > + PRU_MACREG_PROD_H, /* r27 */ /* Higher 32 bits of product. > */ > > + PRU_MACREG_OP_0, /* r28 */ /* First operand. */ > > + PRU_MACREG_OP_1, /* r29 */ /* Second operand. */ > > + PRU_MACREG_ACC_L, /* N/A */ /* Accumulator (not exposed) > */ > > + PRU_MACREG_ACC_H, /* N/A */ /* Higher 32 bits of MAC > > + accumulator. */ > > + PRU_MAC_NREGS > > +}; > > + > > +struct pru_regset > > +{ > > + uint32_t regs[32]; /* Primary registers. */ > > + uint16_t pc; /* IMEM _word_ address. */ > > + uint32_t pc_addr_space_marker; /* IMEM virtual linker offset. This > > + is the artificial offset that > > + we invent in order to "separate" > > + the DMEM and IMEM memory spaces. */ > > + unsigned int carry : 1; > > + uint32_t ctable[32]; /* Constant offsets table for xBCO. */ > > + uint32_t macregs[PRU_MAC_NREGS]; > > + uint32_t scratchpads[XFRID_MAX + 1][32]; > > + struct { > > + uint16_t looptop; /* LOOP top (PC of loop instr). */ > > + uint16_t loopend; /* LOOP end (PC of loop end label). */ > > + int loop_in_progress; /* Whether to check for PC==loopend. */ > > + uint32_t loop_counter; /* LOOP counter. */ > > + } loop; > > + int cycles; > > + int insts; > > +}; > > + > > +struct _sim_cpu { > > + struct pru_regset pru_cpu; > > + sim_cpu_base base; > > +}; > > + > > +struct sim_state { > > + sim_cpu *cpu[MAX_NR_PROCESSORS]; > > + > > + sim_state_base base; > > +}; > > +#endif /* PRU_SIM_MAIN */ > > > >