[PR,d/90086] Fix linker warning and SEGV in core.thread tests

Message ID CABOHX+dcQkp5znQG4sPYeL-TBcid5WEww=BxZ3uzggX-rBBEbQ@mail.gmail.com
State New
Headers show
Series
  • [PR,d/90086] Fix linker warning and SEGV in core.thread tests
Related show

Commit Message

Iain Buclaw April 24, 2019, 11 p.m.
Hi,

This patch removes the monolithic and cumbersome to maintain
core/threadasm.S, and splitted it into multiple parts, one for each
intended target cpu/os.

Added .type and .size directives for all asm implementations of
fiber_switchContent and callWithStackShell where they were missing,
fixing the last remaining failing test on -m32 that I can reproduce
locally.

Bootstrapped and regression tested on x86_64-linux-gnu with multilibs
-m32, -mx32, and -m64.

Committed to trunk as r270560.

-- 
Iain
---
libphobos/ChangeLog:

2019-04-25  Iain Buclaw  <ibuclaw@gdcproject.org>

        PR d/90086
        * m4/druntime/cpu.m4 (DRUNTIME_CPU_SOURCES): New macro.
        * configure.ac: Use it.
        * configure: Regenerate.
        * libdruntime/Makefile.am: Add new config sources to
        DRUNTIME_SOURCES_CONFIGURED.
        * libdruntime/Makefile.in: Regenerate.
        * libdruntime/config/aarch64/switchcontext.S: New file.
        * libdruntime/config/arm/switchcontext.S: New file.
        * libdruntime/config/common/threadasm.S: New file.
        * libdruntime/config/mingw/switchcontext.S: New file.
        * libdruntime/config/mips/switchcontext.S: New file.
        * libdruntime/config/powerpc/switchcontext.S: New file.
        * libdruntime/config/powerpc64/callwithstack.S: New file.
        * libdruntime/config/x86/switchcontext.S: New file.
        * libdruntime/core/threadasm.S: Remove.
---

Comments

Rainer Orth April 25, 2019, 12:44 p.m. | #1
Hi Iain,

> This patch removes the monolithic and cumbersome to maintain

> core/threadasm.S, and splitted it into multiple parts, one for each

> intended target cpu/os.

>

> Added .type and .size directives for all asm implementations of

> fiber_switchContent and callWithStackShell where they were missing,

> fixing the last remaining failing test on -m32 that I can reproduce

> locally.

>

> Bootstrapped and regression tested on x86_64-linux-gnu with multilibs

> -m32, -mx32, and -m64.

>

> Committed to trunk as r270560.


this patch badly broke x86 libphobos testing, as noticed during a
i386-pc-solaris2.11 build.  All link tests FAIL like this:

FAIL: libphobos.cycles/mod1.d --DRT-oncycle=print (test for excess errors)
Excess errors:
Undefined                       first referenced
 symbol                             in file
fiber_switchContext                 /var/gcc/gcc-9.0.1-20190425/11.5-gcc-gas-libphobos/i386-pc-solaris2.11/libphobos/libdruntime/.libs/libgdruntime.a(thread.o)
ld: fatal: symbol referencing errors
collect2: error: ld returned 1 exit status

UNRESOLVED: libphobos.cycles/mod1.d --DRT-oncycle=print compilation failed to produce executable

You need to quote brackets to get them from m4/autoconf macros into
configure.  Fixed as follows, tested on i386-pc-solaris2.11, installed
as obvious.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2019-04-25  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* m4/druntime/cpu.m4 (DRUNTIME_CPU_SOURCES): Quote brackets.
	* configure: Regenerate.
# HG changeset patch
# Parent  a7a44865fd130abcbd002e700515b1b113704d0c
Fix typo in m4/druntime/cpu.m4

diff --git a/libphobos/configure b/libphobos/configure
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -14050,7 +14050,7 @@ fi
       powerpc64)
                druntime_target_cpu_parsed="powerpc64"
                ;;
-      i3456786|x86_64)
+      i[34567]86|x86_64)
                druntime_target_cpu_parsed="x86"
                ;;
   esac
diff --git a/libphobos/m4/druntime/cpu.m4 b/libphobos/m4/druntime/cpu.m4
--- a/libphobos/m4/druntime/cpu.m4
+++ b/libphobos/m4/druntime/cpu.m4
@@ -22,7 +22,7 @@ AC_DEFUN([DRUNTIME_CPU_SOURCES],
       powerpc64)
                druntime_target_cpu_parsed="powerpc64"
                ;;
-      i[34567]86|x86_64)
+      i[[34567]]86|x86_64)
                druntime_target_cpu_parsed="x86"
                ;;
   esac

Patch

diff --git a/libphobos/configure b/libphobos/configure
index 7c019899c5c..67fe34d7184 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -681,6 +681,18 @@  DRUNTIME_OS_AIX_FALSE
 DRUNTIME_OS_AIX_TRUE
 DRUNTIME_OS_UNIX_FALSE
 DRUNTIME_OS_UNIX_TRUE
+DRUNTIME_CPU_X86_FALSE
+DRUNTIME_CPU_X86_TRUE
+DRUNTIME_CPU_POWERPC64_FALSE
+DRUNTIME_CPU_POWERPC64_TRUE
+DRUNTIME_CPU_POWERPC_FALSE
+DRUNTIME_CPU_POWERPC_TRUE
+DRUNTIME_CPU_MIPS_FALSE
+DRUNTIME_CPU_MIPS_TRUE
+DRUNTIME_CPU_ARM_FALSE
+DRUNTIME_CPU_ARM_TRUE
+DRUNTIME_CPU_AARCH64_FALSE
+DRUNTIME_CPU_AARCH64_TRUE
 DRUNTIME_GC_ENABLE_FALSE
 DRUNTIME_GC_ENABLE_TRUE
 libphobos_srcdir
@@ -11623,7 +11635,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11626 "configure"
+#line 11638 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11729,7 +11741,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11732 "configure"
+#line 11744 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14024,6 +14036,74 @@  fi
 
 
 
+  druntime_target_cpu_parsed=""
+  case "$target_cpu" in
+      aarch64*)
+               druntime_target_cpu_parsed="aarch64"
+               ;;
+      arm*)    druntime_target_cpu_parsed="arm"
+               ;;
+      mips*)   druntime_target_cpu_parsed="mips"
+               ;;
+      powerpc) druntime_target_cpu_parsed="powerpc"
+               ;;
+      powerpc64)
+               druntime_target_cpu_parsed="powerpc64"
+               ;;
+      i3456786|x86_64)
+               druntime_target_cpu_parsed="x86"
+               ;;
+  esac
+   if test "$druntime_target_cpu_parsed" = "aarch64"; then
+  DRUNTIME_CPU_AARCH64_TRUE=
+  DRUNTIME_CPU_AARCH64_FALSE='#'
+else
+  DRUNTIME_CPU_AARCH64_TRUE='#'
+  DRUNTIME_CPU_AARCH64_FALSE=
+fi
+
+   if test "$druntime_target_cpu_parsed" = "arm"; then
+  DRUNTIME_CPU_ARM_TRUE=
+  DRUNTIME_CPU_ARM_FALSE='#'
+else
+  DRUNTIME_CPU_ARM_TRUE='#'
+  DRUNTIME_CPU_ARM_FALSE=
+fi
+
+   if test "$druntime_target_cpu_parsed" = "mips"; then
+  DRUNTIME_CPU_MIPS_TRUE=
+  DRUNTIME_CPU_MIPS_FALSE='#'
+else
+  DRUNTIME_CPU_MIPS_TRUE='#'
+  DRUNTIME_CPU_MIPS_FALSE=
+fi
+
+   if test "$druntime_target_cpu_parsed" = "powerpc"; then
+  DRUNTIME_CPU_POWERPC_TRUE=
+  DRUNTIME_CPU_POWERPC_FALSE='#'
+else
+  DRUNTIME_CPU_POWERPC_TRUE='#'
+  DRUNTIME_CPU_POWERPC_FALSE=
+fi
+
+   if test "$druntime_target_cpu_parsed" = "powerpc64"; then
+  DRUNTIME_CPU_POWERPC64_TRUE=
+  DRUNTIME_CPU_POWERPC64_FALSE='#'
+else
+  DRUNTIME_CPU_POWERPC64_TRUE='#'
+  DRUNTIME_CPU_POWERPC64_FALSE=
+fi
+
+   if test "$druntime_target_cpu_parsed" = "x86"; then
+  DRUNTIME_CPU_X86_TRUE=
+  DRUNTIME_CPU_X86_FALSE='#'
+else
+  DRUNTIME_CPU_X86_TRUE='#'
+  DRUNTIME_CPU_X86_FALSE=
+fi
+
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for target OS" >&5
 $as_echo_n "checking for target OS... " >&6; }
 if ${druntime_cv_target_os+:} false; then :
@@ -15413,6 +15493,30 @@  if test -z "${DRUNTIME_GC_ENABLE_TRUE}" && test -z "${DRUNTIME_GC_ENABLE_FALSE}"
   as_fn_error $? "conditional \"DRUNTIME_GC_ENABLE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${DRUNTIME_CPU_AARCH64_TRUE}" && test -z "${DRUNTIME_CPU_AARCH64_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_AARCH64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DRUNTIME_CPU_ARM_TRUE}" && test -z "${DRUNTIME_CPU_ARM_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_ARM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DRUNTIME_CPU_MIPS_TRUE}" && test -z "${DRUNTIME_CPU_MIPS_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_MIPS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DRUNTIME_CPU_POWERPC_TRUE}" && test -z "${DRUNTIME_CPU_POWERPC_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_POWERPC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DRUNTIME_CPU_POWERPC64_TRUE}" && test -z "${DRUNTIME_CPU_POWERPC64_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_POWERPC64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DRUNTIME_CPU_X86_TRUE}" && test -z "${DRUNTIME_CPU_X86_FALSE}"; then
+  as_fn_error $? "conditional \"DRUNTIME_CPU_X86\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${DRUNTIME_OS_UNIX_TRUE}" && test -z "${DRUNTIME_OS_UNIX_FALSE}"; then
   as_fn_error $? "conditional \"DRUNTIME_OS_UNIX\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index d3a7f2709b1..c4a86f2ec5a 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -157,6 +157,7 @@  DRUNTIME_CONFIGURE
 DRUNTIME_MULTILIB
 DRUNTIME_WERROR
 DRUNTIME_GC
+DRUNTIME_CPU_SOURCES
 DRUNTIME_OS_UNIX
 DRUNTIME_OS_SOURCES
 DRUNTIME_OS_THREAD_MODEL
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 8cdea52eb5c..b981f233d71 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -36,43 +36,67 @@  ALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \
 	$(DRUNTIME_DSOURCES_STDCXX)
 
 # Setup source files depending on configure
-ALL_DRUNTIME_COMPILE_DSOURCES = $(DRUNTIME_DSOURCES)
+DRUNTIME_SOURCES_CONFIGURED =
+
 # GC sources
 if DRUNTIME_GC_ENABLE
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GC)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_GC)
 else
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GCSTUB)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_GCSTUB)
 endif
 # OS specific sources
 if DRUNTIME_OS_UNIX
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_POSIX)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_POSIX)
 endif
 if DRUNTIME_OS_DARWIN
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_DARWIN)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_DARWIN)
 endif
 if DRUNTIME_OS_DRAGONFLYBSD
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_DRAGONFLYBSD)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_DRAGONFLYBSD)
 endif
 if DRUNTIME_OS_ANDROID
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_BIONIC)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_BIONIC)
 endif
 if DRUNTIME_OS_FREEBSD
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_FREEBSD)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_FREEBSD)
 endif
 if DRUNTIME_OS_NETBSD
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_NETBSD)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_NETBSD)
 endif
 if DRUNTIME_OS_OPENBSD
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_OPENBSD)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_OPENBSD)
 endif
 if DRUNTIME_OS_LINUX
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_LINUX)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
 endif
 if DRUNTIME_OS_MINGW
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_WINDOWS)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
 endif
 if DRUNTIME_OS_SOLARIS
