Blame gegl/gegl-cpuaccel.c

Packit Service 2781ba
/* GEGL - The GEGL Library
Packit Service 2781ba
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
Packit Service 2781ba
 *
Packit Service 2781ba
 * This library is free software; you can redistribute it and/or
Packit Service 2781ba
 * modify it under the terms of the GNU Lesser General Public
Packit Service 2781ba
 * License as published by the Free Software Foundation; either
Packit Service 2781ba
 * version 3 of the License, or (at your option) any later version.
Packit Service 2781ba
 *
Packit Service 2781ba
 * This library is distributed in the hope that it will be useful,
Packit Service 2781ba
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 2781ba
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 2781ba
 * Lesser General Public License for more details.
Packit Service 2781ba
 *
Packit Service 2781ba
 * You should have received a copy of the GNU Lesser General Public
Packit Service 2781ba
 * License along with this library; if not, write to the
Packit Service 2781ba
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit Service 2781ba
 * Boston, MA 02110-1301, USA.
Packit Service 2781ba
 */
Packit Service 2781ba
Packit Service 2781ba
/*
Packit Service 2781ba
 * x86 bits Copyright (C) Manish Singh <yosh@gimp.org>
Packit Service 2781ba
 */
Packit Service 2781ba
Packit Service 2781ba
/*
Packit Service 2781ba
 * PPC CPU acceleration detection was taken from DirectFB but seems to be
Packit Service 2781ba
 * originating from mpeg2dec with the following copyright:
Packit Service 2781ba
 *
Packit Service 2781ba
 * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
Packit Service 2781ba
 */
Packit Service 2781ba
Packit Service 2781ba
#include "config.h"
Packit Service 2781ba
Packit Service 2781ba
#include <string.h>
Packit Service 2781ba
#include <signal.h>
Packit Service 2781ba
#include <setjmp.h>
Packit Service 2781ba
Packit Service 2781ba
#include <glib.h>
Packit Service 2781ba
Packit Service 2781ba
#include "gegl-cpuaccel.h"
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
static GeglCpuAccelFlags  cpu_accel (void) G_GNUC_CONST;
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
static gboolean  use_cpu_accel = TRUE;
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
/**
Packit Service 2781ba
 * gegl_cpu_accel_get_support:
Packit Service 2781ba
 *
Packit Service 2781ba
 * Query for CPU acceleration support.
Packit Service 2781ba
 *
Packit Service 2781ba
 * Return value: #GeglCpuAccelFlags as supported by the CPU.
Packit Service 2781ba
 *
Packit Service 2781ba
 * Since: GEGL 2.4
Packit Service 2781ba
 */
