diff spandsp-0.0.6pre17/src/testcpuid.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spandsp-0.0.6pre17/src/testcpuid.c	Fri Jun 25 15:50:58 2010 +0200
@@ -0,0 +1,209 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * testcpuid.c - Check the CPU type, to identify special features, like SSE.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ * Stitched together from bits of testing code found here and there
+ *
+ * Copyright (C) 2004 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: testcpuid.c,v 1.13 2009/01/05 13:48:31 steveu Exp $
+ */
+
+/*! \file */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+
+/* Make this file just disappear if we are not on an x86 machine */
+#if defined(__i386__) //  ||  defined(__x86_64__)
+
+#define X86_EFLAGS_CF   0x00000001 /* Carry Flag */
+#define X86_EFLAGS_PF   0x00000004 /* Parity Flag */
+#define X86_EFLAGS_AF   0x00000010 /* Auxillary carry Flag */
+#define X86_EFLAGS_ZF   0x00000040 /* Zero Flag */
+#define X86_EFLAGS_SF   0x00000080 /* Sign Flag */
+#define X86_EFLAGS_TF   0x00000100 /* Trap Flag */
+#define X86_EFLAGS_IF   0x00000200 /* Interrupt Flag */
+#define X86_EFLAGS_DF   0x00000400 /* Direction Flag */
+#define X86_EFLAGS_OF   0x00000800 /* Overflow Flag */
+#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
+#define X86_EFLAGS_NT   0x00004000 /* Nested Task */
+#define X86_EFLAGS_RF   0x00010000 /* Resume Flag */
+#define X86_EFLAGS_VM   0x00020000 /* Virtual Mode */
+#define X86_EFLAGS_AC   0x00040000 /* Alignment Check */
+#define X86_EFLAGS_VIF  0x00080000 /* Virtual Interrupt Flag */
+#define X86_EFLAGS_VIP  0x00100000 /* Virtual Interrupt Pending */
+#define X86_EFLAGS_ID   0x00200000 /* CPUID detection flag */
+
+/* Standard macro to see if a specific flag is changeable */
+static __inline__ int flag_is_changeable_p(uint32_t flag)
+{
+    uint32_t f1;
+    uint32_t f2;
+
+    __asm__ __volatile__ (
+        " pushfl\n"
+        " pushfl\n"
+        " popl %0\n"
+        " movl %0,%1\n"
+        " xorl %2,%0\n"
+        " pushl %0\n"
+        " popfl\n"
+        " pushfl\n"
+        " popl %0\n"
+        " popfl\n"
+        : "=&r" (f1), "=&r" (f2)
+        : "ir" (flag));
+
+    return ((f1^f2) & flag) != 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+/* Probe for the CPUID instruction */
+static int have_cpuid_p(void)
+{
+    return flag_is_changeable_p(X86_EFLAGS_ID);
+}
+/*- End of function --------------------------------------------------------*/
+
+int has_MMX(void)
+{
+    int result;
+
+    if (!have_cpuid_p())
+        return  0;
+    /*endif*/
+    __asm__ __volatile__ (
+        " push  %%ebx;\n"
+	" mov	$1,%%eax;\n"
+	" cpuid;\n"
+	" xor   %%eax,%%eax;\n"
+	" test	$0x800000,%%edx;\n"
+	" jz	1f;\n"	            /* no MMX support */
+	" inc   %%eax;\n"	    /* MMX support */
+        "1:\n"
+        " pop  %%ebx;\n"
+	: "=a" (result)
+        : 
+        : "ecx", "edx");
+    return  result;
+}
+/*- End of function --------------------------------------------------------*/
+        
+int has_SIMD(void)
+{
+    int result;
+
+    if (!have_cpuid_p())
+        return  0;
+    /*endif*/
+    __asm__ __volatile__ (
+        " push  %%ebx;\n"
+	" mov	$1,%%eax;\n"
+	" cpuid;\n"
+	" xor   %%eax,%%eax;\n"
+	" test	$0x02000000,%%edx;\n"
+	" jz	1f;\n"		        /* no SIMD support */
+	" inc	%%eax;\n"		/* SIMD support */
+        "1:\n"
+        " pop  %%ebx;\n"
+	: "=a" (result)
+        : 
+        : "ecx", "edx");
+    return  result;
+}
+/*- End of function --------------------------------------------------------*/
+
+int has_SIMD2(void)
+{
+    int result;
+
+    if (!have_cpuid_p())
+        return  0;
+    /*endif*/
+    __asm__ __volatile__ (
+        " push  %%ebx;\n"
+	" mov	$1,%%eax;\n"
+	" cpuid;\n"
+	" xor   %%eax,%%eax;\n"
+	" test	$0x04000000,%%edx;\n"
+	" jz	1f;\n"		        /* no SIMD2 support */
+	" inc	%%eax;\n"		/* SIMD2 support */
+        "1:\n"
+        " pop  %%ebx;\n"
+	: "=a" (result)
+        : 
+        : "ecx", "edx");
+    return  result;
+}
+/*- End of function --------------------------------------------------------*/
+        
+int has_3DNow(void)
+{
+    int result;
+
+    if (!have_cpuid_p())
+        return  0;
+    /*endif*/
+    __asm__ __volatile__ (
+        " push  %%ebx;\n"
+	" mov	$0x80000000,%%eax;\n"
+	" cpuid;\n"
+        " xor   %%ecx,%%ecx;\n"
+	" cmp	$0x80000000,%%eax;\n"
+	" jbe	1f;\n"		        /* no extended MSR(1), so no 3DNow! */
+	" mov	$0x80000001,%%eax;\n"
+	" cpuid;\n"
+        " xor   %%ecx,%%ecx;\n"
+	" test	$0x80000000,%%edx;\n"
+	" jz	1f;\n"		        /* no 3DNow! support */
+	" inc   %%ecx;\n"		/* 3DNow! support */
+        "1:\n"
+        " pop  %%ebx;\n"
+	: "=c" (result)
+        : 
+        : "eax", "edx");
+    return  result;
+}
+/*- End of function --------------------------------------------------------*/
+
+#if defined(TESTBED)
+int main(int argc, char *argv[])
+{
+    int result;
+
+    result = has_MMX();
+    printf("MMX is %x\n", result);
+    result = has_SIMD();
+    printf("SIMD is %x\n", result);
+    result = has_SIMD2();
+    printf("SIMD2 is %x\n", result);
+    result = has_3DNow();
+    printf("3DNow is %x\n", result);
+    return  0;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.