| /** | |
| * 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. | |
| */ | |
| #ifndef _INC_INTERNAL | |
| #define _INC_INTERNAL | |
| #include <crtdefs.h> | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| #include <limits.h> | |
| #include <fenv.h> | |
| #include <windows.h> | |
| #define __IOINFO_TM_ANSI 0 | |
| #define __IOINFO_TM_UTF8 1 | |
| #define __IOINFO_TM_UTF16LE 2 | |
| #ifdef _MSC_VER | |
| #pragma warning(push) | |
| #pragma warning(disable:4214) | |
| #pragma warning(disable:4820) | |
| #endif | |
| typedef struct { | |
| intptr_t osfhnd; | |
| char osfile; | |
| char pipech; | |
| int lockinitflag; | |
| CRITICAL_SECTION lock; | |
| char textmode : 7; | |
| char unicode : 1; | |
| char pipech2[2]; | |
| } ioinfo; | |
| #ifdef _MSC_VER | |
| #pragma warning(pop) | |
| #endif | |
| #define IOINFO_ARRAY_ELTS (1 << 5) | |
| #define _pioinfo(i) (__pioinfo[(i) >> 5] + ((i) & (IOINFO_ARRAY_ELTS - 1))) | |
| #define _osfile(i) (_pioinfo(i)->osfile) | |
| #define _pipech2(i) (_pioinfo(i)->pipech2) | |
| #define _textmode(i) (_pioinfo(i)->textmode) | |
| #define _tm_unicode(i) (_pioinfo(i)->unicode) | |
| #define _pioinfo_safe(i) ((((i) != -1) && ((i) != -2)) ? _pioinfo(i) : &__badioinfo) | |
| #define _osfhnd_safe(i) (_pioinfo_safe(i)->osfhnd) | |
| #define _osfile_safe(i) (_pioinfo_safe(i)->osfile) | |
| #define _pipech_safe(i) (_pioinfo_safe(i)->pipech) | |
| #define _pipech2_safe(i) (_pioinfo_safe(i)->pipech2) | |
| #define _textmode_safe(i) (_pioinfo_safe(i)->textmode) | |
| #define _tm_unicode_safe(i) (_pioinfo_safe(i)->unicode) | |
| #ifndef __badioinfo | |
| extern ioinfo * __MINGW_IMP_SYMBOL(__badioinfo); | |
| #define __badioinfo (* __MINGW_IMP_SYMBOL(__badioinfo)) | |
| #endif | |
| #ifndef __pioinfo | |
| extern ioinfo ** __MINGW_IMP_SYMBOL(__pioinfo)[]; | |
| #define __pioinfo (* __MINGW_IMP_SYMBOL(__pioinfo)) | |
| #endif | |
| #define _NO_CONSOLE_FILENO (intptr_t)-2 | |
| #ifndef _FILE_DEFINED | |
| #define _FILE_DEFINED | |
| struct _iobuf { | |
| char *_ptr; | |
| int _cnt; | |
| char *_base; | |
| int _flag; | |
| int _file; | |
| int _charbuf; | |
| int _bufsiz; | |
| char *_tmpfname; | |
| }; | |
| typedef struct _iobuf FILE; | |
| #endif | |
| #if !defined (_FILEX_DEFINED) && defined (_WINDOWS_) | |
| #define _FILEX_DEFINED | |
| typedef struct { | |
| FILE f; | |
| CRITICAL_SECTION lock; | |
| } _FILEX; | |
| #endif | |
| extern int _dowildcard; | |
| extern int _newmode; | |
| _CRTIMP wchar_t *** __cdecl __p___winitenv(void); | |
| #define __winitenv (*__p___winitenv()) | |
| _CRTIMP char *** __cdecl __p___initenv(void); | |
| #define __initenv (*__p___initenv()) | |
| _CRTIMP void __cdecl _amsg_exit(int) __MINGW_ATTRIB_NORETURN; | |
| int __CRTDECL _setargv(void); | |
| int __CRTDECL __setargv(void); | |
| int __CRTDECL _wsetargv(void); | |
| int __CRTDECL __wsetargv(void); | |
| int __CRTDECL main(int _Argc, char **_Argv, char **_Env); | |
| int __CRTDECL wmain(int _Argc, wchar_t **_Argv, wchar_t **_Env); | |
| #ifndef _STARTUP_INFO_DEFINED | |
| #define _STARTUP_INFO_DEFINED | |
| typedef struct { | |
| int newmode; | |
| } _startupinfo; | |
| #endif | |
| _CRTIMP int __cdecl __getmainargs(int * _Argc, char *** _Argv, char ***_Env, int _DoWildCard, _startupinfo *_StartInfo); | |
| _CRTIMP int __cdecl __wgetmainargs(int * _Argc, wchar_t ***_Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo *_StartInfo); | |
| #define _CONSOLE_APP 1 | |
| #define _GUI_APP 2 | |
| typedef enum __enative_startup_state { | |
| __uninitialized = 0, __initializing, __initialized | |
| } __enative_startup_state; | |
| extern volatile __enative_startup_state __native_startup_state; | |
| extern void *volatile __native_startup_lock; | |
| extern volatile unsigned int __native_dllmain_reason; | |
| extern volatile unsigned int __native_vcclrit_reason; | |
| _CRTIMP void __cdecl __set_app_type (int); | |
| typedef LONG NTSTATUS; | |
| #include <crtdbg.h> | |
| #include <errno.h> | |
| #if defined(__SSE__) | |
| # define __mingw_has_sse() 1 | |
| #elif defined(__i386__) | |
| int __mingw_has_sse(void); | |
| #else | |
| # 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 | |
| #if (defined(__GNUC__) && __GNUC__ >= 8) || \ | |
| (defined(__clang_major__) && __clang_major__ >= 23) | |
| #define PRAGMA_DIAGNOSTIC_IGNORED_ATTRIBUTE_ALIAS_BEGIN \ | |
| _Pragma("GCC diagnostic push") \ | |
| _Pragma("GCC diagnostic ignored \"-Wattribute-alias\"") | |
| #define PRAGMA_DIAGNOSTIC_IGNORED_ATTRIBUTE_ALIAS_END \ | |
| _Pragma ("GCC diagnostic pop") | |
| #else | |
| #define PRAGMA_DIAGNOSTIC_IGNORED_ATTRIBUTE_ALIAS_BEGIN | |
| #define PRAGMA_DIAGNOSTIC_IGNORED_ATTRIBUTE_ALIAS_END | |
| #endif | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif |