Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stefan Strogin
flac
Commits
99d5154f
Commit
99d5154f
authored
Mar 14, 2014
by
Erik de Castro Lopo
Browse files
libFLAC/cpu.c : Detect SSE correctly on Windows when compiling with MinGW.
Patch-from: lvqcl <lvqcl.mail@gmail.com>
parent
47bd9964
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/libFLAC/cpu.c
View file @
99d5154f
...
...
@@ -151,6 +151,23 @@ static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
return
EXCEPTION_CONTINUE_SEARCH
;
}
# endif
# elif defined(_WIN32) && defined(__GNUC__)
# undef USE_FXSR_FLAVOR
# ifdef USE_FXSR_FLAVOR
/* not guaranteed to work on some unknown future Intel CPUs */
# else
/* exception handler is process-wide; not good for a library */
# include <windows.h>
LONG
WINAPI
sigill_handler_sse_os
(
EXCEPTION_POINTERS
*
ep
);
/* to suppress GCC warning */
LONG
WINAPI
sigill_handler_sse_os
(
EXCEPTION_POINTERS
*
ep
)
{
if
(
ep
->
ExceptionRecord
->
ExceptionCode
==
EXCEPTION_ILLEGAL_INSTRUCTION
)
{
ep
->
ContextRecord
->
Eip
+=
3
+
3
+
6
;
return
EXCEPTION_CONTINUE_EXECUTION
;
}
return
EXCEPTION_CONTINUE_SEARCH
;
}
# endif
# endif
#endif
...
...
@@ -332,6 +349,55 @@ void FLAC__cpu_info(FLAC__CPUInfo *info)
if
(
!
sse
)
info
->
ia32
.
fxsr
=
info
->
ia32
.
sse
=
info
->
ia32
.
sse2
=
info
->
ia32
.
sse3
=
info
->
ia32
.
ssse3
=
info
->
ia32
.
sse41
=
info
->
ia32
.
sse42
=
false
;
# endif
#elif defined(_WIN32) && defined(__GNUC__)
# ifdef USE_FXSR_FLAVOR
int
sse
=
0
;
/* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */
/* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */
if
(
info
->
ia32
.
fxsr
&&
info
->
ia32
.
sse
)
{
struct
{
FLAC__uint32
buff
[
128
];
}
__attribute__
((
aligned
(
16
)))
fxsr
;
FLAC__uint32
old_val
,
new_val
;
asm
volatile
(
"fxsave %0"
:
"=m"
(
fxsr
)
:
"m"
(
fxsr
));
old_val
=
fxsr
.
buff
[
50
];
fxsr
.
buff
[
50
]
^=
0x0013c0de
;
/* change value in the buffer */
asm
volatile
(
"fxrstor %0"
:
"=m"
(
fxsr
)
:
"m"
(
fxsr
));
/* try to change SSE register */
fxsr
.
buff
[
50
]
=
old_val
;
/* restore old value in the buffer */
asm
volatile
(
"fxsave %0 "
:
"=m"
(
fxsr
)
:
"m"
(
fxsr
));
/* old value will be overwritten if SSE register was changed */
new_val
=
fxsr
.
buff
[
50
];
/* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */
fxsr
.
buff
[
50
]
=
old_val
;
/* again restore old value in the buffer */
asm
volatile
(
"fxrstor %0"
:
"=m"
(
fxsr
)
:
"m"
(
fxsr
));
/* restore old values of registers */
if
((
old_val
^
new_val
)
==
0x0013c0de
)
sse
=
1
;
}
if
(
!
sse
)
info
->
ia32
.
fxsr
=
info
->
ia32
.
sse
=
info
->
ia32
.
sse2
=
info
->
ia32
.
sse3
=
info
->
ia32
.
ssse3
=
info
->
ia32
.
sse41
=
info
->
ia32
.
sse42
=
false
;
# else
int
sse
=
0
;
LPTOP_LEVEL_EXCEPTION_FILTER
save
=
SetUnhandledExceptionFilter
(
sigill_handler_sse_os
);
/* see MSVC version above for explanation */
asm
volatile
(
"xorps %%xmm0,%%xmm0
\n\t
"
"incl %0
\n\t
"
"nop
\n\t
"
/* SIGILL jump lands here if "inc" is 9 bytes */
"nop
\n\t
"
"nop
\n\t
"
"nop
\n\t
"
"nop
\n\t
"
"nop
\n\t
"
"nop
\n\t
"
"nop
\n\t
"
"nop"
/* SIGILL jump lands here if "inc" is 1 byte */
:
"=r"
(
sse
)
:
"0"
(
sse
)
);
SetUnhandledExceptionFilter
(
save
);
if
(
!
sse
)
info
->
ia32
.
fxsr
=
info
->
ia32
.
sse
=
info
->
ia32
.
sse2
=
info
->
ia32
.
sse3
=
info
->
ia32
.
ssse3
=
info
->
ia32
.
sse41
=
info
->
ia32
.
sse42
=
false
;
# endif
#else
/* no way to test, disable to be safe */
info
->
ia32
.
fxsr
=
info
->
ia32
.
sse
=
info
->
ia32
.
sse2
=
info
->
ia32
.
sse3
=
info
->
ia32
.
ssse3
=
info
->
ia32
.
sse41
=
info
->
ia32
.
sse42
=
false
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment