1#if defined(__sun__) && defined(__svr4__)
2/* Make sure sigaction() is declared even with -std=c99.  */
3#define __EXTENSIONS__
4#include <signal.h>
5#include <ucontext.h>
6
7static volatile sig_atomic_t sigill_caught;
8
9static void
10sigill_hdlr (int sig __attribute((unused)),
11	     siginfo_t *sip __attribute__((unused)),
12	     ucontext_t *ucp)
13{
14  sigill_caught = 1;
15  /* Set PC to the instruction after the faulting one to skip over it,
16     otherwise we enter an infinite loop.  */
17  ucp->uc_mcontext.gregs[EIP] += 4;
18  setcontext (ucp);
19}
20#endif
21
22/* Check if the OS supports executing SSE instructions.  This function is
23   only used in sse-check.h, sse2-check.h, and sse3-check.h so far since
24   Solaris 8 and 9 won't run on newer CPUs anyway.  */
25
26static int
27sse_os_support (void)
28{
29#if defined(__sun__) && defined(__svr4__)
30  /* Solaris 2 before Solaris 9 4/04 cannot execute SSE instructions
31     even if the CPU supports them.  Programs receive SIGILL instead, so
32     check for that at runtime.  */
33
34  struct sigaction act, oact;
35
36  act.sa_handler = sigill_hdlr;
37  sigemptyset (&act.sa_mask);
38  /* Need to set SA_SIGINFO so a ucontext_t * is passed to the handler.  */
39  act.sa_flags = SA_SIGINFO;
40  sigaction (SIGILL, &act, &oact);
41
42  /* We need a single SSE instruction here so the handler can safely skip
43     over it.  */
44  __asm__ volatile ("movss %xmm2,%xmm1");
45
46  sigaction (SIGILL, &oact, NULL);
47
48  if (sigill_caught)
49    exit (0);
50  else
51    return 1;
52#else
53  return 1;
54#endif /* __sun__ && __svr4__ */
55}
56