public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/mingw)] Sync druntime
@ 2021-04-19 14:10 Iain Buclaw
  0 siblings, 0 replies; 2+ messages in thread
From: Iain Buclaw @ 2021-04-19 14:10 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5cebea340615e0f83834d13c56c72303b24f7d6f

commit 5cebea340615e0f83834d13c56c72303b24f7d6f
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Mon Apr 19 13:51:02 2021 +0200

    Sync druntime

Diff:
---
 libphobos/libdruntime/core/stdc/config.d           |  39 ++-
 libphobos/libdruntime/core/stdc/math.d             | 295 +++++++++++----------
 libphobos/libdruntime/core/stdc/stdio.d            |  82 +++++-
 libphobos/libdruntime/core/stdc/stdlib.d           |  27 +-
 libphobos/libdruntime/core/stdc/tgmath.d           |   7 +
 .../libdruntime/core/sys/darwin/mach/thread_act.d  |  66 +++++
 .../libdruntime/core/sys/openbsd/sys/link_elf.d    |   5 +
 libphobos/libdruntime/core/sys/posix/stdio.d       |  50 ++++
 libphobos/libdruntime/core/sys/windows/com.d       |   4 +-
 libphobos/libdruntime/core/sys/windows/dbghelp.d   |   2 +-
 libphobos/libdruntime/core/sys/windows/dll.d       |   4 +-
 libphobos/libdruntime/core/sys/windows/threadaux.d |   4 +-
 libphobos/libdruntime/core/thread/fiber.d          |  42 ++-
 libphobos/libdruntime/core/thread/osthread.d       |  44 ++-
 libphobos/libdruntime/core/thread/threadbase.d     |   3 +
 15 files changed, 471 insertions(+), 203 deletions(-)

diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index 802f5b6fb21..44bb7077b59 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -186,7 +186,18 @@ else version (Posix)
   }
 }
 
-version (CRuntime_Microsoft)
+version (GNU)
+    alias c_long_double = real;
+else version (LDC)
+    alias c_long_double = real; // 64-bit real for MSVC targets
+else version (SDC)
+{
+    version (X86)
+        alias c_long_double = real;
+    else version (X86_64)
+        alias c_long_double = real;
+}
+else version (CRuntime_Microsoft)
 {
     /* long double is 64 bits, not 80 bits, but is mangled differently
      * than double. To distinguish double from long double, create a wrapper to represent
@@ -222,17 +233,6 @@ else version (DigitalMars)
             alias real c_long_double;
     }
 }
-else version (GNU)
-    alias real c_long_double;
-else version (LDC)
-    alias real c_long_double;
-else version (SDC)
-{
-    version (X86)
-        alias real c_long_double;
-    else version (X86_64)
-        alias real c_long_double;
-}
 
 static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
 
@@ -257,18 +257,9 @@ private struct _Complex(T)
     T im;
 }
 
-version (Posix)
-{
-    align(float.alignof)  enum __c_complex_float : _Complex!float;
-    align(double.alignof) enum __c_complex_double : _Complex!double;
-    align(real.alignof)   enum __c_complex_real : _Complex!real;
-}
-else
-{
-    align(float.sizeof * 2)  enum __c_complex_float : _Complex!float;
-    align(double.sizeof * 2) enum __c_complex_double : _Complex!double;
-    align(real.alignof)      enum __c_complex_real : _Complex!real;
-}
+enum __c_complex_float  : _Complex!float;
+enum __c_complex_double : _Complex!double;
+enum __c_complex_real   : _Complex!c_long_double;
 
 alias c_complex_float = __c_complex_float;
 alias c_complex_double = __c_complex_double;
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index fba78ee233a..2de6e579575 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -424,92 +424,177 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o
     pure int _fpclass(double x);
   }
 
+  version (MinGW)
+  {
     enum
     {
         ///
-        FP_SUBNORMAL = -2,
+        FP_NAN = 0x0100,
         ///
-        FP_NORMAL    = -1,
+        FP_NORMAL = 0x0400,
         ///
-        FP_ZERO      =  0,
+        FP_INFINITE = FP_NAN | FP_NORMAL,
         ///
-        FP_INFINITE  =  1,
+        FP_ZERO = 0x0400,
         ///
-        FP_NAN       =  2,
+        FP_SUBNORMAL = FP_NORMAL | FP_ZERO
     }
 
-  extern(D)
-  {
-    //int fpclassify(real-floating x);
-    ///
-    extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
-    ///
-    extern(C) pragma(mangle, "_dclass")  pure int fpclassify(double x);
-    ///
-    pure int fpclassify()(real x)
-    {
-        static if (real.sizeof == double.sizeof)
-            return fpclassify(cast(double) x);
-        else
-            static assert(false, "fpclassify(real) not supported by MS C runtime");
-    }
+    pure int __fpclassifyf(float x);
+    pure int __fpclassify(double x);
+    pure int __fpclassifyl(real x);
 
-    //int isfinite(real-floating x);
-    ///
-    pure int isfinite()(float x)     { return fpclassify(x) <= 0; }
-    ///
-    pure int isfinite()(double x)    { return fpclassify(x) <= 0; }
-    ///
-    pure int isfinite()(real x)      { return fpclassify(x) <= 0; }
+    pure int __isnanf(float x);
+    pure int __isnan(double x);
+    pure int __isnanl(real x);
 
-    //int isinf(real-floating x);
-    ///
-    pure int isinf()(float x)        { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf()(double x)       { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf()(real x)         { return fpclassify(x) == FP_INFINITE; }
+    pure int __signbitf(float x);
+    pure int __signbit(double x);
+    pure int __signbitl(real x);
 
-    //int isnan(real-floating x);
-    version (none) // requires MSVCRT 12+ (VS 2013)
+    extern (D)
     {
+        //int fpclassify(real-floating x);
+        ///
+        extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
+        ///
+        extern(C) pragma(mangle, "__fpclassify")  pure int fpclassify(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+            pure int fpclassify(real x);
+
+        //int isfinite(real-floating x);
+        ///
+        pure int isfinite(float x)       { return (fpclassify(x) & FP_NORMAL) == 0; }
         ///
-        pure int isnan(float x)      { return fpclassify(x) == FP_NAN; }
+        pure int isfinite(double x)      { return (fpclassify(x) & FP_NORMAL) == 0; }
         ///
-        pure int isnan(double x)     { return fpclassify(x) == FP_NAN; }
+        pure int isfinite(real x)        { return (fpclassify(x) & FP_NORMAL) == 0; }
+
+        //int isinf(real-floating x);
+        ///
+        pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }
+
+        //int isnan(real-floating x);
         ///
-        pure int isnan(real x)       { return fpclassify(x) == FP_NAN; }
+        extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
+        ///
+        extern(C) pragma(mangle, "__isnan")  pure int isnan(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+            pure int isnan(real x);
+
+        //int isnormal(real-floating x);
+        ///
+        int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }
+        ///
+        int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }
+        ///
+        int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }
+
+        //int signbit(real-floating x);
+        ///
+        extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
+        ///
+        extern(C) pragma(mangle, "__signbit")  pure int signbit(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+            int signbit(real x);
     }
-    else // for backward compatibility with older runtimes
+  }
+  else
+  {
+    enum
     {
         ///
-        pure int isnan(float x)      { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+        FP_SUBNORMAL = -2,
+        ///
+        FP_NORMAL    = -1,
         ///
-        extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+        FP_ZERO      =  0,
         ///
-        pure int isnan(real x)       { return _isnan(cast(double) x); }
+        FP_INFINITE  =  1,
+        ///
+        FP_NAN       =  2,
     }
 
-    //int isnormal(real-floating x);
-    ///
-    pure int isnormal()(float x)     { return fpclassify(x) == FP_NORMAL; }
-    ///
-    pure int isnormal()(double x)    { return fpclassify(x) == FP_NORMAL; }
-    ///
-    pure int isnormal()(real x)      { return fpclassify(x) == FP_NORMAL; }
-
-    //int signbit(real-floating x);
-    ///
-    extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
-    ///
-    extern(C) pragma(mangle, "_dsign")  pure int signbit(double x);
-    ///
-    pure int signbit()(real x)
+    extern(D)
     {
-        static if (real.sizeof == double.sizeof)
-            return signbit(cast(double) x);
-        else
-            return (cast(short*)&(x))[4] & 0x8000;
+        //int fpclassify(real-floating x);
+        ///
+        extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
+        ///
+        extern(C) pragma(mangle, "_dclass")  pure int fpclassify(double x);
+        ///
+        pure int fpclassify()(real x)
+        {
+            static if (real.sizeof == double.sizeof)
+                return fpclassify(cast(double) x);
+            else
+                static assert(false, "fpclassify(real) not supported by MS C runtime");
+        }
+
+        //int isfinite(real-floating x);
+        ///
+        pure int isfinite()(float x)     { return fpclassify(x) <= 0; }
+        ///
+        pure int isfinite()(double x)    { return fpclassify(x) <= 0; }
+        ///
+        pure int isfinite()(real x)      { return fpclassify(x) <= 0; }
+
+        //int isinf(real-floating x);
+        ///
+        pure int isinf()(float x)        { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf()(double x)       { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf()(real x)         { return fpclassify(x) == FP_INFINITE; }
+
+        //int isnan(real-floating x);
+        version (none) // requires MSVCRT 12+ (VS 2013)
+        {
+            ///
+            pure int isnan(float x)      { return fpclassify(x) == FP_NAN; }
+            ///
+            pure int isnan(double x)     { return fpclassify(x) == FP_NAN; }
+            ///
+            pure int isnan(real x)       { return fpclassify(x) == FP_NAN; }
+        }
+        else // for backward compatibility with older runtimes
+        {
+            ///
+            pure int isnan(float x)      { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+            ///
+            extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+            ///
+            pure int isnan(real x)       { return _isnan(cast(double) x); }
+        }
+
+        //int isnormal(real-floating x);
+        ///
+        pure int isnormal()(float x)     { return fpclassify(x) == FP_NORMAL; }
+        ///
+        pure int isnormal()(double x)    { return fpclassify(x) == FP_NORMAL; }
+        ///
+        pure int isnormal()(real x)      { return fpclassify(x) == FP_NORMAL; }
+
+        //int signbit(real-floating x);
+        ///
+        extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
+        ///
+        extern(C) pragma(mangle, "_dsign")  pure int signbit(double x);
+        ///
+        pure int signbit()(real x)
+        {
+            static if (real.sizeof == double.sizeof)
+                return signbit(cast(double) x);
+            else
+                return (cast(short*)&(x))[4] & 0x8000;
+        }
     }
   }
 }
@@ -835,88 +920,6 @@ else version (CRuntime_UClibc)
     int signbit(real x);
   }
 }
-else version (MinGW)
-{
-    enum
-    {
-        ///
-        FP_NAN = 0x0100,
-        ///
-        FP_NORMAL = 0x0400,
-        ///
-        FP_INFINITE = FP_NAN | FP_NORMAL,
-        ///
-        FP_ZERO = 0x0400,
-        ///
-        FP_SUBNORMAL = FP_NORMAL | FP_ZERO
-    }
-
-    pure int __fpclassifyf(float x);
-    pure int __fpclassify(double x);
-    pure int __fpclassifyl(real x);
-
-    pure int __isnanf(float x);
-    pure int __isnan(double x);
-    pure int __isnanl(real x);
-
-    pure int __signbitf(float x);
-    pure int __signbit(double x);
-    pure int __signbitl(real x);
-
-  extern (D)
-  {
-    //int fpclassify(real-floating x);
-      ///
-    extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
-    ///
-    extern(C) pragma(mangle, "__fpclassify")  pure int fpclassify(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
-    pure int fpclassify(real x);
-
-    //int isfinite(real-floating x);
-    ///
-    pure int isfinite(float x)       { return (fpclassify(x) & FP_NORMAL) == 0; }
-    ///
-    pure int isfinite(double x)      { return (fpclassify(x) & FP_NORMAL) == 0; }
-    ///
-    pure int isfinite(real x)        { return (fpclassify(x) & FP_NORMAL) == 0; }
-
-    //int isinf(real-floating x);
-    ///
-    pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }
-
-    //int isnan(real-floating x);
-    ///
-    extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
-    ///
-    extern(C) pragma(mangle, "__isnan")  pure int isnan(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
-    pure int isnan(real x);
-
-    //int isnormal(real-floating x);
-    ///
-    int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }
-    ///
-    int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }
-    ///
-    int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }
-
-    //int signbit(real-floating x);
-    ///
-    extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
-    ///
-    extern(C) pragma(mangle, "__signbit")  pure int signbit(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
-    int signbit(real x);
-  }
-}
 else version (Darwin)
 {
     enum
@@ -1166,7 +1169,7 @@ else version (OpenBSD)
         FP_FAST_FMAL = 1,
     }
 
-    pure int __fpclassifyd(double);
+    pure int __fpclassify(double);
     pure int __fpclassifyf(float);
     pure int __fpclassifyl(real);
     pure int __isfinitef(float);
@@ -1188,7 +1191,7 @@ else version (OpenBSD)
       ///
     extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
     ///
-    extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
+    extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
     ///
     extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
 
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index 532a0803f55..c76b922a3eb 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -1347,7 +1347,7 @@ version (CRuntime_DigitalMars)
     ///
     pure int  fileno()(FILE* stream)   { return stream._file; }
   }
-  ///
+    ///
     pragma(printf)
     int   _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
     ///
@@ -1358,6 +1358,26 @@ version (CRuntime_DigitalMars)
     int   _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
     ///
     alias _vsnprintf vsnprintf;
+
+    //
+    // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
+    // unshared version of FILE*, usable when the FILE is locked.
+    //
+
+    ///
+    int _fputc_nlock(int c, _iobuf* fp);
+    ///
+    int _fputwc_nlock(int c, _iobuf* fp);
+    ///
+    int _fgetc_nlock(_iobuf* fp);
+    ///
+    int _fgetwc_nlock(_iobuf* fp);
+    ///
+    int __fp_lock(FILE* fp);
+    ///
+    void __fp_unlock(FILE* fp);
+    ///
+    int setmode(int fd, int mode);
 }
 else version (CRuntime_Microsoft)
 {
@@ -1410,16 +1430,31 @@ else version (CRuntime_Microsoft)
     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
   }
 
+    //
+    // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared
+    // version of FILE*, usable when the FILE is locked.
+    //
+    import core.stdc.stddef : wchar_t;
+    import core.stdc.wchar_ : wint_t;
+
     ///
-    int _fputc_nolock(int c, FILE *fp);
+    int _fputc_nolock(int c, _iobuf* fp);
     ///
-    int _fgetc_nolock(FILE *fp);
-
+    int _fgetc_nolock(_iobuf* fp);
     ///
-    int _lock_file(FILE *fp);
+    wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
     ///
-    int _unlock_file(FILE *fp);
-
+    wint_t _fgetwc_nolock(_iobuf* fp);
+    ///
+    void _lock_file(FILE* fp);
+    ///
+    void _unlock_file(FILE* fp);
+    ///
+    int _setmode(int fd, int mode);
+    ///
+    int _fseeki64(FILE* stream, long offset, int origin);
+    ///
+    long _ftelli64(FILE* stream);
     ///
     intptr_t _get_osfhandle(int fd);
     ///
@@ -1448,6 +1483,23 @@ else version (CRuntime_Glibc)
     ///
     pragma(printf)
     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+
+    //
+    // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared
+    // version of FILE*, usable when the FILE is locked.
+    // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html
+    //
+    import core.stdc.wchar_ : wint_t;
+    import core.stdc.stddef : wchar_t;
+
+    ///
+    int fputc_unlocked(int c, _iobuf* stream);
+    ///
+    int fgetc_unlocked(_iobuf* stream);
+    ///
+    wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream);
+    ///
+    wint_t fgetwc_unlocked(_iobuf* stream);
 }
 else version (Darwin)
 {
@@ -1907,6 +1959,22 @@ version (Windows)
         O_TEXT = _O_TEXT, ///
         _O_BINARY = 0x8000, ///
         O_BINARY = _O_BINARY, ///
+        _O_WTEXT = 0x10000, ///
+        _O_U16TEXT = 0x20000, ///
+        _O_U8TEXT = 0x40000, ///
+        _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), ///
+        O_ACCMODE = _O_ACCMODE, ///
+        _O_RAW = _O_BINARY, ///
+        O_RAW = _O_BINARY, ///
+        _O_NOINHERIT = 0x0080, ///
+        O_NOINHERIT = _O_NOINHERIT, ///
+        _O_TEMPORARY = 0x0040, ///
+        O_TEMPORARY = _O_TEMPORARY, ///
+        _O_SHORT_LIVED = 0x1000, ///
+        _O_SEQUENTIAL = 0x0020, ///
+        O_SEQUENTIAL = _O_SEQUENTIAL, ///
+        _O_RANDOM = 0x0010, ///
+        O_RANDOM = _O_RANDOM, ///
     }
 
     enum
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 5d69b880bc8..35e81a25414 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong   strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
 
 version (CRuntime_Microsoft)
 {
-    // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
-    ///
-    extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
-    {   // Fake it 'till we make it
-        return strtod(nptr, endptr);
+    version (MinGW)
+    {
+        ///
+        real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+        ///
+        alias __mingw_strtold strtold;
+    }
+    else
+    {
+        // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+        ///
+        extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+        {   // Fake it 'till we make it
+            return strtod(nptr, endptr);
+        }
     }
-}
-else version (MinGW)
-{
-    ///
-    real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
-    ///
-    alias __mingw_strtold strtold;
 }
 else
 {
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 2ff1522fd81..2d1a198543f 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1285,6 +1285,13 @@ else
     alias core.stdc.math.fabs          fabs;
     version (CRuntime_Microsoft)
     {
+        version (MinGW)
+        {
+            ///
+            alias core.stdc.math.fabsf     fabs;
+            ///
+            alias core.stdc.math.fabsl     fabs;
+        }
     }
     else
     {
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
index b61673fb4f1..d455d1b8303 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
@@ -38,6 +38,10 @@ version (AArch64)
     version = AnyARM;
 version (ARM)
     version = AnyARM;
+version (PPC)
+    version = AnyPPC;
+version (PPC64)
+    version = AnyPPC;
 
 version (i386)
 {
@@ -235,3 +239,65 @@ else version (AnyARM)
     kern_return_t thread_resume(thread_act_t);
     kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
 }
+else version (AnyPPC)
+{
+    alias thread_act_t = mach_port_t;
+    alias thread_state_t = void;
+    alias thread_state_flavor_t = int;
+    alias mach_msg_type_number_t = natural_t;
+
+    enum
+    {
+        PPC_THREAD_STATE = 1,
+        PPC_FLOAT_STATE = 2,
+        PPC_EXCEPTION_STATE = 3,
+        PPC_VECTOR_STATE = 4,
+        PPC_THREAD_STATE64 = 5,
+        PPC_EXCEPTION_STATE64 = 6,
+        THREAD_STATE_NONE = 7
+    }
+
+    struct ppc_thread_state_t
+    {
+        uint srr0;   /// Instruction address register (PC)
+        uint srr1;   /// Machine state register (supervisor)
+        uint[32] r;  /// General purpose register r0-r31
+        uint cr;     /// Condition register
+        uint xer;    /// User's integer exception register
+        uint lr;     /// Link register
+        uint ctr;    /// Count register
+        uint mq;     /// MQ register (601 only)
+        uint vrsave; /// Vector save register
+    }
+
+    alias ppc_thread_state32_t = ppc_thread_state_t;
+
+    struct ppc_thread_state64_t
+    {
+        ulong srr0;   /// Instruction address register (PC)
+        ulong srr1;   /// Machine state register (supervisor)
+        ulong[32] r;  /// General purpose register r0-r31
+        uint cr;      /// Condition register
+        uint pad0;
+        ulong xer;    /// User's integer exception register
+        ulong lr;     /// Link register
+        ulong ctr;    /// Count register
+        uint vrsave;  /// Vector save register
+        uint pad1;
+    }
+
+    enum : mach_msg_type_number_t
+    {
+        PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof),
+        PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof),
+        PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof),
+    }
+
+    alias MACHINE_THREAD_STATE = PPC_THREAD_STATE;
+    alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT;
+
+    mach_port_t   mach_thread_self();
+    kern_return_t thread_suspend(thread_act_t);
+    kern_return_t thread_resume(thread_act_t);
+    kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
+}
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
index f88671a3160..55fc79268e2 100644
--- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
@@ -63,3 +63,8 @@ private alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_
 
 int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
 int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
+
+int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc
+{
+    return 0;
+}
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 031bcb7341f..41b52da7c64 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -516,6 +516,46 @@ version (CRuntime_Glibc)
     int    putc_unlocked(int, FILE*);
     int    putchar_unlocked(int);
 }
+else version (CRuntime_Musl)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (Darwin)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (FreeBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (NetBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
 else version (OpenBSD)
 {
     void   flockfile(FILE*);
@@ -526,6 +566,16 @@ else version (OpenBSD)
     int    putc_unlocked(int, FILE*);
     int    putchar_unlocked(int);
 }
+else version (DragonFlyBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
 else version (Solaris)
 {
     void   flockfile(FILE*);
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 88007adb141..6935dd94f95 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY   = COINIT.COINIT_SPEED_OVER_MEMORY;
 
 public import core.sys.windows.uuid;
 
-extern (System)
+extern (Windows)
 {
 
 class ComObject : IUnknown
 {
-extern (System):
+extern (Windows):
     HRESULT QueryInterface(const(IID)* riid, void** ppv)
     {
         if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
 
 public import core.sys.windows.dbghelp_types;
 
-extern(System)
+extern(Windows)
 {
     alias BOOL         function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
     alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 3df0d7fd41b..cc2422bcaa0 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -414,7 +414,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
     {
         version (GNU_InlineAsm)
         {
-            asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; }
+            asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
         }
         else
         {
@@ -431,7 +431,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
     {
         version (GNU_InlineAsm)
         {
-            asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; }
+            asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
         }
         else
         {
diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d
index fb4d1ee64ba..34fda656c8c 100644
--- a/libphobos/libdruntime/core/sys/windows/threadaux.d
+++ b/libphobos/libdruntime/core/sys/windows/threadaux.d
@@ -172,7 +172,7 @@ struct thread_aux
             version (GNU_InlineAsm)
             {
                 void** teb;
-                asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" teb; }
+                asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
                 return teb;
             }
             else
@@ -190,7 +190,7 @@ struct thread_aux
             version (GNU_InlineAsm)
             {
                 void** teb;
-                asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" teb; }
+                asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); }
                 return teb;
             }
             else
diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d
index 67d9937e31a..f4c04ce7358 100644
--- a/libphobos/libdruntime/core/thread/fiber.d
+++ b/libphobos/libdruntime/core/thread/fiber.d
@@ -82,6 +82,8 @@ private
 
             version (MinGW)
                 version = GNU_AsmX86_Windows;
+            else version (OSX)
+                version = AsmX86_Posix;
             else version (Posix)
                 version = AsmX86_Posix;
         }
@@ -105,13 +107,21 @@ private
 
             version (MinGW)
                 version = GNU_AsmX86_64_Windows;
+            else version (OSX)
+                version = AsmX86_64_Posix;
             else version (Posix)
                 version = AsmX86_64_Posix;
         }
     }
     else version (PPC)
     {
-        version (Posix)
+        version (OSX)
+        {
+            version = AsmPPC_Darwin;
+            version = AsmExternal;
+            version = AlignFiberStackTo16Byte;
+        }
+        else version (Posix)
         {
             version = AsmPPC_Posix;
             version = AsmExternal;
@@ -119,7 +129,13 @@ private
     }
     else version (PPC64)
     {
-        version (Posix)
+        version (OSX)
+        {
+            version = AsmPPC_Darwin;
+            version = AsmExternal;
+            version = AlignFiberStackTo16Byte;
+        }
+        else version (Posix)
         {
             version = AlignFiberStackTo16Byte;
         }
@@ -1347,6 +1363,28 @@ private:
 
             assert( (cast(size_t) pstack & 0x0f) == 0 );
         }
+        else version (AsmPPC_Darwin)
+        {
+            version (StackGrowsDown) {}
+            else static assert(false, "PowerPC Darwin only supports decrementing stacks");
+
+            uint wsize = size_t.sizeof;
+
+            // linkage + regs + FPRs + VRs
+            uint space = 8 * wsize + 20 * wsize + 18 * 8 + 12 * 16;
+            (cast(ubyte*)pstack - space)[0 .. space] = 0;
+
+            pstack -= wsize * 6;
+            *cast(size_t*)pstack = cast(size_t) &fiber_entryPoint; // LR
+            pstack -= wsize * 22;
+
+            // On Darwin PPC64 pthread self is in R13 (which is reserved).
+            // At present, it is not safe to migrate fibers between threads, but if that
+            // changes, then updating the value of R13 will also need to be handled.
+            version (PPC64)
+              *cast(size_t*)(pstack + wsize) = cast(size_t) Thread.getThis().m_addr;
+            assert( (cast(size_t) pstack & 0x0f) == 0 );
+        }
         else version (AsmMIPS_O32_Posix)
         {
             version (StackGrowsDown) {}
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index 0fffc7ed3f7..31764e69691 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -349,7 +349,8 @@ class Thread : ThreadBase
         }
         else version (Posix)
         {
-            pthread_detach( m_addr );
+            if (m_addr != m_addr.init)
+                pthread_detach( m_addr );
             m_addr = m_addr.init;
         }
         version (Darwin)
@@ -420,6 +421,17 @@ class Thread : ThreadBase
         {
             uint[16]        m_reg; // r0-r15
         }
+        else version (PPC)
+        {
+            // Make the assumption that we only care about non-fp and non-vr regs.
+            // ??? : it seems plausible that a valid address can be copied into a VR.
+            uint[32]        m_reg; // r0-31
+        }
+        else version (PPC64)
+        {
+            // As above.
+            ulong[32]       m_reg; // r0-31
+        }
         else
         {
             static assert(false, "Architecture not supported." );
@@ -578,7 +590,7 @@ class Thread : ThreadBase
     {
         version (Windows)
         {
-            if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
+            if ( m_addr != m_addr.init && WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
                 throw new ThreadException( "Unable to join thread" );
             // NOTE: m_addr must be cleared before m_hndl is closed to avoid
             //       a race condition with isRunning. The operation is done
@@ -589,7 +601,7 @@ class Thread : ThreadBase
         }
         else version (Posix)
         {
-            if ( pthread_join( m_addr, null ) != 0 )
+            if ( m_addr != m_addr.init && pthread_join( m_addr, null ) != 0 )
                 throw new ThreadException( "Unable to join thread" );
             // NOTE: pthread_join acts as a substitute for pthread_detach,
             //       which is normally called by the dtor.  Setting m_addr
@@ -1629,9 +1641,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
             void *bottom;
 
             version (X86)
-                asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+                asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
             else version (X86_64)
-                asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+                asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
             else
                 static assert(false, "Platform not supported.");
 
@@ -1880,6 +1892,28 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc
             t.m_reg[14] = state.lr;
             t.m_reg[15] = state.pc;
         }
+        else version (PPC)
+        {
+            ppc_thread_state_t state = void;
+            mach_msg_type_number_t count = PPC_THREAD_STATE_COUNT;
+
+            if (thread_get_state(t.m_tmach, PPC_THREAD_STATE, &state, &count) != KERN_SUCCESS)
+                onThreadError("Unable to load thread state");
+            if (!t.m_lock)
+                t.m_curr.tstack = cast(void*) state.r[1];
+            t.m_reg[] = state.r[];
+        }
+        else version (PPC64)
+        {
+            ppc_thread_state64_t state = void;
+            mach_msg_type_number_t count = PPC_THREAD_STATE64_COUNT;
+
+            if (thread_get_state(t.m_tmach, PPC_THREAD_STATE64, &state, &count) != KERN_SUCCESS)
+                onThreadError("Unable to load thread state");
+            if (!t.m_lock)
+                t.m_curr.tstack = cast(void*) state.r[1];
+            t.m_reg[] = state.r[];
+        }
         else
         {
             static assert(false, "Architecture not supported." );
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
index 50795e444be..0a8de10e17b 100644
--- a/libphobos/libdruntime/core/thread/threadbase.d
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -10,6 +10,9 @@
  * Source:    $(DRUNTIMESRC core/thread/osthread.d)
  */
 
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
 module core.thread.threadbase;
 
 import core.thread.context;


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc(refs/users/ibuclaw/heads/mingw)] Sync druntime
@ 2021-04-19 14:16 Iain Buclaw
  0 siblings, 0 replies; 2+ messages in thread
