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.bender@gmail.com>
Signed-off-by: LIU Hao <lh_mouse@126.com>
This commit is contained in:
LIU Hao 2024-10-22 23:16:04 +08:00
parent e9a763950a
commit 7a9b6e1616
10 changed files with 68 additions and 63 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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__ */

View File

@ -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 <internal.h>
/* 7.6.2.1
The feclearexcept function clears the supported exceptions

View File

@ -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

View File

@ -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.2
The fegetexceptflag function stores an implementation-defined

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -5,10 +5,7 @@
*/
#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 <internal.h>
/* 7.6.2.5
The fetestexcept function determines which of a specified subset of