-    ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_SOLARIS)
+    DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
+endif
+# CPU specific sources
+if DRUNTIME_CPU_AARCH64
+    DRUNTIME_SOURCES_CONFIGURED += config/aarch64/switchcontext.S
+endif
+if DRUNTIME_CPU_ARM
+    DRUNTIME_SOURCES_CONFIGURED += config/arm/switchcontext.S
+endif
+if DRUNTIME_CPU_MIPS
+    DRUNTIME_SOURCES_CONFIGURED += config/mips/switchcontext.S
+endif
+if DRUNTIME_CPU_POWERPC
+    DRUNTIME_SOURCES_CONFIGURED += config/powerpc/switchcontext.S
+endif
+if DRUNTIME_CPU_POWERPC64
+    DRUNTIME_SOURCES_CONFIGURED += config/powerpc64/callwithstack.S
+endif
+if DRUNTIME_CPU_X86
+if DRUNTIME_OS_MINGW
+    DRUNTIME_SOURCES_CONFIGURED += config/mingw/switchcontext.S
+else
+    DRUNTIME_SOURCES_CONFIGURED += config/x86/switchcontext.S
+endif
 endif
 
 # Provide __start_minfo, __stop_minfo if linker doesn't.
@@ -89,10 +113,10 @@  gcc/drtend.o: gcc/drtstuff.c
 endif
 
 # Generated by configure
-ALL_DRUNTIME_COMPILE_DSOURCES += $(DRUNTIME_DSOURCES_GENERATED)
+DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
 
-ALL_DRUNTIME_SOURCES = $(ALL_DRUNTIME_COMPILE_DSOURCES) $(DRUNTIME_CSOURCES) \
-	$(DRUNTIME_SSOURCES)
+ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \
+	$(DRUNTIME_SOURCES_CONFIGURED) $(DRUNTIME_DSOURCES_GENERATED)
 
 toolexeclib_LTLIBRARIES = libgdruntime.la
 libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES)
@@ -114,13 +138,10 @@  install-data-local:
 	  fi ; \
 	done
 
-
-DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
 # Source file definitions. Boring stuff, auto-generated with
 # https://gist.github.com/jpf91/8ad1dbc9902d6ad876313f134c6527d1
 # Can't use wildcards here:
 # https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
-DRUNTIME_SSOURCES = core/threadasm.S
 
 DRUNTIME_CSOURCES = core/stdc/errno_.c
 
@@ -141,13 +162,13 @@  DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
 	core/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
 	gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
-	gcc/sections/package.d gcc/sections/win32.d \
-	gcc/sections/win64.d gcc/unwind/arm.d gcc/unwind/arm_common.d \
-	gcc/unwind/c6x.d gcc/unwind/generic.d gcc/unwind/package.d \
-	gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d \
-	rt/arrayassign.d rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d \
-	rt/critical_.d rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d \
-	rt/memory.d rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \
+	gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+	gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
+	gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
+	rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \
+	rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \
+	rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \
+	rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \
 	rt/switch_.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \
 	rt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \
 	rt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 61570468c4c..eb290b6a14f 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -107,6 +107,7 @@  POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+
 # GC sources
 @DRUNTIME_GC_ENABLE_TRUE@am__append_1 = $(DRUNTIME_DSOURCES_GC)
 @DRUNTIME_GC_ENABLE_FALSE@am__append_2 = $(DRUNTIME_DSOURCES_GCSTUB)
@@ -121,6 +122,14 @@  target_triplet = @target@
 @DRUNTIME_OS_LINUX_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_LINUX)
 @DRUNTIME_OS_MINGW_TRUE@am__append_11 = $(DRUNTIME_DSOURCES_WINDOWS)
 @DRUNTIME_OS_SOLARIS_TRUE@am__append_12 = $(DRUNTIME_DSOURCES_SOLARIS)
+# CPU specific sources
+@DRUNTIME_CPU_AARCH64_TRUE@am__append_13 = config/aarch64/switchcontext.S
+@DRUNTIME_CPU_ARM_TRUE@am__append_14 = config/arm/switchcontext.S
+@DRUNTIME_CPU_MIPS_TRUE@am__append_15 = config/mips/switchcontext.S
+@DRUNTIME_CPU_POWERPC_TRUE@am__append_16 = config/powerpc/switchcontext.S
+@DRUNTIME_CPU_POWERPC64_TRUE@am__append_17 = config/powerpc64/callwithstack.S
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__append_18 = config/mingw/switchcontext.S
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__append_19 = config/x86/switchcontext.S
 subdir = libdruntime
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -228,13 +237,14 @@  am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
 	rt/util/container/common.lo rt/util/container/hashtab.lo \
 	rt/util/container/treap.lo rt/util/random.lo \
 	rt/util/typeinfo.lo rt/util/utf.lo
-am__objects_2 = gc/bits.lo gc/config.lo gc/gcinterface.lo \
+am__objects_2 = core/stdc/libgdruntime_la-errno_.lo
+am__objects_3 = gc/bits.lo gc/config.lo gc/gcinterface.lo \
 	gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \
 	gc/pooltable.lo gc/proxy.lo
-@DRUNTIME_GC_ENABLE_TRUE@am__objects_3 = $(am__objects_2)
-am__objects_4 = gcstub/gc.lo
-@DRUNTIME_GC_ENABLE_FALSE@am__objects_5 = $(am__objects_4)
-am__objects_6 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
+@DRUNTIME_GC_ENABLE_TRUE@am__objects_4 = $(am__objects_3)
+am__objects_5 = gcstub/gc.lo
+@DRUNTIME_GC_ENABLE_FALSE@am__objects_6 = $(am__objects_5)
+am__objects_7 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/config.lo core/sys/posix/dirent.lo \
 	core/sys/posix/dlfcn.lo core/sys/posix/fcntl.lo \
 	core/sys/posix/grp.lo core/sys/posix/iconv.lo \
@@ -259,8 +269,8 @@  am__objects_6 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \
 	core/sys/posix/syslog.lo core/sys/posix/termios.lo \
 	core/sys/posix/time.lo core/sys/posix/ucontext.lo \
 	core/sys/posix/unistd.lo core/sys/posix/utime.lo
-@DRUNTIME_OS_UNIX_TRUE@am__objects_7 = $(am__objects_6)
-am__objects_8 = core/sys/darwin/crt_externs.lo \
+@DRUNTIME_OS_UNIX_TRUE@am__objects_8 = $(am__objects_7)
+am__objects_9 = core/sys/darwin/crt_externs.lo \
 	core/sys/darwin/dlfcn.lo core/sys/darwin/execinfo.lo \
 	core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \
 	core/sys/darwin/mach/kern_return.lo \
@@ -270,8 +280,8 @@  am__objects_8 = core/sys/darwin/crt_externs.lo \
 	core/sys/darwin/netinet/in_.lo core/sys/darwin/pthread.lo \
 	core/sys/darwin/sys/cdefs.lo core/sys/darwin/sys/event.lo \
 	core/sys/darwin/sys/mman.lo
-@DRUNTIME_OS_DARWIN_TRUE@am__objects_9 = $(am__objects_8)
-am__objects_10 = core/sys/dragonflybsd/dlfcn.lo \
+@DRUNTIME_OS_DARWIN_TRUE@am__objects_10 = $(am__objects_9)
+am__objects_11 = core/sys/dragonflybsd/dlfcn.lo \
 	core/sys/dragonflybsd/execinfo.lo \
 	core/sys/dragonflybsd/netinet/in_.lo \
 	core/sys/dragonflybsd/pthread_np.lo \
@@ -286,10 +296,10 @@  am__objects_10 = core/sys/dragonflybsd/dlfcn.lo \
 	core/sys/dragonflybsd/sys/link_elf.lo \
 	core/sys/dragonflybsd/sys/mman.lo \
 	core/sys/dragonflybsd/time.lo
-@DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__objects_11 = $(am__objects_10)
-am__objects_12 = core/sys/bionic/fcntl.lo core/sys/bionic/unistd.lo
-@DRUNTIME_OS_ANDROID_TRUE@am__objects_13 = $(am__objects_12)
-am__objects_14 = core/sys/freebsd/dlfcn.lo \
+@DRUNTIME_OS_DRAGONFLYBSD_TRUE@am__objects_12 = $(am__objects_11)
+am__objects_13 = core/sys/bionic/fcntl.lo core/sys/bionic/unistd.lo
+@DRUNTIME_OS_ANDROID_TRUE@am__objects_14 = $(am__objects_13)
+am__objects_15 = core/sys/freebsd/dlfcn.lo \
 	core/sys/freebsd/execinfo.lo core/sys/freebsd/netinet/in_.lo \
 	core/sys/freebsd/pthread_np.lo core/sys/freebsd/sys/_bitset.lo \
 	core/sys/freebsd/sys/_cpuset.lo core/sys/freebsd/sys/cdefs.lo \
@@ -299,16 +309,16 @@  am__objects_14 = core/sys/freebsd/dlfcn.lo \
 	core/sys/freebsd/sys/event.lo core/sys/freebsd/sys/link_elf.lo \
 	core/sys/freebsd/sys/mman.lo core/sys/freebsd/sys/mount.lo \
 	core/sys/freebsd/time.lo core/sys/freebsd/unistd.lo
-@DRUNTIME_OS_FREEBSD_TRUE@am__objects_15 = $(am__objects_14)
-am__objects_16 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/execinfo.lo \
+@DRUNTIME_OS_FREEBSD_TRUE@am__objects_16 = $(am__objects_15)
+am__objects_17 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/execinfo.lo \
 	core/sys/netbsd/sys/elf.lo core/sys/netbsd/sys/elf32.lo \
 	core/sys/netbsd/sys/elf64.lo core/sys/netbsd/sys/elf_common.lo \
 	core/sys/netbsd/sys/event.lo core/sys/netbsd/sys/link_elf.lo \
 	core/sys/netbsd/sys/mman.lo core/sys/netbsd/time.lo
-@DRUNTIME_OS_NETBSD_TRUE@am__objects_17 = $(am__objects_16)
-am__objects_18 = core/sys/openbsd/dlfcn.lo
-@DRUNTIME_OS_OPENBSD_TRUE@am__objects_19 = $(am__objects_18)
-am__objects_20 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
+@DRUNTIME_OS_NETBSD_TRUE@am__objects_18 = $(am__objects_17)
+am__objects_19 = core/sys/openbsd/dlfcn.lo
+@DRUNTIME_OS_OPENBSD_TRUE@am__objects_20 = $(am__objects_19)
+am__objects_21 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
 	core/sys/linux/elf.lo core/sys/linux/epoll.lo \
 	core/sys/linux/errno.lo core/sys/linux/execinfo.lo \
 	core/sys/linux/fcntl.lo core/sys/linux/ifaddrs.lo \
@@ -323,8 +333,8 @@  am__objects_20 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
 	core/sys/linux/sys/xattr.lo core/sys/linux/termios.lo \
 	core/sys/linux/time.lo core/sys/linux/timerfd.lo \
 	core/sys/linux/tipc.lo core/sys/linux/unistd.lo
-@DRUNTIME_OS_LINUX_TRUE@am__objects_21 = $(am__objects_20)
-am__objects_22 = core/sys/windows/accctrl.lo \
+@DRUNTIME_OS_LINUX_TRUE@am__objects_22 = $(am__objects_21)
+am__objects_23 = core/sys/windows/accctrl.lo \
 	core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
 	core/sys/windows/basetsd.lo core/sys/windows/basetyps.lo \
 	core/sys/windows/cderr.lo core/sys/windows/cguid.lo \
