Add mfspr-based AltiVec detection code.
[ffmpeg.git] / libavcodec / ppc / check_altivec.c
index 72b4afe..cf55b9a 100644 (file)
 #include <exec/exec.h>
 #include <interfaces/exec.h>
 #include <proto/exec.h>
-#else
-#include <signal.h>
-#include <setjmp.h>
-
-static sigjmp_buf jmpbuf;
-static volatile sig_atomic_t canjump = 0;
-
-static void sigill_handler (int sig)
-{
-    if (!canjump) {
-        signal (sig, SIG_DFL);
-        raise (sig);
-    }
-
-    canjump = 0;
-    siglongjmp (jmpbuf, 1);
-}
 #endif /* __APPLE__ */
 
 /**
@@ -71,25 +54,22 @@ int has_altivec(void)
 
     if (err == 0) return (has_vu != 0);
     return 0;
-#else
-/* Do it the brute-force way, borrowed from the libmpeg2 library. */
-    {
-      signal (SIGILL, sigill_handler);
-      if (sigsetjmp (jmpbuf, 1)) {
-        signal (SIGILL, SIG_DFL);
-      } else {
-        canjump = 1;
-
-        asm volatile ("mtspr 256, %0\n\t"
-                      "vand %%v0, %%v0, %%v0"
-                      :
-                      : "r" (-1));
-
-        signal (SIGILL, SIG_DFL);
+#elif defined(RUNTIME_CPUDETECT)
+    int proc_ver;
+    // support of mfspr PVR emulation added in Linux 2.6.17
+    asm volatile("mfspr %0, 287" : "=r" (proc_ver));
+    proc_ver >>= 16;
+    if (proc_ver  & 0x8000 ||
+        proc_ver == 0x000c ||
+        proc_ver == 0x0039 || proc_ver == 0x003c ||
+        proc_ver == 0x0044 || proc_ver == 0x0045 ||
+        proc_ver == 0x0070)
         return 1;
-      }
-    }
     return 0;
+#else
+    // since we were compiled for altivec, just assume we have it
+    // until someone comes up with a proper way (not involving signal hacks).
+    return 1;
 #endif /* __AMIGAOS4__ */
 }