#
# Enable cilk support for Sparc
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68945
#
diff -ruN gcc-5.4.0/libcilkrts/Makefile.in gcc-5.4.0.new/libcilkrts/Makefile.in
--- gcc-5.4.0/libcilkrts/Makefile.in	2016-05-08 04:45:03.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/Makefile.in	2016-10-25 12:41:02.455042170 +0000
@@ -215,13 +215,13 @@
 AWK = @AWK@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ -D__EXTENSIONS__=1
 CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
+CPPFLAGS = @CPPFLAGS@ -D__EXTENSIONS__=1
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
+CXXFLAGS = @CXXFLAGS@ -D__EXTENSIONS__=1
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
diff -ruN gcc-5.4.0/libcilkrts/configure.ac gcc-5.4.0.new/libcilkrts/configure.ac
--- gcc-5.4.0/libcilkrts/configure.ac	2015-01-26 14:54:31.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/configure.ac	2016-10-25 13:44:57.812274915 +0000
@@ -134,6 +134,10 @@
     config_dir="x86"
     ;;
 
+  sparc-*-*)
+    config_dir="sparc"
+    ;;
+
   *)
     config_dir="generic"
     ;;
diff -ruN gcc-5.4.0/libcilkrts/configure.tgt gcc-5.4.0.new/libcilkrts/configure.tgt
--- gcc-5.4.0/libcilkrts/configure.tgt	2014-11-13 06:03:17.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/configure.tgt	2016-10-25 12:41:02.447691755 +0000
@@ -37,6 +37,12 @@
     ;;
   i?86-*-*)
     ;;
+  sparc-*-*)
+    ;;
+  sparc*-*-*)
+    ;;
+  __sparc*-*-*)
+    ;;
   *-*-*)
     UNSUPPORTED=1
     ;;
diff -ruN gcc-5.4.0/libcilkrts/include/internal/abi.h gcc-5.4.0.new/libcilkrts/include/internal/abi.h
--- gcc-5.4.0/libcilkrts/include/internal/abi.h	2013-10-29 11:37:47.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/include/internal/abi.h	2016-10-25 13:43:14.488675235 +0000
@@ -95,6 +95,21 @@
 
 #endif  /* defined(_MSC_VER) */
 
+#if defined(__sparcv9)
+/**
+ * Subtract SPARC V9 stack bias so the actual stack starts at the allocated
+ * area.
+ * Hardcode value here to avoid dragging in different O/S headers for an
+ * architecture constant.
+ */
+#define CILK_ADJUST_SP(SP) ((SP) - 2047)
+#define CILK_UNADJUST_SP(SP) ((SP) + 2047)
+#else
+#define CILK_ADJUST_SP(SP) SP
+#define CILK_UNADJUST_SP(SP) SP
+#endif
+
+
 /* struct tags */
 typedef struct __cilkrts_stack_frame __cilkrts_stack_frame; ///< struct tag for stack frame
 
diff -ruN gcc-5.4.0/libcilkrts/runtime/cilk_fiber-unix.cpp gcc-5.4.0.new/libcilkrts/runtime/cilk_fiber-unix.cpp
--- gcc-5.4.0/libcilkrts/runtime/cilk_fiber-unix.cpp	2013-11-08 11:52:27.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/cilk_fiber-unix.cpp	2016-10-25 13:41:31.863089060 +0000
@@ -210,7 +210,7 @@
         // enough extra space from the top of the stack we are
         // switching to for any temporaries required for this run()
         // function.
-        JMPBUF_SP(m_resume_jmpbuf) = m_stack_base - frame_size;
+        JMPBUF_SP(m_resume_jmpbuf) = CILK_ADJUST_SP(m_stack_base - frame_size);
 
         // GCC doesn't allow us to call __builtin_longjmp in the same function
         // that calls __builtin_setjmp, so it's been moved into it's own
diff -ruN gcc-5.4.0/libcilkrts/runtime/config/generic/cilk-abi-vla.c gcc-5.4.0.new/libcilkrts/runtime/config/generic/cilk-abi-vla.c
--- gcc-5.4.0/libcilkrts/runtime/config/generic/cilk-abi-vla.c	2013-10-29 11:37:47.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/config/generic/cilk-abi-vla.c	2016-10-25 12:41:02.448086870 +0000
@@ -103,5 +103,5 @@
 
     // Just free the allocated memory to the heap since we don't know
     // how to expand/contract the calling frame
-    vla_internal_heap_free(t, full_size);
+    vla_internal_heap_free(sf, full_size);
 }
diff -ruN gcc-5.4.0/libcilkrts/runtime/config/generic/os-unix-sysdep.c gcc-5.4.0.new/libcilkrts/runtime/config/generic/os-unix-sysdep.c
--- gcc-5.4.0/libcilkrts/runtime/config/generic/os-unix-sysdep.c	2013-10-29 11:37:47.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/config/generic/os-unix-sysdep.c	2016-10-25 12:41:02.448439275 +0000
@@ -43,22 +43,55 @@
 #include "os.h"
 #include "sysdep.h"
 