@@ -407,8 +417,8 @@  am__objects_22 = core/sys/windows/accctrl.lo \
 	core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
 	core/sys/windows/winuser.lo core/sys/windows/winver.lo \
 	core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_23 = $(am__objects_22)
-am__objects_24 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_24 = $(am__objects_23)
+am__objects_25 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
 	core/sys/solaris/execinfo.lo core/sys/solaris/libelf.lo \
 	core/sys/solaris/link.lo core/sys/solaris/sys/elf.lo \
 	core/sys/solaris/sys/elf_386.lo \
@@ -419,17 +429,25 @@  am__objects_24 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
 	core/sys/solaris/sys/priocntl.lo \
 	core/sys/solaris/sys/procset.lo core/sys/solaris/sys/types.lo \
 	core/sys/solaris/time.lo
-@DRUNTIME_OS_SOLARIS_TRUE@am__objects_25 = $(am__objects_24)
-am__objects_26 = gcc/config.lo gcc/libbacktrace.lo
-am__objects_27 = $(am__objects_1) $(am__objects_3) $(am__objects_5) \
-	$(am__objects_7) $(am__objects_9) $(am__objects_11) \
-	$(am__objects_13) $(am__objects_15) $(am__objects_17) \
-	$(am__objects_19) $(am__objects_21) $(am__objects_23) \
-	$(am__objects_25) $(am__objects_26)
-am__objects_28 = core/stdc/libgdruntime_la-errno_.lo
-am__objects_29 = core/libgdruntime_la-threadasm.lo
-am__objects_30 = $(am__objects_27) $(am__objects_28) $(am__objects_29)
-am_libgdruntime_la_OBJECTS = $(am__objects_30)
+@DRUNTIME_OS_SOLARIS_TRUE@am__objects_26 = $(am__objects_25)
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_27 = config/aarch64/libgdruntime_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_28 = config/arm/libgdruntime_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_29 = config/mips/libgdruntime_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_30 = config/powerpc/libgdruntime_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC64_TRUE@am__objects_31 = config/powerpc64/libgdruntime_la-callwithstack.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_32 = config/mingw/libgdruntime_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_33 = config/x86/libgdruntime_la-switchcontext.lo
+am__objects_34 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+	$(am__objects_10) $(am__objects_12) $(am__objects_14) \
+	$(am__objects_16) $(am__objects_18) $(am__objects_20) \
+	$(am__objects_22) $(am__objects_24) $(am__objects_26) \
+	$(am__objects_27) $(am__objects_28) $(am__objects_29) \
+	$(am__objects_30) $(am__objects_31) $(am__objects_32) \
+	$(am__objects_33)
+am__objects_35 = gcc/config.lo gcc/libbacktrace.lo
+am__objects_36 = $(am__objects_1) $(am__objects_2) $(am__objects_34) \
+	$(am__objects_35)
+am_libgdruntime_la_OBJECTS = $(am__objects_36)
 libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -692,20 +710,22 @@  ALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \
 
 
 # Setup source files depending on configure
-
-# Generated by configure
-ALL_DRUNTIME_COMPILE_DSOURCES = $(DRUNTIME_DSOURCES) $(am__append_1) \
-	$(am__append_2) $(am__append_3) $(am__append_4) \
-	$(am__append_5) $(am__append_6) $(am__append_7) \
-	$(am__append_8) $(am__append_9) $(am__append_10) \
-	$(am__append_11) $(am__append_12) \
-	$(DRUNTIME_DSOURCES_GENERATED)
+DRUNTIME_SOURCES_CONFIGURED = $(am__append_1) $(am__append_2) \
+	$(am__append_3) $(am__append_4) $(am__append_5) \
+	$(am__append_6) $(am__append_7) $(am__append_8) \
+	$(am__append_9) $(am__append_10) $(am__append_11) \
+	$(am__append_12) $(am__append_13) $(am__append_14) \
+	$(am__append_15) $(am__append_16) $(am__append_17) \
+	$(am__append_18) $(am__append_19)
 
 # Provide __start_minfo, __stop_minfo if linker doesn't.
 @DRUNTIME_OS_MINFO_BRACKETING_FALSE@DRTSTUFF = gcc/drtbegin.o gcc/drtend.o
 @DRUNTIME_OS_MINFO_BRACKETING_FALSE@toolexeclib_DATA = $(DRTSTUFF)
-ALL_DRUNTIME_SOURCES = $(ALL_DRUNTIME_COMPILE_DSOURCES) $(DRUNTIME_CSOURCES) \
-	$(DRUNTIME_SSOURCES)
+
+# Generated by configure
+DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
+ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \
+	$(DRUNTIME_SOURCES_CONFIGURED) $(DRUNTIME_DSOURCES_GENERATED)
 
 toolexeclib_LTLIBRARIES = libgdruntime.la
 libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES)
@@ -715,12 +735,11 @@  libgdruntime_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../src,-Bgcc \
 
 libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE)
 libgdruntime_la_DEPENDENCIES = $(DRTSTUFF)
-DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
+
 # Source file definitions. Boring stuff, auto-generated with
 # https://gist.github.com/jpf91/8ad1dbc9902d6ad876313f134c6527d1
 # Can't use wildcards here:
 # https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
-DRUNTIME_SSOURCES = core/threadasm.S
 DRUNTIME_CSOURCES = core/stdc/errno_.c
 DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/checkedint.d core/cpuid.d core/demangle.d core/exception.d \
@@ -739,13 +758,13 @@  DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
 	core/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
 	gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
-	gcc/sections/package.d gcc/sections/win32.d \
-	gcc/sections/win64.d gcc/unwind/arm.d gcc/unwind/arm_common.d \
-	gcc/unwind/c6x.d gcc/unwind/generic.d gcc/unwind/package.d \
-	gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d \
-	rt/arrayassign.d rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d \
-	rt/critical_.d rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d \
-	rt/memory.d rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \
+	gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+	gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
+	gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
+	rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \
+	rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \
+	rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \
+	rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \
 	rt/switch_.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \
 	rt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \
 	rt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \
@@ -1182,6 +1201,7 @@  rt/util/container/treap.lo: rt/util/container/$(am__dirstamp)
 rt/util/random.lo: rt/util/$(am__dirstamp)
 rt/util/typeinfo.lo: rt/util/$(am__dirstamp)
 rt/util/utf.lo: rt/util/$(am__dirstamp)
+core/stdc/libgdruntime_la-errno_.lo: core/stdc/$(am__dirstamp)
 gc/$(am__dirstamp):
 	@$(MKDIR_P) gc
 	@: > gc/$(am__dirstamp)
@@ -1629,16 +1649,63 @@  core/sys/solaris/sys/priocntl.lo:  \
 core/sys/solaris/sys/procset.lo: core/sys/solaris/sys/$(am__dirstamp)
 core/sys/solaris/sys/types.lo: core/sys/solaris/sys/$(am__dirstamp)
 core/sys/solaris/time.lo: core/sys/solaris/$(am__dirstamp)
+config/aarch64/$(am__dirstamp):
+	@$(MKDIR_P) config/aarch64
+	@: > config/aarch64/$(am__dirstamp)
+config/aarch64/libgdruntime_la-switchcontext.lo:  \
+	config/aarch64/$(am__dirstamp)
+config/arm/$(am__dirstamp):
+	@$(MKDIR_P) config/arm
+	@: > config/arm/$(am__dirstamp)
+config/arm/libgdruntime_la-switchcontext.lo:  \
+	config/arm/$(am__dirstamp)
+config/mips/$(am__dirstamp):
+	@$(MKDIR_P) config/mips
+	@: > config/mips/$(am__dirstamp)
+config/mips/libgdruntime_la-switchcontext.lo:  \
+	config/mips/$(am__dirstamp)
+config/powerpc/$(am__dirstamp):
+	@$(MKDIR_P) config/powerpc
+	@: > config/powerpc/$(am__dirstamp)
+config/powerpc/libgdruntime_la-switchcontext.lo:  \
+	config/powerpc/$(am__dirstamp)
+config/powerpc64/$(am__dirstamp):
+	@$(MKDIR_P) config/powerpc64
+	@: > config/powerpc64/$(am__dirstamp)
+config/powerpc64/libgdruntime_la-callwithstack.lo:  \
+	config/powerpc64/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+	@$(MKDIR_P) config/mingw
+	@: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-switchcontext.lo:  \
+	config/mingw/$(am__dirstamp)
+config/x86/$(am__dirstamp):
+	@$(MKDIR_P) config/x86
+	@: > config/x86/$(am__dirstamp)
+config/x86/libgdruntime_la-switchcontext.lo:  \
+	config/x86/$(am__dirstamp)
 gcc/config.lo: gcc/$(am__dirstamp)
 gcc/libbacktrace.lo: gcc/$(am__dirstamp)
