在 2024-10-22 22:18, Jacek Caban 写道:
Style-wise, I would perhaps prefer a solution that uses fewer #ifdefs. We could for example change __mingw_has_sse to always return true when it's defined. It would limit optimization opportunities for the compiler, so perhaps we could have it in a header and make it a trivial inline in case __SSE__ is defined? Anyway, the current patch matches how similar things are done in mingw-w64, so I won't insist on that.Even with that patch, the original patch caching cpuid result would still be beneficial for cases when __SSE__ is not defined.
Here's an updated patch. -- Best regards, LIU Hao
From d54cc9e99b4f6130d6e6ac7ac4aaf077026fcb6d Mon Sep 17 00:00:00 2001 From: LIU Hao <lh_mo...@126.com> Date: Tue, 22 Oct 2024 23:16:04 +0800 Subject: [PATCH] crt: Provide a common `__mingw_has_sse()` This commit moves `__mingw_has_sse()` to a separate file, and makes its result cacheable. SSE is required for x86-64, and can be enabled for x86-32 by passing `-msse` to GCC. On ARM and ARM64 it's always absent. A macro is defined if it would be known to return a constant. Co-authored-by: Morilli <molli.ben...@gmail.com> Signed-off-by: LIU Hao <lh_mo...@126.com> --- mingw-w64-crt/Makefile.am | 2 +- mingw-w64-crt/include/internal.h | 8 ++++++ mingw-w64-crt/misc/__mingw_has_sse.c | 37 ++++++++++++++++++++++++++++ mingw-w64-crt/misc/feclearexcept.c | 31 ++--------------------- mingw-w64-crt/misc/fegetenv.c | 6 ++--- mingw-w64-crt/misc/fegetexceptflag.c | 10 +++----- mingw-w64-crt/misc/fesetenv.c | 10 +++----- mingw-w64-crt/misc/fesetexceptflag.c | 10 +++----- mingw-w64-crt/misc/fesetround.c | 8 +++--- mingw-w64-crt/misc/fetestexcept.c | 9 +++---- 10 files changed, 68 insertions(+), 63 deletions(-) create mode 100644 mingw-w64-crt/misc/__mingw_has_sse.c diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 7db657ed7..b5e23e084 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -1044,7 +1044,7 @@ src_libmingwex=\ misc/feclearexcept.c misc/fegetenv.c misc/fegetexceptflag.c misc/fegetround.c misc/feholdexcept.c \ misc/feraiseexcept.c misc/fesetenv.c misc/fesetexceptflag.c misc/fesetround.c misc/fetestexcept.c \ misc/feupdateenv.c misc/ftruncate.c misc/fwide.c misc/getlogin.c misc/getopt.c \ - misc/gettimeofday.c \ + misc/gettimeofday.c misc/__mingw_has_sse.c \ misc/mempcpy.c misc/mingw-aligned-malloc.c \ misc/mingw_matherr.c misc/mingw_mbwc_convert.c misc/mingw_usleep.c misc/mingw_wcstod.c misc/mingw_wcstof.c \ misc/mingw_wcstold.c \ diff --git a/mingw-w64-crt/include/internal.h b/mingw-w64-crt/include/internal.h index 3786ed7a1..752c5dc96 100644 --- a/mingw-w64-crt/include/internal.h +++ b/mingw-w64-crt/include/internal.h @@ -146,6 +146,14 @@ extern "C" { PIMAGE_SECTION_HEADER __cdecl _FindPESection (PBYTE pImageBase, DWORD_PTR rva); BOOL __cdecl _IsNonwritableInCurrentImage (PBYTE pTarget); +#if defined(__SSE__) +# define __mingw_has_sse() 1 +#elif defined(__i386__) + int __mingw_has_sse(void); +#else +# define __mingw_has_sse() 0 +#endif + #ifdef __cplusplus } #endif diff --git a/mingw-w64-crt/misc/__mingw_has_sse.c b/mingw-w64-crt/misc/__mingw_has_sse.c new file mode 100644 index 000000000..e8e8a7059 --- /dev/null +++ b/mingw-w64-crt/misc/__mingw_has_sse.c @@ -0,0 +1,37 @@ +/** + * 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. + */ + +#if defined(__i386__) +int __mingw_has_sse (void); +static int __has_sse = -1; + +int __mingw_has_sse(void) +{ + int cpuInfo[4], infoType = 1; + int o_flag, n_flag; + + if (__has_sse != -1) + return __has_sse; + + __asm__ volatile ("pushfl\n\tpopl %0" : "=mr" (o_flag)); + n_flag = o_flag ^ 0x200000; + __asm__ volatile ("pushl %0\n\tpopfl" : : "g" (n_flag)); + __asm__ volatile ("pushfl\n\tpopl %0" : "=mr" (n_flag)); + if (n_flag == o_flag) + { + __has_sse = 0; + return 0; + } + + __asm__ __volatile__ ( + "cpuid" + : "=a" (cpuInfo[0]), "=b" (cpuInfo[1]), "=c" (cpuInfo[2]), + "=d" (cpuInfo[3]) + : "a" (infoType)); + __has_sse = (cpuInfo[3] & 0x2000000); + return __has_sse; +} +#endif /* __i386__ */ diff --git a/mingw-w64-crt/misc/feclearexcept.c b/mingw-w64-crt/misc/feclearexcept.c index 673528b20..a5ab0f095 100644 --- a/mingw-w64-crt/misc/feclearexcept.c +++ b/mingw-w64-crt/misc/feclearexcept.c @@ -3,36 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> - -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -int __mingw_has_sse (void); -int __mingw_has_sse(void) -{ - int cpuInfo[4],infoType = 1; - -#ifndef _WIN64 - int o_flag, n_flag; - - __asm__ volatile ("pushfl\n\tpopl %0" : "=mr" (o_flag)); - n_flag = o_flag ^ 0x200000; - __asm__ volatile ("pushl %0\n\tpopfl" : : "g" (n_flag)); - __asm__ volatile ("pushfl\n\tpopl %0" : "=mr" (n_flag)); - if (n_flag == o_flag) - return 0; -#endif - - __asm__ __volatile__ ( - "cpuid" - : "=a" (cpuInfo[0]), "=b" (cpuInfo[1]), "=c" (cpuInfo[2]), - "=d" (cpuInfo[3]) - : "a" (infoType)); - if (cpuInfo[3] & 0x2000000) - return 1; - return 0; -} -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <fenv.h> +#include <internal.h> /* 7.6.2.1 The feclearexcept function clears the supported exceptions diff --git a/mingw-w64-crt/misc/fegetenv.c b/mingw-w64-crt/misc/fegetenv.c index 31960816e..e17fd491c 100644 --- a/mingw-w64-crt/misc/fegetenv.c +++ b/mingw-w64-crt/misc/fegetenv.c @@ -3,11 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <fenv.h> +#include <internal.h> /* 7.6.4.1 The fegetenv function stores the current floating-point environment diff --git a/mingw-w64-crt/misc/fegetexceptflag.c b/mingw-w64-crt/misc/fegetexceptflag.c index eaa940a2a..b50ca6fc1 100644 --- a/mingw-w64-crt/misc/fegetexceptflag.c +++ b/mingw-w64-crt/misc/fegetexceptflag.c @@ -3,13 +3,11 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -extern int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <fenv.h> +#include <internal.h> -/* 7.6.2.2 +/* 7.6.2.2 The fegetexceptflag function stores an implementation-defined representation of the exception flags indicated by the argument excepts in the object pointed to by the argument flagp. */ @@ -32,7 +30,7 @@ int fegetexceptflag (fexcept_t * flagp, int excepts) _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; diff --git a/mingw-w64-crt/misc/fesetenv.c b/mingw-w64-crt/misc/fesetenv.c index a3279bddd..76325ce37 100644 --- a/mingw-w64-crt/misc/fesetenv.c +++ b/mingw-w64-crt/misc/fesetenv.c @@ -3,13 +3,11 @@ * 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.h> #include <fenv.h> #include <float.h> - -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -extern int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <internal.h> /* 7.6.4.3 The fesetenv function establishes the floating-point environment @@ -28,7 +26,7 @@ int fesetenv (const fenv_t * envp) { #if defined(_ARM_) || defined(__arm__) if (envp == FE_DFL_ENV) - /* Use the choice made at app startup */ + /* Use the choice made at app startup */ _fpreset(); else __asm__ volatile ("fmxr FPSCR, %0" : : "r" (*envp)); @@ -59,7 +57,7 @@ int fesetenv (const fenv_t * envp) (* __MINGW_IMP_SYMBOL(_fpreset))(); else if (envp == FE_DFL_ENV) - /* Use the choice made at app startup */ + /* Use the choice made at app startup */ _fpreset(); else diff --git a/mingw-w64-crt/misc/fesetexceptflag.c b/mingw-w64-crt/misc/fesetexceptflag.c index 7e3361c6a..095dfea0b 100644 --- a/mingw-w64-crt/misc/fesetexceptflag.c +++ b/mingw-w64-crt/misc/fesetexceptflag.c @@ -3,11 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -extern int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <fenv.h> +#include <internal.h> /* 7.6.2.4 The fesetexceptflag function sets the complete status for those @@ -16,9 +14,9 @@ extern int __mingw_has_sse (void); *flagp shall have been set by a previous call to fegetexceptflag whose second argument represented at least those exceptions represented by the argument excepts. This function does not raise - exceptions, but only sets the state of the flags. */ + exceptions, but only sets the state of the flags. */ -int fesetexceptflag (const fexcept_t * flagp, int excepts) +int fesetexceptflag (const fexcept_t * flagp, int excepts) { fenv_t _env; diff --git a/mingw-w64-crt/misc/fesetround.c b/mingw-w64-crt/misc/fesetround.c index 624a9997d..e51f46cd7 100644 --- a/mingw-w64-crt/misc/fesetround.c +++ b/mingw-w64-crt/misc/fesetround.c @@ -3,11 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ +#include <fenv.h> +#include <internal.h> /* 7.6.3.2 The fesetround function establishes the rounding direction @@ -42,7 +40,7 @@ int fesetround (int mode) _cw &= ~0xc00; _cw |= mode; __asm__ volatile ("fldcw %0;" : : "m" (*&_cw)); - + if (__mingw_has_sse ()) { int mxcsr; diff --git a/mingw-w64-crt/misc/fetestexcept.c b/mingw-w64-crt/misc/fetestexcept.c index da073e6d0..04e75970f 100644 --- a/mingw-w64-crt/misc/fetestexcept.c +++ b/mingw-w64-crt/misc/fetestexcept.c @@ -4,13 +4,10 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#include <fenv.h> +#include <fenv.h> +#include <internal.h> -#if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) -extern int __mingw_has_sse (void); -#endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ - -/* 7.6.2.5 +/* 7.6.2.5 The fetestexcept function determines which of a specified subset of the exception flags are currently set. The excepts argument specifies the exception flags to be queried. -- 2.47.0
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public