[PATCH v2 1/2] Initial PRU port

Dimitar Dimitrov dimitar@dinux.eu
Mon Aug 26 04:14:00 GMT 2019


Hi,

I would like to contribute newlib port for the TI PRU I/O processor [1] [2].

Binutils and GCC ports have already been merged.

The following files need to be regenerated. Let me know if I should post a separate patch for them:
 configure
 libgloss/configure
 libgloss/pru/aclocal.m4
 libgloss/pru/configure
 newlib/libc/machine/configure
 newlib/libc/machine/pru/Makefile.in
 newlib/libc/machine/pru/aclocal.m4
 newlib/libc/machine/pru/configure
 newlib/libm/machine/configure
 newlib/libm/machine/pru/Makefile.in
 newlib/libm/machine/pru/aclocal.m4
 newlib/libm/machine/pru/configure

Regards,
Dimitar

[1] http://processors.wiki.ti.com/index.php/PRU-ICSS
[2] http://beagleboard.org/pru
[3] https://sourceware.org/ml/newlib/2018/msg00392.html

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 configure.ac                             |   4 +
 libgloss/configure.in                    |   3 +
 libgloss/pru/Makefile.in                 | 142 ++++++++++++++++
 libgloss/pru/configure.in                |  66 ++++++++
 libgloss/pru/crt0.S                      |  84 ++++++++++
 libgloss/pru/device-specs/sim            |   5 +
 libgloss/pru/do_global_dtors.c           |  40 +++++
 libgloss/pru/gettimeofday.c              |  31 ++++
 libgloss/pru/inbyte.c                    |  38 +++++
 libgloss/pru/isatty.c                    |  26 +++
 libgloss/pru/ldscripts/gen-ld-scripts.sh |  55 +++++++
 libgloss/pru/ldscripts/pruelf-sim.x      | 200 +++++++++++++++++++++++
 libgloss/pru/outbyte.c                   |  24 +++
 libgloss/pru/print.c                     |  25 +++
 libgloss/pru/putnum.c                    |  42 +++++
 libgloss/pru/raise.c                     |  24 +++
 libgloss/pru/sbrk.c                      |  46 ++++++
 libgloss/pru/stat.c                      |  31 ++++
 libgloss/pru/syscalls.S                  |  65 ++++++++
 newlib/configure.host                    |  14 +-
 newlib/libc/include/machine/ieeefp.h     |   4 +
 newlib/libc/include/machine/setjmp.h     |   5 +
 newlib/libc/machine/configure.in         |   1 +
 newlib/libc/machine/pru/Makefile.am      |  16 ++
 newlib/libc/machine/pru/configure.in     |  14 ++
 newlib/libc/machine/pru/setjmp.s         |  46 ++++++
 26 files changed, 1050 insertions(+), 1 deletion(-)
 create mode 100644 libgloss/pru/Makefile.in
 create mode 100644 libgloss/pru/configure.in
 create mode 100644 libgloss/pru/crt0.S
 create mode 100644 libgloss/pru/device-specs/sim
 create mode 100644 libgloss/pru/do_global_dtors.c
 create mode 100644 libgloss/pru/gettimeofday.c
 create mode 100644 libgloss/pru/inbyte.c
 create mode 100644 libgloss/pru/isatty.c
 create mode 100755 libgloss/pru/ldscripts/gen-ld-scripts.sh
 create mode 100644 libgloss/pru/ldscripts/pruelf-sim.x
 create mode 100644 libgloss/pru/outbyte.c
 create mode 100644 libgloss/pru/print.c
 create mode 100644 libgloss/pru/putnum.c
 create mode 100644 libgloss/pru/raise.c
 create mode 100644 libgloss/pru/sbrk.c
 create mode 100644 libgloss/pru/stat.c
 create mode 100644 libgloss/pru/syscalls.S
 create mode 100644 newlib/libc/machine/pru/Makefile.am
 create mode 100644 newlib/libc/machine/pru/configure.in
 create mode 100644 newlib/libc/machine/pru/setjmp.s

diff --git a/configure.ac b/configure.ac
index cf856e567..28e83a73d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -697,6 +697,10 @@ case "${target}" in
   powerpc-*-aix* | rs6000-*-aix*)
     noconfigdirs="$noconfigdirs target-libssp"
     ;;
+  pru-*-*)
+    # No hosted I/O support.
+    noconfigdirs="$noconfigdirs target-libssp"
+    ;;
   rl78-*-*)
     # libssp uses a misaligned load to trigger a fault, but the RL78
     # doesn't fault for those - instead, it gives a build-time error
diff --git a/libgloss/configure.in b/libgloss/configure.in
index 41843eed1..a681f233f 100644
--- a/libgloss/configure.in
+++ b/libgloss/configure.in
@@ -176,6 +176,9 @@ case "${target}" in
   or1k-*-* | or1knd-*-* )
 	AC_CONFIG_SUBDIRS([or1k])
 	;;
