This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v5 1/2] PRU Simulator port


* Dimitar Dimitrov <dimitar@dinux.eu> [2019-08-26 07:08:16 +0300]:

> I'd like to contribute a sim port for the TI PRU I/O processor. This
> is the fifth version of the patch series.
> 
> The GCC and binutils ports have already been merged. I've sent
> patches for newlib.
> 
> Changes since patch series v4:
>   - Rebased to latest top-of-tree.
>   - Added XCHG instruction support.
> 
> 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

Thanks for sticking with the patch over the years!  I built and tested
this, and all the tests passed.  I have a few (hopefully) minor nits,
but this is all looking pretty good.

> 
> sim/
> 2019-08-25  Dimitar Dimitrov <dimitar@dinux.eu>
> 
> 	* MAINTAINERS: Add myself as PRU maintainer.
> 	* configure: Add PRU.

You should probably say 'Regenerated' here, I'm assuming you didn't
manually edit the 'configure' file.

> 	* configure.tgt: Add PRU.
> 
> sim/common/
> 2019-08-25  Dimitar Dimitrov <dimitar@dinux.eu>
> 
> 	* gennltvals.sh: Add PRU libgloss target.
> 	* nltvals.def: Regenerate from the latest libgloss sources.
> 
> sim/pru/
> 2019-08-25  Dimitar Dimitrov <dimitar@dinux.eu>
> 
> 	* Makefile.in: New file.
> 	* aclocal.m4: New file.
> 	* config.in: New file.

Could you regenerate these files using automake version 1.15.1 please,
this matches the version used for all the other simulator directories
and does make some changes to the content.

> 	* configure: Regenerate.

This file appears to be missing from the patch.

> 	* 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 <dimitar@dinux.eu>
> ---
>  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       | 129 ++++++
>  sim/pru/config.in        | 248 ++++++++++++
>  sim/pru/configure.ac     |  12 +
>  sim/pru/interp.c         | 841 +++++++++++++++++++++++++++++++++++++++
>  sim/pru/pru.h            | 110 +++++
>  sim/pru/pru.isa          | 249 ++++++++++++
>  sim/pru/sim-main.h       |  82 ++++
>  13 files changed, 1747 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/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 <macro@linux-mips.org>
>  moxie		Anthony Green <green@moxielogic.com>
>  msp430		Nick Clifton <nickc@redhat.com>
>  or1k		Stafford Horne <shorne@gmail.com>
> +pru		Dimitar Dimitrov <dimitar@dinux.eu>
>  sh		(global maintainers)
>  sh64		Dave Brolley <brolley@redhat.com>
>  common		Frank Ch. Eigler <fche@redhat.com>
> 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..f32b489870
> --- /dev/null
> +++ b/sim/pru/Makefile.in
> @@ -0,0 +1,29 @@
> +#    Makefile template for Configure for the PRU sim library.
> +#    Copyright (C) 2014-2019 Free Software Foundation, Inc.
> +#    Written by Dimitar Dimitrov <dimitar@dinux.eu>
> +#
> +#    Based on the MCore sim library

According to this page:

  https://sourceware.org/gdb/wiki/ContributionChecklist#Copyright_Header

If a new file is based on an existing file then the start date of the
copyright header should be copied from the original file (which would
be 1990 in this case).   If the new file is your own work being
assigned to the FSF then I think the rule is the from date should be
the first time the file appeared on the mailing list, which is 2016
from what I can find.

This comment applies to all new (non autogenerated) files.

