From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id AA44A39450D3; Mon, 19 Apr 2021 14:16:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA44A39450D3 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/ibuclaw/heads/mingw)] Sync druntime X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/users/ibuclaw/heads/mingw X-Git-Oldrev: 1cadae910b9339f667e83cfee2b3e0400a6cab98 X-Git-Newrev: acf8e40a258b668abeba4b1ab800aae6e46981b7 Message-Id: <20210419141640.AA44A39450D3@sourceware.org> Date: Mon, 19 Apr 2021 14:16:40 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Apr 2021 14:16:40 -0000 https://gcc.gnu.org/g:acf8e40a258b668abeba4b1ab800aae6e46981b7 commit acf8e40a258b668abeba4b1ab800aae6e46981b7 Author: Iain Buclaw 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;