From: Iain Buclaw @ 2021-04-19 14:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:acf8e40a258b668abeba4b1ab800aae6e46981b7

commit acf8e40a258b668abeba4b1ab800aae6e46981b7
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Mon Apr 19 13:51:02 2021 +0200

    Sync druntime

Diff:
---
 libphobos/libdruntime/core/stdc/config.d           |  39 ++-
 libphobos/libdruntime/core/stdc/math.d             | 295 +++++++++++----------
 libphobos/libdruntime/core/stdc/stdio.d            |  82 +++++-
 libphobos/libdruntime/core/stdc/stdlib.d           |  27 +-
 libphobos/libdruntime/core/stdc/tgmath.d           |   7 +
 .../libdruntime/core/sys/darwin/mach/thread_act.d  |  66 +++++
 .../libdruntime/core/sys/openbsd/sys/link_elf.d    |   5 +
 libphobos/libdruntime/core/sys/posix/stdio.d       |  50 ++++
 libphobos/libdruntime/core/sys/windows/com.d       |   4 +-
 libphobos/libdruntime/core/sys/windows/dbghelp.d   |   2 +-
 libphobos/libdruntime/core/sys/windows/dll.d       |   4 +-
 libphobos/libdruntime/core/sys/windows/threadaux.d |   4 +-
 libphobos/libdruntime/core/thread/fiber.d          |  42 ++-
 libphobos/libdruntime/core/thread/osthread.d       |  44 ++-
 libphobos/libdruntime/core/thread/threadbase.d     |   3 +
 15 files changed, 471 insertions(+), 203 deletions(-)

diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index 802f5b6fb21..44bb7077b59 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -186,7 +186,18 @@ else version (Posix)
   }
 }
 
-version (CRuntime_Microsoft)
+version (GNU)
+    alias c_long_double = real;
+else version (LDC)
+    alias c_long_double = real; // 64-bit real for MSVC targets
+else version (SDC)
+{
+    version (X86)
+        alias c_long_double = real;
+    else version (X86_64)
+        alias c_long_double = real;
+}
+else version (CRuntime_Microsoft)
 {
     /* long double is 64 bits, not 80 bits, but is mangled differently
      * than double. To distinguish double from long double, create a wrapper to represent
@@ -222,17 +233,6 @@ else version (DigitalMars)
             alias real c_long_double;
     }
 }
-else version (GNU)
-    alias real c_long_double;
-else version (LDC)
-    alias real c_long_double;
-else version (SDC)
-{
-    version (X86)
-        alias real c_long_double;
-    else version (X86_64)
-        alias real c_long_double;
-}
 
 static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
 
@@ -257,18 +257,9 @@ private struct _Complex(T)
     T im;
 }
 
-version (Posix)
-{
-    align(float.alignof)  enum __c_complex_float : _Complex!float;
-    align(double.alignof) enum __c_complex_double : _Complex!double;
-    align(real.alignof)   enum __c_complex_real : _Complex!real;
-}
-else
-{
-    align(float.sizeof * 2)  enum __c_complex_float : _Complex!float;
-    align(double.sizeof * 2) enum __c_complex_double : _Complex!double;
-    align(real.alignof)      enum __c_complex_real : _Complex!real;
-}
+enum __c_complex_float  : _Complex!float;
+enum __c_complex_double : _Complex!double;
+enum __c_complex_real   : _Complex!c_long_double;
 
 alias c_complex_float = __c_complex_float;
 alias c_complex_double = __c_complex_double;
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index fba78ee233a..2de6e579575 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -424,92 +424,177 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o
     pure int _fpclass(double x);
   }
 
+  version (MinGW)
+  {
     enum
     {
         ///
-        FP_SUBNORMAL = -2,
+        FP_NAN = 0x0100,
         ///
-        FP_NORMAL    = -1,
+        FP_NORMAL = 0x0400,
         ///
-        FP_ZERO      =  0,
+        FP_INFINITE = FP_NAN | FP_NORMAL,
         ///
-        FP_INFINITE  =  1,
+        FP_ZERO = 0x0400,
         ///
-        FP_NAN       =  2,
+        FP_SUBNORMAL = FP_NORMAL | FP_ZERO
     }
 
-  extern(D)
-  {
-    //int fpclassify(real-floating x);
-    ///
-    extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
-    ///
-    extern(C) pragma(mangle, "_dclass")  pure int fpclassify(double x);
-    ///
-    pure int fpclassify()(real x)
-    {
-        static if (real.sizeof == double.sizeof)
-            return fpclassify(cast(double) x);
-        else
-            static assert(false, "fpclassify(real) not supported by MS C runtime");
-    }
+    pure int __fpclassifyf(float x);
+    pure int __fpclassify(double x);
+    pure int __fpclassifyl(real x);
 
-    //int isfinite(real-floating x);
-    ///
-    pure int isfinite()(float x)     { return fpclassify(x) <= 0; }
-    ///
-    pure int isfinite()(double x)    { return fpclassify(x) <= 0; }
-    ///
-    pure int isfinite()(real x)      { return fpclassify(x) <= 0; }
+    pure int __isnanf(float x);
+    pure int __isnan(double x);
+    pure int __isnanl(real x);
 
-    //int isinf(real-floating x);
-    ///
-    pure int isinf()(float x)        { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf()(double x)       { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf()(real x)         { return fpclassify(x) == FP_INFINITE; }
+    pure int __signbitf(float x);
+    pure int __signbit(double x);
+    pure int __signbitl(real x);
 
-    //int isnan(real-floating x);
-    version (none) // requires MSVCRT 12+ (VS 2013)
+    extern (D)
     {
+        //int fpclassify(real-floating x);
+        ///
+        extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
+        ///
+        extern(C) pragma(mangle, "__fpclassify")  pure int fpclassify(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
+            pure int fpclassify(real x);
+
+        //int isfinite(real-floating x);
+        ///
+        pure int isfinite(float x)       { return (fpclassify(x) & FP_NORMAL) == 0; }
         ///
-        pure int isnan(float x)      { return fpclassify(x) == FP_NAN; }
+        pure int isfinite(double x)      { return (fpclassify(x) & FP_NORMAL) == 0; }
         ///
-        pure int isnan(double x)     { return fpclassify(x) == FP_NAN; }
+        pure int isfinite(real x)        { return (fpclassify(x) & FP_NORMAL) == 0; }
+
+        //int isinf(real-floating x);
+        ///
+        pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }
+
+        //int isnan(real-floating x);
         ///
-        pure int isnan(real x)       { return fpclassify(x) == FP_NAN; }
+        extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
+        ///
+        extern(C) pragma(mangle, "__isnan")  pure int isnan(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
+            pure int isnan(real x);
+
+        //int isnormal(real-floating x);
+        ///
+        int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }
+        ///
+        int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }
+        ///
+        int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }
+
+        //int signbit(real-floating x);
+        ///
+        extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
+        ///
+        extern(C) pragma(mangle, "__signbit")  pure int signbit(double x);
+        ///
+        extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
+            int signbit(real x);
     }
-    else // for backward compatibility with older runtimes
+  }
+  else
+  {
+    enum
     {
         ///
-        pure int isnan(float x)      { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+        FP_SUBNORMAL = -2,
+        ///
+        FP_NORMAL    = -1,
         ///
-        extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+        FP_ZERO      =  0,
         ///
-        pure int isnan(real x)       { return _isnan(cast(double) x); }
+        FP_INFINITE  =  1,
+        ///
+        FP_NAN       =  2,
     }
 
-    //int isnormal(real-floating x);
-    ///
-    pure int isnormal()(float x)     { return fpclassify(x) == FP_NORMAL; }
-    ///
-    pure int isnormal()(double x)    { return fpclassify(x) == FP_NORMAL; }
-    ///
-    pure int isnormal()(real x)      { return fpclassify(x) == FP_NORMAL; }
-
-    //int signbit(real-floating x);
-    ///
-    extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
-    ///
-    extern(C) pragma(mangle, "_dsign")  pure int signbit(double x);
-    ///
-    pure int signbit()(real x)
+    extern(D)
     {
-        static if (real.sizeof == double.sizeof)
-            return signbit(cast(double) x);
-        else
-            return (cast(short*)&(x))[4] & 0x8000;
+        //int fpclassify(real-floating x);
+        ///
+        extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x);
+        ///
+        extern(C) pragma(mangle, "_dclass")  pure int fpclassify(double x);
+        ///
+        pure int fpclassify()(real x)
+        {
+            static if (real.sizeof == double.sizeof)
+                return fpclassify(cast(double) x);
+            else
+                static assert(false, "fpclassify(real) not supported by MS C runtime");
+        }
+
+        //int isfinite(real-floating x);
+        ///
+        pure int isfinite()(float x)     { return fpclassify(x) <= 0; }
+        ///
+        pure int isfinite()(double x)    { return fpclassify(x) <= 0; }
+        ///
+        pure int isfinite()(real x)      { return fpclassify(x) <= 0; }
+
+        //int isinf(real-floating x);
+        ///
+        pure int isinf()(float x)        { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf()(double x)       { return fpclassify(x) == FP_INFINITE; }
+        ///
+        pure int isinf()(real x)         { return fpclassify(x) == FP_INFINITE; }
+
+        //int isnan(real-floating x);
+        version (none) // requires MSVCRT 12+ (VS 2013)
+        {
+            ///
+            pure int isnan(float x)      { return fpclassify(x) == FP_NAN; }
+            ///
+            pure int isnan(double x)     { return fpclassify(x) == FP_NAN; }
+            ///
+            pure int isnan(real x)       { return fpclassify(x) == FP_NAN; }
+        }
+        else // for backward compatibility with older runtimes
+        {
+            ///
+            pure int isnan(float x)      { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); }
+            ///
+            extern(C) pragma(mangle, "_isnan") pure int isnan(double x);
+            ///
+            pure int isnan(real x)       { return _isnan(cast(double) x); }
+        }
+
+        //int isnormal(real-floating x);
+        ///
+        pure int isnormal()(float x)     { return fpclassify(x) == FP_NORMAL; }
+        ///
+        pure int isnormal()(double x)    { return fpclassify(x) == FP_NORMAL; }
+        ///
+        pure int isnormal()(real x)      { return fpclassify(x) == FP_NORMAL; }
+
+        //int signbit(real-floating x);
+        ///
+        extern(C) pragma(mangle, "_fdsign") pure int signbit(float x);
+        ///
+        extern(C) pragma(mangle, "_dsign")  pure int signbit(double x);
+        ///
+        pure int signbit()(real x)
+        {
+            static if (real.sizeof == double.sizeof)
+                return signbit(cast(double) x);
+            else
+                return (cast(short*)&(x))[4] & 0x8000;
+        }
     }
   }
 }
@@ -835,88 +920,6 @@ else version (CRuntime_UClibc)
     int signbit(real x);
   }
 }
-else version (MinGW)
-{
-    enum
-    {
-        ///
-        FP_NAN = 0x0100,
-        ///
-        FP_NORMAL = 0x0400,
-        ///
-        FP_INFINITE = FP_NAN | FP_NORMAL,
-        ///
-        FP_ZERO = 0x0400,
-        ///
-        FP_SUBNORMAL = FP_NORMAL | FP_ZERO
-    }
-
-    pure int __fpclassifyf(float x);
-    pure int __fpclassify(double x);
-    pure int __fpclassifyl(real x);
-
-    pure int __isnanf(float x);
-    pure int __isnan(double x);
-    pure int __isnanl(real x);
-
-    pure int __signbitf(float x);
-    pure int __signbit(double x);
-    pure int __signbitl(real x);
-
-  extern (D)
-  {
-    //int fpclassify(real-floating x);
-      ///
-    extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
-    ///
-    extern(C) pragma(mangle, "__fpclassify")  pure int fpclassify(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl")
-    pure int fpclassify(real x);
-
-    //int isfinite(real-floating x);
-    ///
-    pure int isfinite(float x)       { return (fpclassify(x) & FP_NORMAL) == 0; }
-    ///
-    pure int isfinite(double x)      { return (fpclassify(x) & FP_NORMAL) == 0; }
-    ///
-    pure int isfinite(real x)        { return (fpclassify(x) & FP_NORMAL) == 0; }
-
-    //int isinf(real-floating x);
-    ///
-    pure int isinf(float x)          { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf(double x)         { return fpclassify(x) == FP_INFINITE; }
-    ///
-    pure int isinf(real x)           { return fpclassify(x) == FP_INFINITE; }
-
-    //int isnan(real-floating x);
-    ///
-    extern(C) pragma(mangle, "__isnanf") pure int isnan(float x);
-    ///
-    extern(C) pragma(mangle, "__isnan")  pure int isnan(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl")
-    pure int isnan(real x);
-
-    //int isnormal(real-floating x);
-    ///
-    int isnormal(float x)       { return fpclassify(x) == FP_NORMAL; }
-    ///
-    int isnormal(double x)      { return fpclassify(x) == FP_NORMAL; }
-    ///
-    int isnormal(real x)        { return fpclassify(x) == FP_NORMAL; }
-
-    //int signbit(real-floating x);
-    ///
-    extern(C) pragma(mangle, "__signbitf") pure int signbit(float x);
-    ///
-    extern(C) pragma(mangle, "__signbit")  pure int signbit(double x);
-    ///
-    extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl")
-    int signbit(real x);
-  }
-}
 else version (Darwin)
 {
     enum
@@ -1166,7 +1169,7 @@ else version (OpenBSD)
         FP_FAST_FMAL = 1,
     }
 
-    pure int __fpclassifyd(double);
+    pure int __fpclassify(double);
     pure int __fpclassifyf(float);
     pure int __fpclassifyl(real);
     pure int __isfinitef(float);
@@ -1188,7 +1191,7 @@ else version (OpenBSD)
       ///
     extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x);
     ///
-    extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x);
+    extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x);
     ///
     extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x);
 
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index 532a0803f55..c76b922a3eb 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -1347,7 +1347,7 @@ version (CRuntime_DigitalMars)
     ///
     pure int  fileno()(FILE* stream)   { return stream._file; }
   }
-  ///
+    ///
     pragma(printf)
     int   _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
     ///
@@ -1358,6 +1358,26 @@ version (CRuntime_DigitalMars)
     int   _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
     ///
     alias _vsnprintf vsnprintf;
+
+    //
+    // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
+    // unshared version of FILE*, usable when the FILE is locked.
+    //
+
+    ///
+    int _fputc_nlock(int c, _iobuf* fp);
+    ///
+    int _fputwc_nlock(int c, _iobuf* fp);
+    ///
+    int _fgetc_nlock(_iobuf* fp);
+    ///
+    int _fgetwc_nlock(_iobuf* fp);
+    ///
+    int __fp_lock(FILE* fp);
+    ///
+    void __fp_unlock(FILE* fp);
+    ///
+    int setmode(int fd, int mode);
 }
 else version (CRuntime_Microsoft)
 {
@@ -1410,16 +1430,31 @@ else version (CRuntime_Microsoft)
     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
   }
 
+    //
+    // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared
+    // version of FILE*, usable when the FILE is locked.
+    //
+    import core.stdc.stddef : wchar_t;
+    import core.stdc.wchar_ : wint_t;
+
     ///
-    int _fputc_nolock(int c, FILE *fp);
+    int _fputc_nolock(int c, _iobuf* fp);
     ///
-    int _fgetc_nolock(FILE *fp);
-
+    int _fgetc_nolock(_iobuf* fp);
     ///
-    int _lock_file(FILE *fp);
+    wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
     ///
-    int _unlock_file(FILE *fp);
-
+    wint_t _fgetwc_nolock(_iobuf* fp);
+    ///
+    void _lock_file(FILE* fp);
+    ///
+    void _unlock_file(FILE* fp);
+    ///
+    int _setmode(int fd, int mode);
+    ///
+    int _fseeki64(FILE* stream, long offset, int origin);
+    ///
+    long _ftelli64(FILE* stream);
     ///
     intptr_t _get_osfhandle(int fd);
     ///
@@ -1448,6 +1483,23 @@ else version (CRuntime_Glibc)
     ///
     pragma(printf)
     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
+
+    //
+    // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared
+    // version of FILE*, usable when the FILE is locked.
+    // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html
+    //
+    import core.stdc.wchar_ : wint_t;
+    import core.stdc.stddef : wchar_t;
+
+    ///
+    int fputc_unlocked(int c, _iobuf* stream);
+    ///
+    int fgetc_unlocked(_iobuf* stream);
+    ///
+    wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream);
+    ///
+    wint_t fgetwc_unlocked(_iobuf* stream);
 }
 else version (Darwin)
 {
@@ -1907,6 +1959,22 @@ version (Windows)
         O_TEXT = _O_TEXT, ///
         _O_BINARY = 0x8000, ///
         O_BINARY = _O_BINARY, ///
+        _O_WTEXT = 0x10000, ///
+        _O_U16TEXT = 0x20000, ///
+        _O_U8TEXT = 0x40000, ///
+        _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), ///
+        O_ACCMODE = _O_ACCMODE, ///
+        _O_RAW = _O_BINARY, ///
+        O_RAW = _O_BINARY, ///
+        _O_NOINHERIT = 0x0080, ///
+        O_NOINHERIT = _O_NOINHERIT, ///
+        _O_TEMPORARY = 0x0040, ///
+        O_TEMPORARY = _O_TEMPORARY, ///
+        _O_SHORT_LIVED = 0x1000, ///
+        _O_SEQUENTIAL = 0x0020, ///
+        O_SEQUENTIAL = _O_SEQUENTIAL, ///
+        _O_RANDOM = 0x0010, ///
+        O_RANDOM = _O_RANDOM, ///
     }
 
     enum
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 5d69b880bc8..35e81a25414 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong   strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
 
 version (CRuntime_Microsoft)
 {
-    // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
-    ///
-    extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
-    {   // Fake it 'till we make it
-        return strtod(nptr, endptr);
+    version (MinGW)
+    {
+        ///
+        real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+        ///
+        alias __mingw_strtold strtold;
+    }
+    else
+    {
+        // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+        ///
+        extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+        {   // Fake it 'till we make it
+            return strtod(nptr, endptr);
+        }
     }
-}
-else version (MinGW)
-{
-    ///
-    real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
-    ///
-    alias __mingw_strtold strtold;
 }
 else
 {
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 2ff1522fd81..2d1a198543f 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1285,6 +1285,13 @@ else
     alias core.stdc.math.fabs          fabs;
     version (CRuntime_Microsoft)
     {
+        version (MinGW)
+        {
+            ///
+            alias core.stdc.math.fabsf     fabs;
+            ///
+            alias core.stdc.math.fabsl     fabs;
+        }
     }
     else
     {
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
index b61673fb4f1..d455d1b8303 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d
@@ -38,6 +38,10 @@ version (AArch64)
     version = AnyARM;
 version (ARM)
     version = AnyARM;
+version (PPC)
+    version = AnyPPC;
+version (PPC64)
+    version = AnyPPC;
 
 version (i386)
 {
@@ -235,3 +239,65 @@ else version (AnyARM)
     kern_return_t thread_resume(thread_act_t);
     kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
 }
+else version (AnyPPC)
+{
+    alias thread_act_t = mach_port_t;
+    alias thread_state_t = void;
+    alias thread_state_flavor_t = int;
+    alias mach_msg_type_number_t = natural_t;
+
+    enum
+    {
+        PPC_THREAD_STATE = 1,
+        PPC_FLOAT_STATE = 2,
+        PPC_EXCEPTION_STATE = 3,
+        PPC_VECTOR_STATE = 4,
+        PPC_THREAD_STATE64 = 5,
+        PPC_EXCEPTION_STATE64 = 6,
+        THREAD_STATE_NONE = 7
+    }
+
+    struct ppc_thread_state_t
+    {
+        uint srr0;   /// Instruction address register (PC)
+        uint srr1;   /// Machine state register (supervisor)
+        uint[32] r;  /// General purpose register r0-r31
+        uint cr;     /// Condition register
+        uint xer;    /// User's integer exception register
+        uint lr;     /// Link register
+        uint ctr;    /// Count register
+        uint mq;     /// MQ register (601 only)
+        uint vrsave; /// Vector save register
+    }
+
+    alias ppc_thread_state32_t = ppc_thread_state_t;
+
+    struct ppc_thread_state64_t
+    {
+        ulong srr0;   /// Instruction address register (PC)
+        ulong srr1;   /// Machine state register (supervisor)
+        ulong[32] r;  /// General purpose register r0-r31
+        uint cr;      /// Condition register
+        uint pad0;
+        ulong xer;    /// User's integer exception register
+        ulong lr;     /// Link register
+        ulong ctr;    /// Count register
+        uint vrsave;  /// Vector save register
+        uint pad1;
+    }
+
+    enum : mach_msg_type_number_t
+    {
+        PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof),
+        PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof),
+        PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof),
+    }
+
+    alias MACHINE_THREAD_STATE = PPC_THREAD_STATE;
+    alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT;
+
+    mach_port_t   mach_thread_self();
+    kern_return_t thread_suspend(thread_act_t);
+    kern_return_t thread_resume(thread_act_t);
+    kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
+}
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
index f88671a3160..55fc79268e2 100644
--- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d
@@ -63,3 +63,8 @@ private alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_
 
 int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
 int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
+
+int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc
+{
+    return 0;
+}
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 031bcb7341f..41b52da7c64 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -516,6 +516,46 @@ version (CRuntime_Glibc)
     int    putc_unlocked(int, FILE*);
     int    putchar_unlocked(int);
 }
+else version (CRuntime_Musl)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (Darwin)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (FreeBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
+else version (NetBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
 else version (OpenBSD)
 {
     void   flockfile(FILE*);
@@ -526,6 +566,16 @@ else version (OpenBSD)
     int    putc_unlocked(int, FILE*);
     int    putchar_unlocked(int);
 }
+else version (DragonFlyBSD)
+{
+    void   flockfile(FILE*);
+    int    ftrylockfile(FILE*);
+    void   funlockfile(FILE*);
+    int    getc_unlocked(FILE*);
+    int    getchar_unlocked();
+    int    putc_unlocked(int, FILE*);
+    int    putchar_unlocked(int);
+}
 else version (Solaris)
 {
     void   flockfile(FILE*);
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 88007adb141..6935dd94f95 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY   = COINIT.COINIT_SPEED_OVER_MEMORY;
 
 public import core.sys.windows.uuid;
 
-extern (System)
+extern (Windows)
 {
 
 class ComObject : IUnknown
 {
-extern (System):
+extern (Windows):
     HRESULT QueryInterface(const(IID)* riid, void** ppv)
     {
         if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
 
 public import core.sys.windows.dbghelp_types;
 
-extern(System)
+extern(Windows)
 {
     alias BOOL         function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
     alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 3df0d7fd41b..cc2422bcaa0 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -414,7 +414,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
     {
         version (GNU_InlineAsm)
         {
-            asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; }
+            asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
         }
         else
         {
@@ -431,7 +431,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
     {
         version (GNU_InlineAsm)
         {
-            asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; }
+            asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
         }
         else
         {
diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d
index fb4d1ee64ba..34fda656c8c 100644
--- a/libphobos/libdruntime/core/sys/windows/threadaux.d
+++ b/libphobos/libdruntime/core/sys/windows/threadaux.d
@@ -172,7 +172,7 @@ struct thread_aux
             version (GNU_InlineAsm)
             {
                 void** teb;
-                asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" teb; }
+                asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
                 return teb;
             }
             else
@@ -190,7 +190,7 @@ struct thread_aux
             version (GNU_InlineAsm)
             {
                 void** teb;
-                asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" teb; }
+                asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); }
                 return teb;
             }
             else
diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d
index 67d9937e31a..f4c04ce7358 100644
--- a/libphobos/libdruntime/core/thread/fiber.d
+++ b/libphobos/libdruntime/core/thread/fiber.d
@@ -82,6 +82,8 @@ private
 
             version (MinGW)
                 version = GNU_AsmX86_Windows;
+            else version (OSX)
+                version = AsmX86_Posix;
             else version (Posix)
                 version = AsmX86_Posix;
         }
@@ -105,13 +107,21 @@ private
 
             version (MinGW)
                 version = GNU_AsmX86_64_Windows;
+            else version (OSX)
+                version = AsmX86_64_Posix;
             else version (Posix)
                 version = AsmX86_64_Posix;
         }
     }
     else version (PPC)
     {
-        version (Posix)
+        version (OSX)
+        {
+            version = AsmPPC_Darwin;
+            version = AsmExternal;
+            version = AlignFiberStackTo16Byte;
+        }
+        else version (Posix)
         {
             version = AsmPPC_Posix;
             version = AsmExternal;
@@ -119,7 +129,13 @@ private
     }
     else version (PPC64)
     {
-        version (Posix)
+        version (OSX)
+        {
+            version = AsmPPC_Darwin;
+            version = AsmExternal;
+            version = AlignFiberStackTo16Byte;
+        }
+        else version (Posix)
         {
             version = AlignFiberStackTo16Byte;
         }
@@ -1347,6 +1363,28 @@ private:
 
             assert( (cast(size_t) pstack & 0x0f) == 0 );
         }
+        else version (AsmPPC_Darwin)
+        {
+            version (StackGrowsDown) {}
+            else static assert(false, "PowerPC Darwin only supports decrementing stacks");
+
+            uint wsize = size_t.sizeof;
+
+            // linkage + regs + FPRs + VRs
+            uint space = 8 * wsize + 20 * wsize + 18 * 8 + 12 * 16;
+            (cast(ubyte*)pstack - space)[0 .. space] = 0;
+
+            pstack -= wsize * 6;
+            *cast(size_t*)pstack = cast(size_t) &fiber_entryPoint; // LR
+            pstack -= wsize * 22;
+
+            // On Darwin PPC64 pthread self is in R13 (which is reserved).
+            // At present, it is not safe to migrate fibers between threads, but if that
+            // changes, then updating the value of R13 will also need to be handled.
+            version (PPC64)
+              *cast(size_t*)(pstack + wsize) = cast(size_t) Thread.getThis().m_addr;
+            assert( (cast(size_t) pstack & 0x0f) == 0 );
+        }
         else version (AsmMIPS_O32_Posix)
         {
             version (StackGrowsDown) {}
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index 0fffc7ed3f7..31764e69691 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -349,7 +349,8 @@ class Thread : ThreadBase
         }
         else version (Posix)
         {
-            pthread_detach( m_addr );
+            if (m_addr != m_addr.init)
+                pthread_detach( m_addr );
             m_addr = m_addr.init;
         }
         version (Darwin)
@@ -420,6 +421,17 @@ class Thread : ThreadBase
         {
             uint[16]        m_reg; // r0-r15
         }
+        else version (PPC)
+        {
+            // Make the assumption that we only care about non-fp and non-vr regs.
+            // ??? : it seems plausible that a valid address can be copied into a VR.
+            uint[32]        m_reg; // r0-31
+        }
+        else version (PPC64)
+        {
+            // As above.
+            ulong[32]       m_reg; // r0-31
+        }
         else
         {
             static assert(false, "Architecture not supported." );
@@ -578,7 +590,7 @@ class Thread : ThreadBase
     {
         version (Windows)
         {
-            if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
+            if ( m_addr != m_addr.init && WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 )
                 throw new ThreadException( "Unable to join thread" );
             // NOTE: m_addr must be cleared before m_hndl is closed to avoid
             //       a race condition with isRunning. The operation is done
@@ -589,7 +601,7 @@ class Thread : ThreadBase
         }
         else version (Posix)
         {
-            if ( pthread_join( m_addr, null ) != 0 )
+            if ( m_addr != m_addr.init && pthread_join( m_addr, null ) != 0 )
                 throw new ThreadException( "Unable to join thread" );
             // NOTE: pthread_join acts as a substitute for pthread_detach,
             //       which is normally called by the dtor.  Setting m_addr
@@ -1629,9 +1641,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
             void *bottom;
 
             version (X86)
-                asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+                asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
             else version (X86_64)
-                asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+                asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
             else
                 static assert(false, "Platform not supported.");
 
@@ -1880,6 +1892,28 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc
             t.m_reg[14] = state.lr;
             t.m_reg[15] = state.pc;
         }
+        else version (PPC)
+        {
+            ppc_thread_state_t state = void;
+            mach_msg_type_number_t count = PPC_THREAD_STATE_COUNT;
+
+            if (thread_get_state(t.m_tmach, PPC_THREAD_STATE, &state, &count) != KERN_SUCCESS)
+                onThreadError("Unable to load thread state");
+            if (!t.m_lock)
+                t.m_curr.tstack = cast(void*) state.r[1];
+            t.m_reg[] = state.r[];
+        }
+        else version (PPC64)
+        {
+            ppc_thread_state64_t state = void;
+            mach_msg_type_number_t count = PPC_THREAD_STATE64_COUNT;
+
+            if (thread_get_state(t.m_tmach, PPC_THREAD_STATE64, &state, &count) != KERN_SUCCESS)
+                onThreadError("Unable to load thread state");
+            if (!t.m_lock)
+                t.m_curr.tstack = cast(void*) state.r[1];
+            t.m_reg[] = state.r[];
+        }
         else
         {
             static assert(false, "Architecture not supported." );
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
index 50795e444be..0a8de10e17b 100644
--- a/libphobos/libdruntime/core/thread/threadbase.d
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -10,6 +10,9 @@
  * Source:    $(DRUNTIMESRC core/thread/osthread.d)
  */
 
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
 module core.thread.threadbase;
 
 import core.thread.context;


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-04-19 14:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19 14:10 [gcc(refs/users/ibuclaw/heads/mingw)] Sync druntime Iain Buclaw
2021-04-19 14:16 Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).