> +#
> +# 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 <http://www.gnu.org/licenses/>.
> +
> +## 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..517bc73b03
> --- /dev/null
> +++ b/sim/pru/aclocal.m4
> @@ -0,0 +1,129 @@
> +# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
> +
> +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
> +# 2005, 2006, 2007, 2008, 2009  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.
> +
> +# AM_CONDITIONAL                                            -*- Autoconf -*-
> +
> +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
> +# 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.
> +
> +# serial 9
> +
> +# AM_CONDITIONAL(NAME, SHELL-CONDITION)
> +# -------------------------------------
> +# Define a conditional.
> +AC_DEFUN([AM_CONDITIONAL],
> +[AC_PREREQ(2.52)dnl
> + ifelse([$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, 2005  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.
> +
> +# serial 2
> +
> +# 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, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
> +# 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.
> +
> +# serial 5
> +
> +# 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 am_maintainer_other maintainer-specific portions of Makefiles])
> +  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
> +  AC_ARG_ENABLE([maintainer-mode],
> +[  --][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
> +]
> +)
> +
> +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
> +
> +# Copyright (C) 2006, 2008  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.
> +
> +# serial 2
> +
> +# _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..aa3e45ca4a
> --- /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 <dlfcn.h> header file. */
> +#undef HAVE_DLFCN_H
> +
> +/* Define to 1 if you have the <errno.h> header file. */
> +#undef HAVE_ERRNO_H
> +
> +/* Define to 1 if you have the <fcntl.h> header file. */
> +#undef HAVE_FCNTL_H
> +
> +/* Define to 1 if you have the <fpu_control.h> 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 <inttypes.h> 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 <memory.h> 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 <stdint.h> header file. */
> +#undef HAVE_STDINT_H
> +
> +/* Define to 1 if you have the <stdlib.h> header file. */
> +#undef HAVE_STDLIB_H
> +
> +/* Define to 1 if you have the <strings.h> header file. */
> +#undef HAVE_STRINGS_H
> +
> +/* Define to 1 if you have the <string.h> header file. */
> +#undef HAVE_STRING_H
> +
> +/* Define to 1 if `struct stat' is a member of `st_atime'. */
> +#undef HAVE_STRUCT_STAT_ST_ATIME
> +
> +/* Define to 1 if `struct stat' is a member of `st_blksize'. */
> +#undef HAVE_STRUCT_STAT_ST_BLKSIZE
> +
> +/* Define to 1 if `struct stat' is a member of `st_blocks'. */
> +#undef HAVE_STRUCT_STAT_ST_BLOCKS
> +
> +/* Define to 1 if `struct stat' is a member of `st_ctime'. */
> +#undef HAVE_STRUCT_STAT_ST_CTIME
> +
> +/* Define to 1 if `struct stat' is a member of `st_dev'. */
> +#undef HAVE_STRUCT_STAT_ST_DEV
> +
> +/* Define to 1 if `struct stat' is a member of `st_gid'. */
> +#undef HAVE_STRUCT_STAT_ST_GID
> +
> +/* Define to 1 if `struct stat' is a member of `st_ino'. */
> +#undef HAVE_STRUCT_STAT_ST_INO
> +
> +/* Define to 1 if `struct stat' is a member of `st_mode'. */
> +#undef HAVE_STRUCT_STAT_ST_MODE
> +
> +/* Define to 1 if `struct stat' is a member of `st_mtime'. */
> +#undef HAVE_STRUCT_STAT_ST_MTIME
> +
> +/* Define to 1 if `struct stat' is a member of `st_nlink'. */
> +#undef HAVE_STRUCT_STAT_ST_NLINK
> +
> +/* Define to 1 if `struct stat' is a member of `st_rdev'. */
> +#undef HAVE_STRUCT_STAT_ST_RDEV
> +
> +/* Define to 1 if `struct stat' is a member of `st_size'. */
> +#undef HAVE_STRUCT_STAT_ST_SIZE
> +
> +/* Define to 1 if `struct stat' is a member of `st_uid'. */
> +#undef HAVE_STRUCT_STAT_ST_UID
> +
> +/* Define to 1 if you have the <sys/mman.h> header file. */
> +#undef HAVE_SYS_MMAN_H
> +
> +/* Define to 1 if you have the <sys/resource.h> header file. */
> +#undef HAVE_SYS_RESOURCE_H
> +
> +/* Define to 1 if you have the <sys/stat.h> header file. */
> +#undef HAVE_SYS_STAT_H
> +
> +/* Define to 1 if you have the <sys/times.h> header file. */
> +#undef HAVE_SYS_TIMES_H
> +
> +/* Define to 1 if you have the <sys/time.h> header file. */
> +#undef HAVE_SYS_TIME_H
> +
> +/* Define to 1 if you have the <sys/types.h> 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 <time.h> 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 <unistd.h> header file. */
> +#undef HAVE_UNISTD_H
> +
> +/* Define to 1 if you have the <windows.h> 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..54ac06f48e
> --- /dev/null
> +++ b/sim/pru/configure.ac

This file can include a copyright header, see sim/rx/configure.ac for
an example.

> @@ -0,0 +1,12 @@
> +dnl Process this file with autoconf to produce a configure script.
> +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..a794941532
> --- /dev/null
> +++ b/sim/pru/interp.c
> @@ -0,0 +1,841 @@
> +/* Simulator for the Texas Instruments PRU processor
> +   Copyright 2014-2019 Free Software Foundation, Inc.
> +   Inspired by the Microblaze simulator
> +   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
> +
> +   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 <http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stddef.h>
> +#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.
> +
> +   NOTE: 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.  */

You have a double space in "a  regular".

> +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;
> +
> +    }
> +}
> +
> +void
> +sim_engine_run (SIM_DESC sd,
> +		int next_cpu_nr, /* ignore  */
> +		int nr_cpus, /* ignore  */
> +		int siggnal) /* ignore  */

All the functions before this one have a header comment.  But starting
from here they no longer appear.  I'm a fan, so could you add the
missing ones please, even if its just, "Implement standard
sim_engine_run function." or similar.

> +{
> +  SIM_CPU *cpu = STATE_CPU (sd, 0);

'cpu' isn't used.

> +
> +  while (1)
> +    {
> +      sim_step_once (sd);
> +      if (sim_events_tick (sd))
> +	sim_events_process (sd);
> +    }
> +}
> +
> +
> +static sim_cia
> +pru_pc_get (sim_cpu *cpu)
> +{
> +  /* Present PC as byte address.  */
> +  return imem_wordaddr_to_byteaddr (cpu, cpu->pru_cpu.pc);
> +}
> +
> +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);
> +}
> +
> +
> +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;
> +}
> +
> +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);
> +}
> +
> +static DECLARE_OPTION_HANDLER (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;
> +    }
> +}
> +
> +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 }
> +};
> +
> +SIM_DESC
> +sim_open (SIM_OPEN_KIND kind, host_callback *cb,
> +	  struct bfd *abfd, char * const *argv)
> +{
> +  int i;
> +  SIM_CPU *cpu;

I don't think that this 'cpu' is used.  There's another declared in a
nested scope later on that is used, but not this one.

> +  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 the 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;
> +}
> +
> +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..9d74029d90
> --- /dev/null
> +++ b/sim/pru/pru.h
> @@ -0,0 +1,110 @@
> +/* Copyright 2014-2019 Free Software Foundation, Inc.
> +   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
> +
> +   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 <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef PRU_H
> +#define PRU_H
> +
> +#include "config.h"
> +#include "opcode/pru.h"
> +
> +/* NOTE: Needed for handling the dual PRU address space.  */

