1  /* Check if system supports SIMD */
       2  #include <signal.h>
       3  
       4  #if defined(__i386__) || defined(__x86_64__)
       5  # include "cpuid.h"
       6  #endif
       7  
       8  #ifdef __cplusplus
       9  extern "C" {
      10  #endif
      11  extern void abort (void);
      12  extern void exit (int);
      13  #ifdef __cplusplus
      14  }
      15  #endif
      16  
      17  static void
      18  sig_ill_handler (int sig)
      19  {
      20    exit(0);
      21  }
      22  
      23  static void __attribute__((noinline))
      24  check_vect (void)
      25  {
      26    signal(SIGILL, sig_ill_handler);
      27  #if defined(__PAIRED__)
      28    /* 750CL paired-single instruction, 'ps_mul %v0,%v0,%v0'.  */
      29   asm volatile (".long 0x10000032");
      30  #elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc)
      31    /* Altivec instruction, 'vor %v0,%v0,%v0'.  */
      32    asm volatile (".long 0x10000484");
      33  #elif defined(__i386__) || defined(__x86_64__)
      34    {
      35      unsigned int a, b, c, d,
      36        want_level, want_b = 0, want_c = 0, want_d = 0;
      37  
      38      /* Determine what instruction set we've been compiled for, and detect
      39         that we're running with it.  This allows us to at least do a compile
      40         check for, e.g. SSE4.1 when the machine only supports SSE2.  */
      41  # if defined(__AVX2__)
      42      want_level = 7, want_b = bit_AVX2;
      43  # elif defined(__AVX__)
      44      want_level = 1, want_c = bit_AVX;
      45  # elif defined(__SSE4_2__)
      46      want_level = 1, want_c = bit_SSE4_2;
      47  # elif defined(__SSE4_1__)
      48      want_level = 1, want_c = bit_SSE4_1;
      49  # elif defined(__SSSE3__)
      50      want_level = 1, want_c = bit_SSSE3;
      51  # else
      52      want_level = 1, want_d = bit_SSE2;
      53  # endif
      54  
      55      if (!__get_cpuid_count (want_level, 0, &a, &b, &c, &d)
      56  	|| ((b & want_b) | (c & want_c) | (d & want_d)) == 0)
      57        exit (0);
      58    }
      59  #elif defined(__sparc__)
      60    asm volatile (".word\t0x81b007c0");
      61  #elif defined(__arm__)
      62    {
      63      /* On some processors without NEON support, this instruction may
      64         be a no-op, on others it may trap, so check that it executes
      65         correctly.  */
      66      long long a = 0, b = 1;
      67      asm ("vorr %P0, %P1, %P2"
      68  	 : "=w" (a)
      69  	 : "0" (a), "w" (b));
      70      if (a != 1)
      71        exit (0);
      72    }
      73  #elif defined(__mips_msa)
      74    asm volatile ("or.v $w0,$w0,$w0");
      75  #endif
      76    signal (SIGILL, SIG_DFL);
      77  }
      78  
      79  #if defined (__ARM_FEATURE_SVE)
      80  #  if __ARM_FEATURE_SVE_BITS == 0
      81  #    define VECTOR_BITS 1024
      82  #  else
      83  #    define VECTOR_BITS __ARM_FEATURE_SVE_BITS
      84  #  endif
      85  #else
      86  #  define VECTOR_BITS 128
      87  #endif
      88  
      89  /* Which most of our tests are going to #define for internal use, and
      90     which might be exposed by system headers related to signal.h on some
      91     targets, notably VxWorks.  */
      92  #undef OFFSET
      93