+  pru-*-*)
+	AC_CONFIG_SUBDIRS([pru])
+	;;
   nios2-*-*)
 	AC_CONFIG_SUBDIRS([nios2])
 	;;
diff --git a/libgloss/pru/Makefile.in b/libgloss/pru/Makefile.in
new file mode 100644
index 000000000..c15ea3eb4
--- /dev/null
+++ b/libgloss/pru/Makefile.in
@@ -0,0 +1,142 @@
+# Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+
+VPATH = @srcdir@ @srcdir@/..
+
+srcdir = @srcdir@
+objdir = .
+srcroot = $(srcdir)/../..
+objroot = $(objdir)/../..
+top_srcdir = @top_srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+
+bindir = @bindir@
+libdir = @libdir@
+includedir = @includedir@
+tooldir = $(exec_prefix)/$(target_alias)
+
+# Multilib support variables.
+# TOP is used instead of MULTI{BUILD,SRC}TOP.
+MULTIDIRS =
+MULTISUBDIR =
+
+SHELL =	/bin/sh
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+
+CC = @CC@
+
+AS = @AS@
+
+AR = @AR@
+
+LD = @LD@
+
+RANLIB = @RANLIB@
+
+OBJDUMP = `t='$(program_transform_name)'; echo objdump | sed -e $$t`
+OBJCOPY = `t='$(program_transform_name)'; echo objcopy | sed -e $$t`
+
+# linker scripts
+SCRIPTS = `ls ${srcdir}/ldscripts/*.x`
+
+# object files needed
+OBJS = \
+	do_global_dtors.o gettimeofday.o \
+	isatty.o putnum.o raise.o \
+	inbyte.o outbyte.o sbrk.o stat.o syscalls.o \
+	do_global_dtors.o
+
+# Object files specific to particular targets.
+EVALOBJS = ${OBJS}
+
+CRTOBJS = crt0.o crt0-minrt.o
+OUTPUTS = libgloss.a $(CRTOBJS)
+
+INCLUDES = -I$(srcdir)/..
+
+# Note that when building the library, ${MULTILIB} is not the way multilib
+# options are passed; they're passed in $(CFLAGS).
+CFLAGS_FOR_TARGET = ${MULTILIB} ${INCLUDES}
+LDFLAGS_FOR_TARGET = ${MULTILIB}
+
+.c.o:
+	$(CC) $(CFLAGS_FOR_TARGET) -Os $(INCLUDES) -c $(CFLAGS) $<
+
+.C.o:
+	$(CC) $(CFLAGS_FOR_TARGET) -Os $(INCLUDES) -c $(CFLAGS) $<
+.s.o:
+	$(AS) $(ASFLAGS_FOR_TARGET) $(INCLUDES) $(ASFLAGS) -o $*.o $<
+
+#
+# GCC knows to run the preprocessor on .S files before it assembles them.
+#
+.S.o:
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c $<
+
+all: ${OUTPUTS} copy_scripts_to_objdir
+
+copy_scripts_to_objdir: $(srcdir)/ldscripts/gen-ld-scripts.sh
+	cp $(SCRIPTS) $(objdir)
+
+#
+# here's where we build the library for each target
+#
+
+libgloss.a: $(EVALOBJS)
+	${AR} ${ARFLAGS} $@ $(EVALOBJS)
+	${RANLIB} $@
+
+# C Runtime Library startup code.
+crt0.o: $(srcdir)/crt0.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $< -c -o $@
+
+crt0-minrt.o: $(srcdir)/crt0.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -DMINRT $< -c -o $@
+
+doc:	
+
+clean mostlyclean:
+	rm -f $(OUTPUTS) *.i *~ *.o *-test *.srec *.dis *.map *.x
+
+distclean maintainer-clean realclean: clean
+	rm -f Makefile config.status $(OUTPUTS)
+
+.PHONY: install info install-info clean-info
+install: $(OUTPUTS) $(srcdir)/ldscripts/gen-ld-scripts.sh
+	for outputs in ${OUTPUTS}; do\
+	 ${INSTALL_DATA} $${outputs} ${DESTDIR}${tooldir}/lib${MULTISUBDIR}/$${outputs}; \
+	done
+	for s in $(SCRIPTS); do \
+	  b=`basename $$s`; \
+	  ${INSTALL_DATA} $$s ${DESTDIR}${tooldir}/lib${MULTISUBDIR}/$$b ;\
+	done
+	${mkinstalldirs} ${DESTDIR}${tooldir}/lib${MULTISUBDIR}/device-specs; \
+	for s in ${srcdir}/device-specs/*; do \
+	  b=`basename $$s`; \
+	  $(INSTALL_DATA) $$s $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/device-specs/$$b ;\
+	done
+
+info:
+install-info:
+clean-info:
+
+Makefile: $(srcdir)/Makefile.in config.status @host_makefile_frag_path@
+	$(SHELL) config.status
+
+config.status: $(srcdir)/configure
+	$(SHELL) config.status --recheck
diff --git a/libgloss/pru/configure.in b/libgloss/pru/configure.in
new file mode 100644
index 000000000..2a4c946e8
--- /dev/null
+++ b/libgloss/pru/configure.in
@@ -0,0 +1,66 @@
+# Copyright (c) 2008, 2009, 2011, 2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the BSD
+# License.   This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  A copy of this license
+# is available at http://www.opensource.org/licenses. Any Red Hat trademarks that
+# are incorporated in the source code or documentation are not subject to the BSD
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.59)
+AC_INIT(crt0.S)
+
+if test "${enable_shared}" = "yes" ; then
+    echo "Shared libraries not supported for cross compiling, ignored"
+fi
+
+if test "$srcdir" = "." ; then
+  if test "${with_target_subdir}" != "." ; then
+    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
+  else
+    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
+  fi
+else
+  libgloss_topdir="${srcdir}/../.."
+fi
+AC_CONFIG_AUX_DIR($libgloss_topdir)
+
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+
+AC_PROG_INSTALL
+
+LIB_AC_PROG_CC
+AS=${AS-as}
+AC_SUBST(AS)
+AR=${AR-ar}
+AC_SUBST(AR)
+LD=${LD-ld}
+AC_SUBST(LD)
+AC_PROG_RANLIB
+LIB_AM_PROG_AS
+
+host_makefile_frag=${srcdir}/../config/default.mh
+
+dnl We have to assign the same value to other variables because autoconf
+dnl doesn't provide a mechanism to substitute a replacement keyword with
+dnl arbitrary data or pathnames.
+dnl
+host_makefile_frag_path=$host_makefile_frag
+AC_SUBST(host_makefile_frag_path)
+AC_SUBST_FILE(host_makefile_frag)
+
+AC_CONFIG_FILES(Makefile,
+. ${libgloss_topdir}/config-ml.in,
+srcdir=${srcdir}
+target=${target}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="${ac_configure_args} --enable-multilib"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libgloss_topdir=${libgloss_topdir}
+)
+AC_OUTPUT
diff --git a/libgloss/pru/crt0.S b/libgloss/pru/crt0.S
new file mode 100644
index 000000000..871ac72e2
--- /dev/null
+++ b/libgloss/pru/crt0.S
@@ -0,0 +1,84 @@
+/* crt0.S -- PRU startup code
+ *
+ * Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "newlib.h"
+
+	.extern	main
+	.extern	exit
+
+	.text
+	.section .init0, "x"
+	.global	_start
+_start:
+	/* Initialize stack pointer. */
+	ldi32	sp, _stack_top
+
+	/* DATA and BSS are handled by the loader, so nothing to do here. */
+
+#if !defined(MINRT)
+	.extern _do_global_dtors
+	/* Ensure destructors get called.  Call is per GNU ABI (i.e. 32-bit
+	   function pointers).  But it is also compatible with the TI ABI
+	   since GCC supports only little endian PRU.
+
+	   WARNING:  Keep this compatible with both ABIs!  */
+	ldi	r14, %pmem(_do_global_dtors)
+	call	atexit
+
+	/* Call constructors. Use non-call-clobbered registers. */
+	ldi	r5, __init_array_start
+	ldi	r6, __init_array_end
+ctors_loop:
+	qbeq	ctors_done, r5, r6
+	/* ABI dictates 16-bit IMEM pointers. */
+	lbbo	r7, r5, 0, 2
+	call	r7.w0
+	add	r5, r5, 2
+	jmp	ctors_loop
+ctors_done:
+#endif
+
+	/* Just in case main() tries to access argc, argv[] and envp. */
+	zero	r14, 3 * 4
+
+#if !defined(MINRT)
+	.weak __c_args__
+	ldi32	r5, __c_args__
+	qbeq	__skip_c_args, r5, 0
+	lbbo	r14, r5, 0, 4	/* argc */
+	add	r15, r5, 4	/* argv */
+__skip_c_args:
+#endif
+
+	/* Call main */
+	call	main
+
+#if !defined(MINRT)
+	/* Call exit */
+	call	exit
+#endif
+
+	/* We should never reach here. */
+_crt_exit:
+	halt
+	jmp	_crt_exit
+
+	/* PRU obviously has no shared libraries, but dso_handle
+	   helps to achieve better GCC test coverage. Besides,
+	   it should be free with minrt. */
+	.section .data
+	.global __dso_handle
+	.weak __dso_handle
+__dso_handle:
+	.long	0
diff --git a/libgloss/pru/device-specs/sim b/libgloss/pru/device-specs/sim
new file mode 100644
index 000000000..50d4689e0
--- /dev/null
+++ b/libgloss/pru/device-specs/sim
@@ -0,0 +1,5 @@
+*cpp_device:
+-D__SIM__
+
+*link_device:
+%{!r:-Tpruelf-sim.x}
diff --git a/libgloss/pru/do_global_dtors.c b/libgloss/pru/do_global_dtors.c
new file mode 100644
index 000000000..3cc053ed5
--- /dev/null
+++ b/libgloss/pru/do_global_dtors.c
@@ -0,0 +1,40 @@
+/* do_global_dtors - invoke global destructors
+ *
+ * Copyright (c) 2015-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <stdint.h>
+#include <_ansi.h>
+#include "syscall.h"
+
+extern void *__fini_array_start;
+extern void *__fini_array_end;
+
+/*
+ * _do_global_dtors
+ */
+void
+_do_global_dtors (void)
+{
+    /* ABI dictates pointers in init/fini arrays are 16-bit.  */
+    const uint16_t *end = (uint16_t *)&__fini_array_end;
+    const uint16_t *begin = (uint16_t *)&__fini_array_start;
+    const uint16_t *p;
+    void (**dtor) (void);
+
+    /* call destructors in reverse order */
+    for (p = end; p > begin; ) {
+	p--;
+	dtor = (void *)p;
+	(*dtor) ();
+    }
+}
diff --git a/libgloss/pru/gettimeofday.c b/libgloss/pru/gettimeofday.c
new file mode 100644
index 000000000..b4b7cb078
--- /dev/null
+++ b/libgloss/pru/gettimeofday.c
@@ -0,0 +1,31 @@
+/* gettimeofday.c -- get the current time of day
+ *
+ * Copyright (c) 1995, 1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <errno.h>
+#include "glue.h"
+
+#undef errno
+extern int errno;
+struct timeval;
+
+/*
+ * gettimeofday -- no clock
+ * struct timeval * tp, void * tzvp
+ */
+int
+_gettimeofday (struct timeval * tp, void * tzvp)
+{
+    errno = ENOSYS;
+    return -1;
+}
diff --git a/libgloss/pru/inbyte.c b/libgloss/pru/inbyte.c
new file mode 100644
index 000000000..afb8fd927
--- /dev/null
+++ b/libgloss/pru/inbyte.c
@@ -0,0 +1,38 @@
+/* inbyte.c -- inbyte function for remoteproc
+ *
+ * Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <errno.h>
+#include <_ansi.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "glue.h"
+
+extern ssize_t _read(int fd, void *b, size_t count);
+
+int
+inbyte (void)
+{
+  ssize_t n;
+  char c;
+
+  /* PRU has no interrupts, so it is inherently thread-safe. */
+  n = _read(STDIN_FILENO, &c, 1);
+  if (n < 0)
+    return n;
+  else if (n == 0)
+    return -ENODATA;
+  else
+    return 1;
+}
+
diff --git a/libgloss/pru/isatty.c b/libgloss/pru/isatty.c
new file mode 100644
index 000000000..bb160edf2
--- /dev/null
+++ b/libgloss/pru/isatty.c
@@ -0,0 +1,26 @@
+/* isatty.c -- chek the terminal device.
+ * 
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "glue.h"
+
+/*
+ * isatty -- returns 1 if connected to a terminal device,
+ *           returns 0 if not. Since we're hooked up to a
+ *           serial port, we'll say yes _AND return a 1.
+ */
+int
+_isatty (int fd)
+{
+  return (1);
+}
diff --git a/libgloss/pru/ldscripts/gen-ld-scripts.sh b/libgloss/pru/ldscripts/gen-ld-scripts.sh
new file mode 100755
index 000000000..c503232d7
--- /dev/null
+++ b/libgloss/pru/ldscripts/gen-ld-scripts.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# Generate additional MCU-specific linker scripts by using the
+# default PRU-LD linker script.
+#
+# We do it automatically so that:
+#  1. We only change the default linker script in binutils.
+#  2. All the default script complexity stays in binutils.
+#  3. Here in libgloss we care only to enumerate all PRU variants with
+#     their default memory sizes.
+
+dump_modified()
+{
+  IMEM_SIZE=$1
+  DMEM_SIZE=$2
+  HEAP_SIZE=$3
+  STACK_SIZE=$4
+
+  echo "/* WARNING: automatically generated from the default pru-ld script! */"
+  echo -e "\n\n"
+  pru-ld --verbose | awk "
+BEGIN { LDV_MARKER = 0; }
+{
+  if (\$0 == \"==================================================\" )
+    {
+      LDV_MARKER++;
+    }
+  else if (LDV_MARKER != 1)
+    {
+    }
+  else if (\$0 ~ /^  imem.*ORIGIN =.*LENGTH =/)
+    {
+      print \"  imem   (x)   : ORIGIN = 0x20000000, LENGTH = $IMEM_SIZE\"
+    }
+  else if (\$0 ~ /^  dmem.*ORIGIN =.*LENGTH =/)
+    {
+      print \"  dmem   (rw!x) : ORIGIN = 0x0, LENGTH = $DMEM_SIZE\"
+    }
+  else if (\$0 ~ /^__HEAP_SIZE = DEFINED/)
+    {
+      print \"__HEAP_SIZE = DEFINED(__HEAP_SIZE) ? __HEAP_SIZE : $HEAP_SIZE ;\";
+    }
+  else if (\$0 ~ /^__STACK_SIZE = DEFINED/)
+    {
+      print \"__STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : $STACK_SIZE ;\";
+    }
+  else
+    {
+      print \$0;
+    }
+}"
+}
+
+#             IMEM DMEM   HEAP_SIZE    STACK_SIZE
+dump_modified 256K 65536K "32 * 1024 * 1024" "1024 * 1024" | tee pruelf-sim.x
diff --git a/libgloss/pru/ldscripts/pruelf-sim.x b/libgloss/pru/ldscripts/pruelf-sim.x
new file mode 100644
index 000000000..1dc8b4f2e
--- /dev/null
+++ b/libgloss/pru/ldscripts/pruelf-sim.x
@@ -0,0 +1,200 @@
+/* WARNING: automatically generated from the default pru-ld script! */
+
+
+
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-pru","elf32-pru","elf32-pru")
+OUTPUT_ARCH(pru)
+MEMORY
+{
+  imem   (x)   : ORIGIN = 0x20000000, LENGTH = 256K
+  dmem   (rw!x) : ORIGIN = 0x0, LENGTH = 65536K
+}
+__HEAP_SIZE = DEFINED(__HEAP_SIZE) ? __HEAP_SIZE : 32 * 1024 * 1024 ;
+__STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 1024 * 1024 ;
+PROVIDE (_stack_top = ORIGIN(dmem) + LENGTH(dmem));
+ENTRY (_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .gnu.version   : { *(.gnu.version)	}
+  .gnu.version_d   : { *(.gnu.version_d)	}
+  .gnu.version_r   : { *(.gnu.version_r)	}
+  .rel.init      : { *(.rel.init)		}
+  .rela.init     : { *(.rela.init)	}
+  .rel.text      :
+    {
+      *(.rel.text)
+      *(.rel.text.*)
+      *(.rel.text:*)
+      *(.rel.gnu.linkonce.t*)
+    }
+  .rela.text     :
+    {
+      *(.rela.text)
+      *(.rela.text.*)
+      *(.rela.text:*)
+      *(.rela.gnu.linkonce.t*)
+    }
+  .rel.fini      : { *(.rel.fini)		}
+  .rela.fini     : { *(.rela.fini)	}
+  .rel.rodata    :
+    {
+      *(.rel.rodata)
+      *(.rel.rodata.*)
+      *(.rel.rodata:*)
+      *(.rel.gnu.linkonce.r*)
+    }
+  .rela.rodata   :
+    {
+      *(.rela.rodata)
+      *(.rela.rodata.*)
+      *(.rela.rodata:*)
+      *(.rela.gnu.linkonce.r*)
+    }
+  .rel.data      :
+    {
+      *(.rel.data)
+      *(.rel.data.*)
+      *(.rel.data:*)
+      *(.rel.gnu.linkonce.d*)
+    }
+  .rela.data     :
+    {
+      *(.rela.data)
+      *(.rela.data.*)
+      *(.rela.data:*)
+      *(.rela.gnu.linkonce.d*)
+    }
+  .rel.init_array   	  : { *(.rel.init_array)	}
+  .rela.init_array  	  : { *(.rela.init_array)	}
+  .rel.fini_array   	  : { *(.rel.fini_array)	}
+  .rela.fini_array  	  : { *(.rela.fini_array)	}
+  .rel.got     		  : { *(.rel.got)		}
+  .rela.got    		  : { *(.rela.got)	}
+  .rel.bss     		  : { *(.rel.bss)		}
+  .rela.bss    		  : { *(.rela.bss)	}
+  .rel.plt     		  : { *(.rel.plt)		}
+  .rela.plt    		  : { *(.rela.plt)	}
+  /* Internal text space.  */
+  .text   :
+  {
+     _text_start = . ;
+    . = ALIGN(4);
+    *(.init0)  /* Start here after reset.  */
+    KEEP (*(.init0))
+    . = ALIGN(4);
+    *(.text)
+    . = ALIGN(4);
+    *(.text.*)
+    . = ALIGN(4);
+    *(.text:*)
+    . = ALIGN(4);
+    *(.gnu.linkonce.t*)
+    . = ALIGN(4);
+     _text_end = . ;
+  }  > imem
+  .data          :
+  {
+    /* Optional variable that user is prepared to have NULL address.  */
+     *(.data.atzero*)
+    /* CRT is prepared for constructor/destructor table to have
+       a "valid" NULL address.  */
+     __init_array_start = . ;
+     KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
+     KEEP (*(.init_array))
+     __init_array_end = . ;
+     __fini_array_start = . ;
+     KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
+     KEEP (*(.fini_array))
+     __fini_array_end = . ;
+    /* DATA memory starts at address 0.  So to avoid placing a valid static
+       variable at the invalid NULL address, we introduce the .data.atzero
+       section.  If CRT can make some use of it - great.  Otherwise skip a
+       word.  In all cases .data/.bss sections must start at non-zero.  */
+    . += (. == 0 ? 4 : 0);
+     PROVIDE (_data_start = .) ;
+    *(.data)
+     *(.data*)
+     *(.data:*)
+     *(.rodata)  /* We need to include .rodata here if gcc is used.  */
+     *(.rodata.*) /* with -fdata-sections.  */
+     *(.rodata:*)
+    *(.gnu.linkonce.d*)
+    *(.gnu.linkonce.r*)
+    . = ALIGN(4);
+     PROVIDE (_data_end = .) ;
+  }  > dmem
+  .resource_table   :
+  {
+    KEEP (*(.resource_table))
+  }  > dmem
+  .bss   :
+  {
+     PROVIDE (_bss_start = .) ;
+    *(.bss)
+     *(.bss.*)
+     *(.bss:*)
+    *(.gnu.linkonce.b*)
+    *(COMMON)
+     PROVIDE (_bss_end = .) ;
+  }  > dmem
+  /* Global data not cleared after reset.  */
+  .noinit   :
+  {
+     PROVIDE (_noinit_start = .) ;
+    *(.noinit)
+     PROVIDE (_noinit_end = .) ;
+     PROVIDE (_heap_start = .) ;
+     . += __HEAP_SIZE ;
+    /* Stack is not here really.  It will be put at the end of DMEM.
+       But we take into account its size here, in order to allow
+       for MEMORY overflow checking during link time.  */
+     . += __STACK_SIZE ;
+  }  > dmem
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  .note.gnu.build-id   : { *(.note.gnu.build-id) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  /* DWARF Extension.  */
+  .debug_macro    0 : { *(.debug_macro) }
+  .debug_addr     0 : { *(.debug_addr) }
+}
+
+
diff --git a/libgloss/pru/outbyte.c b/libgloss/pru/outbyte.c
new file mode 100644
index 000000000..a13f74f13
--- /dev/null
+++ b/libgloss/pru/outbyte.c
@@ -0,0 +1,24 @@
+/* outbyte.c -- outbyte function for simulator
+ *
+ * Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <unistd.h>
+#include <_ansi.h>
+
+extern ssize_t _write(int fd, const void *b, size_t count);
+
+void
+outbyte (char ch)
+{
+  _write(STDOUT_FILENO, &ch, 1);
+}
diff --git a/libgloss/pru/print.c b/libgloss/pru/print.c
new file mode 100644
index 000000000..00a40b387
--- /dev/null
+++ b/libgloss/pru/print.c
@@ -0,0 +1,25 @@
+/* print.c -- print a string on the output device.
+ *
+ * Copyright (c) 1995, 1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <unistd.h>
+#include "glue.h"
+
+/*
+ * print -- do a raw print of a string
+ */
+void
+_print (char *ptr)
+{
+  _write(STDOUT_FILENO, ptr, strlen(ptr));
+}
diff --git a/libgloss/pru/putnum.c b/libgloss/pru/putnum.c
new file mode 100644
index 000000000..127e1c3dd
--- /dev/null
+++ b/libgloss/pru/putnum.c
@@ -0,0 +1,42 @@
+/* putnum.c -- put a hex number on the output device.
+ * 
+ * Copyright (c) 1995, 1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "glue.h"
+
+extern void print (char *ptr);
+
+/*
+ * putnum -- print a 32 bit number in hex
+ */
+void
+_putnum (unsigned int num)
+{
+  char  buf[9];
+  int   cnt;
+  char  *ptr;
+  int   digit;
+
+  ptr = buf;
+  for (cnt = 7 ; cnt >= 0 ; cnt--) {
+    digit = (num >> (cnt * 4)) & 0xf;
+
+    if (digit <= 9)
+      *ptr++ = (char) ('0' + digit);
+    else
+      *ptr++ = (char) ('a' - 10 + digit);
+  }
+
+  *ptr = (char) 0;
+  print (buf);
+}
diff --git a/libgloss/pru/raise.c b/libgloss/pru/raise.c
new file mode 100644
index 000000000..d8e902605
--- /dev/null
+++ b/libgloss/pru/raise.c
@@ -0,0 +1,24 @@
+/* raise.c -- raise a signal for current process.
+ *
+ * Copyright (c) 1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "glue.h"
+
+extern int _kill (int, int);
+extern int _getpid(void);
+
+int
+_raise (int sig)
+{
+  return _kill (_getpid (), sig);
+}
diff --git a/libgloss/pru/sbrk.c b/libgloss/pru/sbrk.c
new file mode 100644
index 000000000..f14e4ec34
--- /dev/null
+++ b/libgloss/pru/sbrk.c
@@ -0,0 +1,46 @@
+/* sbrk.c -- allocate memory dynamically.
+ * 
+ * Copyright (c) 1995,1996,1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "glue.h"
+
+extern char _heap_start[];
+extern void exit (int) __attribute ((__noreturn__));
+extern int _write (int, char *, int);
+
+caddr_t
+_sbrk (size_t incr)
+{
+  static char *heap_end;
+  char *prev_heap_end;
+  char *sp = (char *)&sp;
+
+  if (heap_end == 0)
+    {
+      heap_end = _heap_start;
+    }
+  prev_heap_end = heap_end;
+  if (heap_end > sp)
+    {
+      _write (1, "Heap and stack collision\n", 25);
+#if 0 /* Calling abort brings in the signal handling code.  */
+      abort ();
+#else
+      exit (1);
+#endif
+    }
+  heap_end += incr;
+  return (caddr_t) prev_heap_end;
+}
diff --git a/libgloss/pru/stat.c b/libgloss/pru/stat.c
new file mode 100644
index 000000000..64cb27253
--- /dev/null
+++ b/libgloss/pru/stat.c
@@ -0,0 +1,31 @@
+/* stat.c -- Get the status of a file.
+ *
+ * Copyright (c) 1995, 1999 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <sys/stat.h>
+#include <errno.h>
+#include "glue.h"
+
+#undef errno
+extern int errno;
+
+/*
+ * stat -- Since we have no file system, we just return an error.
+ */
+int
+_stat (const char *path, struct stat *buf)
+{
+  errno = EIO;
+  return (-1);
+}
+
diff --git a/libgloss/pru/syscalls.S b/libgloss/pru/syscalls.S
new file mode 100644
index 000000000..153ab1708
--- /dev/null
+++ b/libgloss/pru/syscalls.S
@@ -0,0 +1,65 @@
+/* syscalls.S -- PRU system calls code
+ *
+ * Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "newlib.h"
+
+#include "syscall.h"
+
+	.extern _impure_ptr
+
+	/* Handle return from syscall.  */
+	.global	__SC_ret
+	.type	__SC_ret,@function
+	.func
+__SC_ret:
+	/* Check for negative return code */
+	qbbc	__SC_ret_skip_errno_set, r14, 31
+
+	/* Invert return code and store to errno (first int in _impure_ptr).  */
+	rsb	r14, r14, 0
+	ldi32	r1, _impure_ptr
+	sbbo	r14, r1, 0, 4
+	/* Return -1 (for both int32_t or int64_t).  */
+	fill	r14, 8
+
+__SC_ret_skip_errno_set:
+	ret
+	.endfunc
+
+.macro	SC	fname, id
+	.global	\fname
+	.type	\fname,@function
+	.func
+\fname:
+	ldi	r1, \id
+	halt
+	jmp	__SC_ret
+	.endfunc
+.endm
+
+	.text
+
+	/* Syscalls are used only by simulator.  Real HW
+	   users use other methods for communicating with
+	   the host - remoteproc, rpmsg, shared memory.  */
+	SC	_exit, SYS_exit
+	SC	_open, SYS_open
+	SC	_close, SYS_close
+	SC	_read, SYS_read
+	SC	_write, SYS_write
+	SC	_lseek, SYS_lseek
+	SC	_unlink, SYS_unlink
+	SC	_getpid, SYS_getpid
+	SC	_kill, SYS_kill
+	SC	_fstat, SYS_fstat
diff --git a/newlib/configure.host b/newlib/configure.host
index 87bf78a3a..6a6066bb2 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -85,7 +85,7 @@ case "${target_optspace}:${host}" in
   yes:*)
     newlib_cflags="${newlib_cflags} -Os"
     ;;
