evas_cpu: Avoid SIGILL in evas startup on x86

Summary:
To determine if a system supports SIMD instructions, the cpuid facility
should be used.  However, for 15+ years EFL has been trapping SIGILL,
then attempting to execute these intstructions.

Continuing after SIGILL is explicitly undefined behaviour and can never
safely be relied upon - it is possible the CPU will respond to the
unknown instruction in an upredictable way and the program will not
continue correctly.  Even if it hasn't caused problems before, there's
no reason to believe a processor released in the future won't behave
differently.

Lately we've had a couple of bug tickets where SIGILL appears to cause
problems at a system level as well, but there seems little point in
chasing those problems down as we shouldn't even be doing this in the
first place.

ref T6711
ref T6989

We still rely on SIGILL in a few configurations where eina_cpu doesn't
know how to query features properly (powerpc, sparc, and non linux
ARM configurations).  Hopefully someone with expertise on those
platforms can follow up and we can remove this entirely.

Note: MMX2 appears to not really be a thing, and is instead provided by
both 3DNow! and SSE.  We already conflate it with SSE in other parts of
evas, so I've just used SSE here to test for its presence.
Depends on D6313

Reviewers: devilhorns, zmike

Reviewed By: zmike

Subscribers: cedric, #committers, zmike

Tags: #efl

Maniphest Tasks: T6989, T6711

Differential Revision: https://phab.enlightenment.org/D6314
This commit is contained in:
Derek Foreman 2018-06-18 15:12:41 -05:00
parent 1d8a93aa78
commit 6b1ab3cd9c
1 changed files with 6 additions and 68 deletions

View File

@ -1,15 +1,9 @@
#include "evas_common_private.h"
#ifdef BUILD_MMX
#include "evas_mmx.h"
#endif
#ifdef BUILD_NEON
#ifdef BUILD_NEON_INTRINSICS
#include <arm_neon.h>
#endif
#endif
#if defined BUILD_SSE3
#include <immintrin.h>
#endif
#if defined (HAVE_STRUCT_SIGACTION) && defined (HAVE_SIGLONGJMP)
#include <signal.h>
@ -38,46 +32,6 @@ evas_common_cpu_catch_segv(int sig EINA_UNUSED)
}
#endif
void
evas_common_cpu_mmx_test(void)
{
#ifdef BUILD_MMX
pxor_r2r(mm4, mm4);
#endif
}
void
evas_common_cpu_mmx2_test(void)
{
#ifdef BUILD_MMX
char data[16];
data[0] = 0;
mmx_r2m(movntq, mm0, data);
data[0] = 0;
#endif
}
void
evas_common_cpu_sse_test(void)
{
#ifdef BUILD_MMX
int blah[16];
movntq_r2m(mm0, blah);
#endif
}
void evas_common_op_sse3_test(void);
void
evas_common_cpu_sse3_test(void)
{
#ifdef BUILD_SSE3
evas_common_op_sse3_test();
#endif
}
#ifdef BUILD_ALTIVEC
void
evas_common_cpu_altivec_test(void)
@ -181,36 +135,20 @@ evas_common_cpu_init(void)
if (getenv("EVAS_CPU_NO_MMX"))
cpu_feature_mask &= ~CPU_FEATURE_MMX;
else
{
cpu_feature_mask |= CPU_FEATURE_MMX *
evas_common_cpu_feature_test(evas_common_cpu_mmx_test);
evas_common_cpu_end_opt();
}
cpu_feature_mask |= _cpu_check(EINA_CPU_MMX) * CPU_FEATURE_MMX;
if (getenv("EVAS_CPU_NO_MMX2"))
cpu_feature_mask &= ~CPU_FEATURE_MMX2;
else
{
cpu_feature_mask |= CPU_FEATURE_MMX2 *
evas_common_cpu_feature_test(evas_common_cpu_mmx2_test);
evas_common_cpu_end_opt();
}
else /* It seems "MMX2" is actually part of SSE (and 3DNow)? */
cpu_feature_mask |= _cpu_check(EINA_CPU_SSE) * CPU_FEATURE_MMX2;
if (getenv("EVAS_CPU_NO_SSE"))
cpu_feature_mask &= ~CPU_FEATURE_SSE;
else
{
cpu_feature_mask |= CPU_FEATURE_SSE *
evas_common_cpu_feature_test(evas_common_cpu_sse_test);
evas_common_cpu_end_opt();
}
cpu_feature_mask |= _cpu_check(EINA_CPU_SSE) * CPU_FEATURE_SSE;
# ifdef BUILD_SSE3
if (getenv("EVAS_CPU_NO_SSE3"))
cpu_feature_mask &= ~CPU_FEATURE_SSE3;
cpu_feature_mask &= ~CPU_FEATURE_SSE3;
else
{
cpu_feature_mask |= CPU_FEATURE_SSE3 *
evas_common_cpu_feature_test(evas_common_cpu_sse3_test);
evas_common_cpu_end_opt();
}
cpu_feature_mask |= _cpu_check(EINA_CPU_SSE3) * CPU_FEATURE_SSE3;
# endif /* BUILD_SSE3 */
#endif /* BUILD_MMX */
#ifdef BUILD_ALTIVEC