--- cpuid.asm 2003/02/15 15:22:19 1.4 +++ cpuid.asm 2007/03/08 21:40:12 1.11 @@ -1,217 +1,233 @@ -;/****************************************************************************** -; * * -; * This file is part of XviD, a free MPEG-4 video encoder/decoder * -; * * -; * XviD is an implementation of a part of one or more MPEG-4 Video tools * -; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * -; * software module in hardware or software products are advised that its * -; * use may infringe existing patents or copyrights, and any such use * -; * would be at such party's own risk. The original developer of this * -; * software module and his/her company, and subsequent editors and their * -; * companies, will have no liability for use of this software or * -; * modifications or derivatives thereof. * -; * * -; * XviD is free software; you can redistribute it and/or modify it * -; * under the terms of the GNU General Public License as published by * -; * the Free Software Foundation; either version 2 of the License, or * -; * (at your option) any later version. * -; * * -; * XviD 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 General Public License for more details. * -; * * -; * You should have received a copy of the GNU General Public License * -; * along with this program; if not, write to the Free Software * -; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * -; * * -; ******************************************************************************/ -; -;/****************************************************************************** -; * * -; * cpuid.asm, check cpu features * -; * * -; * Copyright (C) 2001 - Michael Militzer , * -; * * -; * For more information visit the XviD homepage: http://www.xvid.org * -; * * -; ******************************************************************************/ -; -;/****************************************************************************** -; * * -; * Revision history: * -; * * -; * 17.12.2001 initial version (Isibaar) * -; * * -; ******************************************************************************/ - -bits 32 - -%define CPUID_TSC 0x00000010 -%define CPUID_MMX 0x00800000 -%define CPUID_SSE 0x02000000 -%define CPUID_SSE2 0x04000000 - -%define EXT_CPUID_3DNOW 0x80000000 -%define EXT_CPUID_AMD_3DNOWEXT 0x40000000 -%define EXT_CPUID_AMD_MMXEXT 0x00400000 - -%define XVID_CPU_MMX 0x00000001 -%define XVID_CPU_MMXEXT 0x00000002 -%define XVID_CPU_SSE 0x00000004 -%define XVID_CPU_SSE2 0x00000008 -%define XVID_CPU_3DNOW 0x00000010 -%define XVID_CPU_3DNOWEXT 0x00000020 -%define XVID_CPU_TSC 0x00000040 +;/**************************************************************************** +; * +; * XVID MPEG-4 VIDEO CODEC +; * - CPUID check processors capabilities - +; * +; * Copyright (C) 2001 Michael Militzer +; * +; * This program is free software ; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation ; either version 2 of the License, or +; * (at your option) any later version. +; * +; * 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 General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License +; * along with this program ; if not, write to the Free Software +; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; * +; * $Id: cpuid.asm,v 1.11 2007/03/08 21:40:12 Isibaar Exp $ +; * +; ***************************************************************************/ +BITS 32 %macro cglobal 1 %ifdef PREFIX - global _%1 - %define %1 _%1 + %ifdef MARK_FUNCS + global _%1:function %1.endfunc-%1 + %define %1 _%1:function %1.endfunc-%1 + %else + global _%1 + %define %1 _%1 + %endif %else - global %1 + %ifdef MARK_FUNCS + global %1:function %1.endfunc-%1 + %else + global %1 + %endif %endif %endmacro -ALIGN 32 - -section .data - -vendorAMD db "AuthenticAMD" - -%macro CHECK_FEATURE 3 - - mov ecx, %1 - and ecx, edx - neg ecx - sbb ecx, ecx - and ecx, %2 - or %3, ecx +;============================================================================= +; Constants +;============================================================================= + +%define CPUID_TSC 0x00000010 +%define CPUID_MMX 0x00800000 +%define CPUID_SSE 0x02000000 +%define CPUID_SSE2 0x04000000 +%define CPUID_SSE3 0x00000001 + +%define EXT_CPUID_3DNOW 0x80000000 +%define EXT_CPUID_AMD_3DNOWEXT 0x40000000 +%define EXT_CPUID_AMD_MMXEXT 0x00400000 + +;;; NB: Make sure these defines match the ones defined in xvid.h +%define XVID_CPU_MMX (1<< 0) +%define XVID_CPU_MMXEXT (1<< 1) +%define XVID_CPU_SSE (1<< 2) +%define XVID_CPU_SSE2 (1<< 3) +%define XVID_CPU_SSE3 (1<< 8) +%define XVID_CPU_3DNOW (1<< 4) +%define XVID_CPU_3DNOWEXT (1<< 5) +%define XVID_CPU_TSC (1<< 6) + +;============================================================================= +; Read only data +;============================================================================= +ALIGN 32 +%ifdef FORMAT_COFF +SECTION .rodata +%else +SECTION .rodata align=16 +%endif + +vendorAMD: + db "AuthenticAMD" + +;============================================================================= +; Macros +;============================================================================= + +%macro CHECK_FEATURE 4 + mov eax, %1 + and eax, %4 + neg eax + sbb eax, eax + and eax, %2 + or %3, eax %endmacro -section .text +;============================================================================= +; Code +;============================================================================= + +SECTION .text ; int check_cpu_feature(void) cglobal check_cpu_features check_cpu_features: - push ebx - push esi - push edi - push ebp - - xor ebp,ebp + push ebx + push esi + push edi + push ebp + + sub esp, 12 ; Stack space for vendor name + + xor ebp, ebp ; CPUID command ? - pushfd - pop eax - mov ecx, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - cmp eax, ecx + pushfd + pop eax + mov ecx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + cmp eax, ecx - jz near .cpu_quit ; no CPUID command -> exit + jz near .cpu_quit ; no CPUID command -> exit ; get vendor string, used later - xor eax, eax - cpuid - mov [esp-12], ebx ; vendor string - mov [esp-12+4], edx - mov [esp-12+8], ecx - test eax, eax - - jz near .cpu_quit - - mov eax, 1 - cpuid - - ; RDTSC command ? - CHECK_FEATURE CPUID_TSC, XVID_CPU_TSC, ebp - - ; MMX support ? - CHECK_FEATURE CPUID_MMX, XVID_CPU_MMX, ebp - - ; SSE support ? - CHECK_FEATURE CPUID_SSE, (XVID_CPU_MMXEXT|XVID_CPU_SSE), ebp - - ; SSE2 support? - CHECK_FEATURE CPUID_SSE2, XVID_CPU_SSE2, ebp - - ; extended functions? - mov eax, 0x80000000 - cpuid - cmp eax, 0x80000000 - jbe near .cpu_quit - - mov eax, 0x80000001 - cpuid - - ; AMD cpu ? - lea esi, [vendorAMD] - lea edi, [esp-12] - mov ecx, 12 - cld - repe cmpsb - jnz .cpu_quit + xor eax, eax + cpuid + mov [esp], ebx ; vendor string + mov [esp+4], edx + mov [esp+8], ecx + test eax, eax + + jz near .cpu_quit + + mov eax, 1 + cpuid + + ; RDTSC command ? + CHECK_FEATURE CPUID_TSC, XVID_CPU_TSC, ebp, edx + + ; MMX support ? + CHECK_FEATURE CPUID_MMX, XVID_CPU_MMX, ebp, edx + + ; SSE support ? + CHECK_FEATURE CPUID_SSE, (XVID_CPU_MMXEXT|XVID_CPU_SSE), ebp, edx + + ; SSE2 support? + CHECK_FEATURE CPUID_SSE2, XVID_CPU_SSE2, ebp, edx + + ; SSE3 support? + CHECK_FEATURE CPUID_SSE3, XVID_CPU_SSE3, ebp, ecx + + ; extended functions? + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000000 + jbe near .cpu_quit + + mov eax, 0x80000001 + cpuid + + ; AMD cpu ? + lea esi, [vendorAMD] + lea edi, [esp] + mov ecx, 12 + cld + repe cmpsb + jnz .cpu_quit - ; 3DNow! support ? - CHECK_FEATURE EXT_CPUID_3DNOW, XVID_CPU_3DNOW, ebp + ; 3DNow! support ? + CHECK_FEATURE EXT_CPUID_3DNOW, XVID_CPU_3DNOW, ebp, edx - ; 3DNOW extended ? - CHECK_FEATURE EXT_CPUID_AMD_3DNOWEXT, XVID_CPU_3DNOWEXT, ebp + ; 3DNOW extended ? + CHECK_FEATURE EXT_CPUID_AMD_3DNOWEXT, XVID_CPU_3DNOWEXT, ebp, edx - ; extended MMX ? - CHECK_FEATURE EXT_CPUID_AMD_MMXEXT, XVID_CPU_MMXEXT, ebp + ; extended MMX ? + CHECK_FEATURE EXT_CPUID_AMD_MMXEXT, XVID_CPU_MMXEXT, ebp, edx .cpu_quit: - mov eax, ebp - - pop ebp - pop edi - pop esi - pop ebx + mov eax, ebp - ret + add esp, 12 + pop ebp + pop edi + pop esi + pop ebx + ret +.endfunc ; sse/sse2 operating support detection routines ; these will trigger an invalid instruction signal if not supported. - +ALIGN 16 cglobal sse_os_trigger -align 16 sse_os_trigger: - xorps xmm0, xmm0 - ret + xorps xmm0, xmm0 + ret +.endfunc +ALIGN 16 cglobal sse2_os_trigger -align 16 sse2_os_trigger: - xorpd xmm0, xmm0 - ret + xorpd xmm0, xmm0 + ret +.endfunc ; enter/exit mmx state - +ALIGN 16 cglobal emms_mmx -align 16 emms_mmx: - emms - ret + emms + ret +.endfunc ; faster enter/exit mmx state - +ALIGN 16 cglobal emms_3dn -align 16 emms_3dn: - femms - ret + femms + ret +.endfunc + +