Packit Service 2781ba
GeglCpuAccelFlags
Packit Service 2781ba
gegl_cpu_accel_get_support (void)
Packit Service 2781ba
{
Packit Service 2781ba
  return use_cpu_accel ? cpu_accel () : GEGL_CPU_ACCEL_NONE;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
/**
Packit Service 2781ba
 * gegl_cpu_accel_set_use:
Packit Service 2781ba
 * @use:  whether to use CPU acceleration features or not
Packit Service 2781ba
 *
Packit Service 2781ba
 * This function is for internal use only.
Packit Service 2781ba
 *
Packit Service 2781ba
 * Since: GEGL 2.4
Packit Service 2781ba
 */
Packit Service 2781ba
void
Packit Service 2781ba
gegl_cpu_accel_set_use (gboolean use)
Packit Service 2781ba
{
Packit Service 2781ba
  use_cpu_accel = use ? TRUE : FALSE;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
#if defined(ARCH_X86) && defined(USE_MMX) && defined(__GNUC__)
Packit Service 2781ba
Packit Service 2781ba
#define HAVE_ACCEL 1
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
typedef enum
Packit Service 2781ba
{
Packit Service 2781ba
  ARCH_X86_VENDOR_NONE,
Packit Service 2781ba
  ARCH_X86_VENDOR_INTEL,
Packit Service 2781ba
  ARCH_X86_VENDOR_AMD,
Packit Service 2781ba
  ARCH_X86_VENDOR_CENTAUR,
Packit Service 2781ba
  ARCH_X86_VENDOR_CYRIX,
Packit Service 2781ba
  ARCH_X86_VENDOR_NSC,
Packit Service 2781ba
  ARCH_X86_VENDOR_TRANSMETA,
Packit Service 2781ba
  ARCH_X86_VENDOR_NEXGEN,
Packit Service 2781ba
  ARCH_X86_VENDOR_RISE,
Packit Service 2781ba
  ARCH_X86_VENDOR_UMC,
Packit Service 2781ba
  ARCH_X86_VENDOR_SIS,
Packit Service 2781ba
  ARCH_X86_VENDOR_UNKNOWN    = 0xff
Packit Service 2781ba
} X86Vendor;
Packit Service 2781ba
Packit Service 2781ba
enum
Packit Service 2781ba
{
Packit Service 2781ba
  ARCH_X86_INTEL_FEATURE_MMX      = 1 << 23,
Packit Service 2781ba
  ARCH_X86_INTEL_FEATURE_XMM      = 1 << 25,
Packit Service 2781ba
  ARCH_X86_INTEL_FEATURE_XMM2     = 1 << 26,
Packit Service 2781ba
Packit Service 2781ba
  ARCH_X86_AMD_FEATURE_MMXEXT     = 1 << 22,
Packit Service 2781ba
  ARCH_X86_AMD_FEATURE_3DNOW      = 1 << 31,
Packit Service 2781ba
Packit Service 2781ba
  ARCH_X86_CENTAUR_FEATURE_MMX    = 1 << 23,
Packit Service 2781ba
  ARCH_X86_CENTAUR_FEATURE_MMXEXT = 1 << 24,
Packit Service 2781ba
  ARCH_X86_CENTAUR_FEATURE_3DNOW  = 1 << 31,
Packit Service 2781ba
Packit Service 2781ba
  ARCH_X86_CYRIX_FEATURE_MMX      = 1 << 23,
Packit Service 2781ba
  ARCH_X86_CYRIX_FEATURE_MMXEXT   = 1 << 24
Packit Service 2781ba
};
Packit Service 2781ba
Packit Service 2781ba
enum
Packit Service 2781ba
{
Packit Service 2781ba
  ARCH_X86_INTEL_FEATURE_PNI      = 1 << 0
Packit Service 2781ba
};
Packit Service 2781ba
Packit Service 2781ba
#if !defined(ARCH_X86_64) && (defined(PIC) || defined(__PIC__))
Packit Service 2781ba
#define cpuid(op,eax,ebx,ecx,edx)  \
Packit Service 2781ba
  __asm__ ("movl %%ebx, %%esi\n\t" \
Packit Service 2781ba
           "cpuid\n\t"             \
Packit Service 2781ba
           "xchgl %%ebx,%%esi"     \
Packit Service 2781ba
           : "=a" (eax),           \
Packit Service 2781ba
             "=S" (ebx),           \
Packit Service 2781ba
             "=c" (ecx),           \
Packit Service 2781ba
             "=d" (edx)            \
Packit Service 2781ba
           : "0" (op))
Packit Service 2781ba
#else
Packit Service 2781ba
#define cpuid(op,eax,ebx,ecx,edx)  \
Packit Service 2781ba
  __asm__ ("cpuid"                 \
Packit Service 2781ba
           : "=a" (eax),           \
Packit Service 2781ba
             "=b" (ebx),           \
Packit Service 2781ba
             "=c" (ecx),           \
Packit Service 2781ba
             "=d" (edx)            \
Packit Service 2781ba
           : "0" (op))
Packit Service 2781ba
#endif
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
static X86Vendor
Packit Service 2781ba
arch_get_vendor (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 eax, ebx, ecx, edx;
Packit Service 2781ba
  guint32 id32[4];
Packit Service 2781ba
  char *id = (char *) id32;
Packit Service 2781ba
Packit Service 2781ba
#ifndef ARCH_X86_64
Packit Service 2781ba
  /* Only need to check this on ia32 */
Packit Service 2781ba
  __asm__ ("pushfl\n\t"
Packit Service 2781ba
           "pushfl\n\t"
Packit Service 2781ba
           "popl %0\n\t"
Packit Service 2781ba
           "movl %0,%1\n\t"
Packit Service 2781ba
           "xorl $0x200000,%0\n\t"
Packit Service 2781ba
           "pushl %0\n\t"
Packit Service 2781ba
           "popfl\n\t"
Packit Service 2781ba
           "pushfl\n\t"
Packit Service 2781ba
           "popl %0\n\t"
Packit Service 2781ba
           "popfl"
Packit Service 2781ba
           : "=a" (eax),
Packit Service 2781ba
             "=c" (ecx)
Packit Service 2781ba
           :
Packit Service 2781ba
           : "cc");
Packit Service 2781ba
Packit Service 2781ba
  if (eax == ecx)
Packit Service 2781ba
    return ARCH_X86_VENDOR_NONE;
Packit Service 2781ba
#endif
Packit Service 2781ba
Packit Service 2781ba
  cpuid (0, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
  if (eax == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_NONE;
Packit Service 2781ba
Packit Service 2781ba
  id32[0] = ebx;
Packit Service 2781ba
  id32[1] = edx;
Packit Service 2781ba
  id32[2] = ecx;
Packit Service 2781ba
Packit Service 2781ba
  id[12] = '\0';
Packit Service 2781ba
Packit Service 2781ba
#ifdef ARCH_X86_64
Packit Service 2781ba
  if (strcmp (id, "AuthenticAMD") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_AMD;
Packit Service 2781ba
  else if (strcmp (id, "GenuineIntel") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_INTEL;
Packit Service 2781ba
#else
Packit Service 2781ba
  if (strcmp (id, "GenuineIntel") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_INTEL;
Packit Service 2781ba
  else if (strcmp (id, "AuthenticAMD") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_AMD;
Packit Service 2781ba
  else if (strcmp (id, "CentaurHauls") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_CENTAUR;
Packit Service 2781ba
  else if (strcmp (id, "CyrixInstead") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_CYRIX;
Packit Service 2781ba
  else if (strcmp (id, "Geode by NSC") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_NSC;
Packit Service 2781ba
  else if (strcmp (id, "GenuineTMx86") == 0 ||
Packit Service 2781ba
           strcmp (id, "TransmetaCPU") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_TRANSMETA;
Packit Service 2781ba
  else if (strcmp (id, "NexGenDriven") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_NEXGEN;
Packit Service 2781ba
  else if (strcmp (id, "RiseRiseRise") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_RISE;
Packit Service 2781ba
  else if (strcmp (id, "UMC UMC UMC ") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_UMC;
Packit Service 2781ba
  else if (strcmp (id, "SiS SiS SiS ") == 0)
Packit Service 2781ba
    return ARCH_X86_VENDOR_SIS;
Packit Service 2781ba
#endif
Packit Service 2781ba
Packit Service 2781ba
  return ARCH_X86_VENDOR_UNKNOWN;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel_intel (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 caps = 0;
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_MMX
Packit Service 2781ba
  {
Packit Service 2781ba
    guint32 eax, ebx, ecx, edx;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (1, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if ((edx & ARCH_X86_INTEL_FEATURE_MMX) == 0)
Packit Service 2781ba
      return 0;
Packit Service 2781ba
Packit Service 2781ba
    caps = GEGL_CPU_ACCEL_X86_MMX;
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
    if (edx & ARCH_X86_INTEL_FEATURE_XMM)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_SSE | GEGL_CPU_ACCEL_X86_MMXEXT;
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_INTEL_FEATURE_XMM2)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_SSE2;
Packit Service 2781ba
Packit Service 2781ba
    if (ecx & ARCH_X86_INTEL_FEATURE_PNI)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_SSE3;
Packit Service 2781ba
#endif /* USE_SSE */
Packit Service 2781ba
  }
Packit Service 2781ba
#endif /* USE_MMX */
Packit Service 2781ba
Packit Service 2781ba
  return caps;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel_amd (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 caps;
Packit Service 2781ba
Packit Service 2781ba
  caps = arch_accel_intel ();
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_MMX
Packit Service 2781ba
  {
Packit Service 2781ba
    guint32 eax, ebx, ecx, edx;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (0x80000000, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (eax < 0x80000001)
Packit Service 2781ba
      return caps;
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
    cpuid (0x80000001, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_AMD_FEATURE_3DNOW)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_3DNOW;
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_AMD_FEATURE_MMXEXT)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_MMXEXT;
Packit Service 2781ba
#endif /* USE_SSE */
Packit Service 2781ba
  }
Packit Service 2781ba
#endif /* USE_MMX */
Packit Service 2781ba
Packit Service 2781ba
  return caps;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel_centaur (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 caps;
Packit Service 2781ba
Packit Service 2781ba
  caps = arch_accel_intel ();
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_MMX
Packit Service 2781ba
  {
Packit Service 2781ba
    guint32 eax, ebx, ecx, edx;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (0x80000000, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (eax < 0x80000001)
Packit Service 2781ba
      return caps;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (0x80000001, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_CENTAUR_FEATURE_MMX)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_MMX;
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
    if (edx & ARCH_X86_CENTAUR_FEATURE_3DNOW)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_3DNOW;
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_CENTAUR_FEATURE_MMXEXT)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_MMXEXT;
Packit Service 2781ba
#endif /* USE_SSE */
Packit Service 2781ba
  }
Packit Service 2781ba
#endif /* USE_MMX */
Packit Service 2781ba
Packit Service 2781ba
  return caps;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel_cyrix (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 caps;
Packit Service 2781ba
Packit Service 2781ba
  caps = arch_accel_intel ();
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_MMX
Packit Service 2781ba
  {
Packit Service 2781ba
    guint32 eax, ebx, ecx, edx;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (0, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (eax != 2)
Packit Service 2781ba
      return caps;
Packit Service 2781ba
Packit Service 2781ba
    cpuid (0x80000001, eax, ebx, ecx, edx);
Packit Service 2781ba
Packit Service 2781ba
    if (edx & ARCH_X86_CYRIX_FEATURE_MMX)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_MMX;
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
    if (edx & ARCH_X86_CYRIX_FEATURE_MMXEXT)
Packit Service 2781ba
      caps |= GEGL_CPU_ACCEL_X86_MMXEXT;
Packit Service 2781ba
#endif /* USE_SSE */
Packit Service 2781ba
  }
Packit Service 2781ba
#endif /* USE_MMX */
Packit Service 2781ba
Packit Service 2781ba
  return caps;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
static jmp_buf sigill_return;
Packit Service 2781ba
Packit Service 2781ba
static void
Packit Service 2781ba
sigill_handler (gint n)
Packit Service 2781ba
{
Packit Service 2781ba
  longjmp (sigill_return, 1);
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static gboolean
Packit Service 2781ba
arch_accel_sse_os_support (void)
Packit Service 2781ba
{
Packit Service 2781ba
  if (setjmp (sigill_return))
Packit Service 2781ba
    {
Packit Service 2781ba
      return FALSE;
Packit Service 2781ba
    }
Packit Service 2781ba
  else
Packit Service 2781ba
    {
Packit Service 2781ba
      signal (SIGILL, sigill_handler);
Packit Service 2781ba
      __asm__ __volatile__ ("xorps %xmm0, %xmm0");
Packit Service 2781ba
      signal (SIGILL, SIG_DFL);
Packit Service 2781ba
    }
Packit Service 2781ba
Packit Service 2781ba
  return TRUE;
Packit Service 2781ba
}
Packit Service 2781ba
#endif /* USE_SSE */
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel (void)
Packit Service 2781ba
{
Packit Service 2781ba
  guint32 caps;
Packit Service 2781ba
  X86Vendor vendor;
Packit Service 2781ba
Packit Service 2781ba
  vendor = arch_get_vendor ();
Packit Service 2781ba
Packit Service 2781ba
  switch (vendor)
Packit Service 2781ba
    {
Packit Service 2781ba
    case ARCH_X86_VENDOR_NONE:
Packit Service 2781ba
      caps = 0;
Packit Service 2781ba
      break;
Packit Service 2781ba
Packit Service 2781ba
    case ARCH_X86_VENDOR_AMD:
Packit Service 2781ba
      caps = arch_accel_amd ();
Packit Service 2781ba
      break;
Packit Service 2781ba
Packit Service 2781ba
    case ARCH_X86_VENDOR_CENTAUR:
Packit Service 2781ba
      caps = arch_accel_centaur ();
Packit Service 2781ba
      break;
Packit Service 2781ba
Packit Service 2781ba
    case ARCH_X86_VENDOR_CYRIX:
Packit Service 2781ba
    case ARCH_X86_VENDOR_NSC:
Packit Service 2781ba
      caps = arch_accel_cyrix ();
Packit Service 2781ba
      break;
Packit Service 2781ba
Packit Service 2781ba
    /* check for what Intel speced, even if UNKNOWN */
Packit Service 2781ba
    default:
Packit Service 2781ba
      caps = arch_accel_intel ();
Packit Service 2781ba
      break;
Packit Service 2781ba
    }
Packit Service 2781ba
Packit Service 2781ba
#ifdef USE_SSE
Packit Service 2781ba
  if ((caps & GEGL_CPU_ACCEL_X86_SSE) && !arch_accel_sse_os_support ())
Packit Service 2781ba
    caps &= ~(GEGL_CPU_ACCEL_X86_SSE | GEGL_CPU_ACCEL_X86_SSE2);
Packit Service 2781ba
#endif
Packit Service 2781ba
Packit Service 2781ba
  return caps;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
#endif /* ARCH_X86 && USE_MMX && __GNUC__ */
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
#if defined(ARCH_PPC) && defined (USE_ALTIVEC)
Packit Service 2781ba
Packit Service 2781ba
#if defined(HAVE_ALTIVEC_SYSCTL)
Packit Service 2781ba
Packit Service 2781ba
#include <sys/sysctl.h>
Packit Service 2781ba
Packit Service 2781ba
#define HAVE_ACCEL 1
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel (void)
Packit Service 2781ba
{
Packit Service 2781ba
  gint     sels[2] = { CTL_HW, HW_VECTORUNIT };
Packit Service 2781ba
  gboolean has_vu  = FALSE;
Packit Service 2781ba
  gsize    length  = sizeof(has_vu);
Packit Service 2781ba
  gint     err;
Packit Service 2781ba
Packit Service 2781ba
  err = sysctl (sels, 2, &has_vu, &length, NULL, 0);
Packit Service 2781ba
Packit Service 2781ba
  if (err == 0 && has_vu)
Packit Service 2781ba
    return GEGL_CPU_ACCEL_PPC_ALTIVEC;
Packit Service 2781ba
Packit Service 2781ba
  return 0;
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
#elif defined(__GNUC__)
Packit Service 2781ba
Packit Service 2781ba
#define HAVE_ACCEL 1
Packit Service 2781ba
Packit Service 2781ba
static          sigjmp_buf   jmpbuf;
Packit Service 2781ba
static volatile sig_atomic_t canjump = 0;
Packit Service 2781ba
Packit Service 2781ba
static void
Packit Service 2781ba
sigill_handler (gint sig)
Packit Service 2781ba
{
Packit Service 2781ba
  if (!canjump)
Packit Service 2781ba
    {
Packit Service 2781ba
      signal (sig, SIG_DFL);
Packit Service 2781ba
      raise (sig);
Packit Service 2781ba
    }
Packit Service 2781ba
Packit Service 2781ba
  canjump = 0;
Packit Service 2781ba
  siglongjmp (jmpbuf, 1);
Packit Service 2781ba
}
Packit Service 2781ba
Packit Service 2781ba
static guint32
Packit Service 2781ba
arch_accel (void)
Packit Service 2781ba
{
Packit Service 2781ba
  signal (SIGILL, sigill_handler);
Packit Service 2781ba
Packit Service 2781ba
  if (sigsetjmp (jmpbuf, 1))
Packit Service 2781ba
    {
Packit Service 2781ba
      signal (SIGILL, SIG_DFL);
Packit Service 2781ba
      return 0;
Packit Service 2781ba
    }
Packit Service 2781ba
Packit Service 2781ba
  canjump = 1;
Packit Service 2781ba
Packit Service 2781ba
  asm volatile ("mtspr 256, %0\n\t"
Packit Service 2781ba
                "vand %%v0, %%v0, %%v0"
Packit Service 2781ba
                :
Packit Service 2781ba
                : "r" (-1));
Packit Service 2781ba
Packit Service 2781ba
  signal (SIGILL, SIG_DFL);
Packit Service 2781ba
Packit Service 2781ba
  return GEGL_CPU_ACCEL_PPC_ALTIVEC;
Packit Service 2781ba
}
Packit Service 2781ba
#endif /* __GNUC__ */
Packit Service 2781ba
Packit Service 2781ba
#endif /* ARCH_PPC && USE_ALTIVEC */
Packit Service 2781ba
Packit Service 2781ba
Packit Service 2781ba
static GeglCpuAccelFlags
Packit Service 2781ba
cpu_accel (void)
Packit Service 2781ba
{
Packit Service 2781ba
#ifdef HAVE_ACCEL
Packit Service 2781ba
  static guint32 accel = ~0U;
Packit Service 2781ba
Packit Service 2781ba
  if (accel != ~0U)
Packit Service 2781ba
    return accel;
Packit Service 2781ba
Packit Service 2781ba
  accel = arch_accel ();
Packit Service 2781ba
Packit Service 2781ba
  return (GeglCpuAccelFlags) accel;
Packit Service 2781ba
Packit Service 2781ba
#else /* !HAVE_ACCEL */
Packit Service 2781ba
  return GEGL_CPU_ACCEL_NONE;
Packit Service 2781ba
#endif
Packit Service 2781ba
}