[mythtv] Re: denoise3d + Athlon XP bug

Jay Merrifield fracmak at gmail.com
Fri Apr 29 04:08:11 UTC 2005


Hey, thanks for submitting the patch for osdsurface.cpp, here's the
diff -u that I'm using with the denoise filter that enables MMX code
for x86_64 processors. Hopefully more to come...

Jay

Index: filter_denoise3d.c
===================================================================
RCS file: /var/lib/mythcvs/mythtv/filters/denoise3d/filter_denoise3d.c,v
retrieving revision 1.12
diff -u -r1.12 filter_denoise3d.c
--- filter_denoise3d.c  19 Aug 2004 20:06:19 -0000      1.12
+++ filter_denoise3d.c  29 Apr 2005 04:05:57 -0000
@@ -26,18 +26,28 @@
 #define MM_MMXEXT 0x0002        /* SSE integer functions or AMD MMX ext */
 #define MM_SSE    0x0008        /* SSE functions */
 #define MM_SSE2   0x0010        /* PIV SSE2 functions */
+#define MM_3DNOWEXT  0x0020 /* AMD 3DNowExt */

-#ifdef i386
+#ifdef MMX

 #include "mmx.h"

 static const mmx_t mz = { 0x0LL };

+#ifdef ARCH_X86_64
+#  define REG_b "rbx"
+#  define REG_S "rsi"
+#else
+#  define REG_b "ebx"
+#  define REG_S "esi"
+#endif
+
+/* ebx saving is necessary for PIC. gcc seems unable to see it alone */
 #define cpuid(index,eax,ebx,ecx,edx)\
     __asm __volatile\
-        ("movl %%ebx, %%esi\n\t"\
+        ("mov %%"REG_b", %%"REG_S"\n\t"\
          "cpuid\n\t"\
-         "xchgl %%ebx, %%esi"\
+         "xchg %%"REG_b", %%"REG_S\
          : "=a" (eax), "=S" (ebx),\
            "=c" (ecx), "=d" (edx)\
          : "0" (index));
@@ -61,114 +71,93 @@
 }

 /* Function to test if multimedia instructions are supported...  */