-  :m32r-* | :d10v-* | :d30v-* | :avr-* | :m32c-* | :msp430*-* | :nds32* | :rl78-* )
+  :m32r-* | :d10v-* | :d30v-* | :avr-* | :m32c-* | :msp430*-* | :nds32* | :pru-* | :rl78-* )
     newlib_cflags="${newlib_cflags} -Os"
     ;;
   no:* | :*)
@@ -289,6 +289,14 @@ case "${host_cpu}" in
   powerpc*)
 	machine_dir=powerpc
 	;;
+  pru*)
+	newlib_cflags="${newlib_cflags} -DPREFER_SIZE_OVER_SPEED"
+	newlib_cflags="${newlib_cflags} -DNO_EXEC"
+	newlib_cflags="${newlib_cflags} -DSMALL_MEMORY"
+	default_newlib_nano_malloc="yes"
+	default_newlib_atexit_dynamic_alloc="no"
+	machine_dir=pru
+	;;
   riscv*)
 	libm_machine_dir=riscv
 	machine_dir=riscv
@@ -854,6 +862,10 @@ newlib_cflags="${newlib_cflags} -DCLOCK_PROVIDED -DMALLOC_PROVIDED -DEXIT_PROVID
 	newlib_cflags="${newlib_cflags} -DHAVE_OPENDIR -DHAVE_RENAME -DHAVE_FCNTL -D_NO_POSIX_SPAWN"
 	syscall_dir=syscalls
 	;;
+  pru*)
+	syscall_dir=syscalls
+	newlib_cflags="${newlib_cflags} -DSMALL_MEMORY -D_REENT_SMALL"
+	;;
   riscv*-*-*)
 	syscall_dir=syscalls
 	;;
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index 911eeb51e..536ac11fc 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -409,6 +409,10 @@
 #define __SMALL_BITFIELDS	/* 16 Bit INT */
 #endif
 
+#ifdef __PRU__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
 #ifdef __RL78__
 #define __IEEE_LITTLE_ENDIAN
 #define __SMALL_BITFIELDS	/* 16 Bit INT */
diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h
index 6b37bcce4..25fdea28c 100644
--- a/newlib/libc/include/machine/setjmp.h
+++ b/newlib/libc/include/machine/setjmp.h
@@ -352,6 +352,11 @@ _BEGIN_STD_C
 #define _JBTYPE unsigned long
 #endif
 
+#ifdef __PRU__
+#define _JBLEN 48
+#define _JBTYPE unsigned int
+#endif
+
 #ifdef __RX__
 #define _JBLEN 0x44
 #endif
diff --git a/newlib/libc/machine/configure.in b/newlib/libc/machine/configure.in
index 0d4068c13..a070b5838 100644
--- a/newlib/libc/machine/configure.in
+++ b/newlib/libc/machine/configure.in
@@ -65,6 +65,7 @@ if test -n "${machine_dir}"; then
 	nvptx) AC_CONFIG_SUBDIRS(nvptx) ;;
 	or1k) AC_CONFIG_SUBDIRS(or1k) ;;
 	powerpc) AC_CONFIG_SUBDIRS(powerpc) ;;