I don't think you need to say "NOTE", this is implied by it being a
comment.

> +#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..017f85ec50
> --- /dev/null
> +++ b/sim/pru/pru.isa
> @@ -0,0 +1,249 @@
> +/* Copyright 2014-2019 Free Software Foundation, Inc.
> +   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
> +
> +   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 <http://www.gnu.org/licenses/>.  */
> +
> +/*
> +   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..4ad7b56a87
> --- /dev/null
> +++ b/sim/pru/sim-main.h
> @@ -0,0 +1,82 @@
> +/* Copyright 2014-2019 Free Software Foundation, Inc.
> +   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
> +
> +   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 <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef PRU_SIM_MAIN
> +#define PRU_SIM_MAIN
> +
> +#include <stdint.h>
> +#include <stddef.h>
> +#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 native order improves

It would be better to say "Keeping this data in host order..." as you
previously talk about host or target order, and only mention native
order here.

> +   the performance of the simulator.  Simulation speed is deemed more
> +   important.  */
> +
> +/* Please keep the same order as the GP registers.  */

It isn't clear to me where the order in "... same order as the GP
registers" comes from.  Is this order defined in the ISA?  Defined in
some other file in GDB or the simulator?   Could you expand on this
comment maybe?

> +enum pru_macreg_id {
> +    PRU_MACREG_MODE,	  /* r25 */
> +    PRU_MACREG_PROD_L,	  /* r26 */
> +    PRU_MACREG_PROD_H,	  /* r27 */
> +    PRU_MACREG_OP_0,	  /* r28 */
> +    PRU_MACREG_OP_1,	  /* r29 */
> +    PRU_MACREG_ACC_L,	  /* N/A */
> +    PRU_MACREG_ACC_H,	  /* N/A */
> +    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 */
> -- 
> 2.20.1
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]