-core/stdc/libgdruntime_la-errno_.lo: core/stdc/$(am__dirstamp)
-core/libgdruntime_la-threadasm.lo: core/$(am__dirstamp)
 
 libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EXTRA_libgdruntime_la_DEPENDENCIES) 
 	$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f config/aarch64/*.$(OBJEXT)
+	-rm -f config/aarch64/*.lo
+	-rm -f config/arm/*.$(OBJEXT)
+	-rm -f config/arm/*.lo
+	-rm -f config/mingw/*.$(OBJEXT)
+	-rm -f config/mingw/*.lo
+	-rm -f config/mips/*.$(OBJEXT)
+	-rm -f config/mips/*.lo
+	-rm -f config/powerpc/*.$(OBJEXT)
+	-rm -f config/powerpc/*.lo
+	-rm -f config/powerpc64/*.$(OBJEXT)
+	-rm -f config/powerpc64/*.lo
+	-rm -f config/x86/*.$(OBJEXT)
+	-rm -f config/x86/*.lo
 	-rm -f core/*.$(OBJEXT)
 	-rm -f core/*.lo
 	-rm -f core/internal/*.$(OBJEXT)
@@ -1734,8 +1801,26 @@  distclean-compile:
 .S.lo:
 	$(AM_V_CPPAS)$(LTCPPASCOMPILE) -c -o $@ $<
 
-core/libgdruntime_la-threadasm.lo: core/threadasm.S
-	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o core/libgdruntime_la-threadasm.lo `test -f 'core/threadasm.S' || echo '$(srcdir)/'`core/threadasm.S
+config/aarch64/libgdruntime_la-switchcontext.lo: config/aarch64/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/aarch64/libgdruntime_la-switchcontext.lo `test -f 'config/aarch64/switchcontext.S' || echo '$(srcdir)/'`config/aarch64/switchcontext.S
+
+config/arm/libgdruntime_la-switchcontext.lo: config/arm/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/arm/libgdruntime_la-switchcontext.lo `test -f 'config/arm/switchcontext.S' || echo '$(srcdir)/'`config/arm/switchcontext.S
+
+config/mips/libgdruntime_la-switchcontext.lo: config/mips/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/mips/libgdruntime_la-switchcontext.lo `test -f 'config/mips/switchcontext.S' || echo '$(srcdir)/'`config/mips/switchcontext.S
+
+config/powerpc/libgdruntime_la-switchcontext.lo: config/powerpc/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/powerpc/libgdruntime_la-switchcontext.lo `test -f 'config/powerpc/switchcontext.S' || echo '$(srcdir)/'`config/powerpc/switchcontext.S
+
+config/powerpc64/libgdruntime_la-callwithstack.lo: config/powerpc64/callwithstack.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/powerpc64/libgdruntime_la-callwithstack.lo `test -f 'config/powerpc64/callwithstack.S' || echo '$(srcdir)/'`config/powerpc64/callwithstack.S
+
+config/mingw/libgdruntime_la-switchcontext.lo: config/mingw/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/mingw/libgdruntime_la-switchcontext.lo `test -f 'config/mingw/switchcontext.S' || echo '$(srcdir)/'`config/mingw/switchcontext.S
+
+config/x86/libgdruntime_la-switchcontext.lo: config/x86/switchcontext.S
+	$(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/x86/libgdruntime_la-switchcontext.lo `test -f 'config/x86/switchcontext.S' || echo '$(srcdir)/'`config/x86/switchcontext.S
 
 .c.o:
 	$(AM_V_CC)$(COMPILE) -c -o $@ $<
@@ -1754,6 +1839,13 @@  mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+	-rm -rf config/aarch64/.libs config/aarch64/_libs
+	-rm -rf config/arm/.libs config/arm/_libs
+	-rm -rf config/mingw/.libs config/mingw/_libs
+	-rm -rf config/mips/.libs config/mips/_libs
+	-rm -rf config/powerpc/.libs config/powerpc/_libs
+	-rm -rf config/powerpc64/.libs config/powerpc64/_libs
+	-rm -rf config/x86/.libs config/x86/_libs
 	-rm -rf core/.libs core/_libs
 	-rm -rf core/internal/.libs core/internal/_libs
 	-rm -rf core/stdc/.libs core/stdc/_libs
@@ -1901,6 +1993,13 @@  clean-generic:
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f config/aarch64/$(am__dirstamp)
+	-rm -f config/arm/$(am__dirstamp)
+	-rm -f config/mingw/$(am__dirstamp)
+	-rm -f config/mips/$(am__dirstamp)
+	-rm -f config/powerpc/$(am__dirstamp)
+	-rm -f config/powerpc64/$(am__dirstamp)
+	-rm -f config/x86/$(am__dirstamp)
 	-rm -f core/$(am__dirstamp)
 	-rm -f core/internal/$(am__dirstamp)
 	-rm -f core/stdc/$(am__dirstamp)
diff --git a/libphobos/libdruntime/config/aarch64/switchcontext.S b/libphobos/libdruntime/config/aarch64/switchcontext.S
new file mode 100644
index 00000000000..0a29baceca6
--- /dev/null
+++ b/libphobos/libdruntime/config/aarch64/switchcontext.S
@@ -0,0 +1,103 @@ 
+/* AArch64 support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+/**
+ * preserve/restore AAPCS64 registers
+ *   x19-x28 5.1.1 64-bit callee saved
+ *   x29 fp, or possibly callee saved reg - depends on platform choice 5.2.3)
+ *   x30 lr
+ *   d8-d15  5.1.2 says callee only must save bottom 64-bits (the "d" regs)
+ *
+ * saved regs on stack will look like:
+ *   19: x19
+ *   18: x20
+ *   ...
+ *   10: x28
+ *    9: x29 (fp)  <-- oldp / *newp save stack top
+ *    8: x30 (lr)
+ *    7: d8
+ *   ...
+ *    0: d15       <-- sp
+ */
+    .text
+    .global CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), %function
+    .align 4
+CSYM(fiber_switchContext):
+    .cfi_startproc
+    stp     d15, d14, [sp, #-20*8]!
+    stp     d13, d12, [sp, #2*8]
+    stp     d11, d10, [sp, #4*8]
+    stp     d9, d8,   [sp, #6*8]
+    stp     x30, x29, [sp, #8*8] // lr, fp
+    stp     x28, x27, [sp, #10*8]
+    stp     x26, x25, [sp, #12*8]
+    stp     x24, x23, [sp, #14*8]
+    stp     x22, x21, [sp, #16*8]
+    stp     x20, x19, [sp, #18*8]
+
+    // oldp is set above saved lr (x30) to hide it and float regs
+    // from GC
+    add     x19, sp, #9*8
+    str     x19, [x0]       // *oldp tstack
+    sub     sp, x1, #9*8    // switch to newp sp
+
+    ldp     x20, x19, [sp, #18*8]
+    ldp     x22, x21, [sp, #16*8]
+    ldp     x24, x23, [sp, #14*8]
+    ldp     x26, x25, [sp, #12*8]
+    ldp     x28, x27, [sp, #10*8]
+    ldp     x30, x29, [sp, #8*8] // lr, fp
+    ldp     d9, d8,   [sp, #6*8]
+    ldp     d11, d10, [sp, #4*8]
+    ldp     d13, d12, [sp, #2*8]
+    ldp     d15, d14, [sp], #20*8
+    ret
+    .cfi_endproc
+    .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+/**
+ * When generating any kind of backtrace (gdb, exception handling) for
+ * a function called in a Fiber, we need to tell the unwinder to stop
+ * at our Fiber main entry point, i.e. we need to mark the bottom of
+ * the call stack. This can be done by clearing the link register lr
+ * prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or
+ * using a .cfi_undefined directive for the link register in the
+ * Fiber entry point. cfi_undefined seems to yield better results in gdb.
+ * Unfortunately we can't place it into fiber_entryPoint using inline
+ * asm, so we use this trampoline instead.
+ */
+    .text
+    .global CSYM(fiber_trampoline)
+    .p2align  2
+    .type CSYM(fiber_trampoline), %function
+CSYM(fiber_trampoline):
+    .cfi_startproc
+    .cfi_undefined x30
+    // fiber_entryPoint never returns
+    bl CSYM(fiber_entryPoint)
+    .cfi_endproc
+    .size CSYM(fiber_trampoline),.-CSYM(fiber_trampoline)
diff --git a/libphobos/libdruntime/config/arm/switchcontext.S b/libphobos/libdruntime/config/arm/switchcontext.S
new file mode 100644
index 00000000000..bc510cf81b5
--- /dev/null
+++ b/libphobos/libdruntime/config/arm/switchcontext.S
@@ -0,0 +1,118 @@ 
+/* ARM support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+#if defined(__ARM_EABI__)
+
+/**
+ * Performs a context switch.
+ *
+ * Parameters:
+ * r0 - void** - ptr to old stack pointer
+ * r1 - void*  - new stack pointer
+ *
+ * ARM EABI registers:
+ * r0-r3   : argument/scratch registers
+ * r4-r10  : callee-save registers
+ * r11     : frame pointer (or a callee save register if fp isn't needed)
+ * r12 =ip : inter procedure register. We can treat it like any other scratch
+ *           register
+ * r13 =sp : stack pointer
+ * r14 =lr : link register, it contains the return address (belonging to the
+ *           function which called us)
+ * r15 =pc : program counter
+ *
+ * For floating point registers:
+ * According to AAPCS (version 2.09, section 5.1.2) only the d8-d15 registers
+ * need to be preserved across method calls. This applies to all ARM FPU
+ * variants, whether they have 16 or 32 double registers NEON support or not,
+ * half-float support or not and so on does not matter.
+ *
+ * Note: If this file was compiled with -mfloat-abi=soft but the code runs on a
+ * softfp system with fpu the d8-d15 registers won't be saved (we do not know
+ * that the system has got a fpu in that case) but the registers might actually
+ * be used by other code if it was compiled with -mfloat-abi=softfp.
+ *
+ * Interworking is only supported on ARMv5+, not on ARM v4T as ARM v4t requires
+ * special stubs when changing from thumb to arm mode or the other way round.
+ */
+
+    .text
+#if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__))
+    .fpu vfp
+#endif
+    .global CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), %function
+    .align 4
+CSYM(fiber_switchContext):
+    .cfi_sections .debug_frame
+    .cfi_startproc
+    .fnstart
+    push {r4-r11}
+    // update the oldp pointer. Link register and floating point registers
+    // stored later to prevent the GC from scanning them.
+    str sp, [r0]
+    // push r0 (or any other register) as well to keep stack 8byte aligned
+    push {r0, lr}
+
+     // ARM_HardFloat  || ARM_SoftFP
+#if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__))
+    vpush {d8-d15}
+    // now switch over to the new stack.
+    // Need to subtract (8*8[d8-d15]+2*4[r0, lr]) to position stack pointer
+    // below the last saved register. Remember we saved the SP before pushing
+    // [r0, lr, d8-d15].
+    sub sp, r1, #72
+    vpop {d8-d15}
+#else
+    sub sp, r1, #8
+#endif
+
+    // we don't really care about r0, we only used that for padding.
+    // r1 is now what used to be in the link register when saving.
+    pop {r0, r1, r4-r11}
+    /**
+     * The link register for the initial jump to fiber_entryPoint must be zero:
+     * The jump actually looks like a normal method call as we jump to the
+     * start of the fiber_entryPoint function. Although fiber_entryPoint never
+     * returns and therefore never accesses lr, it saves lr to the stack.
+     * ARM unwinding will then look at the stack, find lr and think that
+     * fiber_entryPoint was called by the function in lr! So if we have some
+     * address in lr the unwinder will try to continue stack unwinding,
+     * although it's already at the stack base and crash.
+     * In all other cases the content of lr doesn't matter.
+     * Note: If we simply loaded into lr above and then moved lr into pc, the
+     * initial method call to fiber_entryPoint would look as if it was called
+     * from fiber_entryPoint itself, as the fiber_entryPoint address is in lr
+     * on the initial context switch.
+     */
+    mov lr, #0
+    // return by writing lr into pc
+    mov pc, r1
+    .fnend
+    .cfi_endproc
+    .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+#endif
diff --git a/libphobos/libdruntime/config/common/threadasm.S b/libphobos/libdruntime/config/common/threadasm.S
new file mode 100644
index 00000000000..4f43722c2db
--- /dev/null
+++ b/libphobos/libdruntime/config/common/threadasm.S
@@ -0,0 +1,43 @@ 
+/* Support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__
+/*
+ * Mark the resulting object file as not requiring execution permissions on
+ * stack memory. The absence of this section would mark the whole resulting
+ * library as requiring an executable stack, making it impossible to
+ * dynamically load druntime on several Linux platforms where this is
+ * forbidden due to security policies.
+ */
+    .section .note.GNU-stack,"",%progbits
+#endif
+
+/* Let preprocessor tell us if C symbols have a prefix: __USER_LABEL_PREFIX__ */
+#ifdef __USER_LABEL_PREFIX__
+#define __CONCAT2(a, b) a ## b
+#define __CONCAT(a, b) __CONCAT2(a, b)
+#define CSYM(name) __CONCAT(__USER_LABEL_PREFIX__, name)
+#else
+#define CSYM(name) name
+#endif
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
new file mode 100644
index 00000000000..2951feab0df
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -0,0 +1,109 @@ 
+/* Windows i386 support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+#if defined(__x86_64__)
+
+    .text
+    .globl CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), @function
+    .align 16
+CSYM(fiber_switchContext):
+    .cfi_startproc
+    pushq %RBP;
+    movq %RSP, %RBP;
+    pushq %RBX;
+    pushq %R12;
+    pushq %R13;
+    pushq %R14;
+    pushq %R15;
+    pushq %GS:0;
+    pushq %GS:8;
+    pushq %GS:16;
+
+    // store oldp
+    movq %RSP, (%RCX);
+    // load newp to begin context switch
+    movq %RDX, %RSP;
+
+    // load saved state from new stack
+    popq %GS:16;
+    popq %GS:8;
+    popq %GS:0;
+    popq %R15;
+    popq %R14;
+    popq %R13;
+    popq %R12;
+    popq %RBX;
+    popq %RBP;
+
+    // 'return' to complete switch
+    popq %RCX;
+    jmp *%RCX;
+    .cfi_endproc
+    .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+#elif defined(_X86_)
+
+    .text
+    .globl CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), @function
+    .align 16
+CSYM(fiber_switchContext):
+    .cfi_startproc
+    // Save current stack state.save current stack state
+    // Standard CDECL prologue.
+    push %EBP;
+    mov  %ESP, %EBP;
+    push %EDI;
+    push %ESI;
+    push %EBX;
+    push %FS:0;
+    push %FS:4;
+    push %FS:8;
+    push %EAX;
+
+    // store oldp again with more accurate address
+    mov 8(%EBP), %EAX;
+    mov %ESP, (%EAX);
+    // load newp to begin context switch
+    mov 12(%EBP), %ESP;
+
+    // load saved state from new stack
+    pop %EAX;
+    pop %FS:8;
+    pop %FS:4;
+    pop %FS:0;
+    pop %EBX;
+    pop %ESI;
+    pop %EDI;
+    pop %EBP;
+
+    // 'return' to complete switch
+    ret;
+    .cfi_endproc
+    .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+#endif
diff --git a/libphobos/libdruntime/config/mips/switchcontext.S b/libphobos/libdruntime/config/mips/switchcontext.S
new file mode 100644
index 00000000000..7604ba1ebbd
--- /dev/null
+++ b/libphobos/libdruntime/config/mips/switchcontext.S
@@ -0,0 +1,102 @@ 
+/* MIPS support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+#if _MIPS_SIM == _ABIO32
+
+/**
+ * Performs a context switch.
+ *
+ * $a0 - void** - ptr to old stack pointer
+ * $a1 - void*  - new stack pointer
+ *
+ */
+    .text
+    .globl fiber_switchContext
+    .align 2
+    .ent fiber_switchContext,0
+fiber_switchContext:
+    .cfi_startproc
+    addiu $sp, $sp, -(10 * 4)
+
+    // fp regs and return address are stored below the stack
+    // because we don't want the GC to scan them.
+
+#ifdef __mips_hard_float
+#define ALIGN8(val) (val + (-val & 7))
+#define BELOW (ALIGN8(6 * 8 + 4))
+    sdc1 $f20, (0 * 8 - BELOW)($sp)
+    sdc1 $f22, (1 * 8 - BELOW)($sp)
+    sdc1 $f24, (2 * 8 - BELOW)($sp)
+    sdc1 $f26, (3 * 8 - BELOW)($sp)
+    sdc1 $f28, (4 * 8 - BELOW)($sp)
+    sdc1 $f30, (5 * 8 - BELOW)($sp)
+#endif
+    sw $ra, -4($sp)
+
+    sw $s0, (0 * 4)($sp)
+    sw $s1, (1 * 4)($sp)
+    sw $s2, (2 * 4)($sp)
+    sw $s3, (3 * 4)($sp)
+    sw $s4, (4 * 4)($sp)
+    sw $s5, (5 * 4)($sp)
+    sw $s6, (6 * 4)($sp)
+    sw $s7, (7 * 4)($sp)
+    sw $s8, (8 * 4)($sp)
+    sw $gp, (9 * 4)($sp)
+
+    // swap stack pointer
+    sw $sp, 0($a0)
+    move $sp, $a1
+
+#ifdef __mips_hard_float
+    ldc1 $f20, (0 * 8 - BELOW)($sp)
+    ldc1 $f22, (1 * 8 - BELOW)($sp)
+    ldc1 $f24, (2 * 8 - BELOW)($sp)
+    ldc1 $f26, (3 * 8 - BELOW)($sp)
+    ldc1 $f28, (4 * 8 - BELOW)($sp)
+    ldc1 $f30, (5 * 8 - BELOW)($sp)
+#endif
+    lw $ra, -4($sp)
+
+    lw $s0, (0 * 4)($sp)
+    lw $s1, (1 * 4)($sp)
+    lw $s2, (2 * 4)($sp)
+    lw $s3, (3 * 4)($sp)
+    lw $s4, (4 * 4)($sp)
+    lw $s5, (5 * 4)($sp)
+    lw $s6, (6 * 4)($sp)
+    lw $s7, (7 * 4)($sp)
+    lw $s8, (8 * 4)($sp)
+    lw $gp, (9 * 4)($sp)
+
+    addiu $sp, $sp, (10 * 4)
+
+    jr $ra // return
+    .cfi_endproc
+    .end fiber_switchContext
+    .size fiber_switchContext,.-fiber_switchContext
+
+#endif
diff --git a/libphobos/libdruntime/config/powerpc/switchcontext.S b/libphobos/libdruntime/config/powerpc/switchcontext.S
new file mode 100644
index 00000000000..3d0aebde94e
--- /dev/null
+++ b/libphobos/libdruntime/config/powerpc/switchcontext.S
@@ -0,0 +1,150 @@ 
+/* PowerPC support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+/**
+ * Performs a context switch.
+ *
+ * r3 - old context pointer
+ * r4 - new context pointer
+ *
+ */
+    .text
+    .globl CSYM(_fiber_switchContext)
+    .type CSYM(_fiber_switchContext), @function
+    .align 2
+CSYM(_fiber_switchContext):
+    .cfi_startproc
+    /* Save linkage area */
+    mflr        0
+    mfcr        5
+    stw     0, 8(1)
+    stw     5, 4(1)
+
+    /* Save GPRs */
+    stw     11, (-1 * 4)(1)
+    stw     13, (-2 * 4)(1)
+    stw     14, (-3 * 4)(1)
+    stw     15, (-4 * 4)(1)
+    stw     16, (-5 * 4)(1)
+    stw     17, (-6 * 4)(1)
+    stw     18, (-7 * 4)(1)
+    stw     19, (-8 * 4)(1)
+    stw     20, (-9 * 4)(1)
+    stw     21, (-10 * 4)(1)
+    stw     22, (-11 * 4)(1)
+    stw     23, (-12 * 4)(1)
+    stw     24, (-13 * 4)(1)
+    stw     25, (-14 * 4)(1)
+    stw     26, (-15 * 4)(1)
+    stw     27, (-16 * 4)(1)
+    stw     28, (-17 * 4)(1)
+    stw     29, (-18 * 4)(1)
+    stw     30, (-19 * 4)(1)
+    stwu    31, (-20 * 4)(1)
+
+    /* We update the stack pointer here, since we do not want the GC to
+       scan the floating point registers. */
+
+    /* Save FPRs */
+    stfd    14, (-1 * 8)(1)
+    stfd    15, (-2 * 8)(1)
+    stfd    16, (-3 * 8)(1)
+    stfd    17, (-4 * 8)(1)
+    stfd    18, (-5 * 8)(1)
+    stfd    19, (-6 * 8)(1)
+    stfd    20, (-7 * 8)(1)
+    stfd    21, (-8 * 8)(1)
+    stfd    22, (-9 * 8)(1)
+    stfd    23, (-10 * 8)(1)
+    stfd    24, (-11 * 8)(1)
+    stfd    25, (-12 * 8)(1)
+    stfd    26, (-13 * 8)(1)
+    stfd    27, (-14 * 8)(1)
+    stfd    28, (-15 * 8)(1)
+    stfd    29, (-16 * 8)(1)
+    stfd    30, (-17 * 8)(1)
+    stfd    31, (-18 * 8)(1)
+
+    /* Update the old stack pointer */
+    stw     1, 0(3)
+
+    /* Set new stack pointer */
+    addi        1, 4, 20 * 4
+
+    /* Restore linkage area */
+    lwz     0, 8(1)
+    lwz     5, 4(1)
+
+    /* Restore GPRs */
+    lwz     11, (-1 * 4)(1)
+    lwz     13, (-2 * 4)(1)
+    lwz     14, (-3 * 4)(1)
+    lwz     15, (-4 * 4)(1)
+    lwz     16, (-5 * 4)(1)
+    lwz     17, (-6 * 4)(1)
+    lwz     18, (-7 * 4)(1)
+    lwz     19, (-8 * 4)(1)
+    lwz     20, (-9 * 4)(1)
+    lwz     21, (-10 * 4)(1)
+    lwz     22, (-11 * 4)(1)
+    lwz     23, (-12 * 4)(1)
+    lwz     24, (-13 * 4)(1)
+    lwz     25, (-14 * 4)(1)
+    lwz     26, (-15 * 4)(1)
+    lwz     27, (-16 * 4)(1)
+    lwz     28, (-17 * 4)(1)
+    lwz     29, (-18 * 4)(1)
+    lwz     30, (-19 * 4)(1)
+    lwz     31, (-20 * 4)(1)
+
+    /* Restore FPRs */
+    lfd     14, (-1 * 8)(4)
+    lfd     15, (-2 * 8)(4)
+    lfd     16, (-3 * 8)(4)
+    lfd     17, (-4 * 8)(4)
+    lfd     18, (-5 * 8)(4)
+    lfd     19, (-6 * 8)(4)
+    lfd     20, (-7 * 8)(4)
+    lfd     21, (-8 * 8)(4)
+    lfd     22, (-9 * 8)(4)
+    lfd     23, (-10 * 8)(4)
+    lfd     24, (-11 * 8)(4)
+    lfd     25, (-12 * 8)(4)
+    lfd     26, (-13 * 8)(4)
+    lfd     27, (-14 * 8)(4)
+    lfd     28, (-15 * 8)(4)
+    lfd     29, (-16 * 8)(4)
+    lfd     30, (-17 * 8)(4)
+    lfd     31, (-18 * 8)(4)
+
+    /* Set condition and link register */
+    mtcr        5
+    mtlr        0
+
+    /* Return and switch context */
+    blr
+    .cfi_endproc
+    .size CSYM(_fiber_switchContext),.-CSYM(_fiber_switchContext)
diff --git a/libphobos/libdruntime/config/powerpc64/callwithstack.S b/libphobos/libdruntime/config/powerpc64/callwithstack.S
new file mode 100644
index 00000000000..79ecd691199
--- /dev/null
+++ b/libphobos/libdruntime/config/powerpc64/callwithstack.S
@@ -0,0 +1,168 @@ 
+/* PowerPC64 support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define USE_ABI_2
+#define LINKAGE_SZ   32
+#define LR_OFS       16
+#define TOC_OFS      24
+#define GPR_OFS      32
+#define STACK_SZ     (LINKAGE_SZ + 26*8)
+#define OFS_R3_R10   GPR_OFS
+#define OFS_R14_R31  (GPR_OFS+8*8)
+#else
+#define LINKAGE_SZ   48
+#define LR_OFS       16
+#define TOC_OFS      40
+#define GPR_OFS      112
+#define STACK_SZ     (LINKAGE_SZ + 8*8 + 18*8)
+#define OFS_R3_R10   (STACK_SZ+LINKAGE_SZ)
+#define OFS_R14_R31  GPR_OFS
+#endif
+
+    .text
+#if defined( USE_ABI_2 )
+    .abiversion 2
+#endif
+    .globl  _D4core6thread18callWithStackShellFNbMDFNbPvZvZv
+    .align  2
+    .type   _D4core6thread18callWithStackShellFNbMDFNbPvZvZv,@function
+#if defined( USE_ABI_2 )
+    .section .text._D4core6thread18callWithStackShellFNbMDFNbPvZvZv,"a",@progbits
+#else
+    .section .opd,"aw",@progbits
+#endif
+_D4core6thread18callWithStackShellFNbMDFNbPvZvZv:
+#if !defined( USE_ABI_2 )
+    .align  3
+    .quad .L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv
+    .quad .TOC.@tocbase
+    .quad 0
+#endif
+    .text
+/*
+ * Called with:
+ * r3: pointer context
+ * r4: pointer to function
+ */
+.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv:
+    .cfi_startproc
+    stdu    1, -STACK_SZ(1)
+    mflr    0
+    std     0, LR_OFS(1)
+    .cfi_def_cfa_offset 256
+    .cfi_offset lr, 16
+
+    /* Save r14-r31 in general register save area */
+    std     14, (OFS_R14_R31 + 0 * 8)(1)
+    std     15, (OFS_R14_R31 + 1 * 8)(1)
+    std     16, (OFS_R14_R31 + 2 * 8)(1)
+    std     17, (OFS_R14_R31 + 3 * 8)(1)
+    std     18, (OFS_R14_R31 + 4 * 8)(1)
+    std     19, (OFS_R14_R31 + 5 * 8)(1)
+    std     20, (OFS_R14_R31 + 6 * 8)(1)
+    std     21, (OFS_R14_R31 + 7 * 8)(1)
+    std     22, (OFS_R14_R31 + 8 * 8)(1)
+    std     23, (OFS_R14_R31 + 9 * 8)(1)
+    std     24, (OFS_R14_R31 + 10 * 8)(1)
+    std     25, (OFS_R14_R31 + 11 * 8)(1)
+    std     26, (OFS_R14_R31 + 12 * 8)(1)
+    std     27, (OFS_R14_R31 + 13 * 8)(1)
+    std     28, (OFS_R14_R31 + 14 * 8)(1)
+    std     29, (OFS_R14_R31 + 15 * 8)(1)
+    std     30, (OFS_R14_R31 + 16 * 8)(1)
+    std     31, (OFS_R14_R31 + 17 * 8)(1)
+
+    /* Save r3-r10 in parameter save area of caller */
+    std     3, (OFS_R3_R10 + 0 * 8)(1)
+    std     4, (OFS_R3_R10 + 1 * 8)(1)
+    std     5, (OFS_R3_R10 + 2 * 8)(1)
+    std     6, (OFS_R3_R10 + 3 * 8)(1)
+    std     7, (OFS_R3_R10 + 4 * 8)(1)
+    std     8, (OFS_R3_R10 + 5 * 8)(1)
+    std     9, (OFS_R3_R10 + 6 * 8)(1)
+    std     10, (OFS_R3_R10 + 7 * 8)(1)
+
+    /* Save r2 in TOC save area */
+    std     2, TOC_OFS(1)
+
+    /* Do not save r11, r12 and r13. */
+
+    /* Call delegate:
+     * r3: pointer to context
+     * r4: pointer to stack
+     */
+    mr      5, 4
+    mr      4, 1
+    ld      6, 0(5)
+    ld      11, 16(5)
+    ld      2, 8(5)
+    mtctr   6
+    bctrl
+    nop
+
+    /* Restore r2 from TOC save area */
+    ld      2, TOC_OFS(1)
+
+    /* Restore r3-r10 from local variable space */
+    ld      3, (OFS_R3_R10 + 0 * 8)(1)
+    ld      4, (OFS_R3_R10 + 1 * 8)(1)
+    ld      5, (OFS_R3_R10 + 2 * 8)(1)
+    ld      6, (OFS_R3_R10 + 3 * 8)(1)
+    ld      7, (OFS_R3_R10 + 4 * 8)(1)
+    ld      8, (OFS_R3_R10 + 5 * 8)(1)
+    ld      9, (OFS_R3_R10 + 6 * 8)(1)
+    ld      10, (OFS_R3_R10 + 7 * 8)(1)
+
+    /* Restore r14-r31 from general register save area */
+    ld      14, (OFS_R14_R31 + 0 * 8)(1)
+    ld      15, (OFS_R14_R31 + 1 * 8)(1)
+    ld      16, (OFS_R14_R31 + 2 * 8)(1)
+    ld      17, (OFS_R14_R31 + 3 * 8)(1)
+    ld      18, (OFS_R14_R31 + 4 * 8)(1)
+    ld      19, (OFS_R14_R31 + 5 * 8)(1)
+    ld      20, (OFS_R14_R31 + 6 * 8)(1)
+    ld      21, (OFS_R14_R31 + 7 * 8)(1)
+    ld      22, (OFS_R14_R31 + 8 * 8)(1)
+    ld      23, (OFS_R14_R31 + 9 * 8)(1)
+    ld      24, (OFS_R14_R31 + 10 * 8)(1)
+    ld      25, (OFS_R14_R31 + 11 * 8)(1)
+    ld      26, (OFS_R14_R31 + 12 * 8)(1)
+    ld      27, (OFS_R14_R31 + 13 * 8)(1)
+    ld      28, (OFS_R14_R31 + 14 * 8)(1)
+    ld      29, (OFS_R14_R31 + 15 * 8)(1)
+    ld      30, (OFS_R14_R31 + 16 * 8)(1)
+    ld      31, (OFS_R14_R31 + 17 * 8)(1)
+
+    ld      0, LR_OFS(1)
+    mtlr    0
+    addi    1, 1, STACK_SZ
+    blr
+    .long 0
+    .quad 0
+.Lend:
+    .size _D4core6thread18callWithStackShellFNbMDFNbPvZvZv, .Lend-.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv
+    .cfi_endproc
diff --git a/libphobos/libdruntime/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S
new file mode 100644
index 00000000000..be3862f2c50
--- /dev/null
+++ b/libphobos/libdruntime/config/x86/switchcontext.S
@@ -0,0 +1,96 @@ 
+/* i386 support code for fibers and multithreading.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "../common/threadasm.S"
+
+#if defined(__i386__)
+
+    .text
+    .globl CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), @function
+    .align 16
+CSYM(fiber_switchContext):
+    .cfi_startproc
+    // save current stack state
+    push %ebp
+    mov  %esp, %ebp
+    push %edi
+    push %esi
+    push %ebx
+    push %eax
+
+    // store oldp again with more accurate address
+    mov 8(%ebp), %eax
+    mov %esp, (%eax)
+    // load newp to begin context switch
+    mov 12(%ebp), %esp
+
+    // load saved state from new stack
+    pop %eax
+    pop %ebx
+    pop %esi
+    pop %edi
+    pop %ebp
+
+    // 'return' to complete switch
+    ret
+    .cfi_endproc
+    .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+#elif defined(__x86_64__) && !defined(__ILP32__)
+
+    .text
+    .globl CSYM(fiber_switchContext)
+    .type CSYM(fiber_switchContext), @function
+    .align 16
+CSYM(fiber_switchContext):
+    .cfi_startproc
+    // Save current stack state.save current stack state
+    push %rbp
+    mov  %rsp, %rbp
+    push %rbx
+    push %r12
+    push %r13
+    push %r14
+    push %r15
+
+    // store oldp again with more accurate address
+    mov %rsp, (%rdi)
+    // load newp to begin context switch
+    mov %rsi, %rsp
+
+    // load saved state from new stack
+    pop %r15
+    pop %r14
+    pop %r13
+    pop %r12
+    pop %rbx
+    pop %rbp
+
+    // 'return' to complete switch
+    ret
+    .cfi_endproc
+   .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
+
+#endif
diff --git a/libphobos/libdruntime/core/threadasm.S b/libphobos/libdruntime/core/threadasm.S
deleted file mode 100644
index 140e5f9a9e4..00000000000
--- a/libphobos/libdruntime/core/threadasm.S
+++ /dev/null
@@ -1,682 +0,0 @@ 
-/**
- * Support code for mutithreading.
- *
- * Copyright: Copyright Mikola Lysenko 2005 - 2012.
- * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors:   Mikola Lysenko, Martin Nowak, Kai Nacke
- */
-
-/*
- *          Copyright Mikola Lysenko 2005 - 2012.
- * Distributed under the Boost Software License, Version 1.0.
- *    (See accompanying file LICENSE_1_0.txt or copy at
- *          http://www.boost.org/LICENSE_1_0.txt)
- */
-
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
-#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__
-/*
- * Mark the resulting object file as not requiring execution permissions on
- * stack memory. The absence of this section would mark the whole resulting
- * library as requiring an executable stack, making it impossible to
- * dynamically load druntime on several Linux platforms where this is
- * forbidden due to security policies.
- * Use %progbits instead of @progbits to support ARM and X86.
- */
-.section .note.GNU-stack,"",%progbits
-#endif
-
-/* Let preprocessor tell us if C symbols have a prefix: __USER_LABEL_PREFIX__ */
-#ifdef __USER_LABEL_PREFIX__
-#define GLUE2(a, b) a ## b
-#define GLUE(a, b) GLUE2(a, b)
-#define CSYM(name) GLUE(__USER_LABEL_PREFIX__, name)
-#else
-#define CSYM(name) name
-#endif
-
-/************************************************************************************
- * POWER PC ASM BITS
- ************************************************************************************/
-#if defined( __PPC64__ )
-
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-#define USE_ABI_2
-#define LINKAGE_SZ   32
-#define LR_OFS       16
-#define TOC_OFS      24
-#define GPR_OFS      32
-#define STACK_SZ     (LINKAGE_SZ + 26*8)
-#define OFS_R3_R10   GPR_OFS
-#define OFS_R14_R31  (GPR_OFS+8*8)
-#else
-#define LINKAGE_SZ   48
-#define LR_OFS       16
-#define TOC_OFS      40
-#define GPR_OFS      112
-#define STACK_SZ     (LINKAGE_SZ + 8*8 + 18*8)
-#define OFS_R3_R10   (STACK_SZ+LINKAGE_SZ)
-#define OFS_R14_R31  GPR_OFS
-#endif
-
-    .text
-#if defined( USE_ABI_2 )
-    .abiversion 2
-#endif
-    .globl  _D4core6thread18callWithStackShellFNbMDFNbPvZvZv
-    .align  2
-    .type   _D4core6thread18callWithStackShellFNbMDFNbPvZvZv,@function
-#if defined( USE_ABI_2 )
-    .section .text._D4core6thread18callWithStackShellFNbMDFNbPvZvZv,"a",@progbits
-#else
-    .section .opd,"aw",@progbits
-#endif
-_D4core6thread18callWithStackShellFNbMDFNbPvZvZv:
-#if !defined( USE_ABI_2 )
-    .align  3
-    .quad .L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv
-    .quad .TOC.@tocbase
-    .quad 0
-#endif
-    .text
-/*
- * Called with:
- * r3: pointer context
- * r4: pointer to function
- */
-.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv:
-    .cfi_startproc
-    stdu    1, -STACK_SZ(1)
-    mflr    0
-    std     0, LR_OFS(1)
-    .cfi_def_cfa_offset 256
-    .cfi_offset lr, 16
-
-    /* Save r14-r31 in general register save area */
-    std     14, (OFS_R14_R31 + 0 * 8)(1)
-    std     15, (OFS_R14_R31 + 1 * 8)(1)
-    std     16, (OFS_R14_R31 + 2 * 8)(1)
-    std     17, (OFS_R14_R31 + 3 * 8)(1)
-    std     18, (OFS_R14_R31 + 4 * 8)(1)
-    std     19, (OFS_R14_R31 + 5 * 8)(1)
-    std     20, (OFS_R14_R31 + 6 * 8)(1)
-    std     21, (OFS_R14_R31 + 7 * 8)(1)
-    std     22, (OFS_R14_R31 + 8 * 8)(1)
-    std     23, (OFS_R14_R31 + 9 * 8)(1)
-    std     24, (OFS_R14_R31 + 10 * 8)(1)
-    std     25, (OFS_R14_R31 + 11 * 8)(1)
-    std     26, (OFS_R14_R31 + 12 * 8)(1)
-    std     27, (OFS_R14_R31 + 13 * 8)(1)
-    std     28, (OFS_R14_R31 + 14 * 8)(1)
-    std     29, (OFS_R14_R31 + 15 * 8)(1)
-    std     30, (OFS_R14_R31 + 16 * 8)(1)
-    std     31, (OFS_R14_R31 + 17 * 8)(1)
-
-    /* Save r3-r10 in parameter save area of caller */
-    std     3, (OFS_R3_R10 + 0 * 8)(1)
-    std     4, (OFS_R3_R10 + 1 * 8)(1)
-    std     5, (OFS_R3_R10 + 2 * 8)(1)
-    std     6, (OFS_R3_R10 + 3 * 8)(1)
-    std     7, (OFS_R3_R10 + 4 * 8)(1)
-    std     8, (OFS_R3_R10 + 5 * 8)(1)
-    std     9, (OFS_R3_R10 + 6 * 8)(1)
-    std     10, (OFS_R3_R10 + 7 * 8)(1)
-
-    /* Save r2 in TOC save area */
-    std     2, TOC_OFS(1)
-
-    /* Do not save r11, r12 and r13. */
-
-    /* Call delegate:
-     * r3: pointer to context
-     * r4: pointer to stack
-     */
-    mr      5, 4
-    mr      4, 1
-    ld      6, 0(5)
-    ld      11, 16(5)
-    ld      2, 8(5)
-    mtctr   6
-    bctrl
-    nop
-
-    /* Restore r2 from TOC save area */
-    ld      2, TOC_OFS(1)
-
-    /* Restore r3-r10 from local variable space */
-    ld      3, (OFS_R3_R10 + 0 * 8)(1)
-    ld      4, (OFS_R3_R10 + 1 * 8)(1)
-    ld      5, (OFS_R3_R10 + 2 * 8)(1)
-    ld      6, (OFS_R3_R10 + 3 * 8)(1)
-    ld      7, (OFS_R3_R10 + 4 * 8)(1)
-    ld      8, (OFS_R3_R10 + 5 * 8)(1)
-    ld      9, (OFS_R3_R10 + 6 * 8)(1)
-    ld      10, (OFS_R3_R10 + 7 * 8)(1)
-
-    /* Restore r14-r31 from general register save area */
-    ld      14, (OFS_R14_R31 + 0 * 8)(1)
-    ld      15, (OFS_R14_R31 + 1 * 8)(1)
-    ld      16, (OFS_R14_R31 + 2 * 8)(1)
-    ld      17, (OFS_R14_R31 + 3 * 8)(1)
-    ld      18, (OFS_R14_R31 + 4 * 8)(1)
-    ld      19, (OFS_R14_R31 + 5 * 8)(1)
-    ld      20, (OFS_R14_R31 + 6 * 8)(1)
-    ld      21, (OFS_R14_R31 + 7 * 8)(1)
-    ld      22, (OFS_R14_R31 + 8 * 8)(1)
-    ld      23, (OFS_R14_R31 + 9 * 8)(1)
-    ld      24, (OFS_R14_R31 + 10 * 8)(1)
-    ld      25, (OFS_R14_R31 + 11 * 8)(1)
-    ld      26, (OFS_R14_R31 + 12 * 8)(1)
-    ld      27, (OFS_R14_R31 + 13 * 8)(1)
-    ld      28, (OFS_R14_R31 + 14 * 8)(1)
-    ld      29, (OFS_R14_R31 + 15 * 8)(1)
-    ld      30, (OFS_R14_R31 + 16 * 8)(1)
-    ld      31, (OFS_R14_R31 + 17 * 8)(1)
-
-    ld      0, LR_OFS(1)
-    mtlr    0
-    addi    1, 1, STACK_SZ
-    blr
-    .long 0
-    .quad 0
-.Lend:
-    .size _D4core6thread18callWithStackShellFNbMDFNbPvZvZv, .Lend-.L._D4core6thread18callWithStackShellFNbMDFNbPvZvZv
-    .cfi_endproc
-
-#elif defined( __ppc__ ) || defined( __PPC__ ) || defined( __powerpc__ )
-
-
-/**
- * Performs a context switch.
- *
- * r3 - old context pointer
- * r4 - new context pointer
- *
- */
-.text
-.align 2
-.globl _fiber_switchContext
-_fiber_switchContext:
-
-    /* Save linkage area */
-    mflr        0
-    mfcr        5
-    stw     0, 8(1)
-    stw     5, 4(1)
-
-    /* Save GPRs */
-    stw     11, (-1 * 4)(1)
-    stw     13, (-2 * 4)(1)
-    stw     14, (-3 * 4)(1)
-    stw     15, (-4 * 4)(1)
-    stw     16, (-5 * 4)(1)
-    stw     17, (-6 * 4)(1)
-    stw     18, (-7 * 4)(1)
-    stw     19, (-8 * 4)(1)
-    stw     20, (-9 * 4)(1)
-    stw     21, (-10 * 4)(1)
-    stw     22, (-11 * 4)(1)
-    stw     23, (-12 * 4)(1)
-    stw     24, (-13 * 4)(1)
-    stw     25, (-14 * 4)(1)
-    stw     26, (-15 * 4)(1)
-    stw     27, (-16 * 4)(1)
-    stw     28, (-17 * 4)(1)
-    stw     29, (-18 * 4)(1)
-    stw     30, (-19 * 4)(1)
-    stwu    31, (-20 * 4)(1)
-
-    /* We update the stack pointer here, since we do not want the GC to
-       scan the floating point registers. */
-
-    /* Save FPRs */
-    stfd    14, (-1 * 8)(1)
-    stfd    15, (-2 * 8)(1)
-    stfd    16, (-3 * 8)(1)
-    stfd    17, (-4 * 8)(1)
-    stfd    18, (-5 * 8)(1)
-    stfd    19, (-6 * 8)(1)
-    stfd    20, (-7 * 8)(1)
-    stfd    21, (-8 * 8)(1)
-    stfd    22, (-9 * 8)(1)
-    stfd    23, (-10 * 8)(1)
-    stfd    24, (-11 * 8)(1)
-    stfd    25, (-12 * 8)(1)
-    stfd    26, (-13 * 8)(1)
-    stfd    27, (-14 * 8)(1)
-    stfd    28, (-15 * 8)(1)
-    stfd    29, (-16 * 8)(1)
-    stfd    30, (-17 * 8)(1)
-    stfd    31, (-18 * 8)(1)
-
-    /* Update the old stack pointer */
-    stw     1, 0(3)
-
-    /* Set new stack pointer */
-    addi        1, 4, 20 * 4
-
-    /* Restore linkage area */
-    lwz     0, 8(1)
-    lwz     5, 4(1)
-
-    /* Restore GPRs */
-    lwz     11, (-1 * 4)(1)
-    lwz     13, (-2 * 4)(1)
-    lwz     14, (-3 * 4)(1)
-    lwz     15, (-4 * 4)(1)
-    lwz     16, (-5 * 4)(1)
-    lwz     17, (-6 * 4)(1)
-    lwz     18, (-7 * 4)(1)
-    lwz     19, (-8 * 4)(1)
-    lwz     20, (-9 * 4)(1)
-    lwz     21, (-10 * 4)(1)
-    lwz     22, (-11 * 4)(1)
-    lwz     23, (-12 * 4)(1)
-    lwz     24, (-13 * 4)(1)
-    lwz     25, (-14 * 4)(1)
-    lwz     26, (-15 * 4)(1)
-    lwz     27, (-16 * 4)(1)
-    lwz     28, (-17 * 4)(1)
-    lwz     29, (-18 * 4)(1)
-    lwz     30, (-19 * 4)(1)
-    lwz     31, (-20 * 4)(1)
-
-
-    /* Restore FPRs */
-    lfd     14, (-1 * 8)(4)
-    lfd     15, (-2 * 8)(4)
-    lfd     16, (-3 * 8)(4)
-    lfd     17, (-4 * 8)(4)
-    lfd     18, (-5 * 8)(4)
-    lfd     19, (-6 * 8)(4)
-    lfd     20, (-7 * 8)(4)
-    lfd     21, (-8 * 8)(4)
-    lfd     22, (-9 * 8)(4)
-    lfd     23, (-10 * 8)(4)
-    lfd     24, (-11 * 8)(4)
-    lfd     25, (-12 * 8)(4)
-    lfd     26, (-13 * 8)(4)
-    lfd     27, (-14 * 8)(4)
-    lfd     28, (-15 * 8)(4)
-    lfd     29, (-16 * 8)(4)
-    lfd     30, (-17 * 8)(4)
-    lfd     31, (-18 * 8)(4)
-
-    /* Set condition and link register */
-    mtcr        5
-    mtlr        0
-
-    /* Return and switch context */
-    blr
-
-#elif defined(__mips__) && _MIPS_SIM == _ABIO32
-/************************************************************************************
- * MIPS ASM BITS
- ************************************************************************************/
-
-/**
- * Performs a context switch.
- *
- * $a0 - void** - ptr to old stack pointer
- * $a1 - void*  - new stack pointer
- *
- */
-.text
-.globl fiber_switchContext
-fiber_switchContext:
-    addiu $sp, $sp, -(10 * 4)
-
-    // fp regs and return address are stored below the stack
-    // because we don't want the GC to scan them.
-
-#ifdef __mips_hard_float
-#define ALIGN8(val) (val + (-val & 7))
-#define BELOW (ALIGN8(6 * 8 + 4))
-    sdc1 $f20, (0 * 8 - BELOW)($sp)
-    sdc1 $f22, (1 * 8 - BELOW)($sp)
-    sdc1 $f24, (2 * 8 - BELOW)($sp)
-    sdc1 $f26, (3 * 8 - BELOW)($sp)
-    sdc1 $f28, (4 * 8 - BELOW)($sp)
-    sdc1 $f30, (5 * 8 - BELOW)($sp)
-#endif
-    sw $ra, -4($sp)
-
-    sw $s0, (0 * 4)($sp)
-    sw $s1, (1 * 4)($sp)
-    sw $s2, (2 * 4)($sp)
-    sw $s3, (3 * 4)($sp)
-    sw $s4, (4 * 4)($sp)
-    sw $s5, (5 * 4)($sp)
-    sw $s6, (6 * 4)($sp)
-    sw $s7, (7 * 4)($sp)
-    sw $s8, (8 * 4)($sp)
-    sw $gp, (9 * 4)($sp)
-
-    // swap stack pointer
-    sw $sp, 0($a0)
-    move $sp, $a1
-
-#ifdef __mips_hard_float
-    ldc1 $f20, (0 * 8 - BELOW)($sp)
-    ldc1 $f22, (1 * 8 - BELOW)($sp)
-    ldc1 $f24, (2 * 8 - BELOW)($sp)
-    ldc1 $f26, (3 * 8 - BELOW)($sp)
-    ldc1 $f28, (4 * 8 - BELOW)($sp)
-    ldc1 $f30, (5 * 8 - BELOW)($sp)
-#endif
-    lw $ra, -4($sp)
-
-    lw $s0, (0 * 4)($sp)
-    lw $s1, (1 * 4)($sp)
-    lw $s2, (2 * 4)($sp)
-    lw $s3, (3 * 4)($sp)
-    lw $s4, (4 * 4)($sp)
-    lw $s5, (5 * 4)($sp)
-    lw $s6, (6 * 4)($sp)
-    lw $s7, (7 * 4)($sp)
-    lw $s8, (8 * 4)($sp)
-    lw $gp, (9 * 4)($sp)
-
-    addiu $sp, $sp, (10 * 4)
-
-    jr $ra // return
-
-#elif defined(__arm__) && defined(__ARM_EABI__)
-/************************************************************************************
- * ARM ASM BITS
- ************************************************************************************/
-
-/**
- * Performs a context switch.
- *
- * Parameters:
- * r0 - void** - ptr to old stack pointer
- * r1 - void*  - new stack pointer
- *
- * ARM EABI registers:
- * r0-r3   : argument/scratch registers
- * r4-r10  : callee-save registers
- * r11     : frame pointer (or a callee save register if fp isn't needed)
- * r12 =ip : inter procedure register. We can treat it like any other scratch register
- * r13 =sp : stack pointer
- * r14 =lr : link register, it contains the return address (belonging to the function which called us)
- * r15 =pc : program counter
- *
- * For floating point registers:
- * According to AAPCS (version 2.09, section 5.1.2) only the d8-d15 registers need to be preserved
- * across method calls. This applies to all ARM FPU variants, whether they have 16 or 32 double registers
- * NEON support or not, half-float support or not and so on does not matter.
- *
- * Note: If this file was compiled with -mfloat-abi=soft but the code runs on a softfp system with fpu the d8-d15
- * registers won't be saved (we do not know that the system has got a fpu in that case) but the registers might actually
- * be used by other code if it was compiled with -mfloat-abi=softfp.
- *
- * Interworking is only supported on ARMv5+, not on ARM v4T as ARM v4t requires special stubs when changing
- * from thumb to arm mode or the other way round.
- */
-
-.text
-.align  2
-.global fiber_switchContext
-#if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__)) // ARM_HardFloat  || ARM_SoftFP
-  .fpu vfp
-#endif
-.type   fiber_switchContext, %function
-fiber_switchContext:
-    .fnstart
-    push {r4-r11}
-    // update the oldp pointer. Link register and floating point registers stored later to prevent the GC from
-    // scanning them.
-    str sp, [r0]
-    // push r0 (or any other register) as well to keep stack 8byte aligned
-    push {r0, lr}
-
-    #if defined(__ARM_PCS_VFP) || (defined(__ARM_PCS) && !defined(__SOFTFP__)) // ARM_HardFloat  || ARM_SoftFP
-      vpush {d8-d15}
-      // now switch over to the new stack. Need to subtract (8*8[d8-d15]+2*4[r0, lr]) to position stack pointer
-      // below the last saved register. Remember we saved the SP before pushing [r0, lr, d8-d15]
-      sub sp, r1, #72
-      vpop {d8-d15}
-    #else
-      sub sp, r1, #8
-    #endif
-
-    // we don't really care about r0, we only used that for padding.
-    // r1 is now what used to be in the link register when saving.
-    pop {r0, r1, r4-r11}
-    /**
-     * The link register for the initial jump to fiber_entryPoint must be zero: The jump actually
-     * looks like a normal method call as we jump to the start of the fiber_entryPoint function.
-     * Although fiber_entryPoint never returns and therefore never accesses lr, it saves lr to the stack.
-     * ARM unwinding will then look at the stack, find lr and think that fiber_entryPoint was called by
-     * the function in lr! So if we have some address in lr the unwinder will try to continue stack unwinding,
-     * although it's already at the stack base and crash.
-     * In all other cases the content of lr doesn't matter.
-     * Note: If we simply loaded into lr above and then moved lr into pc, the initial method call
-     * to fiber_entryPoint would look as if it was called from fiber_entryPoint itself, as the fiber_entryPoint
-     * address is in lr on the initial context switch.
-     */
-    mov lr, #0
-    // return by writing lr into pc
-    mov pc, r1
-    .fnend
-
-#elif defined(__aarch64__)
-/************************************************************************************
- * AArch64 (arm64) ASM BITS
- ************************************************************************************/
-/**
- * preserve/restore AAPCS64 registers
- *   x19-x28 5.1.1 64-bit callee saved
- *   x29 fp, or possibly callee saved reg - depends on platform choice 5.2.3)
- *   x30 lr
- *   d8-d15  5.1.2 says callee only must save bottom 64-bits (the "d" regs)
- *
- * saved regs on stack will look like:
- *   19: x19
- *   18: x20
- *   ...
- *   10: x28
- *    9: x29 (fp)  <-- oldp / *newp save stack top
- *    8: x30 (lr)
- *    7: d8
- *   ...
- *    0: d15       <-- sp
- */
-        .text
-        .global CSYM(fiber_switchContext)
-        .type   fiber_switchContext, %function
-        .p2align  2
-CSYM(fiber_switchContext):
-        stp     d15, d14, [sp, #-20*8]!
-        stp     d13, d12, [sp, #2*8]
-        stp     d11, d10, [sp, #4*8]
-        stp     d9, d8,   [sp, #6*8]
-        stp     x30, x29, [sp, #8*8] // lr, fp
-        stp     x28, x27, [sp, #10*8]
-        stp     x26, x25, [sp, #12*8]
-        stp     x24, x23, [sp, #14*8]
-        stp     x22, x21, [sp, #16*8]
-        stp     x20, x19, [sp, #18*8]
-
-        // oldp is set above saved lr (x30) to hide it and float regs
-        // from GC
-        add     x19, sp, #9*8
-        str     x19, [x0]       // *oldp tstack
-        sub     sp, x1, #9*8    // switch to newp sp
-
-        ldp     x20, x19, [sp, #18*8]
-        ldp     x22, x21, [sp, #16*8]
-        ldp     x24, x23, [sp, #14*8]
-        ldp     x26, x25, [sp, #12*8]
-        ldp     x28, x27, [sp, #10*8]
-        ldp     x30, x29, [sp, #8*8] // lr, fp
-        ldp     d9, d8,   [sp, #6*8]
-        ldp     d11, d10, [sp, #4*8]
-        ldp     d13, d12, [sp, #2*8]
-        ldp     d15, d14, [sp], #20*8
-        ret
-
-
-/**
- * When generating any kind of backtrace (gdb, exception handling) for
- * a function called in a Fiber, we need to tell the unwinder to stop
- * at our Fiber main entry point, i.e. we need to mark the bottom of
- * the call stack. This can be done by clearing the link register lr
- * prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or
- * using a .cfi_undefined directive for the link register in the
- * Fiber entry point. cfi_undefined seems to yield better results in gdb.
- * Unfortunately we can't place it into fiber_entryPoint using inline
- * asm, so we use this trampoline instead.
- */
-        .text
-        .global CSYM(fiber_trampoline)
-        .p2align  2
-        .type   fiber_trampoline, %function
-CSYM(fiber_trampoline):
-        .cfi_startproc
-        .cfi_undefined x30
-        // fiber_entryPoint never returns
-        bl fiber_entryPoint
-        .cfi_endproc
-
-#elif defined(__MINGW32__)
-/************************************************************************************
- * GDC MinGW ASM BITS
- ************************************************************************************/
-#if defined(__x86_64__)
-.global fiber_switchContext
-fiber_switchContext:
-    pushq %RBP;
-    movq %RSP, %RBP;
-    pushq %RBX;
-    pushq %R12;
-    pushq %R13;
-    pushq %R14;
-    pushq %R15;
-    pushq %GS:0;
-    pushq %GS:8;
-    pushq %GS:16;
-
-    // store oldp
-    movq %RSP, (%RCX);
-    // load newp to begin context switch
-    movq %RDX, %RSP;
-
-    // load saved state from new stack
-    popq %GS:16;
-    popq %GS:8;
-    popq %GS:0;
-    popq %R15;
-    popq %R14;
-    popq %R13;
-    popq %R12;
-    popq %RBX;
-    popq %RBP;
-
-    // 'return' to complete switch
-    popq %RCX;
-    jmp *%RCX;
-#elif defined(_X86_)
-.global _fiber_switchContext
-_fiber_switchContext:
-    // Save current stack state.save current stack state
-    // Standard CDECL prologue.
-    push %EBP;
-    mov  %ESP, %EBP;
-    push %EDI;
-    push %ESI;
-    push %EBX;
-    push %FS:0;
-    push %FS:4;
-    push %FS:8;
-    push %EAX;
-
-    // store oldp again with more accurate address
-    mov 8(%EBP), %EAX;
-    mov %ESP, (%EAX);
-    // load newp to begin context switch
-    mov 12(%EBP), %ESP;
-
-    // load saved state from new stack
-    pop %EAX;
-    pop %FS:8;
-    pop %FS:4;
-    pop %FS:0;
-    pop %EBX;
-    pop %ESI;
-    pop %EDI;
-    pop %EBP;
-
-    // 'return' to complete switch
-    ret;
-#endif
-
-// if POSIX boils down to this (reference http://nadeausoftware.com)
-#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
-/************************************************************************************
- * i386- and x86_64-apple-darwin POSIX ASM BITS
- ************************************************************************************/
-#if defined(__i386__)
-.text
-.p2align 4
-.globl CSYM(fiber_switchContext)
-CSYM(fiber_switchContext):
-    // save current stack state
-    push %ebp
-    mov  %esp, %ebp
-    push %edi
-    push %esi
-    push %ebx
-    push %eax
-
-    // store oldp again with more accurate address
-    mov 8(%ebp), %eax
-    mov %esp, (%eax)
-    // load newp to begin context switch
-    mov 12(%ebp), %esp
-
-    // load saved state from new stack
-    pop %eax
-    pop %ebx
-    pop %esi
-    pop %edi
-    pop %ebp
-
-    // 'return' to complete switch
-    ret
-
-#elif defined(__x86_64__) && !defined(__ILP32__)
-.text
-.p2align 4
-.globl CSYM(fiber_switchContext)
-CSYM(fiber_switchContext):
-    // Save current stack state.save current stack state
-    push %rbp
-    mov  %rsp, %rbp
-    push %rbx
-    push %r12
-    push %r13
-    push %r14
-    push %r15
-
-    // store oldp again with more accurate address
-    mov %rsp, (%rdi)
-    // load newp to begin context switch
-    mov %rsi, %rsp
-
-    // load saved state from new stack
-    pop %r15
-    pop %r14
-    pop %r13
-    pop %r12
-    pop %rbx
-    pop %rbp
-
-    // 'return' to complete switch
-    ret
-#endif	// __x86_64__ && !__ILP32__
-
-#endif	// posix
diff --git a/libphobos/m4/druntime/cpu.m4 b/libphobos/m4/druntime/cpu.m4
index 7f7b1382f60..4795edaa78d 100644
--- a/libphobos/m4/druntime/cpu.m4
+++ b/libphobos/m4/druntime/cpu.m4
@@ -3,6 +3,44 @@ 
 #
 
 
+# DRUNTIME_CPU_SOURCES
+# -------------------
+# Detect target CPU and add DRUNTIME_CPU_XXX conditionals.
+AC_DEFUN([DRUNTIME_CPU_SOURCES],
+[
+  druntime_target_cpu_parsed=""
+  case "$target_cpu" in
+      aarch64*)
+               druntime_target_cpu_parsed="aarch64"
+               ;;
+      arm*)    druntime_target_cpu_parsed="arm"
+               ;;
+      mips*)   druntime_target_cpu_parsed="mips"
+               ;;
+      powerpc) druntime_target_cpu_parsed="powerpc"
+               ;;
+      powerpc64)
+               druntime_target_cpu_parsed="powerpc64"
+               ;;
+      i[34567]86|x86_64)
+               druntime_target_cpu_parsed="x86"
+               ;;
+  esac
+  AM_CONDITIONAL([DRUNTIME_CPU_AARCH64],
+                 [test "$druntime_target_cpu_parsed" = "aarch64"])
+  AM_CONDITIONAL([DRUNTIME_CPU_ARM],
+                 [test "$druntime_target_cpu_parsed" = "arm"])
+  AM_CONDITIONAL([DRUNTIME_CPU_MIPS],
+                 [test "$druntime_target_cpu_parsed" = "mips"])
+  AM_CONDITIONAL([DRUNTIME_CPU_POWERPC],
+                 [test "$druntime_target_cpu_parsed" = "powerpc"])
+  AM_CONDITIONAL([DRUNTIME_CPU_POWERPC64],
+                 [test "$druntime_target_cpu_parsed" = "powerpc64"])
+  AM_CONDITIONAL([DRUNTIME_CPU_X86],
+                 [test "$druntime_target_cpu_parsed" = "x86"])
+])
+
+
 # DRUNTIME_ENABLE_ATOMIC_BUILTINS
 # -------------------------
 # Check support for atomic builtins up to 64 bit.