+	pru) AC_CONFIG_SUBDIRS(pru) ;;
 	rl78) AC_CONFIG_SUBDIRS(rl78) ;;
 	rx) AC_CONFIG_SUBDIRS(rx) ;;
 	sh) AC_CONFIG_SUBDIRS(sh) ;;
diff --git a/newlib/libc/machine/pru/Makefile.am b/newlib/libc/machine/pru/Makefile.am
new file mode 100644
index 000000000..60885128d
--- /dev/null
+++ b/newlib/libc/machine/pru/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
+
+AM_CCASFLAGS = $(INCLUDES)
+
+noinst_LIBRARIES = lib.a
+
+lib_a_SOURCES = setjmp.s
+lib_a_CCASFLAGS=$(AM_CCASFLAGS)
+lib_a_CFLAGS=$(AM_CFLAGS)
+
+ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
+CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
diff --git a/newlib/libc/machine/pru/configure.in b/newlib/libc/machine/pru/configure.in
new file mode 100644
index 000000000..d6eea0e9c
--- /dev/null
+++ b/newlib/libc/machine/pru/configure.in
@@ -0,0 +1,14 @@
+dnl This is the newlib/libc/machine/pru configure.in file.
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([newlib],[NEWLIB_VERSION])
+AC_CONFIG_SRCDIR([setjmp.s])
+
+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake.
+AC_CONFIG_AUX_DIR(../../../..)
+
+NEWLIB_CONFIGURE(../../..)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/newlib/libc/machine/pru/setjmp.s b/newlib/libc/machine/pru/setjmp.s
new file mode 100644
index 000000000..46d950be6
--- /dev/null
+++ b/newlib/libc/machine/pru/setjmp.s
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014-2019 Dimitar Dimitrov <dimitar@dinux.eu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+	.section	.text
+	.align	3
+	.globl	setjmp
+	.type	setjmp,@function
+	.globl	longjmp
+	.type	longjmp,@function
+
+
+setjmp:
+	sbbo	r2, r14, 0, 4*12	/* SP, RA, FP, r5-r13 */
+	ldi	r14, 0
+	ret
+
+longjmp:
+	lbbo	r2, r14, 0, 4*12	/* SP, RA, FP, r5-r13 */
+	mov	r14, r15		/* copy second arg to return location */
+	qbne	1f, r14, 0		/* per stdC, we cannot return 0 */
+	ldi	r14, 1
+1:
+	ret
-- 
2.20.1



More information about the Newlib mailing list