+#if defined(__sparc) || defined(__sparc__)
+# include <sys/times.h>
+# include <limits.h>
+#endif
+
 /*
  * The cycle counter is used for debugging.  This funciton is only called if
  * CILK_PROFILE is defined when the runtime is built.
  */
 COMMON_SYSDEP unsigned long long __cilkrts_getticks(void)
 {
+#if defined(__sparc) || defined(__sparc__)
+  struct tms t;
+
+  if (times(&t) != (clock_t) -1)
+    return (unsigned long long) (t.tms_utime + t.tms_stime);
+
+  return 0ULL;
+#else
 #   warning "unimplemented cycle counter"
     return 0;
+#endif
+}
+
+#if defined(__sparc) || defined(__sparc__)
+#include "os-fence.h"
+/*
+ * SPARC V9 __cilkrts_fence implementation
+ */
+COMMON_SYSDEP void __cilkrts_fence(void)
+{
+  __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad" ::: "memory");
 }
+#endif
 
 /*
  * A "short pause" - called from the Cilk runtime's spinloops.
  */
 COMMON_SYSDEP void __cilkrts_short_pause(void)
 {
+#if defined(__sparc) || defined(__sparc__)
+  /* spin around for 8 cycles */
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+#else
 #   warning __cilkrts_short_pause empty
+#endif
 }
 
 /*
diff -ruN gcc-5.4.0/libcilkrts/runtime/config/sparc/cilk-abi-vla.c gcc-5.4.0.new/libcilkrts/runtime/config/sparc/cilk-abi-vla.c
--- gcc-5.4.0/libcilkrts/runtime/config/sparc/cilk-abi-vla.c	1969-12-31 16:00:00.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/config/sparc/cilk-abi-vla.c	2016-10-25 12:55:40.503713470 +0000
@@ -0,0 +1,104 @@
+/* cilk-abi-vla.cpp                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * 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.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  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.
+ *
+ **************************************************************************/
+
+/*
+ * Implementation of Variable Length Array (VLA) ABI.
+ *
+ * The compiler calls these functions to allocate Variable Length Arrays
+ * at runtime.  The compiler must guarantee that __cilkrts_stack_free() is
+ * called to cleanup any memory allocated by __cilkrts_stack_alloc().
+ *
+ * This generic implementation always allocates the memory from the heap.
+ * Optimally, the implementation should expand the frame of the calling
+ * function if possible, since that will be faster.  See the x86 version
+ * for one possible implementation.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "internal/abi.h"
+#include "cilk-abi-vla-internal.h"
+
+// Allocate space for a variable length array
+CILK_ABI(__cilkrts_void_ptr)
+__cilkrts_stack_alloc(
+    __cilkrts_stack_frame *sf,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align,     // align is always >= minimum stack alignment and
+                        // >= ptr_size as well, and must be a power of 2.
+    uint32_t needs_tag  // non-zero if the pointer being returned needs to
+                        // be tagged
+)
+{
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+
+    // Allocate memory from the heap.  The compiler is responsible
+    // for guaranteeing us a chance to free it before the function
+    // exits
+
+    return (void *)vla_internal_heap_alloc(sf, full_size, align);
+}
+
+// Free the space allocated for a variable length array.
+CILK_ABI(void)
+__cilkrts_stack_free(
+    __cilkrts_stack_frame *sf,
+    void *p,
+    size_t size,
+    size_t distance_from_sp_to_alloca_area,
+    uint32_t align, // same requirements as for align in allocation,
+                    // and must match alignment that was passed when
+                    // doing the allocation 
+    uint32_t known_from_stack  // non-zero if this is known to be allocated
+                               // on the stack, and therefore has no tag
+)
+{
+    // full_size will be a multiple of align, and contains
+    // enough extra space to allocate a marker if one was needed.
+    size_t full_size = (size + align - 1) & ~(align - 1);
+
+    // Just free the allocated memory to the heap since we don't know
+    // how to expand/contract the calling frame
+    vla_internal_heap_free(sf, full_size);
+}
diff -ruN gcc-5.4.0/libcilkrts/runtime/config/sparc/os-fence.h gcc-5.4.0.new/libcilkrts/runtime/config/sparc/os-fence.h
--- gcc-5.4.0/libcilkrts/runtime/config/sparc/os-fence.h	1969-12-31 16:00:00.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/config/sparc/os-fence.h	2016-10-25 12:49:20.080270815 +0000
@@ -0,0 +1,53 @@
+/* os.h                  -*-C++-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * 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.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  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.
+ **************************************************************************/
+
+/* gcc before 4.4 does not implement __sync_synchronize properly */
+#if (__GNUC__ * 10 + __GNUC_MINOR__ > 43)
+#   define HAVE_SYNC_INTRINSICS 1
+#endif
+
+/*
+ * void __cilkrts_fence(void)
+ */
+#ifdef HAVE_SYNC_INTRINSICS
+#   define __cilkrts_fence() __sync_synchronize()
+#elif defined __GNUC__
+#   define __cilkrts_fence() __asm__ volatile ("membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad" ::: "memory")
+#else
+COMMON_SYSDEP void __cilkrts_fence(void);
+#endif
diff -ruN gcc-5.4.0/libcilkrts/runtime/config/sparc/os-unix-sysdep.c gcc-5.4.0.new/libcilkrts/runtime/config/sparc/os-unix-sysdep.c
--- gcc-5.4.0/libcilkrts/runtime/config/sparc/os-unix-sysdep.c	1969-12-31 16:00:00.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/config/sparc/os-unix-sysdep.c	2016-10-25 12:54:40.358602560 +0000
@@ -0,0 +1,82 @@
+/* os-unix-sysdep.c                  -*-C-*-
+ *
+ *************************************************************************
+ *
+ *  @copyright
+ *  Copyright (C) 2009-2013, Intel Corporation
+ *  All rights reserved.
+ *  
+ *  @copyright
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * 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.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *  
+ *  @copyright
+ *  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 contains system-specific code for sparc-based systems
+ */
+
+#include "os.h"
+#include "sysdep.h"
+
+/*
+ * The cycle counter is used for debugging.  This funciton is only called if
+ * CILK_PROFILE is defined when the runtime is built.
+ */
+COMMON_SYSDEP unsigned long long __cilkrts_getticks(void)
+{
+  unsigned long long tick;
+
+#ifdef __sparcv9
+  asm __volatile__("rd %%tick, %0" : "=r" (tick));
+#else
+  asm __volatile__("rd %%tick, %L0\n"
+                   "srlx %L0, 32, %H0" : "=r" (tick));
+#endif
+
+  return tick;
+}
+
+/*
+ * A "short pause" - called from the Cilk runtime's spinloops.
+ */
+COMMON_SYSDEP void __cilkrts_short_pause(void)
+{
+  /* spin around for 8 cycles */
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+  __asm__ __volatile__("rd %ccr, %g0");
+}
+
+/*
+ * Interlocked exchange - used to implement the Cilk runtime's spinloops
+ */
+COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x)
+{
+    x = __sync_lock_test_and_set(ptr, x);
+    return x;
+}
diff -ruN gcc-5.4.0/libcilkrts/runtime/jmpbuf.h gcc-5.4.0.new/libcilkrts/runtime/jmpbuf.h
--- gcc-5.4.0/libcilkrts/runtime/jmpbuf.h	2013-10-29 11:37:47.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/jmpbuf.h	2016-10-25 13:37:43.110335065 +0000
@@ -109,7 +109,7 @@
  */
 inline char *__cilkrts_get_sp(__cilkrts_stack_frame *sf)
 {
-    return (char *)SP(sf);
+    return (char *)CILK_ADJUST_SP(SP(sf));
 }
 
 /**
diff -ruN gcc-5.4.0/libcilkrts/runtime/sysdep-unix.c gcc-5.4.0.new/libcilkrts/runtime/sysdep-unix.c
--- gcc-5.4.0/libcilkrts/runtime/sysdep-unix.c	2013-10-30 15:51:29.000000000 +0000
+++ gcc-5.4.0.new/libcilkrts/runtime/sysdep-unix.c	2016-10-25 13:24:22.075041275 +0000
@@ -81,6 +81,10 @@
 #include <pthread.h>
 #include <unistd.h>
 
+#if defined(sun) || defined(__sun) || defined(__sun__)
+#include <strings.h>
+#endif
+
 #if defined HAVE_ALLOCA_H
 # include <alloca.h>
 #elif defined __GNUC__
@@ -110,6 +114,14 @@
 #   define MAP_ANONYMOUS MAP_ANON
 #endif
 
+#if defined(sun) || defined(__sun) || defined(__sun__)
+#include <sys/resource.h>
+#include <dlfcn.h>
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#endif
+
 #ifdef  __VXWORKS__
 #   include <vxWorks.h>   
 #   include <vxCpuLib.h>  
@@ -498,7 +510,7 @@
 
     CILK_ASSERT(fiber);
     void* sp = (void*)get_sp_for_executing_sf(cilk_fiber_get_stack_base(fiber), ff, sf);
-    SP(sf) = sp;
+    SP(sf) = CILK_ADJUST_SP(sp);
 
     /* Debugging: make sure stack is accessible. */
     ((volatile char *)sp)[-1];
@@ -528,7 +540,7 @@
 #endif
 
     // Set the stack pointer.
-    SP(sf) = new_sp;
+    SP(sf) = CILK_ADJUST_SP(new_sp);
 
 #ifdef RESTORE_X86_FP_STATE
     if (CILK_FRAME_VERSION_VALUE(sf->flags) >= 1) {
