This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
[PATCH 2/4] Add support for ARC to libgloss
- From: Anton Kolesov <Anton dot Kolesov at synopsys dot com>
- To: newlib at sourceware dot org
- Cc: Anton Kolesov <Anton dot Kolesov at synopsys dot com>
- Date: Fri, 30 Oct 2015 22:39:43 +0300
- Subject: [PATCH 2/4] Add support for ARC to libgloss
- Authentication-results: sourceware.org; auth=none
- References: <1446233985-12024-1-git-send-email-Anton dot Kolesov at synopsys dot com>
Only a proprietary ARC nSIM simulator is supported in this patch, free version
of nSIM can be downloaded from
https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi
Same libgloss library is also compatible with a version of CGEN simulator found
on Synopsys ARC GitHub, but this simulator supports only older ARC 600 and 700
cores.
ChangeLog:
2015-10-30 Anton Kolesov <Anton.Kolesov@synopsys.com>
* configure.in: Add ARC support to libgloss.
* configure: Regenerate.
libgloss/ChangeLog:
2015-10-30 Anton Kolesov <Anton.Kolesov@synopsys.com>
* configure: Add ARC support.
* configure.in: Likewise.
* arc/Makefile.in: Likewise.
* arc/aclocal.m4: Likewise.
* arc/configure: Likewise.
* arc/configure.in: Likewise.
* arc/crt0.S: Likewise.
* arc/libcfunc.c: Likewise.
* arc/nsim-syscall.h: Likewise.
* arc/nsim-syscalls.c: Likewise.
* arc/nsim.specs: Likewise.
* arc/sbrk.c: Likewise.
---
configure | 3 -
configure.ac | 3 -
libgloss/arc/Makefile.in | 113 ++
libgloss/arc/aclocal.m4 | 404 +++++
libgloss/arc/configure | 3872 ++++++++++++++++++++++++++++++++++++++++++
libgloss/arc/configure.in | 55 +
libgloss/arc/crt0.S | 241 +++
libgloss/arc/libcfunc.c | 92 +
libgloss/arc/nsim-syscall.h | 457 +++++
libgloss/arc/nsim-syscalls.c | 235 +++
libgloss/arc/nsim.specs | 5 +
libgloss/arc/sbrk.c | 61 +
libgloss/configure | 10 +
libgloss/configure.in | 3 +
14 files changed, 5548 insertions(+), 6 deletions(-)
create mode 100644 libgloss/arc/Makefile.in
create mode 100644 libgloss/arc/aclocal.m4
create mode 100755 libgloss/arc/configure
create mode 100644 libgloss/arc/configure.in
create mode 100644 libgloss/arc/crt0.S
create mode 100644 libgloss/arc/libcfunc.c
create mode 100644 libgloss/arc/nsim-syscall.h
create mode 100644 libgloss/arc/nsim-syscalls.c
create mode 100644 libgloss/arc/nsim.specs
create mode 100644 libgloss/arc/sbrk.c
diff --git a/configure b/configure
index ae23ce4..79b9336 100755
diff --git a/configure.ac b/configure.ac
index 80313d0..2873bdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -956,9 +956,6 @@ case "${target}" in
sh*-*-pe|mips*-*-pe|*arm-wince-pe)
noconfigdirs="$noconfigdirs tcl tk itcl libgui sim"
;;
- arc-*-*|arceb-*-*)
- noconfigdirs="$noconfigdirs target-libgloss"
- ;;
arm-*-pe*)
noconfigdirs="$noconfigdirs target-libgloss"
;;
diff --git a/libgloss/arc/Makefile.in b/libgloss/arc/Makefile.in
new file mode 100644
index 0000000..ab8ad6d
--- /dev/null
+++ b/libgloss/arc/Makefile.in
@@ -0,0 +1,113 @@
+#
+#
+DESTDIR =
+VPATH = @srcdir@ @srcdir@/..
+srcdir = @srcdir@
+objdir = .
+srcroot = $(srcdir)/../..
+objroot = $(objdir)/../..
+mkinstalldirs = $(SHELL) $(srcroot)/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(exec_prefix)/$(target_alias)
+
+objtype = @objtype@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# Multilib support variables.
+# TOP is used instead of MULTI{BUILD,SRC}TOP.
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+SHELL = /bin/sh
+
+CC = @CC@
+
+AS = @AS@
+AR = @AR@
+LD = @LD@
+RANLIB = @RANLIB@
+
+OBJDUMP = `if [ -f ${objroot}/../binutils/objdump ] ; \
+ then echo ${objroot}/../binutils/objdump ; \
+ else t='$(program_transform_name)'; echo objdump | sed -e $$t ; fi`
+OBJCOPY = `if [ -f ${objroot}/../binutils/objcopy ] ; \
+ then echo ${objroot}/../binutils/objcopy ; \
+ else t='$(program_transform_name)'; echo objcopy | sed -e $$t ; fi`
+
+CRT0 = crt0.o
+CRT0_INSTALL = install-crt0
+
+NSIM_BSP = libnsim.a
+NSIM_OBJS = \
+ libcfunc.o \
+ nsim-syscalls.o \
+ sbrk.o
+NSIM_INSTALL = install-nsim
+NSIM_SCRIPTS = nsim.specs
+
+CFLAGS = -g
+
+# Host specific makefile fragment comes in here.
+@host_makefile_frag@
+
+all: $(CRT0) $(NSIM_BSP)
+
+$(NSIM_BSP): $(NSIM_OBJS)
+ $(AR) $(ARFLAGS) $@ $?
+ $(RANLIB) $@
+
+libcfunc.o: libcfunc.c
+nsim-syscalls.o: nsim-syscalls.c
+sbrk.o: sbrk.c
+
+#
+$(CRT0): crt0.S
+
+clean mostlyclean:
+ rm -f *.o *.a
+
+distclean maintainer-clean realclean: clean
+ rm -f Makefile config.status config.log config.cache *~
+
+.PHONY: install info install-info clean-info doc dvi
+install: $(CRT0_INSTALL) $(NSIM_INSTALL)
+
+# multilibdir may not exist yet - libgcc for ARC depends on libc, hence
+# newlib/libgloss is built before libgcc. And in parallel build libgloss maybe
+# built and installed before newlib, therefore libgloss has to create target
+# directory.
+
+$(CRT0_INSTALL):
+ $(mkinstalldirs) $(DESTDIR)${tooldir}/lib${MULTISUBDIR}
+ ${INSTALL_DATA} ${CRT0} $(DESTDIR)${tooldir}/lib${MULTISUBDIR}/$(CRT0)
+
+$(NSIM_INSTALL):
+ $(mkinstalldirs) $(DESTDIR)${tooldir}/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(NSIM_BSP) $(DESTDIR)$(tooldir)/lib$(MULTISUBDIR)/$(NSIM_BSP)
+ for x in $(NSIM_SCRIPTS); do \
+ $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(tooldir)/lib$(MULTISUBDIR)/$$x; done
+
+doc:
+info:
+dvi:
+install-info:
+clean-info:
+
+Makefile: Makefile.in config.status @host_makefile_frag_path@
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
diff --git a/libgloss/arc/aclocal.m4 b/libgloss/arc/aclocal.m4
new file mode 100644
index 0000000..2349523
diff --git a/libgloss/arc/configure b/libgloss/arc/configure
new file mode 100755
index 0000000..2e8a7ed
diff --git a/libgloss/arc/configure.in b/libgloss/arc/configure.in
new file mode 100644
index 0000000..04169f1
--- /dev/null
+++ b/libgloss/arc/configure.in
@@ -0,0 +1,55 @@
+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/arc/crt0.S b/libgloss/arc/crt0.S
new file mode 100644
index 0000000..e4a15eb
--- /dev/null
+++ b/libgloss/arc/crt0.S
@@ -0,0 +1,241 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. 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.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ 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.
+*/
+
+/*
+ The startup code for the ARC family of processors does the following before
+ transferring control to user defined main label:
+ 1. Set sp to __stack_top (link time variable)
+ 2. Set fp to zero
+ 3. Zero out the bss section (for uninitialized globals)
+ After returning from main, the processor is halted and the pipeline is
+ flushed out.
+
+ We expect argc in r0 and argv in r1. These are saved in r13 / r14 during
+ the initialization code.
+*/
+
+ .file "crt0.S"
+ .extern main
+
+#if defined (__EM__) || defined (__HS__)
+ .section .ivt, "a", @progbits
+
+; handler's name, type, number,name, offset in IVT (hex/dec)
+.word __start ; exception 0 program entry point 0x0 0
+.word memory_error ; exception 1 memory_error 0x4 4
+.word instruction_error ; exception 2 instruction_error 0x8 8
+.word EV_MachineCheck ; exception 3 EV_MachineCheck 0xC 12
+.word EV_TLBMissI ; exception 4 EV_TLBMissI 0x10 16
+.word EV_TLBMissD ; exception 5 EV_TLBMissD 0x14 20
+.word EV_ProtV ; exception 6 EV_ProtV 0x18 24
+.word EV_PrivilegeV ; exception 7 EV_PrivilegeV 0x1C 28
+.word EV_SWI ; exception 8 EV_SWI 0x20 32
+.word EV_Trap ; exception 9 EV_Trap 0x24 36
+.word EV_Extension ; exception 10 EV_Extension 0x28 40
+.word EV_DivZero ; exception 11 EV_DivZero 0x2C 44
+.word EV_DCError ; exception 12 EV_DCError 0x30 48
+.word EV_Malignedr ; exception 13 EV_Maligned 0x34 52
+.word _exit_halt ; exception 14 unused 0x38 56
+.word _exit_halt ; exception 15 unused 0x3C 60
+.word IRQ_Timer0 ; IRQ 16 Timer 0 0x40 64
+.word IRQ_Timer1 ; IRQ 17 Timer 1 0x44 68
+.word IRQ_18 ; IRQ 18 0x48 72
+.word IRQ_19 ; IRQ 19 0x4C 76
+.word IRQ_20 ; IRQ 20 0x50 80
+
+
+ .section .text.__startup, "ax", @progbits
+#else
+ .text
+#endif
+
+ .global __start
+ .type __start, @function
+
+#ifdef __ARC601__
+; Startup code for the ARC601 processor
+__start:
+ mov gp, @__SDATA_BEGIN__
+ mov sp, @__stack_top ; Point to top of stack
+ mov r5, 0 ; Zero value
+ mov_s r2, @__sbss_start ; r2 = start of the bss section
+ sub r3, @_end, r2 ; r3 = size of the bss section in bytes
+
+ asr_s r3, r3
+ asr_s r3, r3 ; r3 = size of bss in words
+
+.Lbss_loop:
+ cmp r3, 0xff ; Check for max lp_count
+ mov.le lp_count, r3
+ mov.gt lp_count, 0xff
+ lpnz 2f ; Loop to zero bss
+ st.ab r5,[r2, 4] ; Write word of zeros
+ nop
+2:
+ sub.f r3, r3, 0xff ; Decrement word count
+ jp .Lbss_loop
+
+#else /* __ARC601__ */
+
+; Startup code for the ARC600, ARC700 and ARCv2 processors
+; NOTE: The following restrictions apply on zero overhead loops (other
+; restrictions are not pertinent to this code)
+; - loop end should be 4 instruction words away from the lp_count setting
+; instruction
+; - loop body should have at least two instruction words
+__start:
+#if defined (__HS__)
+ ; Allow unaligned accesses.
+ lr r2, [0xA]
+ bset r2, r2, 19
+ flag r2
+#endif
+ mov gp, @__SDATA_BEGIN__
+ mov_s r2, @__sbss_start ; r2 = start of the bss section
+ sub r3, @_end, r2 ; r3 = size of the bss section in bytes
+ ; set up the loop counter register to the size (in words) of the bss section
+ asr.f lp_count, r3, 2
+#if defined (__ARC600__)
+ ; loop to zero out the bss. Enter loop only if lp_count != 0
+ lpnz @.Lend_zbss
+ add r3, pcl, 20
+ sr r3, [2] ; LP_END
+ ; initialize stack pointer, and this instruction has 2 words
+ mov sp, @__stack_top
+ mov_s r3, 0
+ st.ab r3, [r2, 4] ; zero out the word
+.Lend_zbss:
+#else
+ mov sp, @__stack_top ; initialize stack pointer
+ mov_s r3,0
+ ; loop to zero out the bss. Enter loop only if lp_count != 0
+ lpnz @.Lend_zbss
+ st.ab r3,[r2, 4] ; zero out the word
+ nop
+.Lend_zbss:
+#endif
+
+#endif /* !__ARC601__ */
+
+; Some targets use the .init and .fini sections to create constructors and
+; destructors, and for these targets we need to call the _init function and
+; arrange for _fini to be called at program exit.
+ mov_s r13, r0
+ mov_s r14, r1
+ ; calling atexit drags in malloc, so instead poke the function
+ ; address directly into the reent structure
+ ld r1, [gp, @_impure_ptr@sda]
+ mov_s r0, @_fini
+ add r1, r1, 0x14c ; &_GLOBAL_REENT->atexit0
+ st r1, [r1, -4] ; _GLOBAL_REENT->atexit
+ st_s r0, [r1, 8] ; _GLOBAL_REENT->atexit0._fns[0]
+ mov_s r0, 1
+ st_s r0, [r1, 4] ; _GLOBAL_REENT->atexit0._ind
+; branch to _init
+#if defined (__EM__) || defined (__HS__)
+ jl @_init
+#else
+ bl @_init
+#endif
+ mov_s r0, r13
+ mov_s r1, r14
+; branch to main
+#if defined (__EM__) || defined (__HS__)
+ mov fp,0 ; initialize frame pointer
+ jl @main
+#else
+ bl.d @main
+ mov fp, 0 ; initialize frame pointer
+#endif
+ ; r0 contains exit code
+ j @exit
+
+#if defined (__EM__) || defined (__HS__)
+; ARCv2 default interrupt routines, defined as weak symbols.
+; Default implementation halts the core. To conserve code size those symbols
+; share a single implementation, however as a downside debugger and
+; disassembler will not be able to distinguish one from another.
+.weak memory_error
+.weak instruction_error
+.weak EV_MachineCheck
+.weak EV_TLBMissI
+.weak EV_TLBMissD
+.weak EV_ProtV
+.weak EV_PrivilegeV
+.weak EV_SWI
+.weak EV_Trap
+.weak EV_Extension
+.weak EV_DivZero
+.weak EV_DCError
+.weak EV_Malignedr
+.weak IRQ_Timer0
+.weak IRQ_Timer1
+.weak IRQ_18
+.weak IRQ_19
+.weak IRQ_20
+
+.balign 4
+memory_error :
+instruction_error :
+EV_MachineCheck :
+EV_TLBMissI :
+EV_TLBMissD :
+EV_ProtV :
+EV_PrivilegeV :
+EV_SWI :
+EV_Trap :
+EV_Extension :
+EV_DivZero :
+EV_DCError :
+EV_Malignedr :
+IRQ_Timer0 :
+IRQ_Timer1 :
+IRQ_18 :
+IRQ_19 :
+IRQ_20 :
+.Lloop_halt:
+ flag 0x01
+ nop
+ b .Lloop_halt
+ nop
+#endif
+
+ .section .text._exit_halt,"ax",@progbits
+ .global _exit_halt
+ .type _exit_halt, @function
+
+_exit_halt:
+ ; r0 contains exit code
+ flag 0x01
+ nop
+ nop ; ARCompact requires 3 nops after flag 1
+ nop
+ b @_exit_halt
+ nop
diff --git a/libgloss/arc/libcfunc.c b/libgloss/arc/libcfunc.c
new file mode 100644
index 0000000..c6e64f2
--- /dev/null
+++ b/libgloss/arc/libcfunc.c
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. 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.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ 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.
+*/
+
+/* This file has been copied from libgloss/arm/libcfuncs.c.
+
+ Support files for GNU libc. Files in the C namespace go here.
+ Files in the system namespace (ie those that start with an underscore)
+ go in syscalls.c.
+
+ Note: These functions are in a seperate file so that OS providers can
+ overrride the system call stubs (defined in syscalls.c) without having
+ to provide libc functions as well. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+unsigned __attribute__((weak))
+alarm (unsigned seconds)
+{
+ (void)seconds;
+ return 0;
+}
+
+clock_t _clock (void);
+clock_t __attribute__((weak))
+clock (void)
+{
+ return _clock ();
+}
+
+int _isatty (int fildes);
+int __attribute__((weak))
+isatty (int fildes)
+{
+ return _isatty (fildes);
+}
+
+int __attribute__((weak))
+pause (void)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+unsigned __attribute__((weak))
+sleep (unsigned seconds)
+{
+ clock_t t0 = _clock ();
+ clock_t dt = seconds * CLOCKS_PER_SEC;
+
+ while (_clock () - t0 < dt);
+ return 0;
+}
+
+int __attribute__((weak))
+usleep (useconds_t useconds)
+{
+ clock_t t0 = _clock ();
+ clock_t dt = useconds / (1000000/CLOCKS_PER_SEC);
+
+ while (_clock () - t0 < dt);
+ return 0;
+}
diff --git a/libgloss/arc/nsim-syscall.h b/libgloss/arc/nsim-syscall.h
new file mode 100644
index 0000000..a2009f5
--- /dev/null
+++ b/libgloss/arc/nsim-syscall.h
@@ -0,0 +1,457 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. 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.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ 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.
+*/
+
+#ifndef _ASM_ARC_UNISTD_H
+#define _ASM_ARC_UNISTD_H
+
+#include <stdint.h>
+
+#ifndef __ASSEMBLY__
+/* This file contains the system call numbers. Not all are implemented in nSIM
+ hostlink. Numbers correspond to the old ARCLinux syscalls, but during
+ upstreaming of ARC Linux, those numbers has been changed, hence today ARC
+ Linux and nSIM hostlink use different system call numbers. */
+
+#define SYS_exit 1
+#define SYS__exit SYS_exit
+#define SYS_fork 2
+#define SYS_read 3
+#define SYS_write 4
+#define SYS_open 5
+#define SYS_close 6
+#define SYS_waitpid 7
+#define SYS_creat 8
+#define SYS_link 9
+#define SYS_unlink 10
+#define SYS_execve 11
+#define SYS_chdir 12
+#define SYS_time 13
+#define SYS_mknod 14
+#define SYS_chmod 15
+#define SYS_chown 16
+#define SYS_break 17
+#define SYS_oldstat 18
+#define SYS_lseek 19
+#define SYS_getpid 20
+#define SYS_mount 21
+#define SYS_umount 22
+#define SYS_setuid 23
+#define SYS_getuid 24
+#define SYS_stime 25
+#define SYS_ptrace 26
+#define SYS_alarm 27
+#define SYS_oldfstat 28
+#define SYS_pause 29
+#define SYS_utime 30
+#define SYS_stty 31
+#define SYS_gtty 32
+#define SYS_access 33
+#define SYS_nice 34
+#define SYS_ftime 35
+#define SYS_sync 36
+#define SYS_kill 37
+#define SYS_rename 38
+#define SYS_mkdir 39
+#define SYS_rmdir 40
+#define SYS_dup 41
+#define SYS_pipe 42
+#define SYS_times 43
+#define SYS_prof 44
+#define SYS_brk 45
+#define SYS_setgid 46
+#define SYS_getgid 47
+#define SYS_signal 48
+#define SYS_geteuid 49
+#define SYS_getegid 50
+#define SYS_acct 51
+#define SYS_umount2 52
+#define SYS_lock 53
+#define SYS_ioctl 54
+#define SYS_fcntl 55
+#define SYS_mpx 56
+#define SYS_setpgid 57
+#define SYS_ulimit 58
+#define SYS_oldolduname 59
+#define SYS_umask 60
+#define SYS_chroot 61
+#define SYS_ustat 62
+#define SYS_dup2 63
+#define SYS_getppid 64
+#define SYS_getpgrp 65
+#define SYS_setsid 66
+#define SYS_sigaction 67
+#define SYS_sgetmask 68
+#define SYS_ssetmask 69
+#define SYS_setreuid 70
+#define SYS_setregid 71
+#define SYS_sigsuspend 72
+#define SYS_sigpending 73
+#define SYS_sethostname 74
+#define SYS_setrlimit 75
+#define SYS_old_getrlimit 76
+#define SYS_getrusage 77
+#define SYS_gettimeofday 78
+#define SYS_settimeofday 79
+#define SYS_getgroups 80
+#define SYS_setgroups 81
+#define SYS_select 82
+#define SYS_symlink 83
+#define SYS_oldlstat 84
+#define SYS_readlink 85
+#define SYS_uselib 86
+#define SYS_swapon 87
+#define SYS_reboot 88
+#define SYS_readdir 89
+#define SYS_mmap 90
+#define SYS_munmap 91
+#define SYS_truncate 92
+#define SYS_ftruncate 93
+#define SYS_fchmod 94
+#define SYS_fchown 95
+#define SYS_getpriority 96
+#define SYS_setpriority 97
+#define SYS_profil 98
+#define SYS_statfs 99
+#define SYS_fstatfs 100
+#define SYS_ioperm 101
+#define SYS_socketcall 102
+#define SYS_syslog 103
+#define SYS_setitimer 104
+#define SYS_getitimer 105
+#define SYS_stat 106
+#define SYS_lstat 107
+#define SYS_fstat 108
+#define SYS_olduname 109
+#define SYS_iopl 110 /* not supported */
+#define SYS_vhangup 111
+#define SYS_idle 112 /* Obsolete */
+#define SYS_vm86 113 /* not supported */
+#define SYS_wait4 114
+#define SYS_swapoff 115
+#define SYS_sysinfo 116
+#define SYS_ipc 117
+#define SYS_fsync 118
+#define SYS_sigreturn 119
+#define SYS_clone 120
+#define SYS_setdomainname 121
+#define SYS_uname 122
+#define SYS_cacheflush 123
+#define SYS_adjtimex 124
+#define SYS_mprotect 125
+#define SYS_sigprocmask 126
+#define SYS_create_module 127
+#define SYS_init_module 128
+#define SYS_delete_module 129
+#define SYS_get_kernel_syms 130
+#define SYS_quotactl 131
+#define SYS_getpgid 132
+#define SYS_fchdir 133
+#define SYS_bdflush 134
+#define SYS_sysfs 135
+#define SYS_personality 136
+#define SYS_afs_syscall 137 /* Syscall for Andrew File System */
+#define SYS_setfsuid 138
+#define SYS_setfsgid 139
+#define SYS__llseek 140
+#define SYS_getdents 141
+#define SYS__newselect 142
+#define SYS_flock 143
+#define SYS_msync 144
+#define SYS_readv 145
+#define SYS_writev 146
+#define SYS_getsid 147
+#define SYS_fdatasync 148
+#define SYS__sysctl 149
+#define SYS_mlock 150
+#define SYS_munlock 151
+#define SYS_mlockall 152
+#define SYS_munlockall 153
+#define SYS_sched_setparam 154
+#define SYS_sched_getparam 155
+#define SYS_sched_setscheduler 156
+#define SYS_sched_getscheduler 157
+#define SYS_sched_yield 158
+#define SYS_sched_get_priority_max 159
+#define SYS_sched_get_priority_min 160
+#define SYS_sched_rr_get_interval 161
+#define SYS_nanosleep 162
+#define SYS_mremap 163
+#define SYS_setresuid 164
+#define SYS_getresuid 165
+#define SYS_query_module 167
+#define SYS_poll 168
+#define SYS_nfsservctl 169
+#define SYS_setresgid 170
+#define SYS_getresgid 171
+#define SYS_prctl 172
+#define SYS_rt_sigreturn 173
+#define SYS_rt_sigaction 174
+#define SYS_rt_sigprocmask 175
+#define SYS_rt_sigpending 176
+#define SYS_rt_sigtimedwait 177
+#define SYS_rt_sigqueueinfo 178
+#define SYS_rt_sigsuspend 179
+#define SYS_pread 180
+#define SYS_pwrite 181
+#define SYS_lchown 182
+#define SYS_getcwd 183
+#define SYS_capget 184
+#define SYS_capset 185
+#define SYS_sigaltstack 186
+#define SYS_sendfile 187
+#define SYS_getpmsg 188 /* some people actually want streams */
+#define SYS_putpmsg 189 /* some people actually want streams */
+#define SYS_vfork 190
+#define SYS_getrlimit 191
+#define SYS_mmap2 192
+#define SYS_truncate64 193
+#define SYS_ftruncate64 194
+#define SYS_stat64 195
+#define SYS_lstat64 196
+#define SYS_fstat64 197
+#define SYS_chown32 198
+#define SYS_getuid32 199
+#define SYS_getgid32 200
+#define SYS_geteuid32 201
+#define SYS_getegid32 202
+#define SYS_setreuid32 203
+#define SYS_setregid32 204
+#define SYS_getgroups32 205
+#define SYS_setgroups32 206
+#define SYS_fchown32 207
+#define SYS_setresuid32 208
+#define SYS_getresuid32 209
+#define SYS_setresgid32 210
+#define SYS_getresgid32 211
+#define SYS_lchown32 212
+#define SYS_setuid32 213
+#define SYS_setgid32 214
+#define SYS_setfsuid32 215
+#define SYS_setfsgid32 216
+#define SYS_pivot_root 217
+#define SYS_getdents64 220
+#define SYS_fcntl64 221
+#define SYS_gettid 224
+
+#endif /* ! __ASSEMBLY__ */
+
+#ifdef __ARC700__
+#define SYSCALL \
+ "trap0 \n\t"
+#else
+#define SYSCALL \
+ "swi \n\t"\
+ "nop \n\t"\
+ "nop \n\t"
+#endif /* __ARC700__ */
+
+/* There are two variants of macroses here:
+ - _syscall is a complete function definition of system call
+ - _naked_syscall only invokes system call and can be inserted into other
+ functions. This macro is defined only for those syscall<N>, where it is
+ actually used. */
+
+#define _syscall0(type, name) \
+type _##name () \
+{ \
+ long __res; \
+ __asm__ __volatile__ ("mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name) \
+ : "cc", "r0", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ } \
+ return (type)__res; \
+}
+
+#define _syscall1(type, name, atype, a) \
+type _##name (atype a) \
+{ \
+ long __res; \
+ __asm__ __volatile__ ("mov r0, %2\n\t" \
+ "mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name), \
+ "r" ((long)a) \
+ : "cc", "r0", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ } \
+ return (type)__res; \
+}
+
+#define _naked_syscall2(__res, name, a, b) \
+ __asm__ __volatile__ ("mov r1, %3\n\t" \
+ "mov r0, %2\n\t" \
+ "mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name), \
+ "r" ((long)a), \
+ "r" ((long)b) \
+ : "cc", "r0", "r1", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ }
+
+#define _syscall2(type, name, atype, a, btype, b) \
+type _##name (atype a, btype b) \
+{ \
+ long __res; \
+ _naked_syscall2 (__res, name, a, b) \
+ return (type)__res; \
+}
+
+#define _naked_syscall3(__res, name, a, b, c) \
+ __asm__ __volatile__ ( \
+ "mov r2, %4\n\t" \
+ "mov r1, %3\n\t" \
+ "mov r0, %2\n\t" \
+ "mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name), \
+ "r" ((long)a), \
+ "r" ((long)b), \
+ "r" ((long)c) \
+ : "cc", "r0", "r1", "r2", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ }
+
+#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
+type _##name (atype a, btype b, ctype c) \
+{ \
+ long __res; \
+ _naked_syscall3 (__res, name, a, b, c) \
+ return (type)__res; \
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \
+type _##name (atype a, btype b, ctype c, dtype d) \
+{ \
+ long __res; \
+ __asm__ __volatile__ ( \
+ "mov r3, %5\n\t" \
+ "mov r2, %4\n\t" \
+ "mov r1, %3\n\t" \
+ "mov r0, %2\n\t" \
+ "mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name), \
+ "r" ((long)a), \
+ "r" ((long)b), \
+ "r" ((long)c), \
+ "r" ((long)d) \
+ : "cc", "r0", "r1", "r2", "r3", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ } \
+ return (type)__res; \
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, \
+ etype, e) \
+type _##name (atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+ long __res; \
+ __asm__ __volatile__ ( \
+ "mov r4, %6\n\t" \
+ "mov r3, %5\n\t" \
+ "mov r2, %4\n\t" \
+ "mov r1, %3\n\t" \
+ "mov r0, %2\n\t" \
+ "mov r8, %1\n\t" \
+ SYSCALL \
+ "mov %0, r0" \
+ : "=r" (__res) \
+ : "i" (SYS_##name), \
+ "r" ((long)a), \
+ "r" ((long)b), \
+ "r" ((long)c), \
+ "r" ((long)d), \
+ "r" ((long)e) \
+ : "cc", "r0", "r1", "r2", "r3", "r4", "r8"); \
+ if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
+ errno = -__res; \
+ __res = -1; \
+ } \
+ return (type)__res; \
+}
+
+/* open() flags that are used by nSIM hostlink. See comment for _open()
+ implementation in nsim-syscalls.c. */
+#define ARC_LINUX_RDONLY 0
+#define ARC_LINUX_WRONLY 1
+#define ARC_LINUX_RDWR 2
+#define ARC_LINUX_CREAT 0x0040
+#define ARC_LINUX_APPEND 0x0400
+#define ARC_LINUX_TRUNC 0x0200
+#define ARC_LINUX_EXCL 0x0080
+
+/* stat structure as defined in nSIM hostlink. */
+struct nsim_stat {
+ uint16_t dev;
+ uint16_t __pad1;
+ uint32_t ino;
+ uint16_t mode;
+ uint16_t nlink;
+ uint16_t uid;
+ uint16_t gid;
+ uint16_t rdev;
+ uint16_t __pad2;
+ uint32_t size;
+ uint32_t blksize;
+ uint32_t blocks;
+ uint32_t atime;
+ uint32_t __unused1;
+ uint32_t mtime;
+ uint32_t __unused2;
+ uint32_t ctime;
+ uint32_t __unused3;
+ uint32_t __unused4;
+ uint32_t __unused5;
+};
+
+#endif /* _ASM_ARC_UNISTD_H */
diff --git a/libgloss/arc/nsim-syscalls.c b/libgloss/arc/nsim-syscalls.c
new file mode 100644
index 0000000..7dd0af1
--- /dev/null
+++ b/libgloss/arc/nsim-syscalls.c
@@ -0,0 +1,235 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. 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.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ 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.
+*/
+
+#include <_ansi.h>
+#include <_syslist.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include "glue.h"
+#include "nsim-syscall.h"
+
+/* Those system calls are implemented in both nSIM and CGEN. */
+_syscall3 (_ssize_t, read, int, fd, void *, buf, size_t, count)
+_syscall3 (_ssize_t, write, int, fd, const void *, buf, size_t, count)
+_syscall1 (int, unlink, const char *, pathname)
+_syscall3 (off_t, lseek, int, fd, off_t, offset, int, whence)
+_syscall2 (int, gettimeofday, struct timeval *, tv, void *, tz)
+_syscall1 (_CLOCK_T_, time, _CLOCK_T_ *, t)
+_syscall1 (int, close, int, fd)
+_syscall1 (_CLOCK_T_, times, struct tms *, buf)
+/* stat requires custom implementation. */
+/* _syscall2 (int, stat, const char *, path, struct stat *, st)
+ _syscall2 (int, fstat, int, file, struct stat *, st) */
+/* nSIM implements brk and sbrk, but instead sbrk.c is used. */
+/* _syscall1 (int, brk, void *, addr) */
+/* open requires custom implementation. */
+/* _syscall3 (int, open, const char *, pathname, int, flags, int, mode) */
+
+/* Those syscalls are not available in CGEN simulator. */
+_syscall1 (int, rmdir, const char *, pathname)
+_syscall2 (char *, getcwd, char *, buf, size_t, size)
+/* stat requires custom implementation. */
+/* _syscall2 (int, lstat, const char *, path, struct stat *, st) */
+
+/* Historically "open" flags defined by default in newlib and in Linux for ARC
+ are different - this is true for some other architectures as well, e.g.
+ ARM. To provide compatibility ARC port of newlib had a custom fcntl.h file
+ that has "open" flags identical to Linux ones. Some other architectures
+ (spart64, cris) override default fcntl.h as well, but I'm not sure this is
+ really a good idea. Unlike system call numbers that can be unique to each
+ BSP in libgloss, "open" flags are not abstracted from the application code
+ itself, hence it is not possible to have fcntl.h in the libgloss. To make
+ matters worse, existing simulators already has been built for the Linux-like
+ "open" flags. To preserve compatibility with existing hostlink
+ implementations in simulators, but avoid custom fcntl.h in the future,
+ simulator BSP has to do dynamic rewriting of "open" flags from the newlib
+ default into old ARC Linux flags. Simulators support only most basic flags,
+ therefore only those are translated in this implementation. */
+int
+_open (const char * pathname, int flags, int mode)
+{
+ int nsim_flags = 0;
+
+ /* RDONLY, WRONLY, RDWR are same as newlib default. */
+ nsim_flags |= flags & O_RDONLY;
+ nsim_flags |= flags & O_WRONLY;
+ nsim_flags |= flags & O_RDWR;
+ nsim_flags |= (flags & O_CREAT) ? ARC_LINUX_CREAT : 0;
+ nsim_flags |= (flags & O_APPEND) ? ARC_LINUX_APPEND : 0;
+ nsim_flags |= (flags & O_TRUNC) ? ARC_LINUX_TRUNC : 0;
+ nsim_flags |= (flags & O_EXCL) ? ARC_LINUX_EXCL : 0;
+ /* There are other fcntl flags that are different between newlib and ARC
+ uClibc, however they are not supported by nSIM hostlink, therefore there
+ is no need to translate them. */
+
+ long __res;
+ _naked_syscall3 (__res, open, pathname, nsim_flags, mode)
+ return __res;
+}
+
+/* Should be provided by crt0.S. */
+extern void __attribute__((noreturn)) _exit_halt ();
+
+void
+__attribute__((noreturn))
+_exit (int ret)
+{
+ /* Doing an "exit" system call would work on nSIM with hostlink, but call to
+ _exit_halt, which will do a CPU halt is more universal and will work in
+ many other cases as well, including an FPGA/SoC. */
+ _exit_halt ();
+}
+
+/* This is a copy of newlib/libc/posix/_isatty.c. It is needed because nSIM
+ hostlink doesn't implement isatty system call. Hardware boards on the other
+ hand would want isatty implementation that always returns 1, since they are
+ connected to console and doesn't have file IO. */
+int
+_isatty (int fd)
+{
+ struct stat buf;
+
+ if (fstat (fd, &buf) < 0)
+ {
+ errno = EBADF;
+ return 0;
+ }
+ if (S_ISCHR (buf.st_mode))
+ {
+ return 1;
+ }
+ errno = ENOTTY;
+ return 0;
+}
+
+/* System call "getpid" is implemented in nSIM hostlink, but it is better not
+ to expose it in libgloss. */
+int
+_getpid (void)
+{
+ return __MYPID;
+}
+
+/* System call "kill" is implemented in nSIM hostlink on Linux hosts, but it
+ seems dangerous to expose it. Instead, like most of the other "_kill"
+ implementations in libgloss, this will kill only self. */
+int
+_kill (int pid, int sig)
+{
+ if (pid == __MYPID)
+ {
+ _exit (sig);
+ }
+ errno = ENOSYS;
+ return -1;
+}
+
+static void
+translate_stat (struct nsim_stat *nsim, struct stat *buf)
+{
+ #define TR(field, type) buf->st_ ## field = (type) nsim->field
+ TR (dev, dev_t);
+ TR (ino, ino_t);
+ TR (mode, mode_t);
+ TR (nlink, nlink_t);
+ TR (uid, uid_t);
+ TR (gid, gid_t);
+ TR (rdev, dev_t);
+ TR (size, off_t);
+ TR (atime, time_t);
+ TR (mtime, time_t);
+ TR (ctime, time_t);
+ TR (blksize, long);
+ TR (blocks, long);
+ #undef TR
+}
+
+/* stat/fstat implementation. Situation is similiar to open and its flags -
+ structure is defined in libc, hence cannot be customized in libgloss, yet we
+ have a case where nSIM uses some definition which is not compatible with
+ neither old ARC-custom definition of "struct stat" in newlib, nor with
+ generic newlib implementation. */
+int
+_stat (const char * path, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, path, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+int
+_lstat (const char * path, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, path, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+int
+_fstat (int fd, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, fd, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+/* Some system calls are implemented in nSIM hostlink, but are available only
+ on Linux hosts. To minimize potential compatibility issues they are by
+ default disabled in libgloss build. */
+#ifdef ARC_NSIM_WIN32_HOST
+_syscall3 (int, ioctl, int, fd, int, request, char *, argp)
+_syscall3 (_ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
+_syscall3 (_ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
+_syscall5 (off_t, llseek, int, fd, unsigned long, offset_high,
+ unsigned long, offset_low, loff_t *, result,
+ unsigned int, whence)
+_syscall2 (int, getrusage, int, who, struct rusage *, usage)
+_syscall2 (int, setrlimit, int, resource, const struct rlimit *, rlim)
+_syscall2 (int, getrlimit, int, resource, struct rlimit *, rlim)
+_syscall3 (int, sigaction, int signum, const struct sigaction *, act,
+ struct sigaction *, oldact)
+_syscall0 (uid_t, getuid)
+_syscall0 (gid_t, getgid)
+_syscall0 (uid_t, geteuid)
+_syscall0 (gid_t, getegid)
+_syscall2 (int, kill, pid_t, pid, int, sig)
+_syscall3 (_ssize_t, readlink, const char *, path, char *, buf, size_t, bufsize)
+#endif
diff --git a/libgloss/arc/nsim.specs b/libgloss/arc/nsim.specs
new file mode 100644
index 0000000..aa77eea
--- /dev/null
+++ b/libgloss/arc/nsim.specs
@@ -0,0 +1,5 @@
+%rename link_gcc_c_sequence nsim_link_gcc_c_sequence
+
+*link_gcc_c_sequence:
+%(nsim_link_gcc_c_sequence) --start-group %G -lc -lnsim --end-group
+
diff --git a/libgloss/arc/sbrk.c b/libgloss/arc/sbrk.c
new file mode 100644
index 0000000..8cb8461
--- /dev/null
+++ b/libgloss/arc/sbrk.c
@@ -0,0 +1,61 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. 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.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ 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.
+*/
+
+#include <sys/types.h>
+#include <sys/errno.h>
+
+extern char __start_heap;
+extern char __end_heap;
+
+caddr_t
+_sbrk (size_t nbytes)
+{
+ static char* heap_ptr = NULL;
+ char* prev_heap_ptr;
+
+ if (heap_ptr == NULL)
+ {
+ heap_ptr = &__start_heap;
+ }
+
+ /* Align the 'heap_ptr' so that memory will always be allocated at word
+ boundaries. */
+ heap_ptr = (char *) ((((unsigned long) heap_ptr) + 7) & ~7);
+ prev_heap_ptr = heap_ptr;
+
+ if ((heap_ptr + nbytes) < &__end_heap)
+ {
+ heap_ptr += nbytes;
+ return (caddr_t) prev_heap_ptr;
+ }
+
+ errno = ENOMEM;
+ return (caddr_t) -1;
+}
diff --git a/libgloss/configure b/libgloss/configure
index acd3018..4e8e5c6 100755
diff --git a/libgloss/configure.in b/libgloss/configure.in
index e11eb7d..c7bf259 100644
--- a/libgloss/configure.in
+++ b/libgloss/configure.in
@@ -38,6 +38,9 @@ case "${target}" in
AC_CONFIG_SUBDIRS(aarch64)
config_testsuite=true
;;
+ arc*-*-*)
+ AC_CONFIG_SUBDIRS(arc)
+ ;;
epiphany-*-*)
AC_CONFIG_SUBDIRS(epiphany)
config_testsuite=true
--
2.4.2