From 879bc2e5cb614bdb1b7a2426c9746989089bccd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 16 May 2025 23:27:53 +0200 Subject: [PATCH] mingw: Update MinGW-w64 sources to 38c8142f660b6ba11e7c408f2de1e9f8bfaf839e. --- .../mingw/cfguard/mingw_cfguard_support.c | 8 - lib/libc/mingw/crt/CRT_fp10.c | 8 - lib/libc/mingw/crt/crtdll.c | 129 +++--- lib/libc/mingw/crt/crtexe.c | 15 +- lib/libc/mingw/crt/crtexewin.c | 1 - lib/libc/mingw/crt/dll_argv.c | 4 - lib/libc/mingw/crt/dllargv.c | 4 - lib/libc/mingw/crt/natstart.c | 4 +- lib/libc/mingw/crt/tlssup.c | 4 - lib/libc/mingw/gdtoa/strtodnrp.c | 3 +- lib/libc/mingw/gdtoa/strtopx.c | 23 +- lib/libc/mingw/include/internal.h | 156 +++++++- lib/libc/mingw/intrincs/RtlSecureZeroMemory.c | 2 +- lib/libc/mingw/libsrc/uuid.c | 1 + .../libsrc/ws2tcpip/in6_set_addr_loopback.c | 2 +- .../ws2tcpip/in6_set_addr_unspecified.c | 2 +- .../mingw/libsrc/ws2tcpip/in6addr_setany.c | 5 +- .../libsrc/ws2tcpip/in6addr_setloopback.c | 7 - lib/libc/mingw/math/arm-common/ldexpl.c | 4 - .../_chgsignl.S => arm-common/sincosl.c} | 15 +- lib/libc/mingw/math/arm/_chgsignl.S | 16 - lib/libc/mingw/math/cephes_mconf.h | 4 +- lib/libc/mingw/math/coshl.c | 2 +- lib/libc/mingw/math/erfl.c | 2 +- lib/libc/mingw/math/fmal.c | 2 +- lib/libc/mingw/math/fp_constsl.c | 2 +- lib/libc/mingw/math/fpclassifyl.c | 6 +- lib/libc/mingw/math/frexpl.c | 2 +- lib/libc/mingw/math/isnanl.c | 6 +- lib/libc/mingw/math/lgammal.c | 2 +- lib/libc/mingw/math/llrintl.c | 3 +- lib/libc/mingw/math/lrintl.c | 6 +- lib/libc/mingw/math/modff.c | 2 +- lib/libc/mingw/math/modfl.c | 2 +- lib/libc/mingw/math/rintl.c | 6 +- lib/libc/mingw/math/signbitl.c | 4 +- lib/libc/mingw/math/sinhl.c | 2 +- lib/libc/mingw/math/sqrt.def.h | 2 +- lib/libc/mingw/math/tanhl.c | 2 +- lib/libc/mingw/math/tgammal.c | 2 +- lib/libc/mingw/math/truncl.c | 7 +- lib/libc/mingw/math/x86/pow.def.h | 3 - lib/libc/mingw/misc/dllentrypoint.c | 18 - lib/libc/mingw/misc/feclearexcept.c | 40 +- lib/libc/mingw/misc/fegetenv.c | 31 +- lib/libc/mingw/misc/fegetexceptflag.c | 29 +- lib/libc/mingw/misc/fegetround.c | 19 +- lib/libc/mingw/misc/feholdexcept.c | 23 +- lib/libc/mingw/misc/feraiseexcept.c | 32 +- lib/libc/mingw/misc/fesetenv.c | 91 ++--- lib/libc/mingw/misc/fesetexceptflag.c | 42 +- lib/libc/mingw/misc/fesetround.c | 43 +- lib/libc/mingw/misc/fetestexcept.c | 23 +- lib/libc/mingw/misc/feupdateenv.c | 10 +- lib/libc/mingw/misc/ftw.c | 34 +- lib/libc/mingw/misc/ftw32.c | 19 + lib/libc/mingw/misc/ftw32i64.c | 10 + lib/libc/mingw/misc/ftw64.c | 6 +- lib/libc/mingw/misc/ftw64i32.c | 19 + lib/libc/mingw/misc/mingw-aligned-malloc.c | 40 +- lib/libc/mingw/misc/mingw_controlfp.c | 53 +++ lib/libc/mingw/misc/mingw_getsp.S | 8 +- lib/libc/mingw/misc/mingw_setfp.c | 373 ++++++++++++++++++ lib/libc/mingw/misc/setjmp.S | 2 + lib/libc/mingw/misc/ucrt_tzset.c | 3 - lib/libc/mingw/misc/winbs_uint64.c | 35 +- lib/libc/mingw/misc/winbs_ulong.c | 16 +- lib/libc/mingw/misc/winbs_ushort.c | 13 +- lib/libc/mingw/stdio/__mingw_fix_stat_path.c | 64 +++ lib/libc/mingw/stdio/__mingw_fix_wstat_path.c | 64 +++ lib/libc/mingw/stdio/_findfirst64i32.c | 2 +- lib/libc/mingw/stdio/_findnext64i32.c | 2 +- lib/libc/mingw/stdio/_fstat64i32.c | 28 +- lib/libc/mingw/stdio/_stat.c | 120 ------ lib/libc/mingw/stdio/_stat64i32.c | 89 +---- lib/libc/mingw/stdio/_wfindfirst64i32.c | 2 +- lib/libc/mingw/stdio/_wfindnext64i32.c | 2 +- lib/libc/mingw/stdio/_wstat.c | 119 ------ lib/libc/mingw/stdio/_wstat64i32.c | 89 +---- lib/libc/mingw/stdio/mingw_pformat.c | 21 +- lib/libc/mingw/stdio/mingw_sformat.c | 10 +- lib/libc/mingw/stdio/mingw_swformat.c | 10 +- lib/libc/mingw/stdio/mingw_vfscanf.c | 4 +- lib/libc/mingw/stdio/mingw_vfwscanf.c | 4 +- lib/libc/mingw/stdio/mingw_vsscanf.c | 5 +- lib/libc/mingw/stdio/mingw_vswscanf.c | 5 +- .../stdio/ucrt___local_stdio_printf_options.c | 15 + .../stdio/ucrt___local_stdio_scanf_options.c | 15 + lib/libc/mingw/stdio/ucrt__scprintf.c | 1 - lib/libc/mingw/stdio/ucrt__snprintf.c | 1 - lib/libc/mingw/stdio/ucrt__snscanf.c | 3 +- lib/libc/mingw/stdio/ucrt__snwprintf.c | 18 - lib/libc/mingw/stdio/ucrt__vsnprintf.c | 1 - lib/libc/mingw/stdio/ucrt__vsnwprintf.c | 1 - lib/libc/mingw/stdio/ucrt_fprintf.c | 1 - lib/libc/mingw/stdio/ucrt_fscanf.c | 3 +- lib/libc/mingw/stdio/ucrt_fwprintf.c | 20 +- lib/libc/mingw/stdio/ucrt_fwscanf.c | 18 + lib/libc/mingw/stdio/ucrt_ms_fwprintf.c | 3 +- lib/libc/mingw/stdio/ucrt_printf.c | 1 - lib/libc/mingw/stdio/ucrt_scanf.c | 3 +- lib/libc/mingw/stdio/ucrt_snprintf.c | 1 - lib/libc/mingw/stdio/ucrt_snwprintf.c | 19 + lib/libc/mingw/stdio/ucrt_sprintf.c | 1 - lib/libc/mingw/stdio/ucrt_sscanf.c | 4 +- lib/libc/mingw/stdio/ucrt_swprintf.c | 29 ++ lib/libc/mingw/stdio/ucrt_swscanf.c | 18 + lib/libc/mingw/stdio/ucrt_vfprintf.c | 1 - lib/libc/mingw/stdio/ucrt_vfscanf.c | 3 +- lib/libc/mingw/stdio/ucrt_vfwprintf.c | 14 + lib/libc/mingw/stdio/ucrt_vfwscanf.c | 13 + lib/libc/mingw/stdio/ucrt_vprintf.c | 1 - lib/libc/mingw/stdio/ucrt_vscanf.c | 3 +- lib/libc/mingw/stdio/ucrt_vsnprintf.c | 1 - lib/libc/mingw/stdio/ucrt_vsnwprintf.c | 14 + lib/libc/mingw/stdio/ucrt_vsprintf.c | 1 - lib/libc/mingw/stdio/ucrt_vsscanf.c | 3 +- lib/libc/mingw/stdio/ucrt_vswprintf.c | 26 ++ lib/libc/mingw/stdio/ucrt_vwprintf.c | 14 + lib/libc/mingw/stdio/ucrt_vwscanf.c | 13 + .../{ucrt_ms_fprintf.c => ucrt_wprintf.c} | 11 +- lib/libc/mingw/stdio/ucrt_wscanf.c | 18 + lib/libc/mingw/winpthreads/barrier.c | 26 +- lib/libc/mingw/winpthreads/barrier.h | 2 - lib/libc/mingw/winpthreads/clock.c | 127 +++++- lib/libc/mingw/winpthreads/cond.c | 110 ++---- lib/libc/mingw/winpthreads/cond.h | 8 +- lib/libc/mingw/winpthreads/misc.c | 17 +- lib/libc/mingw/winpthreads/misc.h | 35 +- lib/libc/mingw/winpthreads/mutex.c | 35 +- lib/libc/mingw/winpthreads/nanosleep.c | 44 ++- lib/libc/mingw/winpthreads/ref.c | 34 -- lib/libc/mingw/winpthreads/ref.h | 29 -- lib/libc/mingw/winpthreads/rwlock.c | 105 ++--- lib/libc/mingw/winpthreads/rwlock.h | 3 - lib/libc/mingw/winpthreads/sched.c | 16 +- lib/libc/mingw/winpthreads/sem.c | 36 +- lib/libc/mingw/winpthreads/sem.h | 2 - lib/libc/mingw/winpthreads/spinlock.c | 10 +- lib/libc/mingw/winpthreads/thread.c | 112 +++--- lib/libc/mingw/winpthreads/thread.h | 7 +- .../mingw/winpthreads/winpthread_internal.h | 27 -- src/libs/mingw.zig | 36 +- 143 files changed, 1798 insertions(+), 1489 deletions(-) rename lib/libc/mingw/math/{arm64/_chgsignl.S => arm-common/sincosl.c} (52%) delete mode 100644 lib/libc/mingw/math/arm/_chgsignl.S delete mode 100644 lib/libc/mingw/misc/dllentrypoint.c create mode 100644 lib/libc/mingw/misc/ftw32.c create mode 100644 lib/libc/mingw/misc/ftw32i64.c create mode 100644 lib/libc/mingw/misc/ftw64i32.c create mode 100644 lib/libc/mingw/misc/mingw_controlfp.c create mode 100644 lib/libc/mingw/misc/mingw_setfp.c create mode 100644 lib/libc/mingw/stdio/__mingw_fix_stat_path.c create mode 100644 lib/libc/mingw/stdio/__mingw_fix_wstat_path.c delete mode 100644 lib/libc/mingw/stdio/_stat.c delete mode 100644 lib/libc/mingw/stdio/_wstat.c create mode 100644 lib/libc/mingw/stdio/ucrt___local_stdio_printf_options.c create mode 100644 lib/libc/mingw/stdio/ucrt___local_stdio_scanf_options.c create mode 100644 lib/libc/mingw/stdio/ucrt_fwscanf.c create mode 100644 lib/libc/mingw/stdio/ucrt_snwprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_swprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_swscanf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vfwprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vfwscanf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vsnwprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vswprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vwprintf.c create mode 100644 lib/libc/mingw/stdio/ucrt_vwscanf.c rename lib/libc/mingw/stdio/{ucrt_ms_fprintf.c => ucrt_wprintf.c} (53%) create mode 100644 lib/libc/mingw/stdio/ucrt_wscanf.c delete mode 100644 lib/libc/mingw/winpthreads/ref.c delete mode 100644 lib/libc/mingw/winpthreads/ref.h delete mode 100644 lib/libc/mingw/winpthreads/winpthread_internal.h diff --git a/lib/libc/mingw/cfguard/mingw_cfguard_support.c b/lib/libc/mingw/cfguard/mingw_cfguard_support.c index 1e777ebfc0..5c736e1623 100644 --- a/lib/libc/mingw/cfguard/mingw_cfguard_support.c +++ b/lib/libc/mingw/cfguard/mingw_cfguard_support.c @@ -17,14 +17,6 @@ // really matter here because this is a no-op anyway. static void __guard_check_icall_dummy(void) {} -// When CFGuard is not active, directly tail-call the target address, which -// is passed via %rax. -__asm__( - ".globl __guard_dispatch_icall_dummy\n" - "__guard_dispatch_icall_dummy:\n" - " jmp *%rax\n" -); - // This is intentionally declared as _not_ a function pointer, so that the // jmp instruction is not included as a valid call target for CFGuard. extern void *__guard_dispatch_icall_dummy; diff --git a/lib/libc/mingw/crt/CRT_fp10.c b/lib/libc/mingw/crt/CRT_fp10.c index f39b5175f7..c8a8bfbeeb 100644 --- a/lib/libc/mingw/crt/CRT_fp10.c +++ b/lib/libc/mingw/crt/CRT_fp10.c @@ -8,19 +8,11 @@ void _fpreset (void); void _fpreset (void) { -#if defined(_ARM_) || defined(__arm__) - __asm__ __volatile__ ( - "vmsr fpscr, %0\n\t" : : "r"(0 /* INITIAL_FPSCR */)); -#elif defined(_ARM64_) || defined(__aarch64__) - __asm__ __volatile__ ( - "msr fpcr, %0\n\t" : : "r"(0LL /* INITIAL_FPSCR */)); -#else #ifdef __GNUC__ __asm__ ("fninit"); #else /* msvc: */ __asm fninit; #endif -#endif } #ifdef __GNUC__ diff --git a/lib/libc/mingw/crt/crtdll.c b/lib/libc/mingw/crt/crtdll.c index 90da38e604..6bee08f596 100644 --- a/lib/libc/mingw/crt/crtdll.c +++ b/lib/libc/mingw/crt/crtdll.c @@ -4,12 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#ifdef CRTDLL -#undef CRTDLL -#ifndef _DLL -#define _DLL -#endif - #include #include #include @@ -19,20 +13,14 @@ #include #ifndef _CRTIMP -#ifdef CRTDLL -#define _CRTIMP __declspec(dllexport) -#else -#ifdef _DLL #define _CRTIMP __declspec(dllimport) -#else -#define _CRTIMP -#endif -#endif #endif #include #include -extern void __cdecl _initterm(_PVFV *,_PVFV *); +#if defined(__x86_64__) && !defined(__SEH__) +extern int __mingw_init_ehandler (void); +#endif extern void __main (); extern void _pei386_runtime_relocator (void); extern _PIFV __xi_a[]; @@ -50,20 +38,6 @@ static _onexit_table_t atexit_table; extern int __mingw_app_type; -extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved); - -extern WINBOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID); - -static int pre_c_init (void); - -_CRTALLOC(".CRT$XIAA") _PIFV pcinit = pre_c_init; - -static int -pre_c_init (void) -{ - return _initialize_onexit_table(&atexit_table); -} - WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { if (dwReason == DLL_PROCESS_DETACH) @@ -77,10 +51,11 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { void *lock_free = NULL; void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; - int nested = FALSE; + BOOL nested = FALSE; + int ret = 0; - while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, - fiberid, 0)) != 0) + while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, + fiberid, NULL)) != 0) { if (lock_free == fiberid) { @@ -89,25 +64,37 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) } Sleep(1000); } - if (__native_startup_state == __initializing) + if (__native_startup_state != __uninitialized) { _amsg_exit (31); } - else if (__native_startup_state == __uninitialized) + else { __native_startup_state = __initializing; - if (_initterm_e (__xi_a, __xi_z) != 0) - return FALSE; - } - if (__native_startup_state == __initializing) - { + _pei386_runtime_relocator (); +#if defined(__x86_64__) && !defined(__SEH__) + __mingw_init_ehandler (); +#endif + ret = _initialize_onexit_table (&atexit_table); + if (ret != 0) + goto i__leave; + ret = _initterm_e (__xi_a, __xi_z); + if (ret != 0) + goto i__leave; _initterm (__xc_a, __xc_z); + __main (); + __native_startup_state = __initialized; } +i__leave: if (! nested) { - (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); + (void) InterlockedExchangePointer (&__native_startup_lock, NULL); + } + if (ret != 0) + { + return FALSE; } if (__dyn_tls_init_callback != NULL) { @@ -118,8 +105,16 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) else if (dwReason == DLL_PROCESS_DETACH) { void *lock_free = NULL; - while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0) + void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase; + BOOL nested = FALSE; + + while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, fiberid, NULL)) != 0) { + if (lock_free == fiberid) + { + nested = TRUE; + break; + } Sleep(1000); } if (__native_startup_state != __initialized) @@ -130,84 +125,56 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { _execute_onexit_table(&atexit_table); __native_startup_state = __uninitialized; - (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); + } + if (! nested) + { + (void) InterlockedExchangePointer (&__native_startup_lock, NULL); } } return TRUE; } -static WINBOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID); - WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID); -#if defined(__x86_64__) && !defined(__SEH__) -int __mingw_init_ehandler (void); -#endif +#if defined(__i386__) || defined(_X86_) +/* We need to make sure that we align the stack to 16 bytes for the sake of SSE + opts in DllMain or in functions called from DllMain. */ +__attribute__((force_align_arg_pointer)) +#endif __attribute__((used)) /* required due to GNU LD bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30300 */ WINBOOL WINAPI DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) -{ - __mingw_app_type = 0; - return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved); -} - -static -#if defined(__i386__) || defined(_X86_) -/* We need to make sure that we align the stack to 16 bytes for the sake of SSE - opts in DllMain/DllEntryPoint or in functions called from DllMain/DllEntryPoint. */ -__attribute__((force_align_arg_pointer)) -#endif -__declspec(noinline) WINBOOL -__DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { WINBOOL retcode = TRUE; + __mingw_app_type = 0; __native_dllmain_reason = dwReason; - if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0) + if (dwReason == DLL_PROCESS_DETACH && __proc_attached <= 0) { retcode = FALSE; goto i__leave; } - _pei386_runtime_relocator (); - -#if defined(__x86_64__) && !defined(__SEH__) - if (dwReason == DLL_PROCESS_ATTACH) - __mingw_init_ehandler (); -#endif if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) { retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); if (!retcode) goto i__leave; - retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); - if (! retcode) - { - if (dwReason == DLL_PROCESS_ATTACH) - _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); - goto i__leave; - } } - if (dwReason == DLL_PROCESS_ATTACH) - __main (); retcode = DllMain(hDllHandle,dwReason,lpreserved); if (dwReason == DLL_PROCESS_ATTACH && ! retcode) { DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved); - DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved); _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved); } if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH) { - retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved); - if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE) - retcode = FALSE; + retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); } i__leave: __native_dllmain_reason = UINT_MAX; return retcode ; } -#endif int __cdecl atexit (_PVFV func) { diff --git a/lib/libc/mingw/crt/crtexe.c b/lib/libc/mingw/crt/crtexe.c index 328cc305b9..4bc8a92f49 100644 --- a/lib/libc/mingw/crt/crtexe.c +++ b/lib/libc/mingw/crt/crtexe.c @@ -4,13 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#undef CRTDLL -#ifndef _DLL -#define _DLL -#endif - -#define SPECIAL_CRTEXE - #include #include #include @@ -211,9 +204,9 @@ __tmainCRTStartup (void) { void *lock_free = NULL; void *fiberid = ((PNT_TIB)NtCurrentTeb())->StackBase; - int nested = FALSE; - while((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock, - fiberid, 0)) != 0) + BOOL nested = FALSE; + while((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, + fiberid, NULL)) != 0) { if (lock_free == fiberid) { @@ -242,7 +235,7 @@ __tmainCRTStartup (void) } _ASSERTE(__native_startup_state == __initialized); if (! nested) - (VOID)InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0); + (VOID)InterlockedExchangePointer (&__native_startup_lock, NULL); if (__dyn_tls_init_callback != NULL) __dyn_tls_init_callback (NULL, DLL_THREAD_ATTACH, NULL); diff --git a/lib/libc/mingw/crt/crtexewin.c b/lib/libc/mingw/crt/crtexewin.c index 26179fa905..af860f3e76 100644 --- a/lib/libc/mingw/crt/crtexewin.c +++ b/lib/libc/mingw/crt/crtexewin.c @@ -56,7 +56,6 @@ int _tmain (int __UNUSED_PARAM(argc), { STARTUPINFO StartupInfo; - memset (&StartupInfo, 0, sizeof (STARTUPINFO)); GetStartupInfo (&StartupInfo); if (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) nShowCmd = StartupInfo.wShowWindow; diff --git a/lib/libc/mingw/crt/dll_argv.c b/lib/libc/mingw/crt/dll_argv.c index 19eeda7cd6..4e2674dc5e 100644 --- a/lib/libc/mingw/crt/dll_argv.c +++ b/lib/libc/mingw/crt/dll_argv.c @@ -4,10 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#ifdef CRTDLL -#undef CRTDLL -#endif - #include extern int _dowildcard; diff --git a/lib/libc/mingw/crt/dllargv.c b/lib/libc/mingw/crt/dllargv.c index df0453430d..d6be1bc7c2 100644 --- a/lib/libc/mingw/crt/dllargv.c +++ b/lib/libc/mingw/crt/dllargv.c @@ -4,10 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#ifdef CRTDLL -#undef CRTDLL -#endif - #include int __CRTDECL diff --git a/lib/libc/mingw/crt/natstart.c b/lib/libc/mingw/crt/natstart.c index 06def19d51..5008790e1e 100644 --- a/lib/libc/mingw/crt/natstart.c +++ b/lib/libc/mingw/crt/natstart.c @@ -10,5 +10,5 @@ _PGLOBAL volatile unsigned int __native_dllmain_reason = UINT_MAX; volatile unsigned int __native_vcclrit_reason = UINT_MAX; -volatile __enative_startup_state __native_startup_state; -volatile void *__native_startup_lock; +volatile __enative_startup_state __native_startup_state = __uninitialized; +void *volatile __native_startup_lock = NULL; diff --git a/lib/libc/mingw/crt/tlssup.c b/lib/libc/mingw/crt/tlssup.c index de546dcb4d..09ddcc42e6 100644 --- a/lib/libc/mingw/crt/tlssup.c +++ b/lib/libc/mingw/crt/tlssup.c @@ -6,10 +6,6 @@ * Written by Kai Tietz */ -#ifdef CRTDLL -#undef CRTDLL -#endif - #include #ifndef WIN32_LEAN_AND_MEAN diff --git a/lib/libc/mingw/gdtoa/strtodnrp.c b/lib/libc/mingw/gdtoa/strtodnrp.c index bc5e861110..9304866bfd 100644 --- a/lib/libc/mingw/gdtoa/strtodnrp.c +++ b/lib/libc/mingw/gdtoa/strtodnrp.c @@ -85,8 +85,7 @@ double __cdecl __mingw_strtod (const char * __restrict__ src, char ** __restrict__ endptr) __attribute__((alias("__strtod"))); -#if !(defined(_AMD64_) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386__)) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ /* For systems other than x86, where long double == double, provide the * long double functions as aliases to __strtod. */ diff --git a/lib/libc/mingw/gdtoa/strtopx.c b/lib/libc/mingw/gdtoa/strtopx.c index a5bc3ec60e..b80a79476a 100644 --- a/lib/libc/mingw/gdtoa/strtopx.c +++ b/lib/libc/mingw/gdtoa/strtopx.c @@ -53,8 +53,19 @@ THIS SOFTWARE. #define _4 0 #endif +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ +/* For ARM, where long double == double, provide the long double function as + * an alias for __strtod. Do this in a separate object file from other + * functions, to avoid linker conflicts if object files import both 'strtold' + * from libucrt*.a and the object file providing '__strtod'. */ +long double __cdecl +strtold (const char * __restrict__ src, char ** __restrict__ endptr) +{ + return __mingw_strtod(src, endptr); +} + /* This is specific to the x86 80 bit long doubles. */ -#if defined(_AMD64_) || defined(__x86_64__) || \ +#elif defined(_AMD64_) || defined(__x86_64__) || \ defined(_X86_) || defined(__i386__) typedef union lD { @@ -133,14 +144,4 @@ long double __cdecl strtold (const char * __restrict__ src, char ** __restrict__ endptr) __attribute__((alias("__strtold"))); -#elif defined(__arm__) || defined(__aarch64__) || defined(_ARM_) || defined(_ARM64_) -/* For ARM, where long double == double, provide the long double function as - * an alias for __strtod. Do this in a separate object file from other - * functions, to avoid linker conflicts if object files import both 'strtold' - * from libucrt*.a and the object file providing '__strtod'. */ -long double __cdecl -strtold (const char * __restrict__ src, char ** __restrict__ endptr) -{ - return __mingw_strtod(src, endptr); -} #endif diff --git a/lib/libc/mingw/include/internal.h b/lib/libc/mingw/include/internal.h index 752c5dc966..997a89b189 100644 --- a/lib/libc/mingw/include/internal.h +++ b/lib/libc/mingw/include/internal.h @@ -14,6 +14,7 @@ extern "C" { #endif #include +#include #include #pragma pack(push,_CRT_PACKING) @@ -130,7 +131,7 @@ extern "C" { } __enative_startup_state; extern volatile __enative_startup_state __native_startup_state; - extern volatile void *__native_startup_lock; + extern void *volatile __native_startup_lock; extern volatile unsigned int __native_dllmain_reason; extern volatile unsigned int __native_vcclrit_reason; @@ -154,6 +155,159 @@ extern "C" { # define __mingw_has_sse() 0 #endif +#if defined(__i386__) || defined(__x86_64__) +enum fenv_masks +{ + /* x87 encoding constants */ + FENV_X_INVALID = 0x00100010, + FENV_X_DENORMAL = 0x00200020, + FENV_X_ZERODIVIDE = 0x00080008, + FENV_X_OVERFLOW = 0x00040004, + FENV_X_UNDERFLOW = 0x00020002, + FENV_X_INEXACT = 0x00010001, + FENV_X_AFFINE = 0x00004000, + FENV_X_UP = 0x00800200, + FENV_X_DOWN = 0x00400100, + FENV_X_24 = 0x00002000, + FENV_X_53 = 0x00001000, + /* SSE encoding constants: they share the same lower word as their x87 counterparts + * but differ in the upper word */ + FENV_Y_INVALID = 0x10000010, + FENV_Y_DENORMAL = 0x20000020, + FENV_Y_ZERODIVIDE = 0x08000008, + FENV_Y_OVERFLOW = 0x04000004, + FENV_Y_UNDERFLOW = 0x02000002, + FENV_Y_INEXACT = 0x01000001, + FENV_Y_UP = 0x80000200, + FENV_Y_DOWN = 0x40000100, + FENV_Y_FLUSH = 0x00000400, + FENV_Y_FLUSH_SAVE = 0x00000800 +}; + +/* encodes the x87 (represented as x) or SSE (represented as y) control/status word in a ulong */ +static inline unsigned long fenv_encode(unsigned int x, unsigned int y) +{ + unsigned long ret = 0; + + if (x & _EM_INVALID) ret |= FENV_X_INVALID; + if (x & _EM_DENORMAL) ret |= FENV_X_DENORMAL; + if (x & _EM_ZERODIVIDE) ret |= FENV_X_ZERODIVIDE; + if (x & _EM_OVERFLOW) ret |= FENV_X_OVERFLOW; + if (x & _EM_UNDERFLOW) ret |= FENV_X_UNDERFLOW; + if (x & _EM_INEXACT) ret |= FENV_X_INEXACT; + if (x & _IC_AFFINE) ret |= FENV_X_AFFINE; + if (x & _RC_UP) ret |= FENV_X_UP; + if (x & _RC_DOWN) ret |= FENV_X_DOWN; + if (x & _PC_24) ret |= FENV_X_24; + if (x & _PC_53) ret |= FENV_X_53; + + if (y & _EM_INVALID) ret |= FENV_Y_INVALID; + if (y & _EM_DENORMAL) ret |= FENV_Y_DENORMAL; + if (y & _EM_ZERODIVIDE) ret |= FENV_Y_ZERODIVIDE; + if (y & _EM_OVERFLOW) ret |= FENV_Y_OVERFLOW; + if (y & _EM_UNDERFLOW) ret |= FENV_Y_UNDERFLOW; + if (y & _EM_INEXACT) ret |= FENV_Y_INEXACT; + if (y & _RC_UP) ret |= FENV_Y_UP; + if (y & _RC_DOWN) ret |= FENV_Y_DOWN; + if (y & _DN_FLUSH) ret |= FENV_Y_FLUSH; + if (y & _DN_FLUSH_OPERANDS_SAVE_RESULTS) ret |= FENV_Y_FLUSH_SAVE; + + return ret; +} + +/* decodes the x87 (represented as x) or SSE (represented as y) control/status word in a ulong */ +static inline BOOL fenv_decode(unsigned long enc, unsigned int *x, unsigned int *y) +{ + *x = *y = 0; + if ((enc & FENV_X_INVALID) == FENV_X_INVALID) *x |= _EM_INVALID; + if ((enc & FENV_X_DENORMAL) == FENV_X_DENORMAL) *x |= _EM_DENORMAL; + if ((enc & FENV_X_ZERODIVIDE) == FENV_X_ZERODIVIDE) *x |= _EM_ZERODIVIDE; + if ((enc & FENV_X_OVERFLOW) == FENV_X_OVERFLOW) *x |= _EM_OVERFLOW; + if ((enc & FENV_X_UNDERFLOW) == FENV_X_UNDERFLOW) *x |= _EM_UNDERFLOW; + if ((enc & FENV_X_INEXACT) == FENV_X_INEXACT) *x |= _EM_INEXACT; + if ((enc & FENV_X_AFFINE) == FENV_X_AFFINE) *x |= _IC_AFFINE; + if ((enc & FENV_X_UP) == FENV_X_UP) *x |= _RC_UP; + if ((enc & FENV_X_DOWN) == FENV_X_DOWN) *x |= _RC_DOWN; + if ((enc & FENV_X_24) == FENV_X_24) *x |= _PC_24; + if ((enc & FENV_X_53) == FENV_X_53) *x |= _PC_53; + + if ((enc & FENV_Y_INVALID) == FENV_Y_INVALID) *y |= _EM_INVALID; + if ((enc & FENV_Y_DENORMAL) == FENV_Y_DENORMAL) *y |= _EM_DENORMAL; + if ((enc & FENV_Y_ZERODIVIDE) == FENV_Y_ZERODIVIDE) *y |= _EM_ZERODIVIDE; + if ((enc & FENV_Y_OVERFLOW) == FENV_Y_OVERFLOW) *y |= _EM_OVERFLOW; + if ((enc & FENV_Y_UNDERFLOW) == FENV_Y_UNDERFLOW) *y |= _EM_UNDERFLOW; + if ((enc & FENV_Y_INEXACT) == FENV_Y_INEXACT) *y |= _EM_INEXACT; + if ((enc & FENV_Y_UP) == FENV_Y_UP) *y |= _RC_UP; + if ((enc & FENV_Y_DOWN) == FENV_Y_DOWN) *y |= _RC_DOWN; + if ((enc & FENV_Y_FLUSH) == FENV_Y_FLUSH) *y |= _DN_FLUSH; + if ((enc & FENV_Y_FLUSH_SAVE) == FENV_Y_FLUSH_SAVE) *y |= _DN_FLUSH_OPERANDS_SAVE_RESULTS; + + return fenv_encode(*x, *y) == enc; +} +#else +static inline unsigned long fenv_encode(unsigned int x, unsigned int y) +{ + /* Encode _EM_DENORMAL as 0x20 for Windows compatibility. */ + if (y & _EM_DENORMAL) + y = (y & ~_EM_DENORMAL) | 0x20; + + return x | y; +} + +static inline BOOL fenv_decode(unsigned long enc, unsigned int *x, unsigned int *y) +{ + /* Decode 0x20 as _EM_DENORMAL. */ + if (enc & 0x20) + enc = (enc & ~0x20) | _EM_DENORMAL; + + *x = *y = enc; + return TRUE; +} +#endif + +void __mingw_setfp( unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask ); +void __mingw_setfp_sse( unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask ); +unsigned int __mingw_controlfp(unsigned int newval, unsigned int mask); +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) +int __mingw_control87_2(unsigned int, unsigned int, unsigned int *, unsigned int *); +#endif + +static inline unsigned int __mingw_statusfp(void) +{ + unsigned int flags = 0; +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + unsigned int x86_sw, sse2_sw = 0; + __mingw_setfp(NULL, 0, &x86_sw, 0); + if (__mingw_has_sse()) + __mingw_setfp_sse(NULL, 0, &sse2_sw, 0); + flags = x86_sw | sse2_sw; +#else + __mingw_setfp(NULL, 0, &flags, 0); +#endif + return flags; +} + +/* Use naked functions only on Clang. GCC doesn’t support them on ARM targets and + * has broken behavior on x86_64 by emitting .seh_endprologue. */ +#ifndef __clang__ + +#define __ASM_DEFINE_FUNC(rettype, name, args, code) \ + asm(".text\n\t" \ + ".p2align 2\n\t" \ + ".globl " __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) "\n\t" \ + ".def " __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) "; .scl 2; .type 32; .endef\n\t" \ + __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) ":\n\t" \ + code "\n\t"); + +#else + +#define __ASM_DEFINE_FUNC(rettype, name, args, code) \ + rettype __attribute__((naked)) name args { \ + asm(code "\n\t"); \ + } + +#endif + #ifdef __cplusplus } #endif diff --git a/lib/libc/mingw/intrincs/RtlSecureZeroMemory.c b/lib/libc/mingw/intrincs/RtlSecureZeroMemory.c index 8255a1e238..a5819037e1 100644 --- a/lib/libc/mingw/intrincs/RtlSecureZeroMemory.c +++ b/lib/libc/mingw/intrincs/RtlSecureZeroMemory.c @@ -4,7 +4,7 @@ PVOID WINAPI RtlSecureZeroMemory(PVOID ptr,SIZE_T cnt) { volatile char *vptr = (volatile char *)ptr; -#ifdef __x86_64 +#if defined(__x86_64__) && !defined(__arm64ec__) __stosb ((PBYTE)((DWORD64)vptr),0,cnt); #else while (cnt != 0) diff --git a/lib/libc/mingw/libsrc/uuid.c b/lib/libc/mingw/libsrc/uuid.c index 0a88ca1e30..48d555b38d 100644 --- a/lib/libc/mingw/libsrc/uuid.c +++ b/lib/libc/mingw/libsrc/uuid.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_loopback.c b/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_loopback.c index 8548ae742d..30d06c168e 100644 --- a/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_loopback.c +++ b/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_loopback.c @@ -8,6 +8,6 @@ void IN6_SET_ADDR_LOOPBACK(struct in6_addr *a) { - memset(a->s6_bytes, 0, sizeof(struct in6_addr)); + *a = (struct in6_addr){0}; a->s6_bytes[15] = 1; } diff --git a/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_unspecified.c b/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_unspecified.c index c15ff9302e..4a79c0e88a 100644 --- a/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_unspecified.c +++ b/lib/libc/mingw/libsrc/ws2tcpip/in6_set_addr_unspecified.c @@ -8,5 +8,5 @@ void IN6_SET_ADDR_UNSPECIFIED(struct in6_addr *a) { - memset(a->s6_bytes, 0, sizeof(struct in6_addr)); + *a = (struct in6_addr){0}; } diff --git a/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setany.c b/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setany.c index 6b401676b9..323f4a2467 100644 --- a/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setany.c +++ b/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setany.c @@ -6,14 +6,11 @@ #include #include -#undef IN6_SET_ADDR_UNSPECIFIED -#define IN6_SET_ADDR_UNSPECIFIED(a) memset((a)->s6_bytes,0,sizeof(struct in6_addr)) - void IN6ADDR_SETANY(struct sockaddr_in6 *a) { a->sin6_family = AF_INET6; a->sin6_port = 0; a->sin6_flowinfo = 0; - IN6_SET_ADDR_UNSPECIFIED(&a->sin6_addr); + a->sin6_addr = (struct in6_addr){0}; a->sin6_scope_id = 0; } diff --git a/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setloopback.c b/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setloopback.c index 9693a00b2c..5967cd9e21 100644 --- a/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setloopback.c +++ b/lib/libc/mingw/libsrc/ws2tcpip/in6addr_setloopback.c @@ -6,13 +6,6 @@ #include #include -#undef IN6_SET_ADDR_LOOPBACK -#define IN6_SET_ADDR_LOOPBACK(a) \ - do { \ - memset((a)->s6_bytes,0,sizeof(struct in6_addr));\ - (a)->s6_bytes[15] = 1; \ - } while (0) - void IN6ADDR_SETLOOPBACK(struct sockaddr_in6 *a) { a->sin6_family = AF_INET6; diff --git a/lib/libc/mingw/math/arm-common/ldexpl.c b/lib/libc/mingw/math/arm-common/ldexpl.c index 2c2a9e51a7..2a2a3771ce 100644 --- a/lib/libc/mingw/math/arm-common/ldexpl.c +++ b/lib/libc/mingw/math/arm-common/ldexpl.c @@ -8,9 +8,5 @@ long double ldexpl(long double x, int n) { -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) return ldexp(x, n); -#else -#error Not supported on your platform yet -#endif } diff --git a/lib/libc/mingw/math/arm64/_chgsignl.S b/lib/libc/mingw/math/arm-common/sincosl.c similarity index 52% rename from lib/libc/mingw/math/arm64/_chgsignl.S rename to lib/libc/mingw/math/arm-common/sincosl.c index 0472c7093e..8caeaec5a9 100644 --- a/lib/libc/mingw/math/arm64/_chgsignl.S +++ b/lib/libc/mingw/math/arm-common/sincosl.c @@ -4,13 +4,10 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <_mingw_mac.h> +#include - .file "_chgignl.S" - .text - .align 2 - .globl __MINGW_USYMBOL(_chgsignl) - .def __MINGW_USYMBOL(_chgsignl); .scl 2; .type 32; .endef -__MINGW_USYMBOL(_chgsignl): - fneg d0, d0 - ret +void sincosl(long double x, long double *s, long double *c) +{ + *s = sinl(x); + *c = cosl(x); +} diff --git a/lib/libc/mingw/math/arm/_chgsignl.S b/lib/libc/mingw/math/arm/_chgsignl.S deleted file mode 100644 index 355d35530d..0000000000 --- a/lib/libc/mingw/math/arm/_chgsignl.S +++ /dev/null @@ -1,16 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include <_mingw_mac.h> - - .file "_chgignl.S" - .text - .align 4 - .globl __MINGW_USYMBOL(_chgsignl) - .def __MINGW_USYMBOL(_chgsignl); .scl 2; .type 32; .endef -__MINGW_USYMBOL(_chgsignl): - vneg.f64 d0, d0 - bx lr diff --git a/lib/libc/mingw/math/cephes_mconf.h b/lib/libc/mingw/math/cephes_mconf.h index f502f187b0..4941dc64fd 100644 --- a/lib/libc/mingw/math/cephes_mconf.h +++ b/lib/libc/mingw/math/cephes_mconf.h @@ -66,7 +66,7 @@ extern double __QNAN; #endif /*long double*/ -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ #define MAXNUML 1.7976931348623158E308 #define MAXLOGL 7.09782712893383996843E2 #define MINLOGL -7.08396418532264106224E2 @@ -84,7 +84,7 @@ extern double __QNAN; #define PIL 3.1415926535897932384626L #define PIO2L 1.5707963267948966192313L #define PIO4L 7.8539816339744830961566E-1L -#endif /* defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) */ +#endif /* __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ */ #define isfinitel isfinite #define isinfl isinf diff --git a/lib/libc/mingw/math/coshl.c b/lib/libc/mingw/math/coshl.c index c5aaa73ecf..acc0094a47 100644 --- a/lib/libc/mingw/math/coshl.c +++ b/lib/libc/mingw/math/coshl.c @@ -5,7 +5,7 @@ */ #include "cephes_mconf.h" -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ #include long double coshl(long double x) diff --git a/lib/libc/mingw/math/erfl.c b/lib/libc/mingw/math/erfl.c index 1408cf5423..b1001dfa11 100644 --- a/lib/libc/mingw/math/erfl.c +++ b/lib/libc/mingw/math/erfl.c @@ -108,7 +108,7 @@ Copyright 1984, 1995 by Stephen L. Moshier long double erfl(long double x); -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ long double erfcl(long double x) { return erfc(x); diff --git a/lib/libc/mingw/math/fmal.c b/lib/libc/mingw/math/fmal.c index 67e5c503ab..3db856e7c9 100644 --- a/lib/libc/mingw/math/fmal.c +++ b/lib/libc/mingw/math/fmal.c @@ -5,7 +5,7 @@ */ long double fmal(long double x, long double y, long double z); -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ double fma(double x, double y, double z); diff --git a/lib/libc/mingw/math/fp_constsl.c b/lib/libc/mingw/math/fp_constsl.c index 8804082097..2bb00f7463 100644 --- a/lib/libc/mingw/math/fp_constsl.c +++ b/lib/libc/mingw/math/fp_constsl.c @@ -16,7 +16,7 @@ const union _ieee_rep __DENORML = { __LONG_DOUBLE_DENORM_REP }; long double nanl (const char *); long double nanl (const char * tagp __attribute__((unused)) ) { -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ return nan(""); #else return __QNANL.ldouble_val; diff --git a/lib/libc/mingw/math/fpclassifyl.c b/lib/libc/mingw/math/fpclassifyl.c index 3ee487e13d..0c057bd1cc 100644 --- a/lib/libc/mingw/math/fpclassifyl.c +++ b/lib/libc/mingw/math/fpclassifyl.c @@ -6,7 +6,9 @@ #include int __fpclassifyl (long double _x){ -#if defined(__x86_64__) || defined(_AMD64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ + return __fpclassify(_x); +#elif defined(_AMD64_) || defined(__x86_64__) __mingw_ldbl_type_t hlp; unsigned int e; hlp.x = _x; @@ -23,8 +25,6 @@ int __fpclassifyl (long double _x){ return (((hlp.lh.high & 0x7fffffff) | hlp.lh.low) == 0 ? FP_INFINITE : FP_NAN); return FP_NORMAL; -#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) - return __fpclassify(_x); #elif defined(__i386__) || defined(_X86_) unsigned short sw; __asm__ __volatile__ ( diff --git a/lib/libc/mingw/math/frexpl.c b/lib/libc/mingw/math/frexpl.c index f686a74633..f60b68bcde 100644 --- a/lib/libc/mingw/math/frexpl.c +++ b/lib/libc/mingw/math/frexpl.c @@ -5,7 +5,7 @@ */ long double frexpl(long double value, int* exp); -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ double frexp(double value, int* exp); diff --git a/lib/libc/mingw/math/isnanl.c b/lib/libc/mingw/math/isnanl.c index ff4ca6e423..fdc2529a9f 100644 --- a/lib/libc/mingw/math/isnanl.c +++ b/lib/libc/mingw/math/isnanl.c @@ -8,7 +8,9 @@ int __isnanl (long double _x) { -#if defined(__x86_64__) || defined(_AMD64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ + return __isnan(_x); +#elif defined(__x86_64__) || defined(_AMD64_) __mingw_ldbl_type_t ld; int xx, signexp; @@ -18,8 +20,6 @@ __isnanl (long double _x) signexp |= (unsigned int) (xx | (-xx)) >> 31; signexp = 0xfffe - signexp; return (int) ((unsigned int) signexp) >> 16; -#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) - return __isnan(_x); #elif defined(__i386__) || defined(_X86_) unsigned short _sw; __asm__ __volatile__ ("fxam;" diff --git a/lib/libc/mingw/math/lgammal.c b/lib/libc/mingw/math/lgammal.c index 998c6a90dd..1ccf7fce08 100644 --- a/lib/libc/mingw/math/lgammal.c +++ b/lib/libc/mingw/math/lgammal.c @@ -5,7 +5,7 @@ */ #include "cephes_mconf.h" -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ double lgamma(double x); long double lgammal(long double x) diff --git a/lib/libc/mingw/math/llrintl.c b/lib/libc/mingw/math/llrintl.c index 6a2bf73d8f..027686a921 100644 --- a/lib/libc/mingw/math/llrintl.c +++ b/lib/libc/mingw/math/llrintl.c @@ -9,7 +9,8 @@ long long llrintl (long double x) { long long retval = 0ll; -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) +#if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) || \ + defined(_X86_) || defined(__i386__) __asm__ __volatile__ ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); #else int mode = fegetround(); diff --git a/lib/libc/mingw/math/lrintl.c b/lib/libc/mingw/math/lrintl.c index d710fac051..0bdd5784fe 100644 --- a/lib/libc/mingw/math/lrintl.c +++ b/lib/libc/mingw/math/lrintl.c @@ -8,10 +8,10 @@ long lrintl (long double x) { long retval = 0l; -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) - __asm__ __volatile__ ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); -#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ retval = lrint(x); +#elif defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) + __asm__ __volatile__ ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); #endif return retval; } diff --git a/lib/libc/mingw/math/modff.c b/lib/libc/mingw/math/modff.c index dcf19cfedf..d2f8514d4d 100644 --- a/lib/libc/mingw/math/modff.c +++ b/lib/libc/mingw/math/modff.c @@ -13,7 +13,7 @@ modff (float value, float* iptr) float int_part = 0.0F; /* truncate */ /* truncate */ -#if defined(_AMD64_) || defined(__x86_64__) +#if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) asm volatile ("subq $8, %%rsp\n" "fnstcw 4(%%rsp)\n" "movzwl 4(%%rsp), %%eax\n" diff --git a/lib/libc/mingw/math/modfl.c b/lib/libc/mingw/math/modfl.c index 33593e6def..60b9b81b92 100644 --- a/lib/libc/mingw/math/modfl.c +++ b/lib/libc/mingw/math/modfl.c @@ -12,7 +12,7 @@ modfl (long double value, long double* iptr) { long double int_part = 0.0L; /* truncate */ -#if defined(_AMD64_) || defined(__x86_64__) +#if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) asm volatile ("subq $8, %%rsp\n" "fnstcw 4(%%rsp)\n" "movzwl 4(%%rsp), %%eax\n" diff --git a/lib/libc/mingw/math/rintl.c b/lib/libc/mingw/math/rintl.c index 1c37803306..da30c7aa2e 100644 --- a/lib/libc/mingw/math/rintl.c +++ b/lib/libc/mingw/math/rintl.c @@ -7,10 +7,10 @@ long double rintl (long double x) { long double retval = 0.0L; -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) - __asm__ __volatile__ ("frndint;": "=t" (retval) : "0" (x)); -#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ retval = rint(x); +#elif defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) + __asm__ __volatile__ ("frndint;": "=t" (retval) : "0" (x)); #endif return retval; } diff --git a/lib/libc/mingw/math/signbitl.c b/lib/libc/mingw/math/signbitl.c index 19f2938dbc..b4dba713b5 100644 --- a/lib/libc/mingw/math/signbitl.c +++ b/lib/libc/mingw/math/signbitl.c @@ -9,11 +9,11 @@ int __signbitl (long double x) { -#if defined(__x86_64__) || defined(_AMD64_) +#if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) __mingw_ldbl_type_t ld; ld.x = x; return ((ld.lh.sign_exponent & 0x8000) != 0); -#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#elif defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) || defined(__arm64ec__) || defined(_ARM64EC_) return __signbit(x); #elif defined(__i386__) || defined(_X86_) unsigned short sw; diff --git a/lib/libc/mingw/math/sinhl.c b/lib/libc/mingw/math/sinhl.c index aa6f0a9c34..fbf7edd67c 100644 --- a/lib/libc/mingw/math/sinhl.c +++ b/lib/libc/mingw/math/sinhl.c @@ -6,7 +6,7 @@ #include "cephes_mconf.h" #include -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ #include long double sinhl(long double x) diff --git a/lib/libc/mingw/math/sqrt.def.h b/lib/libc/mingw/math/sqrt.def.h index ed1e663ba7..43bd5a37d1 100644 --- a/lib/libc/mingw/math/sqrt.def.h +++ b/lib/libc/mingw/math/sqrt.def.h @@ -77,7 +77,7 @@ __FLT_ABI (sqrt) (__FLT_TYPE x) #else asm volatile ("fsqrtd %[dst], %[src];\n" : [dst] "=w" (res) : [src] "w" (x)); #endif -#elif defined(__aarch64__) || defined(_ARM64_) +#elif defined(__aarch64__) || defined(_ARM64_) || defined(__arm64ec__) || defined(_ARM64EC_) #if _NEW_COMPLEX_FLOAT asm volatile ("fsqrt %s[dst], %s[src]\n" : [dst] "=w" (res) : [src] "w" (x)); #else diff --git a/lib/libc/mingw/math/tanhl.c b/lib/libc/mingw/math/tanhl.c index da3fc5e25d..326adb2ae2 100644 --- a/lib/libc/mingw/math/tanhl.c +++ b/lib/libc/mingw/math/tanhl.c @@ -8,7 +8,7 @@ #define _SET_ERRNO(x) #endif -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ #include long double tanhl(long double x) diff --git a/lib/libc/mingw/math/tgammal.c b/lib/libc/mingw/math/tgammal.c index 1c7d4ea945..cfd694fe08 100644 --- a/lib/libc/mingw/math/tgammal.c +++ b/lib/libc/mingw/math/tgammal.c @@ -5,7 +5,7 @@ */ #include "cephes_mconf.h" -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ double tgamma(double x); long double tgammal(long double x) diff --git a/lib/libc/mingw/math/truncl.c b/lib/libc/mingw/math/truncl.c index 3b47e53d1b..a28fed3dcb 100644 --- a/lib/libc/mingw/math/truncl.c +++ b/lib/libc/mingw/math/truncl.c @@ -3,21 +3,20 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include + #include long double truncl (long double _x) { -#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ return trunc(_x); #else long double retval = 0.0L; unsigned short saved_cw; unsigned short tmp_cw; __asm__ __volatile__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */ - tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) - | FE_TOWARDZERO; + tmp_cw = saved_cw | 0xc00; /* round towards zero */ __asm__ __volatile__ ("fldcw %0;" : : "m" (tmp_cw)); __asm__ __volatile__ ("frndint;" : "=t" (retval) : "0" (_x)); /* round towards zero */ __asm__ __volatile__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */ diff --git a/lib/libc/mingw/math/x86/pow.def.h b/lib/libc/mingw/math/x86/pow.def.h index 0cf0739fee..f8c715abdf 100644 --- a/lib/libc/mingw/math/x86/pow.def.h +++ b/lib/libc/mingw/math/x86/pow.def.h @@ -69,11 +69,8 @@ #include "../complex/complex_internal.h" #include #include -#include #include #include -#define FE_ROUNDING_MASK \ - (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO) static __FLT_TYPE internal_modf (__FLT_TYPE value, __FLT_TYPE *iptr) diff --git a/lib/libc/mingw/misc/dllentrypoint.c b/lib/libc/mingw/misc/dllentrypoint.c deleted file mode 100644 index 0e3581ba67..0000000000 --- a/lib/libc/mingw/misc/dllentrypoint.c +++ /dev/null @@ -1,18 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include -#define _DECL_DLLMAIN -#include - -BOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID); - -BOOL WINAPI DllEntryPoint (HANDLE __UNUSED_PARAM(hDllHandle), - DWORD __UNUSED_PARAM(dwReason), - LPVOID __UNUSED_PARAM(lpreserved)) -{ - return TRUE; -} diff --git a/lib/libc/mingw/misc/feclearexcept.c b/lib/libc/mingw/misc/feclearexcept.c index a5ab0f0959..5fa811fbe9 100644 --- a/lib/libc/mingw/misc/feclearexcept.c +++ b/lib/libc/mingw/misc/feclearexcept.c @@ -4,44 +4,18 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include #include /* 7.6.2.1 The feclearexcept function clears the supported exceptions represented by its argument. */ -int feclearexcept (int excepts) +int feclearexcept(int flags) { - fenv_t _env; -#if defined(_ARM_) || defined(__arm__) - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - _env.__cw &= ~(excepts & FE_ALL_EXCEPT); - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - (void) _env; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - fpcr &= ~(excepts & FE_ALL_EXCEPT); - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); -#else - int _mxcsr; - if (excepts == FE_ALL_EXCEPT) - { - __asm__ volatile ("fnclex"); - } - else - { - __asm__ volatile ("fnstenv %0" : "=m" (_env)); - _env.__status_word &= ~(excepts & FE_ALL_EXCEPT); - __asm__ volatile ("fldenv %0" : : "m" (_env)); - } - if (__mingw_has_sse ()) - { - __asm__ volatile ("stmxcsr %0" : "=m" (_mxcsr)); - _mxcsr &= ~(((excepts & FE_ALL_EXCEPT))); - __asm__ volatile ("ldmxcsr %0" : : "m" (_mxcsr)); - } -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return (0); + fenv_t env; + + fegetenv(&env); + flags &= FE_ALL_EXCEPT; + env._Fe_stat &= ~fenv_encode(flags, flags); + return fesetenv(&env); } diff --git a/lib/libc/mingw/misc/fegetenv.c b/lib/libc/mingw/misc/fegetenv.c index e17fd491c7..c1169cda7c 100644 --- a/lib/libc/mingw/misc/fegetenv.c +++ b/lib/libc/mingw/misc/fegetenv.c @@ -4,34 +4,25 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include #include /* 7.6.4.1 The fegetenv function stores the current floating-point environment in the object pointed to by envp. */ -int fegetenv (fenv_t * envp) +int fegetenv(fenv_t *env) { -#if defined(_ARM_) || defined(__arm__) - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (*envp)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - envp->__cw = fpcr; +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + unsigned int x87, sse; + __mingw_control87_2(0, 0, &x87, &sse); + env->_Fe_ctl = fenv_encode(x87, sse); + __mingw_setfp(NULL, 0, &x87, 0); + __mingw_setfp_sse(NULL, 0, &sse, 0); + env->_Fe_stat = fenv_encode(x87, sse); #else - __asm__ __volatile__ ("fnstenv %0;": "=m" (*envp)); - /* fnstenv sets control word to non-stop for all exceptions, so we - need to reload our env to restore the original mask. */ - __asm__ __volatile__ ("fldenv %0" : : "m" (*envp)); - if (__mingw_has_sse ()) - { - int _mxcsr; - __asm__ __volatile__ ("stmxcsr %0" : "=m" (_mxcsr)); - envp->__unused0 = (((unsigned int) _mxcsr) >> 16); - envp->__unused1 = (((unsigned int) _mxcsr) & 0xffff); - } -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ + env->_Fe_ctl = fenv_encode(0, __mingw_controlfp(0, 0)); + env->_Fe_stat = fenv_encode(0, __mingw_statusfp()); +#endif return 0; } diff --git a/lib/libc/mingw/misc/fegetexceptflag.c b/lib/libc/mingw/misc/fegetexceptflag.c index b50ca6fc1f..cc9bdde4b7 100644 --- a/lib/libc/mingw/misc/fegetexceptflag.c +++ b/lib/libc/mingw/misc/fegetexceptflag.c @@ -12,26 +12,15 @@ representation of the exception flags indicated by the argument excepts in the object pointed to by the argument flagp. */ -int fegetexceptflag (fexcept_t * flagp, int excepts) +int fegetexceptflag(fexcept_t *status, int excepts) { -#if defined(_ARM_) || defined(__arm__) - fenv_t _env; - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - *flagp = _env.__cw & excepts & FE_ALL_EXCEPT; -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - *flagp = fpcr & excepts & FE_ALL_EXCEPT; +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + unsigned int x87, sse; + __mingw_setfp(NULL, 0, &x87, 0); + __mingw_setfp_sse(NULL, 0, &sse, 0); + *status = fenv_encode(x87 & excepts, sse & excepts); #else - int _mxcsr; - unsigned short _status; - - __asm__ volatile ("fnstsw %0" : "=am" (_status)); - _mxcsr = 0; - if (__mingw_has_sse ()) - __asm__ volatile ("stmxcsr %0" : "=m" (_mxcsr)); - - *flagp = (_mxcsr | _status) & excepts & FE_ALL_EXCEPT; -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + *status = fenv_encode(0, __mingw_statusfp() & excepts); +#endif + return 0; } diff --git a/lib/libc/mingw/misc/fegetround.c b/lib/libc/mingw/misc/fegetround.c index d2fdb77252..22d392ef91 100644 --- a/lib/libc/mingw/misc/fegetround.c +++ b/lib/libc/mingw/misc/fegetround.c @@ -3,26 +3,13 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include +#include /* 7.6.3.1 The fegetround function returns the value of the rounding direction macro representing the current rounding direction. */ -int -fegetround (void) +int fegetround(void) { -#if defined(_ARM_) || defined(__arm__) - fenv_t _env; - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - return (_env.__cw & (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - return (fpcr & (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)); -#else - int _control; - __asm__ volatile ("fnstcw %0" : "=m" (*&_control)); - return (_control & (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)); -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ + return __mingw_controlfp(0, 0) & _MCW_RC; } diff --git a/lib/libc/mingw/misc/feholdexcept.c b/lib/libc/mingw/misc/feholdexcept.c index 8736faadf0..8048430b7e 100644 --- a/lib/libc/mingw/misc/feholdexcept.c +++ b/lib/libc/mingw/misc/feholdexcept.c @@ -11,25 +11,8 @@ flags, and then installs a non-stop (continue on exceptions) mode, if available, for all exceptions. */ -int feholdexcept (fenv_t * envp) +int feholdexcept(fenv_t *env) { -#if defined(_ARM_) || defined(__arm__) - fenv_t _env; - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - envp->__cw = _env.__cw; - _env.__cw &= ~(FE_ALL_EXCEPT); - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - envp->__cw = fpcr; - fpcr &= ~(FE_ALL_EXCEPT); - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); -#else - __asm__ __volatile__ ("fnstenv %0;" : "=m" (* envp)); /* save current into envp */ - /* fnstenv sets control word to non-stop for all exceptions, so all we - need to do is clear the exception flags. */ - __asm__ __volatile__ ("fnclex"); -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + fegetenv(env); + return feclearexcept(FE_ALL_EXCEPT); } diff --git a/lib/libc/mingw/misc/feraiseexcept.c b/lib/libc/mingw/misc/feraiseexcept.c index 8ec36f732a..041b8a772c 100644 --- a/lib/libc/mingw/misc/feraiseexcept.c +++ b/lib/libc/mingw/misc/feraiseexcept.c @@ -3,7 +3,7 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include +#include /* 7.6.2.3 The feraiseexcept function raises the supported exceptions @@ -13,24 +13,16 @@ the inexact exception whenever it raises the overflow or underflow exception is implementation-defined. */ -int feraiseexcept (int excepts) +int feraiseexcept(int flags) { - fenv_t _env; -#if defined(_ARM_) || defined(__arm__) - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - _env.__cw |= excepts & FE_ALL_EXCEPT; - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - (void) _env; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - fpcr |= excepts & FE_ALL_EXCEPT; - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); -#else - __asm__ volatile ("fnstenv %0;" : "=m" (_env)); - _env.__status_word |= excepts & FE_ALL_EXCEPT; - __asm__ volatile ("fldenv %0;" - "fwait;" : : "m" (_env)); -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + fenv_t env; + + flags &= FE_ALL_EXCEPT; + fegetenv(&env); + env._Fe_stat |= fenv_encode(flags, flags); + fesetenv(&env); +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + __asm__ volatile ("fwait\n\t"); +#endif + return 0; } diff --git a/lib/libc/mingw/misc/fesetenv.c b/lib/libc/mingw/misc/fesetenv.c index 76325ce377..432192763a 100644 --- a/lib/libc/mingw/misc/fesetenv.c +++ b/lib/libc/mingw/misc/fesetenv.c @@ -4,11 +4,24 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <_mingw.h> -#include -#include #include +/* The FE_DFL_ENV macro is required by standard. + fesetenv will use the environment set at app startup.*/ +const fenv_t __mingw_fe_dfl_env = { 0, 0 }; + +/* The C99 standard (7.6.9) allows us to define implementation-specific macros for + different fp environments */ +#if defined(__i386__) || defined(__x86_64__) + +/* The default Intel x87 floating point environment (64-bit mantissa) */ +const fenv_t __mingw_fe_pc64_env = { 0x3f3f003f, 0 }; + +/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */ +const fenv_t __mingw_fe_pc53_env = { 0x3f3f103f, 0 }; + +#endif + /* 7.6.4.3 The fesetenv function establishes the floating-point environment represented by the object pointed to by envp. The argument envp @@ -22,61 +35,27 @@ extern void (* __MINGW_IMP_SYMBOL(_fpreset))(void); extern void _fpreset(void); -int fesetenv (const fenv_t * envp) +int fesetenv(const fenv_t *env) { -#if defined(_ARM_) || defined(__arm__) - if (envp == FE_DFL_ENV) - /* Use the choice made at app startup */ - _fpreset(); - else - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (*envp)); -#elif defined(_ARM64_) || defined(__aarch64__) - if (envp == FE_DFL_ENV) { - /* Use the choice made at app startup */ - _fpreset(); - } else { - unsigned __int64 fpcr = envp->__cw; - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); - } -#else - if (envp == FE_PC64_ENV) - /* - * fninit initializes the control register to 0x37f, - * the status register to zero and the tag word to 0FFFFh. - * The other registers are unaffected. - */ - __asm__ __volatile__ ("fninit"); + unsigned int x87_cw, cw, x87_stat, stat; + unsigned int mask = ~0u; - else if (envp == FE_PC53_ENV) - /* - * MS _fpreset() does same *except* it sets control word - * to 0x27f (53-bit precision). - * We force calling _fpreset in msvcrt.dll - */ - - (* __MINGW_IMP_SYMBOL(_fpreset))(); - - else if (envp == FE_DFL_ENV) - /* Use the choice made at app startup */ - _fpreset(); - - else - { - fenv_t env = *envp; - int has_sse = __mingw_has_sse (); - int _mxcsr; - /*_mxcsr = ((int)envp->__unused0 << 16) | (int)envp->__unused1; *//* mxcsr low and high */ - if (has_sse) - __asm__ ("stmxcsr %0" : "=m" (*&_mxcsr)); - env.__unused0 = 0xffff; - env.__unused1 = 0xffff; - __asm__ volatile ("fldenv %0" : : "m" (env) - : "st", "st(1)", "st(2)", "st(3)", "st(4)", - "st(5)", "st(6)", "st(7)"); - if (has_sse) - __asm__ volatile ("ldmxcsr %0" : : "m" (*&_mxcsr)); + if (!env->_Fe_ctl && !env->_Fe_stat) { + _fpreset(); + return 0; } -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + if (!fenv_decode(env->_Fe_ctl, &x87_cw, &cw)) + return 1; + if (!fenv_decode(env->_Fe_stat, &x87_stat, &stat)) + return 1; + +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + __mingw_setfp(&x87_cw, mask, &x87_stat, ~0); + if (__mingw_has_sse()) + __mingw_setfp_sse(&cw, mask, &stat, ~0); +#else + __mingw_setfp(&cw, mask, &stat, ~0); +#endif + return 0; } diff --git a/lib/libc/mingw/misc/fesetexceptflag.c b/lib/libc/mingw/misc/fesetexceptflag.c index 095dfea0b9..9faedbb535 100644 --- a/lib/libc/mingw/misc/fesetexceptflag.c +++ b/lib/libc/mingw/misc/fesetexceptflag.c @@ -4,7 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include #include /* 7.6.2.4 @@ -16,39 +15,16 @@ represented by the argument excepts. This function does not raise exceptions, but only sets the state of the flags. */ -int fesetexceptflag (const fexcept_t * flagp, int excepts) +int fesetexceptflag(const fexcept_t *status, int excepts) { - fenv_t _env; + fenv_t env; - excepts &= FE_ALL_EXCEPT; + excepts &= FE_ALL_EXCEPT; + if(!excepts) + return 0; -#if defined(_ARM_) || defined(__arm__) - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - _env.__cw &= ~excepts; - _env.__cw |= (*flagp & excepts); - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - (void) _env; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - fpcr &= ~excepts; - fpcr |= (*flagp & excepts); - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); -#else - __asm__ volatile ("fnstenv %0;" : "=m" (_env)); - _env.__status_word &= ~excepts; - _env.__status_word |= (*flagp & excepts); - __asm__ volatile ("fldenv %0;" : : "m" (_env)); - - if (__mingw_has_sse ()) - { - int sse_cw; - __asm__ volatile ("stmxcsr %0;" : "=m" (sse_cw)); - sse_cw &= ~(excepts << 7); - sse_cw |= ((*flagp & excepts) << 7); - __asm__ volatile ("ldmxcsr %0" : : "m" (sse_cw)); - } - -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + fegetenv(&env); + env._Fe_stat &= ~fenv_encode(excepts, excepts); + env._Fe_stat |= *status & fenv_encode(excepts, excepts); + return fesetenv(&env); } diff --git a/lib/libc/mingw/misc/fesetround.c b/lib/libc/mingw/misc/fesetround.c index e51f46cd7d..9bf7c35998 100644 --- a/lib/libc/mingw/misc/fesetround.c +++ b/lib/libc/mingw/misc/fesetround.c @@ -13,43 +13,10 @@ to the value of a rounding direction macro, the rounding direction is not changed. */ -int fesetround (int mode) +int fesetround(int round_mode) { -#if defined(_ARM_) || defined(__arm__) - fenv_t _env; - if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) != 0) - return -1; - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - _env.__cw &= ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO); - _env.__cw |= mode; - __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) != 0) - return -1; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - fpcr &= ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO); - fpcr |= mode; - __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); -#else - unsigned short _cw; - if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) - != 0) - return -1; - __asm__ volatile ("fnstcw %0;": "=m" (*&_cw)); - _cw &= ~0xc00; - _cw |= mode; - __asm__ volatile ("fldcw %0;" : : "m" (*&_cw)); - - if (__mingw_has_sse ()) - { - int mxcsr; - - __asm__ volatile ("stmxcsr %0" : "=m" (*&mxcsr)); - mxcsr &= ~0x6000; - mxcsr |= mode << 3; - __asm__ volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); - } -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ - return 0; + if (round_mode & (~_MCW_RC)) + return 1; + __mingw_controlfp(round_mode, _MCW_RC); + return 0; } diff --git a/lib/libc/mingw/misc/fetestexcept.c b/lib/libc/mingw/misc/fetestexcept.c index 04e75970fc..4c9abfb5aa 100644 --- a/lib/libc/mingw/misc/fetestexcept.c +++ b/lib/libc/mingw/misc/fetestexcept.c @@ -15,26 +15,7 @@ exception macros corresponding to the currently set exceptions included in excepts. */ -int fetestexcept (int excepts) +int fetestexcept(int flags) { -#if defined(_ARM_) || defined(__arm__) - fenv_t _env; - __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); - return _env.__cw & excepts & FE_ALL_EXCEPT; -#elif defined(_ARM64_) || defined(__aarch64__) - unsigned __int64 fpcr; - __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); - return fpcr & excepts & FE_ALL_EXCEPT; -#else - unsigned short _sw; - __asm__ __volatile__ ("fnstsw %%ax" : "=a" (_sw)); - - if (__mingw_has_sse ()) - { - int sse_sw; - __asm__ __volatile__ ("stmxcsr %0;" : "=m" (sse_sw)); - _sw |= sse_sw; - } - return _sw & excepts & FE_ALL_EXCEPT; -#endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ + return __mingw_statusfp() & flags; } diff --git a/lib/libc/mingw/misc/feupdateenv.c b/lib/libc/mingw/misc/feupdateenv.c index aea95902bb..8774d7402b 100644 --- a/lib/libc/mingw/misc/feupdateenv.c +++ b/lib/libc/mingw/misc/feupdateenv.c @@ -13,13 +13,9 @@ set by a call to feholdexcept or fegetenv, or equal the macro FE_DFL_ENV or an implementation-defined environment macro. */ -/* FIXME: this works but surely there must be a better way. */ - -int feupdateenv (const fenv_t * envp) +int feupdateenv(const fenv_t *env) { - unsigned int _fexcept = fetestexcept (FE_ALL_EXCEPT); /*save excepts */ - fesetenv (envp); /* install the env */ - feraiseexcept (_fexcept); /* raise the except */ - return 0; + int except = fetestexcept(FE_ALL_EXCEPT); + return fesetenv(env) || feraiseexcept(except); } diff --git a/lib/libc/mingw/misc/ftw.c b/lib/libc/mingw/misc/ftw.c index 74d05aa715..f520ef63da 100644 --- a/lib/libc/mingw/misc/ftw.c +++ b/lib/libc/mingw/misc/ftw.c @@ -15,11 +15,9 @@ #include #include -#ifdef IMPL_FTW64 -#define stat stat64 -#define nftw nftw64 -#define ftw ftw64 -#endif +int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat); +int __cdecl stat32i64(const char *_Filename, struct _stat32i64 *_Stat); +int __cdecl stat64i32(const char *_Filename, struct _stat64i32 *_Stat); typedef struct dir_data_t { DIR *h; @@ -36,14 +34,14 @@ typedef struct ctx_t { dir_data_t **dirs; char *buf; struct FTW ftw; - int (*fcb) (const char *, const struct stat *, int , struct FTW *); + int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *); size_t cur_dir, msz_dir, buf_sz; int flags; dev_t dev; } ctx_t; static int add_object (ctx_t *); -static int do_dir (ctx_t *, struct stat *, dir_data_t *); +static int do_dir (ctx_t *, STRUCT_STAT *, dir_data_t *); static int do_entity (ctx_t *, dir_data_t *, const char *, size_t); static int do_it (const char *, int, void *, int, int); @@ -225,7 +223,7 @@ open_directory (ctx_t *ctx, dir_data_t *dirp) static int do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen) { - struct stat st; + STRUCT_STAT st; char *h; size_t cnt_sz; int ret = 0, flag = 0; @@ -249,7 +247,7 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen) name = ctx->buf; - if (stat (name, &st) < 0) + if (FUNC_STAT (name, &st) < 0) { if (errno != EACCES && errno != ENOENT) ret = -1; @@ -257,7 +255,7 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen) flag = FTW_NS; if (!(ctx->flags & FTW_PHYS)) - stat (name, &st); + FUNC_STAT (name, &st); } else flag = (S_ISDIR (st.st_mode) ? FTW_D : FTW_F); @@ -281,7 +279,7 @@ do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen) static int -do_dir (ctx_t *ctx, struct stat *st, __UNUSED_PARAM(dir_data_t *old_dir)) +do_dir (ctx_t *ctx, STRUCT_STAT *st, __UNUSED_PARAM(dir_data_t *old_dir)) { dir_data_t dir; struct dirent *d; @@ -378,7 +376,7 @@ static int do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void *fcb, int descriptors, int flags) { struct ctx_t ctx; - struct stat st; + STRUCT_STAT st; int ret = 0; int sv_e; char *cp; @@ -417,12 +415,12 @@ do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void *fcb, int descriptors, ctx.ftw.level = 0; ctx.ftw.base = cp - ctx.buf; ctx.flags = flags; - ctx.fcb = (int (*) (const char *, const struct stat *, int , struct FTW *)) fcb; + ctx.fcb = (int (*) (const char *, const STRUCT_STAT *, int , struct FTW *)) fcb; ctx.objs = NULL; if (!ret) { - if (stat (ctx.buf, &st) < 0) + if (FUNC_STAT (ctx.buf, &st) < 0) ret = -1; else if (S_ISDIR (st.st_mode)) { @@ -451,13 +449,17 @@ do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void *fcb, int descriptors, } int -ftw (const char *path, int (*fcb) (const char *, const struct stat *, int), int descriptors) +FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors); +int +FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors) { return do_it (path, 0, fcb, descriptors, 0); } int -nftw (const char *path, int (*fcb) (const char *, const struct stat *, int , struct FTW *), int descriptors, int flags) +FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags); +int +FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags) { return do_it (path, 1, fcb, descriptors, flags); } diff --git a/lib/libc/mingw/misc/ftw32.c b/lib/libc/mingw/misc/ftw32.c new file mode 100644 index 0000000000..5eb9e374ee --- /dev/null +++ b/lib/libc/mingw/misc/ftw32.c @@ -0,0 +1,19 @@ +/** + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#define FUNC_FTW ftw32 +#define FUNC_NFTW nftw32 +#define FUNC_STAT stat32 +#define STRUCT_STAT struct _stat32 +#include "ftw.c" + +/* On 32-bit systems is stat ABI compatible with stat32 */ +#ifndef _WIN64 +#undef nftw +#undef ftw +struct stat; +int __attribute__ ((alias ("nftw32"))) __cdecl nftw(const char *, int (*) (const char *, const struct stat *, int, struct FTW *), int, int); +int __attribute__ ((alias ("ftw32"))) __cdecl ftw(const char *, int (*) (const char *, const struct stat *, int), int); +#endif diff --git a/lib/libc/mingw/misc/ftw32i64.c b/lib/libc/mingw/misc/ftw32i64.c new file mode 100644 index 0000000000..20985fb705 --- /dev/null +++ b/lib/libc/mingw/misc/ftw32i64.c @@ -0,0 +1,10 @@ +/** + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#define FUNC_FTW ftw32i64 +#define FUNC_NFTW nftw32i64 +#define FUNC_STAT stat32i64 +#define STRUCT_STAT struct _stat32i64 +#include "ftw.c" diff --git a/lib/libc/mingw/misc/ftw64.c b/lib/libc/mingw/misc/ftw64.c index 3e45847efe..72e22a214e 100644 --- a/lib/libc/mingw/misc/ftw64.c +++ b/lib/libc/mingw/misc/ftw64.c @@ -3,6 +3,8 @@ * No warranty is given; refer to the file DISCLAIMER within this package. */ -#define IMPL_FTW64 1 - +#define FUNC_FTW ftw64 +#define FUNC_NFTW nftw64 +#define FUNC_STAT stat64 +#define STRUCT_STAT struct stat64 #include "ftw.c" diff --git a/lib/libc/mingw/misc/ftw64i32.c b/lib/libc/mingw/misc/ftw64i32.c new file mode 100644 index 0000000000..2ded6ec4ae --- /dev/null +++ b/lib/libc/mingw/misc/ftw64i32.c @@ -0,0 +1,19 @@ +/** + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#define FUNC_FTW ftw64i32 +#define FUNC_NFTW nftw64i32 +#define FUNC_STAT stat64i32 +#define STRUCT_STAT struct _stat64i32 +#include "ftw.c" + +/* On 64-bit systems is stat ABI compatible with stat64i32 */ +#ifdef _WIN64 +#undef nftw +#undef ftw +struct stat; +int __attribute__ ((alias ("nftw64i32"))) __cdecl nftw(const char *, int (*) (const char *, const struct stat *, int, struct FTW *), int, int); +int __attribute__ ((alias ("ftw64i32"))) __cdecl ftw(const char *, int (*) (const char *, const struct stat *, int), int); +#endif diff --git a/lib/libc/mingw/misc/mingw-aligned-malloc.c b/lib/libc/mingw/misc/mingw-aligned-malloc.c index ca5f866e2f..02872c921a 100644 --- a/lib/libc/mingw/misc/mingw-aligned-malloc.c +++ b/lib/libc/mingw/misc/mingw-aligned-malloc.c @@ -18,16 +18,14 @@ #include /* uintptr_t */ #include /* memmove */ -/* Forward declarations: */ -void *__mingw_aligned_offset_malloc (size_t, size_t, size_t); - #define NOT_POWER_OF_TWO(n) (((n) & ((n) - 1))) #define UI(p) ((uintptr_t) (p)) #define CP(p) ((char *) p) +#define GAP(offset) ((0 - offset) & (sizeof (void *) -1)) #define PTR_ALIGN(p0, alignment, offset) \ - ((void *) (((UI(p0) + (alignment + sizeof(void*)) + offset) \ - & (~UI(alignment - 1))) \ + ((void *) (((UI(p0) + (alignment + GAP(offset) + sizeof(void*)) + offset) \ + & (~UI(alignment))) \ - offset)) /* Pointer must sometimes be aligned; assume sizeof(void*) is a power of two. */ @@ -47,12 +45,13 @@ __mingw_aligned_offset_malloc (size_t size, size_t alignment, size_t offset) return ((void *) 0); if (alignment < sizeof (void *)) alignment = sizeof (void *); + alignment--; /* Including the extra sizeof(void*) is overkill on a 32-bit machine, since malloc is already 8-byte aligned, as long as we enforce alignment >= 8 ...but oh well. */ - p0 = malloc (size + (alignment + sizeof (void *))); + p0 = malloc (size + (alignment + GAP (offset) + sizeof (void *))); if (!p0) return ((void *) 0); p = PTR_ALIGN (p0, alignment, offset); @@ -91,6 +90,7 @@ __mingw_aligned_offset_realloc (void *memblock, size_t size, } if (alignment < sizeof (void *)) alignment = sizeof (void *); + alignment--; p0 = ORIG_PTR (memblock); /* It is an error for the alignment to change. */ @@ -98,7 +98,7 @@ __mingw_aligned_offset_realloc (void *memblock, size_t size, goto bad; shift = CP (memblock) - CP (p0); - p0 = realloc (p0, size + (alignment + sizeof (void *))); + p0 = realloc (p0, size + (alignment + GAP (offset) + sizeof (void *))); if (!p0) return ((void *) 0); p = PTR_ALIGN (p0, alignment, offset); @@ -121,3 +121,29 @@ __mingw_aligned_realloc (void *memblock, size_t size, size_t alignment) { return __mingw_aligned_offset_realloc (memblock, size, alignment, 0); } + +size_t +__mingw_aligned_msize (void *memblock, size_t alignment, size_t offset) +{ + void *p0; + + if (!memblock || NOT_POWER_OF_TWO (alignment)) + { + errno = EINVAL; + return (size_t)-1; + } + if (alignment < sizeof (void *)) + alignment = sizeof (void *); + alignment--; + + p0 = ORIG_PTR (memblock); + + /* It is an error if the alignment or offset does not match. */ + if (memblock != PTR_ALIGN (p0, alignment, offset)) + { + errno = EINVAL; + return (size_t)-1; + } + + return _msize (p0) - (alignment + GAP (offset) + sizeof (void *)); +} diff --git a/lib/libc/mingw/misc/mingw_controlfp.c b/lib/libc/mingw/misc/mingw_controlfp.c new file mode 100644 index 0000000000..c7f553a4dd --- /dev/null +++ b/lib/libc/mingw/misc/mingw_controlfp.c @@ -0,0 +1,53 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include "internal.h" + +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) +/* Internal MinGW version of _control87_2 */ +int __mingw_control87_2( unsigned int newval, unsigned int mask, + unsigned int *x86_cw, unsigned int *sse2_cw ) +{ + if (x86_cw) + { + *x86_cw = newval; + __mingw_setfp(x86_cw, mask, NULL, 0); + } + + if (!sse2_cw) return 1; + + if (__mingw_has_sse()) + { + *sse2_cw = newval; + __mingw_setfp_sse(sse2_cw, mask, NULL, 0); + } + else *sse2_cw = 0; + + return 1; +} +#endif + +/* Internal MinGW version of _control87 */ +unsigned int __mingw_controlfp(unsigned int newval, unsigned int mask) +{ + unsigned int flags = 0; +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) + unsigned int sse2_cw; + + __mingw_control87_2( newval, mask, &flags, &sse2_cw ); + + if (__mingw_has_sse()) + { + if ((flags ^ sse2_cw) & (_MCW_EM | _MCW_RC)) flags |= _EM_AMBIGUOUS; + flags |= sse2_cw; + } +#else + flags = newval; + __mingw_setfp(&flags, mask, NULL, 0); +#endif + return flags; +} + diff --git a/lib/libc/mingw/misc/mingw_getsp.S b/lib/libc/mingw/misc/mingw_getsp.S index 1e83b7383c..08dfc37e13 100644 --- a/lib/libc/mingw/misc/mingw_getsp.S +++ b/lib/libc/mingw/misc/mingw_getsp.S @@ -15,7 +15,10 @@ .globl __MINGW_USYMBOL(mingw_getsp) .def __MINGW_USYMBOL(mingw_getsp); .scl 2; .type 32; .endef __MINGW_USYMBOL(mingw_getsp): -#if defined(_AMD64_) || defined(__x86_64__) +#if defined(_ARM64_) || defined(__aarch64__) || defined(__arm64ec__) + mov x0, sp + ret +#elif defined(_AMD64_) || defined(__x86_64__) leaq 8(%rsp),%rax ret #elif defined(_X86_) || defined(__i386__) @@ -24,7 +27,4 @@ __MINGW_USYMBOL(mingw_getsp): #elif defined(_ARM_) || defined(__arm__) mov r0, sp bx lr -#elif defined(_ARM64_) || defined(__aarch64__) - mov x0, sp - ret #endif diff --git a/lib/libc/mingw/misc/mingw_setfp.c b/lib/libc/mingw/misc/mingw_setfp.c new file mode 100644 index 0000000000..14fda6e248 --- /dev/null +++ b/lib/libc/mingw/misc/mingw_setfp.c @@ -0,0 +1,373 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include "internal.h" + +#if defined(__i386__) || defined(__x86_64__) + +static unsigned int get_mxcsr(void) +{ + unsigned int ret; +#ifdef __arm64ec__ + extern NTSTATUS (*__os_arm64x_get_x64_information)(ULONG,void*,void*); + __os_arm64x_get_x64_information( 0, &ret, NULL ); +#else + __asm__ __volatile__( "stmxcsr %0" : "=m" (ret) ); +#endif + return ret; +} + +static void set_mxcsr( unsigned int val ) +{ +#ifdef __arm64ec__ + extern NTSTATUS (*__os_arm64x_set_x64_information)(ULONG,ULONG_PTR,void*); + __os_arm64x_set_x64_information( 0, val, NULL ); +#else + __asm__ __volatile__( "ldmxcsr %0" : : "m" (val) ); +#endif +} + +void __mingw_setfp_sse( unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask ) +{ + unsigned int old_fpword, fpword = get_mxcsr(); + unsigned int flags; + + old_fpword = fpword; + + cw_mask &= _MCW_EM | _MCW_RC | _MCW_DN; + sw_mask &= _MCW_EM; + + if (sw) + { + flags = 0; + if (fpword & 0x1) flags |= _SW_INVALID; + if (fpword & 0x2) flags |= _SW_DENORMAL; + if (fpword & 0x4) flags |= _SW_ZERODIVIDE; + if (fpword & 0x8) flags |= _SW_OVERFLOW; + if (fpword & 0x10) flags |= _SW_UNDERFLOW; + if (fpword & 0x20) flags |= _SW_INEXACT; + + *sw = (flags & ~sw_mask) | (*sw & sw_mask); + fpword &= ~0x3f; + if (*sw & _SW_INVALID) fpword |= 0x1; + if (*sw & _SW_DENORMAL) fpword |= 0x2; + if (*sw & _SW_ZERODIVIDE) fpword |= 0x4; + if (*sw & _SW_OVERFLOW) fpword |= 0x8; + if (*sw & _SW_UNDERFLOW) fpword |= 0x10; + if (*sw & _SW_INEXACT) fpword |= 0x20; + *sw = flags; + } + + if (cw) + { + flags = 0; + if (fpword & 0x80) flags |= _EM_INVALID; + if (fpword & 0x100) flags |= _EM_DENORMAL; + if (fpword & 0x200) flags |= _EM_ZERODIVIDE; + if (fpword & 0x400) flags |= _EM_OVERFLOW; + if (fpword & 0x800) flags |= _EM_UNDERFLOW; + if (fpword & 0x1000) flags |= _EM_INEXACT; + switch (fpword & 0x6000) + { + case 0x6000: flags |= _RC_UP|_RC_DOWN; break; + case 0x4000: flags |= _RC_UP; break; + case 0x2000: flags |= _RC_DOWN; break; + } + switch (fpword & 0x8040) + { + case 0x0040: flags |= _DN_FLUSH_OPERANDS_SAVE_RESULTS; break; + case 0x8000: flags |= _DN_SAVE_OPERANDS_FLUSH_RESULTS; break; + case 0x8040: flags |= _DN_FLUSH; break; + } + + *cw = (flags & ~cw_mask) | (*cw & cw_mask); + fpword &= ~0xffc0; + if (*cw & _EM_INVALID) fpword |= 0x80; + if (*cw & _EM_DENORMAL) fpword |= 0x100; + if (*cw & _EM_ZERODIVIDE) fpword |= 0x200; + if (*cw & _EM_OVERFLOW) fpword |= 0x400; + if (*cw & _EM_UNDERFLOW) fpword |= 0x800; + if (*cw & _EM_INEXACT) fpword |= 0x1000; + switch (*cw & _MCW_RC) + { + case _RC_UP|_RC_DOWN: fpword |= 0x6000; break; + case _RC_UP: fpword |= 0x4000; break; + case _RC_DOWN: fpword |= 0x2000; break; + } + switch (*cw & _MCW_DN) + { + case _DN_FLUSH_OPERANDS_SAVE_RESULTS: fpword |= 0x0040; break; + case _DN_SAVE_OPERANDS_FLUSH_RESULTS: fpword |= 0x8000; break; + case _DN_FLUSH: fpword |= 0x8040; break; + } + + /* clear status word if anything changes */ + if (fpword != old_fpword && !sw) fpword &= ~0x3f; + } + + if (fpword != old_fpword) set_mxcsr( fpword ); +} +#endif + +void __mingw_setfp( unsigned int *cw, unsigned int cw_mask, + unsigned int *sw, unsigned int sw_mask ) +{ +#if defined(__arm64ec__) + __mingw_setfp_sse(cw, cw_mask, sw, sw_mask); +#elif defined(__i386__) || defined(__x86_64__) + unsigned long oldcw = 0, newcw = 0; + unsigned long oldsw = 0, newsw = 0; + unsigned int flags; + + cw_mask &= _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC; + sw_mask &= _MCW_EM; + + if (sw) + { + __asm__ __volatile__( "fstsw %0" : "=m" (newsw) ); + oldsw = newsw; + + flags = 0; + if (newsw & 0x1) flags |= _SW_INVALID; + if (newsw & 0x2) flags |= _SW_DENORMAL; + if (newsw & 0x4) flags |= _SW_ZERODIVIDE; + if (newsw & 0x8) flags |= _SW_OVERFLOW; + if (newsw & 0x10) flags |= _SW_UNDERFLOW; + if (newsw & 0x20) flags |= _SW_INEXACT; + + *sw = (flags & ~sw_mask) | (*sw & sw_mask); + newsw &= ~0x3f; + if (*sw & _SW_INVALID) newsw |= 0x1; + if (*sw & _SW_DENORMAL) newsw |= 0x2; + if (*sw & _SW_ZERODIVIDE) newsw |= 0x4; + if (*sw & _SW_OVERFLOW) newsw |= 0x8; + if (*sw & _SW_UNDERFLOW) newsw |= 0x10; + if (*sw & _SW_INEXACT) newsw |= 0x20; + *sw = flags; + } + + if (cw) + { + __asm__ __volatile__( "fstcw %0" : "=m" (newcw) ); + oldcw = newcw; + + flags = 0; + if (newcw & 0x1) flags |= _EM_INVALID; + if (newcw & 0x2) flags |= _EM_DENORMAL; + if (newcw & 0x4) flags |= _EM_ZERODIVIDE; + if (newcw & 0x8) flags |= _EM_OVERFLOW; + if (newcw & 0x10) flags |= _EM_UNDERFLOW; + if (newcw & 0x20) flags |= _EM_INEXACT; + switch (newcw & 0xc00) + { + case 0xc00: flags |= _RC_UP|_RC_DOWN; break; + case 0x800: flags |= _RC_UP; break; + case 0x400: flags |= _RC_DOWN; break; + } + switch (newcw & 0x300) + { + case 0x0: flags |= _PC_24; break; + case 0x200: flags |= _PC_53; break; + case 0x300: flags |= _PC_64; break; + } + if (newcw & 0x1000) flags |= _IC_AFFINE; + + *cw = (flags & ~cw_mask) | (*cw & cw_mask); + newcw &= ~0x1f3f; + if (*cw & _EM_INVALID) newcw |= 0x1; + if (*cw & _EM_DENORMAL) newcw |= 0x2; + if (*cw & _EM_ZERODIVIDE) newcw |= 0x4; + if (*cw & _EM_OVERFLOW) newcw |= 0x8; + if (*cw & _EM_UNDERFLOW) newcw |= 0x10; + if (*cw & _EM_INEXACT) newcw |= 0x20; + switch (*cw & _MCW_RC) + { + case _RC_UP|_RC_DOWN: newcw |= 0xc00; break; + case _RC_UP: newcw |= 0x800; break; + case _RC_DOWN: newcw |= 0x400; break; + } + switch (*cw & _MCW_PC) + { + case _PC_64: newcw |= 0x300; break; + case _PC_53: newcw |= 0x200; break; + case _PC_24: newcw |= 0x0; break; + } + if (*cw & _IC_AFFINE) newcw |= 0x1000; + } + + if (oldsw != newsw && (newsw & 0x3f)) + { + struct { + WORD control_word; + WORD unused1; + WORD status_word; + WORD unused2; + WORD tag_word; + WORD unused3; + DWORD instruction_pointer; + WORD code_segment; + WORD unused4; + DWORD operand_addr; + WORD data_segment; + WORD unused5; + } fenv; + + __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) ); + fenv.control_word = newcw; + fenv.status_word = newsw; + __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)", + "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" ); + return; + } + + if (oldsw != newsw) + __asm__ __volatile__( "fnclex" ); + if (oldcw != newcw) + __asm__ __volatile__( "fldcw %0" : : "m" (newcw) ); +#elif defined(__aarch64__) + ULONG_PTR old_fpsr = 0, fpsr = 0, old_fpcr = 0, fpcr = 0; + unsigned int flags; + + cw_mask &= _MCW_EM | _MCW_RC; + sw_mask &= _MCW_EM; + + if (sw) + { + __asm__ __volatile__( "mrs %0, fpsr" : "=r" (fpsr) ); + old_fpsr = fpsr; + + flags = 0; + if (fpsr & 0x1) flags |= _SW_INVALID; + if (fpsr & 0x2) flags |= _SW_ZERODIVIDE; + if (fpsr & 0x4) flags |= _SW_OVERFLOW; + if (fpsr & 0x8) flags |= _SW_UNDERFLOW; + if (fpsr & 0x10) flags |= _SW_INEXACT; + if (fpsr & 0x80) flags |= _SW_DENORMAL; + + *sw = (flags & ~sw_mask) | (*sw & sw_mask); + fpsr &= ~0x9f; + if (*sw & _SW_INVALID) fpsr |= 0x1; + if (*sw & _SW_ZERODIVIDE) fpsr |= 0x2; + if (*sw & _SW_OVERFLOW) fpsr |= 0x4; + if (*sw & _SW_UNDERFLOW) fpsr |= 0x8; + if (*sw & _SW_INEXACT) fpsr |= 0x10; + if (*sw & _SW_DENORMAL) fpsr |= 0x80; + *sw = flags; + } + + if (cw) + { + __asm__ __volatile__( "mrs %0, fpcr" : "=r" (fpcr) ); + old_fpcr = fpcr; + + flags = 0; + if (!(fpcr & 0x100)) flags |= _EM_INVALID; + if (!(fpcr & 0x200)) flags |= _EM_ZERODIVIDE; + if (!(fpcr & 0x400)) flags |= _EM_OVERFLOW; + if (!(fpcr & 0x800)) flags |= _EM_UNDERFLOW; + if (!(fpcr & 0x1000)) flags |= _EM_INEXACT; + if (!(fpcr & 0x8000)) flags |= _EM_DENORMAL; + switch (fpcr & 0xc00000) + { + case 0x400000: flags |= _RC_UP; break; + case 0x800000: flags |= _RC_DOWN; break; + case 0xc00000: flags |= _RC_CHOP; break; + } + + *cw = (flags & ~cw_mask) | (*cw & cw_mask); + fpcr &= ~0xc09f00ul; + if (!(*cw & _EM_INVALID)) fpcr |= 0x100; + if (!(*cw & _EM_ZERODIVIDE)) fpcr |= 0x200; + if (!(*cw & _EM_OVERFLOW)) fpcr |= 0x400; + if (!(*cw & _EM_UNDERFLOW)) fpcr |= 0x800; + if (!(*cw & _EM_INEXACT)) fpcr |= 0x1000; + if (!(*cw & _EM_DENORMAL)) fpcr |= 0x8000; + switch (*cw & _MCW_RC) + { + case _RC_CHOP: fpcr |= 0xc00000; break; + case _RC_UP: fpcr |= 0x400000; break; + case _RC_DOWN: fpcr |= 0x800000; break; + } + } + + /* mask exceptions if needed */ + if (old_fpcr != fpcr && ~(old_fpcr >> 8) & fpsr & 0x9f != fpsr & 0x9f) + { + ULONG_PTR mask = fpcr & ~0x9f00; + __asm__ __volatile__( "msr fpcr, %0" :: "r" (mask) ); + } + + if (old_fpsr != fpsr) + __asm__ __volatile__( "msr fpsr, %0" :: "r" (fpsr) ); + if (old_fpcr != fpcr) + __asm__ __volatile__( "msr fpcr, %0" :: "r" (fpcr) ); +#elif defined(__arm__) + DWORD old_fpscr, fpscr; + unsigned int flags; + + __asm__ __volatile__( "vmrs %0, fpscr" : "=r" (fpscr) ); + old_fpscr = fpscr; + + cw_mask &= _MCW_EM | _MCW_RC; + sw_mask &= _MCW_EM; + + if (sw) + { + flags = 0; + if (fpscr & 0x1) flags |= _SW_INVALID; + if (fpscr & 0x2) flags |= _SW_ZERODIVIDE; + if (fpscr & 0x4) flags |= _SW_OVERFLOW; + if (fpscr & 0x8) flags |= _SW_UNDERFLOW; + if (fpscr & 0x10) flags |= _SW_INEXACT; + if (fpscr & 0x80) flags |= _SW_DENORMAL; + + *sw = (flags & ~sw_mask) | (*sw & sw_mask); + fpscr &= ~0x9f; + if (*sw & _SW_INVALID) fpscr |= 0x1; + if (*sw & _SW_ZERODIVIDE) fpscr |= 0x2; + if (*sw & _SW_OVERFLOW) fpscr |= 0x4; + if (*sw & _SW_UNDERFLOW) fpscr |= 0x8; + if (*sw & _SW_INEXACT) fpscr |= 0x10; + if (*sw & _SW_DENORMAL) fpscr |= 0x80; + *sw = flags; + } + + if (cw) + { + flags = 0; + if (!(fpscr & 0x100)) flags |= _EM_INVALID; + if (!(fpscr & 0x200)) flags |= _EM_ZERODIVIDE; + if (!(fpscr & 0x400)) flags |= _EM_OVERFLOW; + if (!(fpscr & 0x800)) flags |= _EM_UNDERFLOW; + if (!(fpscr & 0x1000)) flags |= _EM_INEXACT; + if (!(fpscr & 0x8000)) flags |= _EM_DENORMAL; + switch (fpscr & 0xc00000) + { + case 0x400000: flags |= _RC_UP; break; + case 0x800000: flags |= _RC_DOWN; break; + case 0xc00000: flags |= _RC_CHOP; break; + } + + *cw = (flags & ~cw_mask) | (*cw & cw_mask); + fpscr &= ~0xc09f00ul; + if (!(*cw & _EM_INVALID)) fpscr |= 0x100; + if (!(*cw & _EM_ZERODIVIDE)) fpscr |= 0x200; + if (!(*cw & _EM_OVERFLOW)) fpscr |= 0x400; + if (!(*cw & _EM_UNDERFLOW)) fpscr |= 0x800; + if (!(*cw & _EM_INEXACT)) fpscr |= 0x1000; + if (!(*cw & _EM_DENORMAL)) fpscr |= 0x8000; + switch (*cw & _MCW_RC) + { + case _RC_CHOP: fpscr |= 0xc00000; break; + case _RC_UP: fpscr |= 0x400000; break; + case _RC_DOWN: fpscr |= 0x800000; break; + } + } + + if (old_fpscr != fpscr) + __asm__ __volatile__( "vmsr fpscr, %0" :: "r" (fpscr) ); +#endif +} diff --git a/lib/libc/mingw/misc/setjmp.S b/lib/libc/mingw/misc/setjmp.S index 0c06b86320..2baaae49c8 100644 --- a/lib/libc/mingw/misc/setjmp.S +++ b/lib/libc/mingw/misc/setjmp.S @@ -6,6 +6,7 @@ #include <_mingw_mac.h> +#ifndef __arm64ec__ .globl __MINGW_USYMBOL(__intrinsic_setjmp) .def __MINGW_USYMBOL(__intrinsic_setjmp); .scl 2; .type 32; .endef @@ -115,3 +116,4 @@ __MINGW_USYMBOL(__intrinsic_setjmpex): mov x0, #0 ret #endif +#endif /* __arm64ec__ */ diff --git a/lib/libc/mingw/misc/ucrt_tzset.c b/lib/libc/mingw/misc/ucrt_tzset.c index fbb2cc830c..7157ba2268 100644 --- a/lib/libc/mingw/misc/ucrt_tzset.c +++ b/lib/libc/mingw/misc/ucrt_tzset.c @@ -40,6 +40,3 @@ void __cdecl tzset(void) { _tzset(); } - -// Dummy/unused __imp_ wrappers, to make GNU ld not autoexport these symbols. -void __cdecl (*__MINGW_IMP_SYMBOL(tzset))(void) = tzset; diff --git a/lib/libc/mingw/misc/winbs_uint64.c b/lib/libc/mingw/misc/winbs_uint64.c index c0b316221c..0158eb6f72 100644 --- a/lib/libc/mingw/misc/winbs_uint64.c +++ b/lib/libc/mingw/misc/winbs_uint64.c @@ -2,38 +2,5 @@ unsigned long long __cdecl _byteswap_uint64(unsigned long long _Int64); unsigned long long __cdecl _byteswap_uint64(unsigned long long _Int64) { -#if defined(_AMD64_) || defined(__x86_64__) - unsigned long long retval; - __asm__ __volatile__ ("bswapq %[retval]" : [retval] "=rm" (retval) : "[retval]" (_Int64)); - return retval; -#elif defined(_X86_) || defined(__i386__) - union { - long long int64part; - struct { - unsigned long lowpart; - unsigned long hipart; - }; - } retval; - retval.int64part = _Int64; - __asm__ __volatile__ ("bswapl %[lowpart]\n" - "bswapl %[hipart]\n" - : [lowpart] "=rm" (retval.hipart), [hipart] "=rm" (retval.lowpart) : "[lowpart]" (retval.lowpart), "[hipart]" (retval.hipart)); - return retval.int64part; -#else - unsigned char *b = (void*)&_Int64; - unsigned char tmp; - tmp = b[0]; - b[0] = b[7]; - b[7] = tmp; - tmp = b[1]; - b[1] = b[6]; - b[6] = tmp; - tmp = b[2]; - b[2] = b[5]; - b[5] = tmp; - tmp = b[3]; - b[3] = b[4]; - b[4] = tmp; - return _Int64; -#endif + return __builtin_bswap64(_Int64); } diff --git a/lib/libc/mingw/misc/winbs_ulong.c b/lib/libc/mingw/misc/winbs_ulong.c index 9cd6b29070..e23c113a5f 100644 --- a/lib/libc/mingw/misc/winbs_ulong.c +++ b/lib/libc/mingw/misc/winbs_ulong.c @@ -2,19 +2,5 @@ unsigned long __cdecl _byteswap_ulong (unsigned long _Long); unsigned long __cdecl _byteswap_ulong (unsigned long _Long) { -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) - unsigned long retval; - __asm__ __volatile__ ("bswapl %[retval]" : [retval] "=rm" (retval) : "[retval]" (_Long)); - return retval; -#else - unsigned char *b = (void*)&_Long; - unsigned char tmp; - tmp = b[0]; - b[0] = b[3]; - b[3] = tmp; - tmp = b[1]; - b[1] = b[2]; - b[2] = tmp; - return _Long; -#endif /* defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) */ + return __builtin_bswap32(_Long); } diff --git a/lib/libc/mingw/misc/winbs_ushort.c b/lib/libc/mingw/misc/winbs_ushort.c index 46b57fda46..b1b9ef3295 100644 --- a/lib/libc/mingw/misc/winbs_ushort.c +++ b/lib/libc/mingw/misc/winbs_ushort.c @@ -2,16 +2,5 @@ unsigned short __cdecl _byteswap_ushort(unsigned short _Short); unsigned short __cdecl _byteswap_ushort(unsigned short _Short) { -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) - unsigned short retval; - __asm__ __volatile__ ("rorw $8, %w[retval]" : [retval] "=rm" (retval) : "[retval]" (_Short)); - return retval; -#else - unsigned char *b = (void*)&_Short; - unsigned char tmp; - tmp = b[0]; - b[0] = b[1]; - b[1] = tmp; - return _Short; -#endif /* defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) */ + return __builtin_bswap16(_Short); } diff --git a/lib/libc/mingw/stdio/__mingw_fix_stat_path.c b/lib/libc/mingw/stdio/__mingw_fix_stat_path.c new file mode 100644 index 0000000000..564658473f --- /dev/null +++ b/lib/libc/mingw/stdio/__mingw_fix_stat_path.c @@ -0,0 +1,64 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include +#include + +/** + * Returns _path without trailing slash if any + * + * - if _path has no trailing slash, the function returns it + * - if _path has a trailing slash, but is of the form C:/, then it returns it + * - otherwise, the function creates a new string, which is a copy of _path + * without the trailing slash. It is then the responsibility of the caller + * to free it. + */ + +char* __mingw_fix_stat_path (const char* _path); +char* __mingw_fix_stat_path (const char* _path) +{ + int len; + char *p; + + p = (char*)_path; + + if (_path && *_path) { + len = strlen (_path); + + /* Ignore X:\ */ + + if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':')) + return p; + + /* Check UNC \\abc\\ */ + if ((_path[0] == '\\' || _path[0] == '/') + && (_path[1] == '\\' || _path[1] == '/')) + { + const char *r = &_path[2]; + while (*r != 0 && *r != '\\' && *r != '/') + ++r; + if (*r != 0) + ++r; + if (*r == 0) + return p; + while (*r != 0 && *r != '\\' && *r != '/') + ++r; + if (*r != 0) + ++r; + if (*r == 0) + return p; + } + + if (_path[len - 1] == '/' || _path[len - 1] == '\\') + { + p = (char*)malloc (len); + memcpy (p, _path, len - 1); + p[len - 1] = '\0'; + } + } + + return p; +} diff --git a/lib/libc/mingw/stdio/__mingw_fix_wstat_path.c b/lib/libc/mingw/stdio/__mingw_fix_wstat_path.c new file mode 100644 index 0000000000..838e4aa30d --- /dev/null +++ b/lib/libc/mingw/stdio/__mingw_fix_wstat_path.c @@ -0,0 +1,64 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include +#include + +/** + * Returns _path without trailing slash if any + * + * - if _path has no trailing slash, the function returns it + * - if _path has a trailing slash, but is of the form C:/, then it returns it + * - otherwise, the function creates a new string, which is a copy of _path + * without the trailing slash. It is then the responsibility of the caller + * to free it. + */ + +wchar_t* __mingw_fix_wstat_path (const wchar_t* _path); +wchar_t* __mingw_fix_wstat_path (const wchar_t* _path) +{ + int len; + wchar_t *p; + + p = (wchar_t*)_path; + + if (_path && *_path) { + len = wcslen (_path); + + /* Ignore X:\ */ + + if (len <= 1 || ((len == 2 || len == 3) && _path[1] == L':')) + return p; + + /* Check UNC \\abc\\ */ + if ((_path[0] == L'\\' || _path[0] == L'/') + && (_path[1] == L'\\' || _path[1] == L'/')) + { + const wchar_t *r = &_path[2]; + while (*r != 0 && *r != L'\\' && *r != L'/') + ++r; + if (*r != 0) + ++r; + if (*r == 0) + return p; + while (*r != 0 && *r != L'\\' && *r != L'/') + ++r; + if (*r != 0) + ++r; + if (*r == 0) + return p; + } + + if (_path[len - 1] == L'/' || _path[len - 1] == L'\\') + { + p = (wchar_t*)malloc (len * sizeof(wchar_t)); + memcpy (p, _path, (len - 1) * sizeof(wchar_t)); + p[len - 1] = L'\0'; + } + } + + return p; +} diff --git a/lib/libc/mingw/stdio/_findfirst64i32.c b/lib/libc/mingw/stdio/_findfirst64i32.c index 8942dc153a..020ecee6a6 100644 --- a/lib/libc/mingw/stdio/_findfirst64i32.c +++ b/lib/libc/mingw/stdio/_findfirst64i32.c @@ -7,7 +7,7 @@ intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t * struct __finddata64_t fd; intptr_t ret = _findfirst64(_Filename,&fd); if (ret == -1) { - memset(_FindData,0,sizeof(struct _finddata64i32_t)); + *_FindData = (struct _finddata64i32_t){0}; return -1; } _FindData->attrib=fd.attrib; diff --git a/lib/libc/mingw/stdio/_findnext64i32.c b/lib/libc/mingw/stdio/_findnext64i32.c index 90ae454432..e756846b92 100644 --- a/lib/libc/mingw/stdio/_findnext64i32.c +++ b/lib/libc/mingw/stdio/_findnext64i32.c @@ -7,7 +7,7 @@ int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindDa struct __finddata64_t fd; int ret = _findnext64(_FindHandle,&fd); if (ret == -1) { - memset(_FindData,0,sizeof(struct _finddata64i32_t)); + *_FindData = (struct _finddata64i32_t){0}; return -1; } _FindData->attrib=fd.attrib; diff --git a/lib/libc/mingw/stdio/_fstat64i32.c b/lib/libc/mingw/stdio/_fstat64i32.c index 57cc492d77..dbc689c809 100644 --- a/lib/libc/mingw/stdio/_fstat64i32.c +++ b/lib/libc/mingw/stdio/_fstat64i32.c @@ -1,14 +1,26 @@ -#define __CRT__NO_INLINE +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + #include +/* When the file size does not fit into the st_size field: + * crtdll-msvcr90 msvcr100 msvcr110+ + * st_size truncate 0 0 + * errno no change no change EOVERFLOW + * returns 0 -1 -1 + * + * This file is used only for pre-msvcr80 builds, + * So use the pre-msvcr80 behavior - truncate without error. + */ int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat) { struct _stat64 st; int ret=_fstat64(_FileDes,&st); - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + if (ret != 0) + return ret; _Stat->st_dev=st.st_dev; _Stat->st_ino=st.st_ino; _Stat->st_mode=st.st_mode; @@ -16,10 +28,10 @@ int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; /* 32bit size */ + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_fstat64i32))(int, struct _stat64i32 *) = _fstat64i32; diff --git a/lib/libc/mingw/stdio/_stat.c b/lib/libc/mingw/stdio/_stat.c deleted file mode 100644 index fbb985e389..0000000000 --- a/lib/libc/mingw/stdio/_stat.c +++ /dev/null @@ -1,120 +0,0 @@ -#define __CRT__NO_INLINE -#include -#include - -/** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. - */ - -static char* -_mingw_no_trailing_slash (const char* _path) -{ - int len; - char *p; - - p = (char*)_path; - - if (_path && *_path) { - len = strlen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':')) - return p; - - /* Check UNC \\abc\\ */ - if ((_path[0] == '\\' || _path[0] == '/') - && (_path[1] == '\\' || _path[1] == '/')) - { - const char *r = &_path[2]; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == '/' || _path[len - 1] == '\\') - { - p = (char*)malloc (len); - memcpy (p, _path, len - 1); - p[len - 1] = '\0'; - } - } - - return p; -} -/* FIXME: Relying on _USE_32BIT_TIME_T, which is a user-macro, -during CRT compilation is plainly broken. Need an appropriate -implementation to provide users the ability of compiling the -CRT only with 32-bit time_t behavior. */ -#if defined(_USE_32BIT_TIME_T) -int __cdecl -stat(const char *_Filename,struct stat *_Stat) -{ - struct _stat32 st; - char *_path = _mingw_no_trailing_slash(_Filename); - - int ret=_stat32(_path,&st); - - if (_path != _Filename) - free (_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct stat)); - return -1; - } - /* struct stat and struct _stat32 - are the same for this case. */ - memcpy(_Stat, &st, sizeof(struct _stat32)); - return ret; -} -#else -int __cdecl -stat(const char *_Filename,struct stat *_Stat) -{ - struct _stat64 st; - char *_path = _mingw_no_trailing_slash(_Filename); - - int ret=_stat64(_path,&st); - - if (_path != _Filename) - free (_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct stat)); - return -1; - } - /* struct stat and struct _stat64i32 - are the same for this case. */ - _Stat->st_dev=st.st_dev; - _Stat->st_ino=st.st_ino; - _Stat->st_mode=st.st_mode; - _Stat->st_nlink=st.st_nlink; - _Stat->st_uid=st.st_uid; - _Stat->st_gid=st.st_gid; - _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; - _Stat->st_atime=st.st_atime; - _Stat->st_mtime=st.st_mtime; - _Stat->st_ctime=st.st_ctime; - return ret; -} -#endif - -/* Add __imp__fstat and __imp__stat symbols. */ -int (*__MINGW_IMP_SYMBOL(stat))(const char *,struct stat *) = &stat; - diff --git a/lib/libc/mingw/stdio/_stat64i32.c b/lib/libc/mingw/stdio/_stat64i32.c index 19adf5b0ee..a6c3243a64 100644 --- a/lib/libc/mingw/stdio/_stat64i32.c +++ b/lib/libc/mingw/stdio/_stat64i32.c @@ -1,77 +1,26 @@ -#define __CRT__NO_INLINE -#include -#include - /** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -static char* -_mingw_no_trailing_slash (const char* _path) -{ - int len; - char *p; - - p = (char*)_path; - - if (_path && *_path) { - len = strlen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':')) - return p; - - /* Check UNC \\abc\\ */ - if ((_path[0] == '\\' || _path[0] == '/') - && (_path[1] == '\\' || _path[1] == '/')) - { - const char *r = &_path[2]; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != '\\' && *r != '/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == '/' || _path[len - 1] == '\\') - { - p = (char*)malloc (len); - memcpy (p, _path, len - 1); - p[len - 1] = '\0'; - } - } - - return p; -} +#include +/* When the file size does not fit into the st_size field: + * crtdll-msvcr90 msvcr100 msvcr110+ + * st_size truncate 0 0 + * errno no change no change EOVERFLOW + * returns 0 -1 -1 + * + * This file is used only for pre-msvcr80 builds, + * So use the pre-msvcr80 behavior - truncate without error. + */ int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat) { struct _stat64 st; - char *_path = _mingw_no_trailing_slash(_Name); - - int ret=_stat64(_path,&st); - - if (_path != _Name) - free(_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + int ret=_stat64(_Name,&st); + if (ret != 0) + return ret; _Stat->st_dev=st.st_dev; _Stat->st_ino=st.st_ino; _Stat->st_mode=st.st_mode; @@ -79,10 +28,10 @@ int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_stat64i32))(const char *, struct _stat64i32 *) = _stat64i32; diff --git a/lib/libc/mingw/stdio/_wfindfirst64i32.c b/lib/libc/mingw/stdio/_wfindfirst64i32.c index d355e524ea..6cfe849f39 100644 --- a/lib/libc/mingw/stdio/_wfindfirst64i32.c +++ b/lib/libc/mingw/stdio/_wfindfirst64i32.c @@ -7,7 +7,7 @@ intptr_t __cdecl _wfindfirst64i32(const wchar_t *_Filename,struct _wfinddata64i3 struct _wfinddata64_t fd; intptr_t ret = _wfindfirst64(_Filename,&fd); if (ret == -1) { - memset(_FindData,0,sizeof(struct _wfinddata64i32_t)); + *_FindData = (struct _wfinddata64i32_t){0}; return -1; } _FindData->attrib=fd.attrib; diff --git a/lib/libc/mingw/stdio/_wfindnext64i32.c b/lib/libc/mingw/stdio/_wfindnext64i32.c index c8d5342750..9753916ea5 100644 --- a/lib/libc/mingw/stdio/_wfindnext64i32.c +++ b/lib/libc/mingw/stdio/_wfindnext64i32.c @@ -7,7 +7,7 @@ int __cdecl _wfindnext64i32(intptr_t _FindHandle,struct _wfinddata64i32_t *_Find struct _wfinddata64_t fd; int ret = _wfindnext64(_FindHandle,&fd); if (ret == -1) { - memset(_FindData,0,sizeof(struct _wfinddata64i32_t)); + *_FindData = (struct _wfinddata64i32_t){0}; return -1; } _FindData->attrib=fd.attrib; diff --git a/lib/libc/mingw/stdio/_wstat.c b/lib/libc/mingw/stdio/_wstat.c deleted file mode 100644 index 08566168fb..0000000000 --- a/lib/libc/mingw/stdio/_wstat.c +++ /dev/null @@ -1,119 +0,0 @@ -#define __CRT__NO_INLINE -#include -#include -#include - -/** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. - */ - -static wchar_t* -_mingw_no_trailing_slash (const wchar_t* _path) -{ - int len; - wchar_t *p; - - p = (wchar_t*)_path; - - if (_path && *_path) { - len = wcslen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == L':')) - return p; - - /* Check UNC \\abc\\ */ - if ((_path[0] == L'\\' || _path[0] == L'/') - && (_path[1] == L'\\' || _path[1] == L'/')) - { - const wchar_t *r = &_path[2]; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == L'/' || _path[len - 1] == L'\\') - { - p = (wchar_t*)malloc (len * sizeof(wchar_t)); - memcpy (p, _path, (len - 1) * sizeof(wchar_t)); - p[len - 1] = L'\0'; - } - } - - return p; -} - -/* FIXME: Relying on _USE_32BIT_TIME_T, which is a user-macro, -during CRT compilation is plainly broken. Need an appropriate -implementation to provide users the ability of compiling the -CRT only with 32-bit time_t behavior. */ -#if defined(_USE_32BIT_TIME_T) -int __cdecl -wstat(const wchar_t *_Filename,struct stat *_Stat) -{ - struct _stat32 st; - wchar_t *_path = _mingw_no_trailing_slash(_Filename); - - int ret=_wstat32(_path,&st); - - if (_path != _Filename) - free (_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct stat)); - return -1; - } - /* struct stat and struct _stat32 - are the same for this case. */ - memcpy(_Stat, &st, sizeof(struct _stat32)); - return ret; -} -#else -int __cdecl -wstat(const wchar_t *_Filename,struct stat *_Stat) -{ - struct _stat64 st; - wchar_t *_path = _mingw_no_trailing_slash(_Filename); - - int ret=_wstat64(_path,&st); - - if (_path != _Filename) - free (_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct stat)); - return -1; - } - /* struct stat and struct _stat64i32 - are the same for this case. */ - _Stat->st_dev=st.st_dev; - _Stat->st_ino=st.st_ino; - _Stat->st_mode=st.st_mode; - _Stat->st_nlink=st.st_nlink; - _Stat->st_uid=st.st_uid; - _Stat->st_gid=st.st_gid; - _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; - _Stat->st_atime=st.st_atime; - _Stat->st_mtime=st.st_mtime; - _Stat->st_ctime=st.st_ctime; - return ret; -} -#endif - diff --git a/lib/libc/mingw/stdio/_wstat64i32.c b/lib/libc/mingw/stdio/_wstat64i32.c index d6ee07a3d5..292d0b4a6a 100644 --- a/lib/libc/mingw/stdio/_wstat64i32.c +++ b/lib/libc/mingw/stdio/_wstat64i32.c @@ -1,77 +1,26 @@ -#define __CRT__NO_INLINE -#include -#include - /** - * Returns _path without trailing slash if any - * - * - if _path has no trailing slash, the function returns it - * - if _path has a trailing slash, but is of the form C:/, then it returns it - * - otherwise, the function creates a new string, which is a copy of _path - * without the trailing slash. It is then the responsibility of the caller - * to free it. + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -static wchar_t* -_mingw_no_trailing_slash (const wchar_t* _path) -{ - int len; - wchar_t *p; - - p = (wchar_t*)_path; - - if (_path && *_path) { - len = wcslen (_path); - - /* Ignore X:\ */ - - if (len <= 1 || ((len == 2 || len == 3) && _path[1] == L':')) - return p; - - /* Check UNC \\abc\\ */ - if ((_path[0] == L'\\' || _path[0] == L'/') - && (_path[1] == L'\\' || _path[1] == L'/')) - { - const wchar_t *r = &_path[2]; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - while (*r != 0 && *r != L'\\' && *r != L'/') - ++r; - if (*r != 0) - ++r; - if (*r == 0) - return p; - } - - if (_path[len - 1] == L'/' || _path[len - 1] == L'\\') - { - p = (wchar_t*)malloc (len * sizeof(wchar_t)); - memcpy (p, _path, (len - 1) * sizeof(wchar_t)); - p[len - 1] = L'\0'; - } - } - - return p; -} +#include +/* When the file size does not fit into the st_size field: + * crtdll-msvcr90 msvcr100 msvcr110+ + * st_size truncate 0 0 + * errno no change no change EOVERFLOW + * returns 0 -1 -1 + * + * This file is used only for pre-msvcr80 builds, + * So use the pre-msvcr80 behavior - truncate without error. + */ int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat) { struct _stat64 st; - wchar_t *_path = _mingw_no_trailing_slash(_Name); - - int ret=_wstat64(_path,&st); - - if (_path != _Name) - free(_path); - - if (ret == -1) { - memset(_Stat,0,sizeof(struct _stat64i32)); - return -1; - } + int ret=_wstat64(_Name,&st); + if (ret != 0) + return ret; _Stat->st_dev=st.st_dev; _Stat->st_ino=st.st_ino; _Stat->st_mode=st.st_mode; @@ -79,10 +28,10 @@ int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat) _Stat->st_uid=st.st_uid; _Stat->st_gid=st.st_gid; _Stat->st_rdev=st.st_rdev; - _Stat->st_size=(_off_t) st.st_size; + _Stat->st_size=(_off_t) st.st_size; /* truncate 64-bit st_size to 32-bit */ _Stat->st_atime=st.st_atime; _Stat->st_mtime=st.st_mtime; _Stat->st_ctime=st.st_ctime; - return ret; + return 0; } - +int (__cdecl *__MINGW_IMP_SYMBOL(_wstat64i32))(const wchar_t *, struct _stat64i32 *) = _wstat64i32; diff --git a/lib/libc/mingw/stdio/mingw_pformat.c b/lib/libc/mingw/stdio/mingw_pformat.c index fd53ce1a83..d094e7ace2 100644 --- a/lib/libc/mingw/stdio/mingw_pformat.c +++ b/lib/libc/mingw/stdio/mingw_pformat.c @@ -512,8 +512,7 @@ void __pformat_putchars( const char *s, int count, __pformat_t *stream ) wchar_t w[12], *p; while( count > 0 ) { - mbstate_t ps; - memset(&ps, 0, sizeof(ps) ); + mbstate_t ps = {0}; --count; p = &w[0]; l = mbrtowc (p, s, strlen (s), &ps); @@ -1175,11 +1174,8 @@ void __pformat_emit_radix_point( __pformat_t *stream ) /* Radix point initialisation not yet completed; * establish a multibyte to `wchar_t' converter... */ - int len; wchar_t rpchr; mbstate_t state; - - /* Initialise the conversion state... - */ - memset( &state, 0, sizeof( state ) ); + int len; wchar_t rpchr; + mbstate_t state = {0}; /* Fetch and convert the localised radix point representation... */ @@ -1203,11 +1199,8 @@ void __pformat_emit_radix_point( __pformat_t *stream ) #ifdef __BUILD_WIDEAPI __pformat_putc (stream->rpchr, stream); #else - int len; char buf[len = stream->rplen]; mbstate_t state; - - /* Initialise the conversion state... - */ - memset( &state, 0, sizeof( state ) ); + int len; char buf[len = stream->rplen]; + mbstate_t state = {0}; /* Convert the `wchar_t' representation to multibyte... */ @@ -3123,8 +3116,8 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) if (state == PFORMAT_INIT) { stream.flags |= PFORMAT_GROUPED; /* $$$$ */ - int len; wchar_t rpchr; mbstate_t cstate; - memset (&cstate, 0, sizeof(state)); + int len; wchar_t rpchr; + mbstate_t cstate = {0}; if ((len = mbrtowc( &rpchr, localeconv()->thousands_sep, 16, &cstate)) > 0) stream.thousands_chr = rpchr; stream.thousands_chr_len = len; diff --git a/lib/libc/mingw/stdio/mingw_sformat.c b/lib/libc/mingw/stdio/mingw_sformat.c index 040c2ae887..81757cb1eb 100644 --- a/lib/libc/mingw/stdio/mingw_sformat.c +++ b/lib/libc/mingw/stdio/mingw_sformat.c @@ -307,7 +307,7 @@ __mingw_sformat (_IFP *s, const char *format, va_list argp) char seen_dot, seen_exp, is_neg, not_in; char *tmp_wbuf_ptr, buf[MB_LEN_MAX]; const char *lc_decimal_point, *lc_thousands_sep; - mbstate_t state, cstate; + mbstate_t state = {0}, cstate; union { unsigned long long ull; unsigned long ul; @@ -323,8 +323,6 @@ __mingw_sformat (_IFP *s, const char *format, va_list argp) return EOF; } - memset (&state, 0, sizeof (state)); - lc_decimal_point = localeconv()->decimal_point; lc_thousands_sep = localeconv()->thousands_sep; if (lc_thousands_sep != NULL && *lc_thousands_sep == 0) @@ -682,7 +680,7 @@ __mingw_sformat (_IFP *s, const char *format, va_list argp) if ((c = in_ch (s, &read_in)) == EOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&cstate, 0, sizeof (cstate)); + cstate = (mbstate_t){0}; do { @@ -854,7 +852,7 @@ __mingw_sformat (_IFP *s, const char *format, va_list argp) if ((c = in_ch (s, &read_in)) == EOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&cstate, 0, sizeof (cstate)); + cstate = (mbstate_t){0}; do { @@ -1459,7 +1457,7 @@ __mingw_sformat (_IFP *s, const char *format, va_list argp) if ((c = in_ch (s, &read_in)) == EOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&cstate, 0, sizeof (cstate)); + cstate = (mbstate_t){0}; do { diff --git a/lib/libc/mingw/stdio/mingw_swformat.c b/lib/libc/mingw/stdio/mingw_swformat.c index 5f4b2c08f3..6cc354cc91 100644 --- a/lib/libc/mingw/stdio/mingw_swformat.c +++ b/lib/libc/mingw/stdio/mingw_swformat.c @@ -332,10 +332,10 @@ __mingw_swformat (_IFPW *s, const wchar_t *format, va_list argp) return EOF; } - memset (&state, 0, sizeof(state)); + state = (mbstate_t){0}; clen = mbrtowc( &wc, localeconv()->decimal_point, 16, &state); lc_decimal_point = (clen > 0 ? wc : '.'); - memset( &state, 0, sizeof( state ) ); + state = (mbstate_t){0}; clen = mbrtowc( &wc, localeconv()->thousands_sep, 16, &state); lc_thousands_sep = (clen > 0 ? wc : 0); @@ -596,7 +596,7 @@ __mingw_swformat (_IFPW *s, const wchar_t *format, va_list argp) if ((c = in_ch (s, &read_in)) == WEOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&state, 0, sizeof (state)); + state = (mbstate_t){0}; do { @@ -744,7 +744,7 @@ __mingw_swformat (_IFPW *s, const wchar_t *format, va_list argp) if ((c = in_ch (s, &read_in)) == WEOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&state, 0, sizeof (state)); + state = (mbstate_t){0}; do { @@ -1459,7 +1459,7 @@ __mingw_swformat (_IFPW *s, const wchar_t *format, va_list argp) if ((c = in_ch (s, &read_in)) == WEOF) return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - memset (&state, 0, sizeof (state)); + state = (mbstate_t){0}; do { diff --git a/lib/libc/mingw/stdio/mingw_vfscanf.c b/lib/libc/mingw/stdio/mingw_vfscanf.c index eadc9be321..2d1814ef57 100644 --- a/lib/libc/mingw/stdio/mingw_vfscanf.c +++ b/lib/libc/mingw/stdio/mingw_vfscanf.c @@ -7,8 +7,6 @@ int __mingw_vfscanf (FILE *s, const char *format, va_list argp) { - _IFP ifp; - memset (&ifp, 0, sizeof (_IFP)); - ifp.fp = s; + _IFP ifp = { .fp = s }; return __mingw_sformat (&ifp, format, argp); } diff --git a/lib/libc/mingw/stdio/mingw_vfwscanf.c b/lib/libc/mingw/stdio/mingw_vfwscanf.c index dfb156f6d0..ddfe47a854 100644 --- a/lib/libc/mingw/stdio/mingw_vfwscanf.c +++ b/lib/libc/mingw/stdio/mingw_vfwscanf.c @@ -7,8 +7,6 @@ int __mingw_vfwscanf (FILE *s, const wchar_t *format, va_list argp) { - _IFPW ifp; - memset (&ifp, 0, sizeof (_IFPW)); - ifp.fp = s; + _IFPW ifp = { .fp = s }; return __mingw_swformat (&ifp, format, argp); } diff --git a/lib/libc/mingw/stdio/mingw_vsscanf.c b/lib/libc/mingw/stdio/mingw_vsscanf.c index 52d72d9f0a..9bff458410 100644 --- a/lib/libc/mingw/stdio/mingw_vsscanf.c +++ b/lib/libc/mingw/stdio/mingw_vsscanf.c @@ -7,9 +7,6 @@ int __mingw_vsscanf (const char *s, const char *format, va_list argp) { - _IFP ifp; - memset (&ifp, 0, sizeof (_IFP)); - ifp.str = s; - ifp.is_string = 1; + _IFP ifp = { .str = s, .is_string = 1 }; return __mingw_sformat (&ifp, format, argp); } diff --git a/lib/libc/mingw/stdio/mingw_vswscanf.c b/lib/libc/mingw/stdio/mingw_vswscanf.c index 48767f2297..9f23837f7d 100644 --- a/lib/libc/mingw/stdio/mingw_vswscanf.c +++ b/lib/libc/mingw/stdio/mingw_vswscanf.c @@ -7,9 +7,6 @@ int __mingw_vswscanf (const wchar_t *s, const wchar_t *format, va_list argp) { - _IFPW ifp; - memset (&ifp, 0, sizeof (_IFPW)); - ifp.str = s; - ifp.is_string = 1; + _IFPW ifp = { .str = s, .is_string = 1 }; return __mingw_swformat (&ifp, format, argp); } diff --git a/lib/libc/mingw/stdio/ucrt___local_stdio_printf_options.c b/lib/libc/mingw/stdio/ucrt___local_stdio_printf_options.c new file mode 100644 index 0000000000..986c4fd104 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt___local_stdio_printf_options.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +static unsigned __int64 options = _CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS | _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING; + +unsigned __int64* __local_stdio_printf_options(void) { + return &options; +} diff --git a/lib/libc/mingw/stdio/ucrt___local_stdio_scanf_options.c b/lib/libc/mingw/stdio/ucrt___local_stdio_scanf_options.c new file mode 100644 index 0000000000..2dbd324560 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt___local_stdio_scanf_options.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +static unsigned __int64 options = _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS; + +unsigned __int64* __local_stdio_scanf_options(void) { + return &options; +} diff --git a/lib/libc/mingw/stdio/ucrt__scprintf.c b/lib/libc/mingw/stdio/ucrt__scprintf.c index 72e3216151..0da8210fb3 100644 --- a/lib/libc/mingw/stdio/ucrt__scprintf.c +++ b/lib/libc/mingw/stdio/ucrt__scprintf.c @@ -18,4 +18,3 @@ int __cdecl _scprintf(const char * __restrict__ _Format, ...) va_end(_ArgList); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(_scprintf))(const char *__restrict__, ...) = _scprintf; diff --git a/lib/libc/mingw/stdio/ucrt__snprintf.c b/lib/libc/mingw/stdio/ucrt__snprintf.c index 7b8794c90a..4f2dc80e50 100644 --- a/lib/libc/mingw/stdio/ucrt__snprintf.c +++ b/lib/libc/mingw/stdio/ucrt__snprintf.c @@ -18,4 +18,3 @@ int __cdecl _snprintf(char * __restrict__ _Dest, size_t _Count, const char * __r va_end(_Args); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(_snprintf))(char *__restrict__, size_t, const char *__restrict__, ...) = _snprintf; diff --git a/lib/libc/mingw/stdio/ucrt__snscanf.c b/lib/libc/mingw/stdio/ucrt__snscanf.c index 341b0e5ad8..bd9dfdd383 100644 --- a/lib/libc/mingw/stdio/ucrt__snscanf.c +++ b/lib/libc/mingw/stdio/ucrt__snscanf.c @@ -14,8 +14,7 @@ int __cdecl _snscanf(const char * __restrict__ _Src, size_t _MaxCount, const cha int ret; va_list _ArgList; va_start(_ArgList, _Format); - ret = __stdio_common_vsscanf(0, _Src, _MaxCount, _Format, NULL, _ArgList); + ret = __stdio_common_vsscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, _Src, _MaxCount, _Format, NULL, _ArgList); va_end(_ArgList); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(_snscanf))(const char *__restrict__, size_t, const char * __restrict__, ...) = _snscanf; diff --git a/lib/libc/mingw/stdio/ucrt__snwprintf.c b/lib/libc/mingw/stdio/ucrt__snwprintf.c index 07cdf18a46..5f5a435884 100644 --- a/lib/libc/mingw/stdio/ucrt__snwprintf.c +++ b/lib/libc/mingw/stdio/ucrt__snwprintf.c @@ -4,25 +4,12 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -// For ucrt, this function normally is an inline function in stdio.h. -// libmingwex doesn't use the ucrt version of headers, and wassert.c can -// end up requiring a concrete version of it. - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winline" -#endif - #undef __MSVCRT_VERSION__ #define _UCRT -#define _snwprintf real__snwprintf - #include #include -#undef _snwprintf - int __cdecl _snwprintf(wchar_t * restrict _Dest, size_t _Count, const wchar_t * restrict _Format, ...); int __cdecl _snwprintf(wchar_t * restrict _Dest, size_t _Count, const wchar_t * restrict _Format, ...) @@ -34,8 +21,3 @@ int __cdecl _snwprintf(wchar_t * restrict _Dest, size_t _Count, const wchar_t * va_end(ap); return ret; } - -int __cdecl (*__MINGW_IMP_SYMBOL(_snwprintf))(wchar_t *restrict, size_t, const wchar_t *restrict, ...) = _snwprintf; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif diff --git a/lib/libc/mingw/stdio/ucrt__vsnprintf.c b/lib/libc/mingw/stdio/ucrt__vsnprintf.c index fbdf4f8811..758b4b5251 100644 --- a/lib/libc/mingw/stdio/ucrt__vsnprintf.c +++ b/lib/libc/mingw/stdio/ucrt__vsnprintf.c @@ -12,4 +12,3 @@ int __cdecl _vsnprintf(char * __restrict__ _Dest,size_t _Count,const char * __re { return __stdio_common_vsprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, _Dest, _Count, _Format, NULL, _Args); } -int __cdecl (*__MINGW_IMP_SYMBOL(_vsnprintf))(char *__restrict__, size_t, const char *__restrict__, va_list) = _vsnprintf; diff --git a/lib/libc/mingw/stdio/ucrt__vsnwprintf.c b/lib/libc/mingw/stdio/ucrt__vsnwprintf.c index 7f88fee8e5..376a683b9a 100644 --- a/lib/libc/mingw/stdio/ucrt__vsnwprintf.c +++ b/lib/libc/mingw/stdio/ucrt__vsnwprintf.c @@ -12,4 +12,3 @@ int __cdecl _vsnwprintf(wchar_t * __restrict__ _Dest,size_t _Count,const wchar_t { return __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, _Dest, _Count, _Format, NULL, _Args); } -int __cdecl (*__MINGW_IMP_SYMBOL(_vsnwprintf))(wchar_t *__restrict__, size_t, const wchar_t *__restrict__, va_list) = _vsnwprintf; diff --git a/lib/libc/mingw/stdio/ucrt_fprintf.c b/lib/libc/mingw/stdio/ucrt_fprintf.c index ab223d62f0..0b06b14e96 100644 --- a/lib/libc/mingw/stdio/ucrt_fprintf.c +++ b/lib/libc/mingw/stdio/ucrt_fprintf.c @@ -17,4 +17,3 @@ int __cdecl fprintf(FILE * __restrict__ _File,const char * __restrict__ _Format, __builtin_va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(fprintf))(FILE *__restrict__, const char *__restrict__, ...) = fprintf; diff --git a/lib/libc/mingw/stdio/ucrt_fscanf.c b/lib/libc/mingw/stdio/ucrt_fscanf.c index 4b013f0a7c..32149fcdff 100644 --- a/lib/libc/mingw/stdio/ucrt_fscanf.c +++ b/lib/libc/mingw/stdio/ucrt_fscanf.c @@ -12,8 +12,7 @@ int __cdecl fscanf(FILE * __restrict__ _File,const char * __restrict__ _Format,. __builtin_va_list __ap; int __ret; __builtin_va_start(__ap, _Format); - __ret = __stdio_common_vfscanf(0, _File, _Format, NULL, __ap); + __ret = __stdio_common_vfscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, _File, _Format, NULL, __ap); __builtin_va_end(__ap); return __ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(fscanf))(FILE *__restrict__, const char *__restrict__, ...) = fscanf; diff --git a/lib/libc/mingw/stdio/ucrt_fwprintf.c b/lib/libc/mingw/stdio/ucrt_fwprintf.c index d51a6d6925..159f9f4a99 100644 --- a/lib/libc/mingw/stdio/ucrt_fwprintf.c +++ b/lib/libc/mingw/stdio/ucrt_fwprintf.c @@ -4,25 +4,12 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -// For ucrt, this function normally is an inline function in stdio.h. -// libmingwex doesn't use the ucrt version of headers, and wassert.c can -// end up requiring a concrete version of it. - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winline" -#endif - #undef __MSVCRT_VERSION__ #define _UCRT -#define fwprintf real_fwprintf - #include #include -#undef fwprintf - int __cdecl fwprintf(FILE *ptr, const wchar_t *fmt, ...); int __cdecl fwprintf(FILE *ptr, const wchar_t *fmt, ...) @@ -30,12 +17,7 @@ int __cdecl fwprintf(FILE *ptr, const wchar_t *fmt, ...) va_list ap; int ret; va_start(ap, fmt); - ret = vfwprintf(ptr, fmt, ap); + ret = __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, ptr, fmt, NULL, ap); va_end(ap); return ret; } - -int __cdecl (*__MINGW_IMP_SYMBOL(fwprintf))(FILE *, const wchar_t *, ...) = fwprintf; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif diff --git a/lib/libc/mingw/stdio/ucrt_fwscanf.c b/lib/libc/mingw/stdio/ucrt_fwscanf.c new file mode 100644 index 0000000000..a9dcc8b823 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_fwscanf.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl fwscanf(FILE * __restrict__ _File,const wchar_t * __restrict__ _Format,...) { + __builtin_va_list __ap; + int __ret; + __builtin_va_start(__ap, _Format); + __ret = __stdio_common_vfwscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, _File, _Format, NULL, __ap); + __builtin_va_end(__ap); + return __ret; +} diff --git a/lib/libc/mingw/stdio/ucrt_ms_fwprintf.c b/lib/libc/mingw/stdio/ucrt_ms_fwprintf.c index f44c78d941..b79073322d 100644 --- a/lib/libc/mingw/stdio/ucrt_ms_fwprintf.c +++ b/lib/libc/mingw/stdio/ucrt_ms_fwprintf.c @@ -17,8 +17,7 @@ int __cdecl __ms_fwprintf(FILE *file, const wchar_t *fmt, ...) va_list ap; int ret; va_start(ap, fmt); - ret = __stdio_common_vfwprintf(_CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS, file, fmt, NULL, ap); + ret = __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, file, fmt, NULL, ap); va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(__ms_fwprintf))(FILE *, const wchar_t *, ...) = __ms_fwprintf; diff --git a/lib/libc/mingw/stdio/ucrt_printf.c b/lib/libc/mingw/stdio/ucrt_printf.c index 4ecf1548ca..02d2f706bf 100644 --- a/lib/libc/mingw/stdio/ucrt_printf.c +++ b/lib/libc/mingw/stdio/ucrt_printf.c @@ -17,4 +17,3 @@ int __cdecl printf(const char * __restrict__ _Format,...) __builtin_va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(printf))(const char *__restrict__, ...) = printf; diff --git a/lib/libc/mingw/stdio/ucrt_scanf.c b/lib/libc/mingw/stdio/ucrt_scanf.c index 0e5035d150..9bd086adfc 100644 --- a/lib/libc/mingw/stdio/ucrt_scanf.c +++ b/lib/libc/mingw/stdio/ucrt_scanf.c @@ -12,8 +12,7 @@ int __cdecl scanf(const char * __restrict__ _Format,...) { __builtin_va_list __ap; int __ret; __builtin_va_start(__ap, _Format); - __ret = __stdio_common_vfscanf(0, stdin, _Format, NULL, __ap); + __ret = __stdio_common_vfscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, stdin, _Format, NULL, __ap); __builtin_va_end(__ap); return __ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(scanf))(const char *__restrict__, ...) = scanf; diff --git a/lib/libc/mingw/stdio/ucrt_snprintf.c b/lib/libc/mingw/stdio/ucrt_snprintf.c index 56bc7400ea..19b8329259 100644 --- a/lib/libc/mingw/stdio/ucrt_snprintf.c +++ b/lib/libc/mingw/stdio/ucrt_snprintf.c @@ -17,4 +17,3 @@ int __cdecl snprintf (char * __restrict__ __stream, size_t __n, const char * __r __builtin_va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(snprintf))(char *__restrict__, size_t, const char *__restrict__, ...) = snprintf; diff --git a/lib/libc/mingw/stdio/ucrt_snwprintf.c b/lib/libc/mingw/stdio/ucrt_snwprintf.c new file mode 100644 index 0000000000..975fb7b7e2 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_snwprintf.c @@ -0,0 +1,19 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...) +{ + __builtin_va_list __ap; + int __ret; + __builtin_va_start(__ap, format); + __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, __ap); + __builtin_va_end(__ap); + return __ret; +} diff --git a/lib/libc/mingw/stdio/ucrt_sprintf.c b/lib/libc/mingw/stdio/ucrt_sprintf.c index 69ee54cae5..5da61d1e4d 100644 --- a/lib/libc/mingw/stdio/ucrt_sprintf.c +++ b/lib/libc/mingw/stdio/ucrt_sprintf.c @@ -17,4 +17,3 @@ int __cdecl sprintf(char * __restrict__ _Dest,const char * __restrict__ _Format, __builtin_va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(sprintf))(char *__restrict__, const char *__restrict__, ...) = sprintf; diff --git a/lib/libc/mingw/stdio/ucrt_sscanf.c b/lib/libc/mingw/stdio/ucrt_sscanf.c index eb87379c42..752ecdc4bd 100644 --- a/lib/libc/mingw/stdio/ucrt_sscanf.c +++ b/lib/libc/mingw/stdio/ucrt_sscanf.c @@ -12,9 +12,7 @@ int __cdecl sscanf(const char * __restrict__ _Src,const char * __restrict__ _For __builtin_va_list __ap; int __ret; __builtin_va_start(__ap, _Format); - __ret = __stdio_common_vsscanf(0, _Src, (size_t)-1, _Format, NULL, __ap); + __ret = __stdio_common_vsscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, _Src, (size_t)-1, _Format, NULL, __ap); __builtin_va_end(__ap); return __ret; } - -int __cdecl (*__MINGW_IMP_SYMBOL(sscanf))(const char *__restrict__, const char *__restrict__, ...) = sscanf; diff --git a/lib/libc/mingw/stdio/ucrt_swprintf.c b/lib/libc/mingw/stdio/ucrt_swprintf.c new file mode 100644 index 0000000000..8e73141c1e --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_swprintf.c @@ -0,0 +1,29 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl swprintf(wchar_t * __restrict__ _Dest,size_t _Count,const wchar_t * __restrict__ _Format,...) +{ + __builtin_va_list __ap; + int __ret; + /* + * __stdio_common_vswprintf() for case _Dest == NULL and _Count == 0 and + * without _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR option, is + * executed in "standard snprintf behavior" and returns number of (wide) + * chars required to allocate. For all other cases it is executed in a way + * that returns negative value on error. But C95+ compliant swprintf() for + * case _Count == 0 returns negative value, so handle this case specially. + */ + if (_Dest == NULL && _Count == 0) + return -1; + __builtin_va_start(__ap, _Format); + __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Dest, _Count, _Format, NULL, __ap); + __builtin_va_end(__ap); + return __ret < 0 ? -1 : __ret; +} diff --git a/lib/libc/mingw/stdio/ucrt_swscanf.c b/lib/libc/mingw/stdio/ucrt_swscanf.c new file mode 100644 index 0000000000..1a13d8b934 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_swscanf.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl swscanf(const wchar_t * __restrict__ _Src,const wchar_t * __restrict__ _Format,...) { + __builtin_va_list __ap; + int __ret; + __builtin_va_start(__ap, _Format); + __ret = __stdio_common_vswscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, _Src, (size_t)-1, _Format, NULL, __ap); + __builtin_va_end(__ap); + return __ret; +} diff --git a/lib/libc/mingw/stdio/ucrt_vfprintf.c b/lib/libc/mingw/stdio/ucrt_vfprintf.c index 7ee9c9b746..6ac1bb8c11 100644 --- a/lib/libc/mingw/stdio/ucrt_vfprintf.c +++ b/lib/libc/mingw/stdio/ucrt_vfprintf.c @@ -12,4 +12,3 @@ int __cdecl vfprintf(FILE * __restrict__ _File,const char * __restrict__ _Format { return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _File, _Format, NULL, _ArgList); } -int __cdecl (*__MINGW_IMP_SYMBOL(vfprintf))(FILE *__restrict__, const char *__restrict__, va_list) = vfprintf; diff --git a/lib/libc/mingw/stdio/ucrt_vfscanf.c b/lib/libc/mingw/stdio/ucrt_vfscanf.c index 8d1a76a8be..a8a3a7dffc 100644 --- a/lib/libc/mingw/stdio/ucrt_vfscanf.c +++ b/lib/libc/mingw/stdio/ucrt_vfscanf.c @@ -9,6 +9,5 @@ #include int __cdecl vfscanf (FILE *__stream, const char *__format, __builtin_va_list __local_argv) { - return __stdio_common_vfscanf(0, __stream, __format, NULL, __local_argv); + return __stdio_common_vfscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, __stream, __format, NULL, __local_argv); } -int __cdecl (*__MINGW_IMP_SYMBOL(vfscanf))(FILE *, const char *, __builtin_va_list) = vfscanf; diff --git a/lib/libc/mingw/stdio/ucrt_vfwprintf.c b/lib/libc/mingw/stdio/ucrt_vfwprintf.c new file mode 100644 index 0000000000..ba09b09770 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vfwprintf.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vfwprintf(FILE * __restrict__ _File, const wchar_t * __restrict__ _Format, va_list _ArgList) +{ + return __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _File, _Format, NULL, _ArgList); +} diff --git a/lib/libc/mingw/stdio/ucrt_vfwscanf.c b/lib/libc/mingw/stdio/ucrt_vfwscanf.c new file mode 100644 index 0000000000..249bc3b2b4 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vfwscanf.c @@ -0,0 +1,13 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vfwscanf (FILE *__stream, const wchar_t *__format, __builtin_va_list __local_argv) { + return __stdio_common_vfwscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, __stream, __format, NULL, __local_argv); +} diff --git a/lib/libc/mingw/stdio/ucrt_vprintf.c b/lib/libc/mingw/stdio/ucrt_vprintf.c index 2964dd1bec..abae22a90d 100644 --- a/lib/libc/mingw/stdio/ucrt_vprintf.c +++ b/lib/libc/mingw/stdio/ucrt_vprintf.c @@ -12,4 +12,3 @@ int __cdecl vprintf(const char * __restrict__ _Format,va_list _ArgList) { return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, stdout, _Format, NULL, _ArgList); } -int __cdecl (*__MINGW_IMP_SYMBOL(vprintf))(const char *__restrict__, va_list) = vprintf; diff --git a/lib/libc/mingw/stdio/ucrt_vscanf.c b/lib/libc/mingw/stdio/ucrt_vscanf.c index fc5ae1b1e0..1142507f98 100644 --- a/lib/libc/mingw/stdio/ucrt_vscanf.c +++ b/lib/libc/mingw/stdio/ucrt_vscanf.c @@ -9,6 +9,5 @@ #include int __cdecl vscanf(const char *__format, __builtin_va_list __local_argv) { - return __stdio_common_vfscanf(0, stdin, __format, NULL, __local_argv); + return __stdio_common_vfscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, stdin, __format, NULL, __local_argv); } -int __cdecl (*__MINGW_IMP_SYMBOL(vscanf))(const char *, __builtin_va_list) = vscanf; diff --git a/lib/libc/mingw/stdio/ucrt_vsnprintf.c b/lib/libc/mingw/stdio/ucrt_vsnprintf.c index 94ed44add1..5ccf5fafe5 100644 --- a/lib/libc/mingw/stdio/ucrt_vsnprintf.c +++ b/lib/libc/mingw/stdio/ucrt_vsnprintf.c @@ -12,4 +12,3 @@ int __cdecl vsnprintf (char * __restrict__ __stream, size_t __n, const char * __ { return __stdio_common_vsprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, __stream, __n, __format, NULL, __local_argv); } -int __cdecl (*__MINGW_IMP_SYMBOL(vsnprintf))(char *__restrict__, size_t, const char *__restrict__, va_list) = vsnprintf; diff --git a/lib/libc/mingw/stdio/ucrt_vsnwprintf.c b/lib/libc/mingw/stdio/ucrt_vsnwprintf.c new file mode 100644 index 0000000000..eb9d1b63b7 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vsnwprintf.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg) +{ + return __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, arg); +} diff --git a/lib/libc/mingw/stdio/ucrt_vsprintf.c b/lib/libc/mingw/stdio/ucrt_vsprintf.c index 3bdddd6c63..a9f5593f1a 100644 --- a/lib/libc/mingw/stdio/ucrt_vsprintf.c +++ b/lib/libc/mingw/stdio/ucrt_vsprintf.c @@ -12,4 +12,3 @@ int __cdecl vsprintf(char * __restrict__ _Dest,const char * __restrict__ _Format { return __stdio_common_vsprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, _Dest, (size_t)-1, _Format, NULL, _Args); } -int __cdecl (*__MINGW_IMP_SYMBOL(vsprintf))(char *__restrict__, const char *__restrict__, va_list) = vsprintf; diff --git a/lib/libc/mingw/stdio/ucrt_vsscanf.c b/lib/libc/mingw/stdio/ucrt_vsscanf.c index 1fb76fcf1b..1e2d7be596 100644 --- a/lib/libc/mingw/stdio/ucrt_vsscanf.c +++ b/lib/libc/mingw/stdio/ucrt_vsscanf.c @@ -9,6 +9,5 @@ #include int __cdecl vsscanf (const char * __restrict__ __source, const char * __restrict__ __format, __builtin_va_list __local_argv) { - return __stdio_common_vsscanf(0, __source, (size_t)-1, __format, NULL, __local_argv); + return __stdio_common_vsscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, __source, (size_t)-1, __format, NULL, __local_argv); } -int __cdecl (*__MINGW_IMP_SYMBOL(vsscanf))(const char *__restrict, const char *__restrict__, __builtin_va_list) = vsscanf; diff --git a/lib/libc/mingw/stdio/ucrt_vswprintf.c b/lib/libc/mingw/stdio/ucrt_vswprintf.c new file mode 100644 index 0000000000..ebbb940db3 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vswprintf.c @@ -0,0 +1,26 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vswprintf(wchar_t * __restrict__ _Dest,size_t _Count,const wchar_t * __restrict__ _Format,va_list _Args) +{ + int __ret; + /* + * __stdio_common_vswprintf() for case _Dest == NULL and _Count == 0 and + * without _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR option, is + * executed in "standard snprintf behavior" and returns number of (wide) + * chars required to allocate. For all other cases it is executed in a way + * that returns negative value on error. But C95+ compliant vswprintf() for + * case _Count == 0 returns negative value, so handle this case specially. + */ + if (_Dest == NULL && _Count == 0) + return -1; + __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Dest, _Count, _Format, NULL, _Args); + return __ret < 0 ? -1 : __ret; +} diff --git a/lib/libc/mingw/stdio/ucrt_vwprintf.c b/lib/libc/mingw/stdio/ucrt_vwprintf.c new file mode 100644 index 0000000000..3433b501f3 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vwprintf.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vwprintf(const wchar_t * __restrict__ _Format, va_list _ArgList) +{ + return __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, stdout, _Format, NULL, _ArgList); +} diff --git a/lib/libc/mingw/stdio/ucrt_vwscanf.c b/lib/libc/mingw/stdio/ucrt_vwscanf.c new file mode 100644 index 0000000000..adc7570cad --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_vwscanf.c @@ -0,0 +1,13 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl vwscanf(const wchar_t *__format, __builtin_va_list __local_argv) { + return __stdio_common_vfwscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, stdin, __format, NULL, __local_argv); +} diff --git a/lib/libc/mingw/stdio/ucrt_ms_fprintf.c b/lib/libc/mingw/stdio/ucrt_wprintf.c similarity index 53% rename from lib/libc/mingw/stdio/ucrt_ms_fprintf.c rename to lib/libc/mingw/stdio/ucrt_wprintf.c index 15588bcae7..60d1c15623 100644 --- a/lib/libc/mingw/stdio/ucrt_ms_fprintf.c +++ b/lib/libc/mingw/stdio/ucrt_wprintf.c @@ -7,16 +7,17 @@ #undef __MSVCRT_VERSION__ #define _UCRT -#include #include +#include -int __cdecl __ms_fprintf(FILE * restrict file, const char * restrict format, ...) +int __cdecl wprintf(const wchar_t *fmt, ...); + +int __cdecl wprintf(const wchar_t *fmt, ...) { va_list ap; int ret; - va_start(ap, format); - ret = __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, file, format, NULL, ap); + va_start(ap, fmt); + ret = __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, stdout, fmt, NULL, ap); va_end(ap); return ret; } -int __cdecl (*__MINGW_IMP_SYMBOL(__ms_fprintf))(FILE * restrict, const char * restrict, ...) = __ms_fprintf; diff --git a/lib/libc/mingw/stdio/ucrt_wscanf.c b/lib/libc/mingw/stdio/ucrt_wscanf.c new file mode 100644 index 0000000000..907caf65d7 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_wscanf.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT +#include + +int __cdecl wscanf(const wchar_t * __restrict__ _Format,...) { + __builtin_va_list __ap; + int __ret; + __builtin_va_start(__ap, _Format); + __ret = __stdio_common_vfwscanf(_CRT_INTERNAL_LOCAL_SCANF_OPTIONS, stdin, _Format, NULL, __ap); + __builtin_va_end(__ap); + return __ret; +} diff --git a/lib/libc/mingw/winpthreads/barrier.c b/lib/libc/mingw/winpthreads/barrier.c index e973aaaa7b..b1be5126aa 100644 --- a/lib/libc/mingw/winpthreads/barrier.c +++ b/lib/libc/mingw/winpthreads/barrier.c @@ -20,12 +20,22 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include #include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +/* public header files */ #include "pthread.h" +#include "semaphore.h" +/* internal header files */ #include "barrier.h" -#include "ref.h" #include "misc.h" static pthread_spinlock_t barrier_global = PTHREAD_SPINLOCK_INITIALIZER; @@ -34,9 +44,7 @@ static WINPTHREADS_ATTRIBUTE((noinline)) int barrier_unref(volatile pthread_barrier_t *barrier, int res) { pthread_spin_lock(&barrier_global); -#ifdef WINPTHREAD_DBG assert((((barrier_t *)*barrier)->valid == LIFE_BARRIER) && (((barrier_t *)*barrier)->busy > 0)); -#endif ((barrier_t *)*barrier)->busy -= 1; pthread_spin_unlock(&barrier_global); return res; @@ -64,7 +72,7 @@ barrier_ref_destroy(volatile pthread_barrier_t *barrier, pthread_barrier_t *bDes *bDestroy = NULL; pthread_spin_lock(&barrier_global); - + if (!barrier || !*barrier || ((barrier_t *)*barrier)->valid != LIFE_BARRIER) r = EINVAL; else { barrier_t *b_ = (barrier_t *)*barrier; @@ -92,15 +100,15 @@ int pthread_barrier_destroy(pthread_barrier_t *b_) pthread_barrier_t bDestroy; barrier_t *b; int r; - + while ((r = barrier_ref_destroy(b_,&bDestroy)) == EBUSY) Sleep(0); - + if (r) return r; b = (barrier_t *)bDestroy; - + pthread_mutex_lock(&b->m); if (sem_destroy(&b->sems[0]) != 0) diff --git a/lib/libc/mingw/winpthreads/barrier.h b/lib/libc/mingw/winpthreads/barrier.h index 5509678bef..1d1e83da66 100644 --- a/lib/libc/mingw/winpthreads/barrier.h +++ b/lib/libc/mingw/winpthreads/barrier.h @@ -34,8 +34,6 @@ return EINVAL; \ } while (0) -#include "semaphore.h" - typedef struct barrier_t barrier_t; struct barrier_t { diff --git a/lib/libc/mingw/winpthreads/clock.c b/lib/libc/mingw/winpthreads/clock.c index 954d845b15..922c5de5dc 100644 --- a/lib/libc/mingw/winpthreads/clock.c +++ b/lib/libc/mingw/winpthreads/clock.c @@ -4,15 +4,23 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include #include #include #include + +#define WIN32_LEAN_AND_MEAN #include -#ifndef IN_WINPTHREAD -#define IN_WINPTHREAD 1 -#endif -#include "pthread.h" + +#define WINPTHREAD_CLOCK_DECL WINPTHREAD_API + +/* public header files */ #include "pthread_time.h" +/* internal header files */ #include "misc.h" #define POW10_7 10000000 @@ -51,7 +59,7 @@ static WINPTHREADS_INLINE int lc_set_errno(int result) * If the function fails, the return value is -1, * with errno set to indicate the error. */ -int clock_getres(clockid_t clock_id, struct timespec *res) +static int __clock_getres(clockid_t clock_id, struct _timespec64 *res) { clockid_t id = clock_id; @@ -113,7 +121,7 @@ int clock_getres(clockid_t clock_id, struct timespec *res) * If the function fails, the return value is -1, * with errno set to indicate the error. */ -int clock_gettime(clockid_t clock_id, struct timespec *tp) +static int __clock_gettime(clockid_t clock_id, struct _timespec64 *tp) { unsigned __int64 t; LARGE_INTEGER pf, pc; @@ -172,7 +180,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) return 0; } - case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_THREAD_CPUTIME_ID: { if(0 == GetThreadTimes(GetCurrentThread(), &ct.ft, &et.ft, &kt.ft, &ut.ft)) return lc_set_errno(EINVAL); @@ -201,20 +209,20 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) * If the function fails, the return value is -1, * with errno set to indicate the error. */ -int clock_nanosleep(clockid_t clock_id, int flags, - const struct timespec *request, - struct timespec *remain) +static int __clock_nanosleep(clockid_t clock_id, int flags, + const struct _timespec64 *request, + struct _timespec64 *remain) { - struct timespec tp; + struct _timespec64 tp; if (clock_id != CLOCK_REALTIME) return lc_set_errno(EINVAL); if (flags == 0) - return nanosleep(request, remain); + return nanosleep64(request, remain); /* TIMER_ABSTIME = 1 */ - clock_gettime(CLOCK_REALTIME, &tp); + __clock_gettime(CLOCK_REALTIME, &tp); tp.tv_sec = request->tv_sec - tp.tv_sec; tp.tv_nsec = request->tv_nsec - tp.tv_nsec; @@ -223,7 +231,7 @@ int clock_nanosleep(clockid_t clock_id, int flags, tp.tv_sec --; } - return nanosleep(&tp, remain); + return nanosleep64(&tp, remain); } /** @@ -234,7 +242,7 @@ int clock_nanosleep(clockid_t clock_id, int flags, * If the function fails, the return value is -1, * with errno set to indicate the error. */ -int clock_settime(clockid_t clock_id, const struct timespec *tp) +static int __clock_settime(clockid_t clock_id, const struct _timespec64 *tp) { SYSTEMTIME st; @@ -255,3 +263,92 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) return 0; } + +/** + * Versions to use with 64-bit time_t (struct _timespec64) + */ + +int clock_getres64 (clockid_t clock_id, struct _timespec64 *tp) +{ + return __clock_getres (clock_id, tp); +} + +int clock_gettime64 (clockid_t clock_id, struct _timespec64 *tp) +{ + return __clock_gettime (clock_id, tp); +} + +int clock_settime64 (clockid_t clock_id, const struct _timespec64 *tp) +{ + return __clock_settime (clock_id, tp); +} + +int clock_nanosleep64 (clockid_t clock_id, int flags, + const struct _timespec64 *request, struct _timespec64 *remain) +{ + return __clock_nanosleep (clock_id, flags, request, remain); +} + +/** + * Versions to use with 32-bit time_t (struct _timespec32) + */ + +int clock_getres32 (clockid_t clock_id, struct _timespec32 *tp) +{ + struct _timespec64 tp64 = {0}; + + if (__clock_getres (clock_id, &tp64) == -1) + return -1; + + tp->tv_sec = (__time32_t) tp64.tv_sec; + tp->tv_nsec = tp64.tv_nsec; + + return 0; +} + +int clock_gettime32 (clockid_t clock_id, struct _timespec32 *tp) +{ + struct _timespec64 tp64 = {0}; + + if (__clock_gettime (clock_id, &tp64) == -1) + return -1; + + if (tp64.tv_sec > INT_MAX) + { + _set_errno (EOVERFLOW); + return -1; + } + + tp->tv_sec = (__time32_t) tp64.tv_sec; + tp->tv_nsec = tp64.tv_nsec; + + return 0; +} + +int clock_settime32 (clockid_t clock_id, const struct _timespec32 *tp) +{ + struct _timespec64 tp64 = {.tv_sec = tp->tv_sec, .tv_nsec = tp->tv_nsec}; + return __clock_settime (clock_id, &tp64); +} + +int clock_nanosleep32 (clockid_t clock_id, int flags, + const struct _timespec32 *request, struct _timespec32 *remain) +{ + struct _timespec64 request64 = { + .tv_sec = request->tv_sec, + .tv_nsec = request->tv_nsec + }; + struct _timespec64 remain64 = {0}; + + if (__clock_nanosleep (clock_id, flags, &request64, &remain64) == -1) + return -1; + + assert (remain64.tv_sec <= INT_MAX); + + if (remain != NULL) { + remain->tv_sec = (__time32_t)remain64.tv_sec; + remain->tv_nsec = remain64.tv_nsec; + } + + return 0; +} diff --git a/lib/libc/mingw/winpthreads/cond.c b/lib/libc/mingw/winpthreads/cond.c index 813648f0e6..a77cd3ef0f 100644 --- a/lib/libc/mingw/winpthreads/cond.c +++ b/lib/libc/mingw/winpthreads/cond.c @@ -24,17 +24,27 @@ * Posix Condition Variables for Microsoft Windows. * 22-9-2010 Partly based on the ACE framework implementation. */ -#include -#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include #include + +#define WIN32_LEAN_AND_MEAN +#include + +#define WINPTHREAD_COND_DECL WINPTHREAD_API + +/* public header files */ #include "pthread.h" #include "pthread_time.h" -#include "ref.h" +/* internal header files */ #include "cond.h" -#include "thread.h" #include "misc.h" -#include "winpthread_internal.h" +#include "thread.h" #include "pthread_compat.h" @@ -52,41 +62,13 @@ typedef struct sCondWaitHelper { int do_sema_b_wait_intern (HANDLE sema, int nointerrupt, DWORD timeout); -#ifdef WINPTHREAD_DBG -static int print_state = 0; -static FILE *fo; -void cond_print_set(int state, FILE *f) -{ - if (f) fo = f; - if (!fo) fo = stdout; - print_state = state; -} - -void cond_print(volatile pthread_cond_t *c, char *txt) -{ - if (!print_state) return; - cond_t *c_ = (cond_t *)*c; - if (c_ == NULL) { - fprintf(fo,"C%p %lu %s\n",(void *)*c,GetCurrentThreadId(),txt); - } else { - fprintf(fo,"C%p %lu V=%0X w=%ld %s\n", - (void *)*c, - GetCurrentThreadId(), - (int)c_->valid, - c_->waiters_count_, - txt - ); - } -} -#endif - static pthread_spinlock_t cond_locked = PTHREAD_SPINLOCK_INITIALIZER; static int cond_static_init (pthread_cond_t *c) { int r = 0; - + pthread_spin_lock (&cond_locked); if (c == NULL) r = EINVAL; @@ -143,40 +125,6 @@ pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clock_id) return 0; } -int -__pthread_clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *rqtp, - struct timespec *rmtp) -{ - unsigned long long tick, tick2; - unsigned long long delay; - DWORD dw; - - if (clock_id != CLOCK_REALTIME - && clock_id != CLOCK_MONOTONIC - && clock_id != CLOCK_PROCESS_CPUTIME_ID) - return EINVAL; - if ((flags & TIMER_ABSTIME) != 0) - delay = _pthread_rel_time_in_ms (rqtp); - else - delay = _pthread_time_in_ms_from_timespec (rqtp); - do - { - dw = (DWORD) (delay >= 99999ULL ? 99999ULL : delay); - tick = _pthread_time_in_ms (); - pthread_delay_np_ms (dw); - tick2 = _pthread_time_in_ms (); - tick2 -= tick; - if (tick2 >= delay) - delay = 0; - else - delay -= tick2; - } - while (delay != 0ULL); - if (rmtp) - memset (rmtp, 0, sizeof (*rmtp)); - return 0; -} - int pthread_condattr_setpshared (pthread_condattr_t *a, int s) { @@ -218,7 +166,7 @@ pthread_cond_init (pthread_cond_t *c, const pthread_condattr_t *a) _c->sema_b = CreateSemaphore (NULL, /* no security */ 0, /* initially 0 */ 0x7fffffff, /* max count */ - NULL); + NULL); if (_c->sema_q == NULL || _c->sema_b == NULL) { if (_c->sema_q != NULL) CloseHandle (_c->sema_q); @@ -356,7 +304,7 @@ pthread_cond_broadcast (pthread_cond_t *c) { cond_t *_c; int r; - int relCnt = 0; + int relCnt = 0; if (!c || !*c) return EINVAL; @@ -465,7 +413,7 @@ tryagain: } static int -pthread_cond_timedwait_impl (pthread_cond_t *c, pthread_mutex_t *external_mutex, const struct timespec *t, int rel) +pthread_cond_timedwait_impl (pthread_cond_t *c, pthread_mutex_t *external_mutex, const struct _timespec64 *t, int rel) { sCondWaitHelper ch; DWORD dwr; @@ -531,17 +479,31 @@ tryagain: } int -pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, const struct timespec *t) +pthread_cond_timedwait64(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec64 *t) { return pthread_cond_timedwait_impl(c, m, t, 0); } int -pthread_cond_timedwait_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct timespec *t) +pthread_cond_timedwait32(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec32 *t) +{ + struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec}; + return pthread_cond_timedwait_impl(c, m, &t64, 0); +} + +int +pthread_cond_timedwait64_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec64 *t) { return pthread_cond_timedwait_impl(c, m, t, 1); } +int +pthread_cond_timedwait32_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec32 *t) +{ + struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec}; + return pthread_cond_timedwait_impl(c, m, &t64, 1); +} + static void cleanup_wait (void *arg) { @@ -751,5 +713,5 @@ do_sema_b_release(HANDLE sema, LONG count,CRITICAL_SECTION *cs, LONG *val) } InterlockedExchangeAdd(val, -count); LeaveCriticalSection(cs); - return EINVAL; + return EINVAL; } diff --git a/lib/libc/mingw/winpthreads/cond.h b/lib/libc/mingw/winpthreads/cond.h index 5e869e957c..fcf7db3559 100644 --- a/lib/libc/mingw/winpthreads/cond.h +++ b/lib/libc/mingw/winpthreads/cond.h @@ -23,8 +23,6 @@ #ifndef WIN_PTHREADS_COND_H #define WIN_PTHREADS_COND_H -#include - #define CHECK_COND(c) \ do { \ if (!(c) || !*c || (*c == PTHREAD_COND_INITIALIZER) \ @@ -40,7 +38,7 @@ typedef struct cond_t cond_t; struct cond_t { - unsigned int valid; + unsigned int valid; int busy; LONG waiters_count_; /* Number of waiting threads. */ LONG waiters_count_unblock_; /* Number of waiting threads whitch can be unblocked. */ @@ -56,8 +54,4 @@ struct cond_t became signaled. */ }; -void cond_print_set(int state, FILE *f); - -void cond_print(volatile pthread_cond_t *c, char *txt); - #endif diff --git a/lib/libc/mingw/winpthreads/misc.c b/lib/libc/mingw/winpthreads/misc.c index c426f59cbe..d9c55041ee 100644 --- a/lib/libc/mingw/winpthreads/misc.c +++ b/lib/libc/mingw/winpthreads/misc.c @@ -20,8 +20,16 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define WIN32_LEAN_AND_MEAN #include + +/* public header files */ #include "pthread.h" +/* internal header files */ #include "misc.h" void (WINAPI *_pthread_get_system_time_best_as_file_time) (LPFILETIME) = NULL; @@ -29,6 +37,8 @@ static ULONGLONG (WINAPI *_pthread_get_tick_count_64) (VOID); HRESULT (WINAPI *_pthread_set_thread_description) (HANDLE, PCWSTR) = NULL; #if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" __attribute__((constructor(0))) #endif static void winpthreads_init(void) @@ -55,6 +65,9 @@ static void winpthreads_init(void) (HRESULT (WINAPI *)(HANDLE, PCWSTR))(void*) GetProcAddress(mod, "SetThreadDescription"); } } +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif #if defined(_MSC_VER) && !defined(__clang__) /* Force a reference to __xc_t to prevent whole program optimization @@ -82,7 +95,7 @@ unsigned long long _pthread_time_in_ms(void) - 0x19DB1DED53E8000ULL) / 10000ULL; } -unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts) +unsigned long long _pthread_time_in_ms_from_timespec(const struct _timespec64 *ts) { unsigned long long t = (unsigned long long) ts->tv_sec * 1000LL; /* The +999999 is here to ensure that the division always rounds up */ @@ -91,7 +104,7 @@ unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts) return t; } -unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts) +unsigned long long _pthread_rel_time_in_ms(const struct _timespec64 *ts) { unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts); unsigned long long t2 = _pthread_time_in_ms(); diff --git a/lib/libc/mingw/winpthreads/misc.h b/lib/libc/mingw/winpthreads/misc.h index a853dd085c..f954ad451c 100644 --- a/lib/libc/mingw/winpthreads/misc.h +++ b/lib/libc/mingw/winpthreads/misc.h @@ -23,37 +23,10 @@ #ifndef WIN_PTHREADS_MISC_H #define WIN_PTHREADS_MISC_H +#include +/* public header files */ #include "pthread_compat.h" -#ifndef assert - -#ifndef ASSERT_TRACE -# define ASSERT_TRACE 0 -#else -# undef ASSERT_TRACE -# define ASSERT_TRACE 0 -#endif - -# define assert(e) \ - ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ - "Assertion succeeded: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), \ - fflush(stderr) : \ - 0) : \ - (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), exit(1), 0)) - -# define fixme(e) \ - ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ - "Assertion succeeded: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), \ - fflush(stderr) : \ - 0) : \ - (fprintf(stderr, "FIXME: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), 0, 0)) - -#endif - #define PTR2INT(x) ((int)(uintptr_t)(x)) #if SIZE_MAX>UINT_MAX @@ -102,8 +75,8 @@ static WINPTHREADS_INLINE unsigned long dwMilliSecs(unsigned long long ms) } unsigned long long _pthread_time_in_ms(void); -unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts); -unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts); +unsigned long long _pthread_time_in_ms_from_timespec(const struct _timespec64 *ts); +unsigned long long _pthread_rel_time_in_ms(const struct _timespec64 *ts); unsigned long _pthread_wait_for_single_object (void *handle, unsigned long timeout); unsigned long _pthread_wait_for_multiple_objects (unsigned long count, void **handles, unsigned int all, unsigned long timeout); diff --git a/lib/libc/mingw/winpthreads/mutex.c b/lib/libc/mingw/winpthreads/mutex.c index 866e18d943..b901209769 100644 --- a/lib/libc/mingw/winpthreads/mutex.c +++ b/lib/libc/mingw/winpthreads/mutex.c @@ -21,11 +21,22 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#define WINPTHREAD_MUTEX_DECL WINPTHREAD_API + +/* public header files */ #include "pthread.h" +/* internal header files */ #include "misc.h" typedef enum { @@ -184,7 +195,8 @@ pthread_mutex_lock (pthread_mutex_t *m) return pthread_mutex_lock_intern (m, INFINITE); } -int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts) +/* Internal version which always uses `struct _timespec64`. */ +static int __pthread_mutex_timedlock(pthread_mutex_t *m, const struct _timespec64 *ts) { unsigned long long patience; if (ts != NULL) { @@ -199,8 +211,19 @@ int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts) return pthread_mutex_lock_intern(m, patience); } +int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts) +{ + return __pthread_mutex_timedlock (m, ts); +} + +int pthread_mutex_timedlock32(pthread_mutex_t *m, const struct _timespec32 *ts) +{ + struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec}; + return __pthread_mutex_timedlock (m, &ts64); +} + int pthread_mutex_unlock(pthread_mutex_t *m) -{ +{ /* Here m might an initialiser of an error-checking or recursive mutex, in which case the behaviour is well-defined, so we can't skip this check. */ mutex_impl_t *mi = mutex_impl(m); @@ -305,9 +328,9 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *a, int *type) { if (!a || !type) return EINVAL; - + *type = *a & 3; - + return 0; } diff --git a/lib/libc/mingw/winpthreads/nanosleep.c b/lib/libc/mingw/winpthreads/nanosleep.c index 0cce4492e2..a81bf2c894 100644 --- a/lib/libc/mingw/winpthreads/nanosleep.c +++ b/lib/libc/mingw/winpthreads/nanosleep.c @@ -4,12 +4,24 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include #include #include + +#define WIN32_LEAN_AND_MEAN #include + +#define WINPTHREAD_NANOSLEEP_DECL WINPTHREAD_API + +/* public header files */ #include "pthread.h" #include "pthread_time.h" -#include "winpthread_internal.h" +/* internal header files */ +#include "thread.h" #define POW10_3 1000 #define POW10_4 10000 @@ -25,7 +37,7 @@ * If the function fails, the return value is -1, * with errno set to indicate the error. */ -int nanosleep(const struct timespec *request, struct timespec *remain) +static int __nanosleep(const struct _timespec64 *request, struct _timespec64 *remain) { unsigned long ms, rc = 0; unsigned __int64 u64, want, real; @@ -48,7 +60,7 @@ int nanosleep(const struct timespec *request, struct timespec *remain) else ms = (unsigned long) u64; u64 -= ms; - rc = pthread_delay_np_ms(ms); + rc = _pthread_delay_np_ms(ms); } if (rc != 0) { /* WAIT_IO_COMPLETION (192) */ @@ -69,3 +81,29 @@ int nanosleep(const struct timespec *request, struct timespec *remain) return 0; } + +int nanosleep64(const struct _timespec64 *request, struct _timespec64 *remain) +{ + return __nanosleep (request, remain); +} + +int nanosleep32(const struct _timespec32 *request, struct _timespec32 *remain) +{ + struct _timespec64 request64 = { + .tv_sec = request->tv_sec, + .tv_nsec = request->tv_nsec + }; + struct _timespec64 remain64 = {0}; + + if (__nanosleep (&request64, &remain64) == -1) + return -1; + + assert (remain64.tv_sec <= INT_MAX); + + if (remain != NULL) { + remain->tv_sec = (__time32_t)remain64.tv_sec; + remain->tv_nsec = remain64.tv_nsec; + } + + return 0; +} diff --git a/lib/libc/mingw/winpthreads/ref.c b/lib/libc/mingw/winpthreads/ref.c deleted file mode 100644 index 0344d457e9..0000000000 --- a/lib/libc/mingw/winpthreads/ref.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (c) 2011-2016 mingw-w64 project - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include -#include -#include -#include "pthread.h" -#include "semaphore.h" -#include "rwlock.h" -#include "cond.h" -#include "barrier.h" -#include "sem.h" -#include "ref.h" -#include "misc.h" - diff --git a/lib/libc/mingw/winpthreads/ref.h b/lib/libc/mingw/winpthreads/ref.h deleted file mode 100644 index 5ca67506fa..0000000000 --- a/lib/libc/mingw/winpthreads/ref.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (c) 2011-2016 mingw-w64 project - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef WIN_PTHREADS_REF_H -#define WIN_PTHREADS_REF_H -#include "pthread.h" -#include "semaphore.h" - -#endif - diff --git a/lib/libc/mingw/winpthreads/rwlock.c b/lib/libc/mingw/winpthreads/rwlock.c index 76669dff13..68ef2a7330 100644 --- a/lib/libc/mingw/winpthreads/rwlock.c +++ b/lib/libc/mingw/winpthreads/rwlock.c @@ -20,14 +20,25 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include #include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#define WINPTHREAD_RWLOCK_DECL WINPTHREAD_API + +/* public header files */ #include "pthread.h" -#include "thread.h" -#include "ref.h" -#include "rwlock.h" +/* internal header files */ #include "misc.h" +#include "rwlock.h" +#include "thread.h" static pthread_spinlock_t rwl_global = PTHREAD_SPINLOCK_INITIALIZER; @@ -36,9 +47,7 @@ static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_unref(volatile pthread_rwlock_t *rwl, int res) { pthread_spin_lock(&rwl_global); -#ifdef WINPTHREAD_DBG assert((((rwlock_t *)*rwl)->valid == LIFE_RWLOCK) && (((rwlock_t *)*rwl)->busy > 0)); -#endif ((rwlock_t *)*rwl)->busy--; pthread_spin_unlock(&rwl_global); return res; @@ -87,7 +96,7 @@ static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref_destroy(pthread_rwlock_t *r *rDestroy = (pthread_rwlock_t)NULL; pthread_spin_lock(&rwl_global); - + if (!rwl || !*rwl) r = EINVAL; else { rwlock_t *r_ = (rwlock_t *)*rwl; @@ -128,30 +137,6 @@ static int rwlock_free_both_locks(rwlock_t *rwlock, int last_fail) return ret; } -#ifdef WINPTHREAD_DBG -static int print_state = 0; -void rwl_print_set(int state) -{ - print_state = state; -} - -void rwl_print(volatile pthread_rwlock_t *rwl, char *txt) -{ - if (!print_state) return; - rwlock_t *r = (rwlock_t *)*rwl; - if (r == NULL) { - printf("RWL%p %lu %s\n",(void *)*rwl,GetCurrentThreadId(),txt); - } else { - printf("RWL%p %lu V=%0X B=%d r=%ld w=%ld L=%p %s\n", - (void *)*rwl, - GetCurrentThreadId(), - (int)r->valid, - (int)r->busy, - 0L,0L,NULL,txt); - } -} -#endif - static pthread_spinlock_t cond_locked = PTHREAD_SPINLOCK_INITIALIZER; static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t *rw) @@ -165,7 +150,7 @@ static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t } r = pthread_rwlock_init (rw, NULL); pthread_spin_unlock(&cond_locked); - + return r; } @@ -178,7 +163,7 @@ int pthread_rwlock_init (pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t * return EINVAL; *rwlock_ = (pthread_rwlock_t)NULL; if ((rwlock = calloc(1, sizeof(*rwlock))) == NULL) - return ENOMEM; + return ENOMEM; rwlock->valid = DEAD_RWLOCK; rwlock->nex_count = rwlock->nsh_count = rwlock->ncomplete = 0; @@ -203,18 +188,18 @@ int pthread_rwlock_init (pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t * rwlock->valid = LIFE_RWLOCK; *rwlock_ = (pthread_rwlock_t)rwlock; return r; -} +} int pthread_rwlock_destroy (pthread_rwlock_t *rwlock_) { rwlock_t *rwlock; pthread_rwlock_t rDestroy; int r, r2; - + pthread_spin_lock(&cond_locked); r = rwl_ref_destroy(rwlock_,&rDestroy); pthread_spin_unlock(&cond_locked); - + if(r) return r; if(!rDestroy) return 0; /* destroyed a (still) static initialized rwl */ @@ -245,7 +230,7 @@ int pthread_rwlock_destroy (pthread_rwlock_t *rwlock_) rwlock->valid = DEAD_RWLOCK; free((void *)rDestroy); return 0; -} +} int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock_) { @@ -279,7 +264,8 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock_) return rwl_unref(rwlock_, ret); } -int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec *ts) +/* Internal version which always uses `struct _timespec64`. */ +static int __pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts) { rwlock_t *rwlock; int ret; @@ -290,12 +276,12 @@ int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec if(ret != 0) return ret; rwlock = (rwlock_t *)*rwlock_; - if ((ret = pthread_mutex_timedlock (&rwlock->mex, ts)) != 0) + if ((ret = pthread_mutex_timedlock64 (&rwlock->mex, ts)) != 0) return rwl_unref(rwlock_, ret); InterlockedIncrement(&rwlock->nsh_count); if (rwlock->nsh_count == INT_MAX) { - ret = pthread_mutex_timedlock(&rwlock->mcomplete, ts); + ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts); if (ret != 0) { if (ret == ETIMEDOUT) @@ -312,6 +298,17 @@ int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec return rwl_unref(rwlock_, ret); } +int pthread_rwlock_timedrdlock64(pthread_rwlock_t *l, const struct _timespec64 *ts) +{ + return __pthread_rwlock_timedrdlock (l, ts); +} + +int pthread_rwlock_timedrdlock32(pthread_rwlock_t *l, const struct _timespec32 *ts) +{ + struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec}; + return __pthread_rwlock_timedrdlock (l, &ts64); +} + int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock_) { rwlock_t *rwlock; @@ -340,7 +337,7 @@ int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock_) } ret = pthread_mutex_unlock(&rwlock->mex); return rwl_unref(rwlock_,ret); -} +} int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock_) { @@ -378,7 +375,7 @@ int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock_) } rwlock->nex_count = 1; return rwl_unref(rwlock_, 0); -} +} int pthread_rwlock_unlock (pthread_rwlock_t *rwlock_) { @@ -409,7 +406,7 @@ int pthread_rwlock_unlock (pthread_rwlock_t *rwlock_) ret = rwlock_free_both_locks(rwlock, 0); } return rwl_unref(rwlock_, ret); -} +} static void st_cancelwrite (void *arg) { @@ -459,7 +456,8 @@ int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock_) return rwl_unref(rwlock_,ret); } -int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec *ts) +/* Internal version which always uses `struct _timespec64`. */ +static int __pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts) { int ret; rwlock_t *rwlock; @@ -471,10 +469,10 @@ int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec return ret; rwlock = (rwlock_t *)*rwlock_; - ret = pthread_mutex_timedlock(&rwlock->mex, ts); + ret = pthread_mutex_timedlock64(&rwlock->mex, ts); if (ret != 0) return rwl_unref(rwlock_,ret); - ret = pthread_mutex_timedlock (&rwlock->mcomplete, ts); + ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts); if (ret != 0) { pthread_mutex_unlock(&rwlock->mex); @@ -492,7 +490,7 @@ int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec rwlock->ncomplete = -rwlock->nsh_count; pthread_cleanup_push(st_cancelwrite, (void *) rwlock); do { - ret = pthread_cond_timedwait(&rwlock->ccomplete, &rwlock->mcomplete, ts); + ret = pthread_cond_timedwait64(&rwlock->ccomplete, &rwlock->mcomplete, ts); } while (rwlock->ncomplete < 0 && !ret); pthread_cleanup_pop(!ret ? 0 : 1); @@ -505,6 +503,17 @@ int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec return rwl_unref(rwlock_,ret); } +int pthread_rwlock_timedwrlock64(pthread_rwlock_t *rwlock, const struct _timespec64 *ts) +{ + return __pthread_rwlock_timedwrlock (rwlock, ts); +} + +int pthread_rwlock_timedwrlock32(pthread_rwlock_t *rwlock, const struct _timespec32 *ts) +{ + struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec}; + return __pthread_rwlock_timedwrlock (rwlock, &ts64); +} + int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a) { if (!a) diff --git a/lib/libc/mingw/winpthreads/rwlock.h b/lib/libc/mingw/winpthreads/rwlock.h index 2d640faa93..8faf12b9f5 100644 --- a/lib/libc/mingw/winpthreads/rwlock.h +++ b/lib/libc/mingw/winpthreads/rwlock.h @@ -43,7 +43,4 @@ struct rwlock_t { #define RWL_SET 0x01 #define RWL_TRY 0x02 -void rwl_print(volatile pthread_rwlock_t *rwl, char *txt); -void rwl_print_set(int state); - #endif diff --git a/lib/libc/mingw/winpthreads/sched.c b/lib/libc/mingw/winpthreads/sched.c index 976bcc1052..0bdcc3ca99 100644 --- a/lib/libc/mingw/winpthreads/sched.c +++ b/lib/libc/mingw/winpthreads/sched.c @@ -20,12 +20,20 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include -#include "pthread.h" -#include "thread.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include + +#define WIN32_LEAN_AND_MEAN +#include + +/* public header files */ +#include "pthread.h" +/* internal header files */ #include "misc.h" +#include "thread.h" int sched_get_priority_min(int pol) { diff --git a/lib/libc/mingw/winpthreads/sem.c b/lib/libc/mingw/winpthreads/sem.c index 340ff69e08..37abf2e115 100644 --- a/lib/libc/mingw/winpthreads/sem.c +++ b/lib/libc/mingw/winpthreads/sem.c @@ -20,15 +20,23 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +/* public header files */ #include "pthread.h" -#include "thread.h" -#include "misc.h" #include "semaphore.h" +/* internal header files */ +#include "misc.h" #include "sem.h" -#include "ref.h" +#include "thread.h" int do_sema_b_wait_intern (HANDLE sema, int nointerrupt, DWORD timeout); @@ -212,8 +220,9 @@ sem_wait (sem_t *sem) return sem_result (ret); } -int -sem_timedwait (sem_t *sem, const struct timespec *t) +/* Internal version which always uses `struct _timespec64`. */ +static int +__sem_timedwait (sem_t *sem, const struct _timespec64 *t) { int cur_v, ret = 0; DWORD dwr; @@ -251,6 +260,17 @@ sem_timedwait (sem_t *sem, const struct timespec *t) return sem_result (ret); } +int sem_timedwait64(sem_t *sem, const struct _timespec64 *t) +{ + return __sem_timedwait (sem, t); +} + +int sem_timedwait32(sem_t *sem, const struct _timespec32 *t) +{ + struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec}; + return __sem_timedwait (sem, &t64); +} + int sem_post (sem_t *sem) { @@ -350,5 +370,5 @@ sem_getvalue (sem_t *sem, int *sval) *sval = (int) sv->value; pthread_mutex_unlock (&sv->vlock); - return 0; + return 0; } diff --git a/lib/libc/mingw/winpthreads/sem.h b/lib/libc/mingw/winpthreads/sem.h index 3b3ace7f73..ddfc00a65d 100644 --- a/lib/libc/mingw/winpthreads/sem.h +++ b/lib/libc/mingw/winpthreads/sem.h @@ -23,8 +23,6 @@ #ifndef WIN_SEM #define WIN_SEM -#include - #define LIFE_SEM 0xBAB1F00D #define DEAD_SEM 0xDEADBEEF diff --git a/lib/libc/mingw/winpthreads/spinlock.c b/lib/libc/mingw/winpthreads/spinlock.c index 224c5a06e0..eb21509d60 100644 --- a/lib/libc/mingw/winpthreads/spinlock.c +++ b/lib/libc/mingw/winpthreads/spinlock.c @@ -21,8 +21,16 @@ DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define WIN32_LEAN_AND_MEAN #include + +/* public header files */ #include "pthread.h" +/* internal header files */ #include "misc.h" /* We use the pthread_spinlock_t itself as a lock: @@ -56,7 +64,7 @@ pthread_spin_lock (pthread_spinlock_t *lock) } while (*lk == 0); return 0; } - + int pthread_spin_trylock (pthread_spinlock_t *lock) { diff --git a/lib/libc/mingw/winpthreads/thread.c b/lib/libc/mingw/winpthreads/thread.c index d5b3aaa054..c0b36bb1f8 100644 --- a/lib/libc/mingw/winpthreads/thread.c +++ b/lib/libc/mingw/winpthreads/thread.c @@ -20,16 +20,27 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define WINPTHREAD_THREAD_DECL WINPTHREAD_API + +/* public header files */ #include "pthread.h" -#include "thread.h" +/* internal header files */ #include "misc.h" -#include "winpthread_internal.h" +#include "thread.h" static _pthread_v *__pthread_self_lite (void); @@ -537,34 +548,6 @@ WINPTHREADS_ATTRIBUTE((WINPTHREADS_SECTION(".CRT$XLF"))) extern const PIMAGE_TLS_CALLBACK __xl_f; const PIMAGE_TLS_CALLBACK __xl_f = __dyn_tls_pthread; - -#ifdef WINPTHREAD_DBG -static int print_state = 0; -void thread_print_set (int state) -{ - print_state = state; -} - -void -thread_print (volatile pthread_t t, char *txt) -{ - if (!print_state) - return; - if (!t) - printf("T%p %lu %s\n",NULL,GetCurrentThreadId(),txt); - else - { - printf("T%p %lu V=%0X H=%p %s\n", - (void *) __pth_gpointer_locked (t), - GetCurrentThreadId(), - (__pth_gpointer_locked (t))->valid, - (__pth_gpointer_locked (t))->h, - txt - ); - } -} -#endif - /* Internal collect-once structure. */ typedef struct collect_once_t { pthread_once_t *o; @@ -677,8 +660,8 @@ pthread_timechange_handler_np(void *dummy) /* Compatibility routine for pthread-win32. It waits for ellapse of interval and additionally checks for possible thread-cancelation. */ -int -pthread_delay_np (const struct timespec *interval) +static int +__pthread_delay_np (const struct _timespec64 *interval) { DWORD to = (!interval ? 0 : dwMilliSecs (_pthread_time_in_ms_from_timespec (interval))); struct _pthread_v *s = __pthread_self_lite (); @@ -699,10 +682,21 @@ pthread_delay_np (const struct timespec *interval) return 0; } -int pthread_delay_np_ms (DWORD to); +int +pthread_delay64_np (const struct _timespec64 *interval) +{ + return __pthread_delay_np(interval); +} int -pthread_delay_np_ms (DWORD to) +pthread_delay32_np (const struct _timespec32 *interval) +{ + struct _timespec64 interval64 = {.tv_sec = interval->tv_sec, .tv_nsec = interval->tv_nsec}; + return __pthread_delay_np(&interval64); +} + +int +_pthread_delay_np_ms (DWORD to) { struct _pthread_v *s = __pthread_self_lite (); @@ -725,7 +719,7 @@ pthread_delay_np_ms (DWORD to) /* Compatibility routine for pthread-win32. It returns the amount of available CPUs on system. */ int -pthread_num_processors_np(void) +pthread_num_processors_np(void) { int r = 0; DWORD_PTR ProcessAffinityMask, SystemAffinityMask; @@ -742,10 +736,10 @@ pthread_num_processors_np(void) /* Compatiblity routine for pthread-win32. Allows to set amount of used CPUs for process. */ int -pthread_set_num_processors_np(int n) +pthread_set_num_processors_np(int n) { DWORD_PTR ProcessAffinityMask, ProcessNewAffinityMask = 0, SystemAffinityMask; - int r = 0; + int r = 0; /* need at least 1 */ n = n ? n : 1; if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) @@ -878,7 +872,7 @@ pthread_key_delete (pthread_key_t key) return EINVAL; pthread_rwlock_wrlock (&_pthread_key_lock); - + _pthread_key_dest[key] = NULL; /* Start next search from our location */ @@ -910,7 +904,7 @@ pthread_setspecific (pthread_key_t key, const void *value) { DWORD lasterr = GetLastError (); _pthread_v *t = __pthread_self_lite (); - + pthread_spin_lock (&t->spin_keys); if (key >= t->keymax) @@ -1522,7 +1516,7 @@ void _fpreset (void); #if defined(__i386__) /* Align ESP on 16-byte boundaries. */ -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +# if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) __attribute__((force_align_arg_pointer)) # endif #endif @@ -1553,17 +1547,7 @@ pthread_create_wrapper (void *args) if (tv->func) trslt = (intptr_t) tv->func(tv->ret_arg); #ifdef __SEH__ - asm ("\tnop\n\t.tl_end: nop\n" -#ifdef __arm__ - "\t.seh_handler __C_specific_handler, %except\n" -#else - "\t.seh_handler __C_specific_handler, @except\n" -#endif - "\t.seh_handlerdata\n" - "\t.long 1\n" - "\t.rva .tl_start, .tl_end, _gnu_exception_handler ,.tl_end\n" - "\t.text" - ); + asm ("\tnop\n\t.tl_end: nop\n"); #endif pthread_mutex_lock (&mtx_pthr_locked); tv->ret_arg = (void*) trslt; @@ -1601,6 +1585,19 @@ pthread_create_wrapper (void *args) Sleep (0); _endthreadex (rslt); return rslt; + +#if defined(__SEH__) + asm( +#ifdef __arm__ + "\t.seh_handler __C_specific_handler, %except\n" +#else + "\t.seh_handler __C_specific_handler, @except\n" +#endif + "\t.seh_handlerdata\n" + "\t.long 1\n" + "\t.rva .tl_start, .tl_end, _gnu_exception_handler ,.tl_end\n" + "\t.text\n"); +#endif } int @@ -1881,13 +1878,14 @@ pthread_setname_np (pthread_t thread, const char *name) if (_pthread_set_thread_description != NULL) { - size_t required_size = mbstowcs(NULL, name, 0); + mbstate_t mbs = {0}; + size_t required_size = mbsrtowcs(NULL, &name, 0, &mbs); if (required_size != (size_t)-1) { wchar_t *wname = malloc((required_size + 1) * sizeof(wchar_t)); if (wname != NULL) { - mbstowcs(wname, name, required_size + 1); + mbsrtowcs(wname, &name, required_size + 1, &mbs); _pthread_set_thread_description(tv->h, wname); free(wname); } diff --git a/lib/libc/mingw/winpthreads/thread.h b/lib/libc/mingw/winpthreads/thread.h index 1603bae589..90f9cd39a2 100644 --- a/lib/libc/mingw/winpthreads/thread.h +++ b/lib/libc/mingw/winpthreads/thread.h @@ -23,8 +23,8 @@ #ifndef WIN_PTHREAD_H #define WIN_PTHREAD_H -#include #include +/* internal header files */ #include "rwlock.h" #define LIFE_THREAD 0xBAB1F00D @@ -69,11 +69,8 @@ typedef struct __pthread_idlist { int _pthread_tryjoin(pthread_t t, void **res); void _pthread_setnobreak(int); -#ifdef WINPTHREAD_DBG -void thread_print_set(int state); -void thread_print(volatile pthread_t t, char *txt); -#endif int __pthread_shallcancel(void); WINPTHREAD_API struct _pthread_v * __pth_gpointer_locked (pthread_t id); +int _pthread_delay_np_ms (DWORD to); #endif diff --git a/lib/libc/mingw/winpthreads/winpthread_internal.h b/lib/libc/mingw/winpthreads/winpthread_internal.h deleted file mode 100644 index eb6838c34b..0000000000 --- a/lib/libc/mingw/winpthreads/winpthread_internal.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2011-2016 mingw-w64 project - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef WINPTHREAD_INTERNAL_H -#define WINPTHREAD_INTERNAL_H -WINPTHREAD_API struct _pthread_v * __pth_gpointer_locked (pthread_t id); -int pthread_delay_np_ms (DWORD to); -#endif /*WINPTHREAD_INTERNAL_H*/ diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 8b5197a43b..ef6dfa6275 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -154,7 +154,8 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre try addCcArgs(comp, arena, &winpthreads_args); try winpthreads_args.appendSlice(&[_][]const u8{ "-DIN_WINPTHREAD", - "-DWIN32_LEAN_AND_MEAN", + // winpthreads incorrectly assumes that Clang has `-Wprio-ctor-dtor`. + "-Wno-unknown-warning-option", }); switch (comp.compilerRtOptMode()) { @@ -485,7 +486,6 @@ const mingw32_generic_src = [_][]const u8{ "crt" ++ path.sep_str ++ "pesect.c", "crt" ++ path.sep_str ++ "udllargc.c", "crt" ++ path.sep_str ++ "xthdloc.c", - "crt" ++ path.sep_str ++ "CRT_fp10.c", "crt" ++ path.sep_str ++ "mingw_helpers.c", "crt" ++ path.sep_str ++ "pseudo-reloc.c", "crt" ++ path.sep_str ++ "udll_argv.c", @@ -609,7 +609,6 @@ const mingw32_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "delayimp.c", "misc" ++ path.sep_str ++ "dirent.c", "misc" ++ path.sep_str ++ "dirname.c", - "misc" ++ path.sep_str ++ "dllentrypoint.c", "misc" ++ path.sep_str ++ "dllmain.c", "misc" ++ path.sep_str ++ "feclearexcept.c", "misc" ++ path.sep_str ++ "fegetenv.c", @@ -621,10 +620,14 @@ const mingw32_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "fesetexceptflag.c", "misc" ++ path.sep_str ++ "fesetround.c", "misc" ++ path.sep_str ++ "fetestexcept.c", + "misc" ++ path.sep_str ++ "mingw_controlfp.c", + "misc" ++ path.sep_str ++ "mingw_setfp.c", "misc" ++ path.sep_str ++ "feupdateenv.c", "misc" ++ path.sep_str ++ "ftruncate.c", - "misc" ++ path.sep_str ++ "ftw.c", + "misc" ++ path.sep_str ++ "ftw32.c", + "misc" ++ path.sep_str ++ "ftw32i64.c", "misc" ++ path.sep_str ++ "ftw64.c", + "misc" ++ path.sep_str ++ "ftw64i32.c", "misc" ++ path.sep_str ++ "fwide.c", "misc" ++ path.sep_str ++ "getlogin.c", "misc" ++ path.sep_str ++ "getopt.c", @@ -669,12 +672,12 @@ const mingw32_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "_findfirst64i32.c", "stdio" ++ path.sep_str ++ "_findnext64i32.c", "stdio" ++ path.sep_str ++ "_fstat64i32.c", - "stdio" ++ path.sep_str ++ "_stat.c", "stdio" ++ path.sep_str ++ "_stat64i32.c", "stdio" ++ path.sep_str ++ "_wfindfirst64i32.c", "stdio" ++ path.sep_str ++ "_wfindnext64i32.c", - "stdio" ++ path.sep_str ++ "_wstat.c", "stdio" ++ path.sep_str ++ "_wstat64i32.c", + "stdio" ++ path.sep_str ++ "__mingw_fix_stat_path.c", + "stdio" ++ path.sep_str ++ "__mingw_fix_wstat_path.c", "stdio" ++ path.sep_str ++ "asprintf.c", "stdio" ++ path.sep_str ++ "fopen64.c", "stdio" ++ path.sep_str ++ "fseeko32.c", @@ -749,23 +752,36 @@ const mingw32_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "ucrt__vscprintf.c", "stdio" ++ path.sep_str ++ "ucrt__vsnprintf.c", "stdio" ++ path.sep_str ++ "ucrt__vsnwprintf.c", + "stdio" ++ path.sep_str ++ "ucrt___local_stdio_printf_options.c", + "stdio" ++ path.sep_str ++ "ucrt___local_stdio_scanf_options.c", "stdio" ++ path.sep_str ++ "ucrt_fprintf.c", "stdio" ++ path.sep_str ++ "ucrt_fscanf.c", "stdio" ++ path.sep_str ++ "ucrt_fwprintf.c", - "stdio" ++ path.sep_str ++ "ucrt_ms_fprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_fwscanf.c", "stdio" ++ path.sep_str ++ "ucrt_ms_fwprintf.c", "stdio" ++ path.sep_str ++ "ucrt_printf.c", "stdio" ++ path.sep_str ++ "ucrt_scanf.c", "stdio" ++ path.sep_str ++ "ucrt_snprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_snwprintf.c", "stdio" ++ path.sep_str ++ "ucrt_sprintf.c", "stdio" ++ path.sep_str ++ "ucrt_sscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_swscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_swprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vfprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vfscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_vfwscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_vfwprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vscanf.c", "stdio" ++ path.sep_str ++ "ucrt_vsnprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_vsnwprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vsprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_vswprintf.c", "stdio" ++ path.sep_str ++ "ucrt_vsscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_vwscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_wscanf.c", + "stdio" ++ path.sep_str ++ "ucrt_vwprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_wprintf.c", "string" ++ path.sep_str ++ "ucrt__wcstok.c", // uuid "libsrc" ++ path.sep_str ++ "ativscp-uuid.c", @@ -889,6 +905,8 @@ const mingw32_generic_src = [_][]const u8{ }; const mingw32_x86_src = [_][]const u8{ + // mingw32 + "crt" ++ path.sep_str ++ "CRT_fp10.c", // mingwex "math" ++ path.sep_str ++ "cbrtl.c", "math" ++ path.sep_str ++ "erfl.c", @@ -971,11 +989,11 @@ const mingw32_x86_32_src = [_][]const u8{ const mingw32_arm_src = [_][]const u8{ // mingwex "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ldexpl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "sincosl.c", }; const mingw32_arm32_src = [_][]const u8{ // mingwex - "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rint.c", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rintf.c", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "sincos.S", @@ -983,7 +1001,6 @@ const mingw32_arm32_src = [_][]const u8{ const mingw32_arm64_src = [_][]const u8{ // mingwex - "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "sincos.S", @@ -997,7 +1014,6 @@ const mingw32_winpthreads_src = [_][]const u8{ "winpthreads" ++ path.sep_str ++ "misc.c", "winpthreads" ++ path.sep_str ++ "mutex.c", "winpthreads" ++ path.sep_str ++ "nanosleep.c", - "winpthreads" ++ path.sep_str ++ "ref.c", "winpthreads" ++ path.sep_str ++ "rwlock.c", "winpthreads" ++ path.sep_str ++ "sched.c", "winpthreads" ++ path.sep_str ++ "sem.c",