Mercurial > hg > audiostuff
view 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 source
/* * 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 ------------------------------------------------------------*/