mirror of
https://git.code.sf.net/p/mingw-w64/mingw-w64
synced 2024-11-23 01:44:43 +08:00
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:
parent
e9a763950a
commit
7a9b6e1616
@ -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 \
|
||||
|
@ -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
|
||||
|
37
mingw-w64-crt/misc/__mingw_has_sse.c
Normal file
37
mingw-w64-crt/misc/__mingw_has_sse.c
Normal 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__ */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
#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.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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user