-int
-mm_support (void)
+int mm_support(void)
 {
-    int rval;
+    int rval = 0;
     int eax, ebx, ecx, edx;
+    int max_std_level=0, max_ext_level, std_caps=0, ext_caps=0;
+    long a, c;

     __asm__ __volatile__ (
-                             /* See if CPUID instruction is supported ... */
-                             /* ... Get copies of EFLAGS into eax and ecx */
-                             "pushf\n\t" "popl %0\n\t" "movl %0, %1\n\t"
-                             /* ... Toggle the ID bit in one copy and store */
-                             /*     to the EFLAGS reg */
-                             "xorl $0x200000, %0\n\t" "push %0\n\t" "popf\n\t"
-                             /* ... Get the (hopefully modified) EFLAGS */
-                             "pushf\n\t"
-                             "popl %0\n\t":"=a" (eax), "=c" (ecx)::"cc");
-
-    if (eax == ecx)
-        return 0;               /* CPUID not supported */
-
-    cpuid (0, eax, ebx, ecx, edx);
-
-    if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
-    {
-
-        /* intel */
-      inteltest:
-        cpuid (1, eax, ebx, ecx, edx);
-        if ((edx & 0x00800000) == 0)
-            return 0;
-        rval = MM_MMX;
-        if (edx & 0x02000000)
-            rval |= MM_MMXEXT | MM_SSE;
-        if (edx & 0x04000000)
-            rval |= MM_SSE2;
-        return rval;
-    }
-    else if (ebx == 0x68747541 && edx == 0x69746e65 && ecx == 0x444d4163)
-    {
-        /* AMD */
-        cpuid (0x80000000, eax, ebx, ecx, edx);
-        if ((unsigned) eax < 0x80000001)
-            goto inteltest;
-        cpuid (0x80000001, eax, ebx, ecx, edx);
-        if ((edx & 0x00800000) == 0)
-            return 0;
-        rval = MM_MMX;
-        if (edx & 0x80000000)
-            rval |= MM_3DNOW;
-        if (edx & 0x00400000)
-            rval |= MM_MMXEXT;
-        return rval;
-    }
-    else if (ebx == 0x746e6543 && edx == 0x48727561 && ecx == 0x736c7561)
-    {                           /*  "CentaurHauls" */
-        /* VIA C3 */
-        cpuid (0x80000000, eax, ebx, ecx, edx);
-        if ((unsigned) eax < 0x80000001)
-            goto inteltest;
-        cpuid (0x80000001, eax, ebx, ecx, edx);
-        rval = 0;
-        if (edx & (1 << 31))
-            rval |= MM_3DNOW;
-        if (edx & (1 << 23))
-            rval |= MM_MMX;
-        if (edx & (1 << 24))
-            rval |= MM_MMXEXT;
-        if (rval==0)
-            goto inteltest;
-        return rval;
-    }
-    else if (ebx == 0x69727943 && edx == 0x736e4978 && ecx == 0x64616574)
-    {
-        /* Cyrix Section */
-        /* See if extended CPUID level 80000001 is supported */
-        /* The value of CPUID/80000001 for the 6x86MX is undefined
+                             /* See if CPUID instruction is supported ... */
+                             /* ... Get copies of EFLAGS into eax and ecx */
+                              "pushf\n\t"
+                              "pop %0\n\t"
+                              "mov %0, %1\n\t"
+
+                          /* ... Toggle the ID bit in one copy and store */
+                         /*     to the EFLAGS reg */
+                          "xor $0x200000, %0\n\t"
+                          "push %0\n\t"
+                          "popf\n\t"
+                          /* ... Get the (hopefully modified) EFLAGS */
+                          "pushf\n\t"
+                          "pop %0\n\t"
+                          : "=a" (a), "=c" (c)
+                          :
+                          : "cc"
+                          );
+
+
+  if (a == c)
+    return 0; /* CPUID not supported */
+
+
+  if(max_std_level >= 1){
+    cpuid(1, eax, ebx, ecx, std_caps);
+    if (std_caps & (1<<23))
+      rval |= MM_MMX;
+    if (std_caps & (1<<25))
+      rval |= MM_MMXEXT | MM_SSE;
+    if (std_caps & (1<<26))
+      rval |= MM_SSE2;
+  }
+
+  cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
+  if(max_ext_level >= 0x80000001){
+    cpuid(0x80000001, eax, ebx, ecx, ext_caps);
+    if (ext_caps & (1<<31))
+      rval |= MM_3DNOW;
+    if (ext_caps & (1<<30))
+      rval |= MM_3DNOWEXT;
+    if (ext_caps & (1<<23))
+      rval |= MM_MMX;
+  }
+
+  cpuid(0, eax, ebx, ecx, edx);
+  if (       ebx == 0x68747541 &&
+               edx == 0x69746e65 &&
+            ecx == 0x444d4163) {
+      /* AMD */
+    if(ext_caps & (1<<22))
+      rval |= MM_MMXEXT;
+  } else if (ebx == 0x746e6543 &&
+               edx == 0x48727561 &&
+            ecx == 0x736c7561) {  /*  "CentaurHauls" */
+      /* VIA C3 */
+    if(ext_caps & (1<<24))
+      rval |= MM_MMXEXT;
+  } else if (ebx == 0x69727943 &&
+               edx == 0x736e4978 &&
+            ecx == 0x64616574) {
+    /* Cyrix Section */
+    /* See if extended CPUID level 80000001 is supported */
+    /* The value of CPUID/80000001 for the 6x86MX is undefined
            according to the Cyrix CPU Detection Guide (Preliminary
            Rev. 1.01 table 1), so we'll check the value of eax for
            CPUID/0 to see if standard CPUID level 2 is supported.
            According to the table, the only CPU which supports level
            2 is also the only one which supports extended CPUID levels.
-         */
-        if (eax != 2)
-            goto inteltest;
-        cpuid (0x80000001, eax, ebx, ecx, edx);
-        if ((eax & 0x00800000) == 0)
-            return 0;
-        rval = MM_MMX;
-        if (eax & 0x01000000)
-            rval |= MM_MMXEXT;
-        return rval;
-    }
-    else if (ebx == 0x756e6547 && edx == 0x54656e69 && ecx == 0x3638784d)
-    {
-        /* Tranmeta Crusoe */
-        cpuid(0x80000000, eax, ebx, ecx, edx);
-        if ((unsigned)eax < 0x80000001)
-            return 0;
-        cpuid(0x80000001, eax, ebx, ecx, edx);
-        if ((edx & 0x00800000) == 0)
-            return 0;
-        return MM_MMX;
-    }
-    else
-    {
-        return 0;
-    }
+    */
+    if (eax < 2)
+      return rval;
+    if (ext_caps & (1<<24))
+      rval |= MM_MMXEXT;
+  }
+    return rval;
 }
+
+
 #else
 #define emms()
 int mm_support(void) { return 0; }
@@ -248,7 +237,7 @@
     }
 }

-#ifdef i386
+#ifdef MMX

 static void
 denoiseMMX (uint8_t * Frame,


More information about the mythtv-dev mailing list