vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

cpu.c (5832B)


      1 /* libFLAC - Free Lossless Audio Codec library
      2  * Copyright (C) 2001,2002,2003,2004,2005  Josh Coalson
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * - Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *
     11  * - Redistributions in binary form must reproduce the above copyright
     12  * notice, this list of conditions and the following disclaimer in the
     13  * documentation and/or other materials provided with the distribution.
     14  *
     15  * - Neither the name of the Xiph.org Foundation nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
     23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include "private/cpu.h"
     33 #include <stdlib.h>
     34 #include <stdio.h>
     35 
     36 #ifdef HAVE_CONFIG_H
     37 #include <config.h>
     38 #endif
     39 
     40 #if defined FLAC__CPU_PPC
     41 #if !defined FLAC__NO_ASM
     42 #if defined FLAC__SYS_DARWIN
     43 #include <sys/sysctl.h>
     44 #include <mach/mach.h>
     45 #include <mach/mach_host.h>
     46 #include <mach/host_info.h>
     47 #include <mach/machine.h>
     48 #ifndef CPU_SUBTYPE_POWERPC_970
     49 #define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
     50 #endif
     51 #else /* FLAC__SYS_DARWIN */
     52 #include <signal.h>
     53 #include <setjmp.h>
     54 
     55 static sigjmp_buf jmpbuf;
     56 static volatile sig_atomic_t canjump = 0;
     57 
     58 static void sigill_handler (int sig)
     59 {
     60 	if (!canjump) {
     61 		signal (sig, SIG_DFL);
     62 		raise (sig);
     63 	}
     64 	canjump = 0;
     65 	siglongjmp (jmpbuf, 1);
     66 }
     67 #endif /* FLAC__SYS_DARWIN */
     68 #endif /* FLAC__NO_ASM */
     69 #endif /* FLAC__CPU_PPC */
     70 
     71 const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
     72 const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
     73 const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
     74 const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
     75 const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
     76 
     77 const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000;
     78 const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
     79 const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
     80 
     81 
     82 void FLAC__cpu_info(FLAC__CPUInfo *info)
     83 {
     84 #ifdef FLAC__CPU_IA32
     85 	info->type = FLAC__CPUINFO_TYPE_IA32;
     86 #if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
     87 	info->use_asm = true;
     88 	{
     89 		unsigned cpuid = FLAC__cpu_info_asm_ia32();
     90 		info->data.ia32.cmov = (cpuid & FLAC__CPUINFO_IA32_CPUID_CMOV)? true : false;
     91 		info->data.ia32.mmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_MMX)? true : false;
     92 		info->data.ia32.fxsr = (cpuid & FLAC__CPUINFO_IA32_CPUID_FXSR)? true : false;
     93 		info->data.ia32.sse = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE)? true : false;
     94 		info->data.ia32.sse2 = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE2)? true : false;
     95 
     96 #ifndef FLAC__SSE_OS
     97 		info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = false;
     98 #endif
     99 
    100 #ifdef FLAC__USE_3DNOW
    101 		cpuid = FLAC__cpu_info_extended_amd_asm_ia32();
    102 		info->data.ia32._3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW)? true : false;
    103 		info->data.ia32.ext3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false;
    104 		info->data.ia32.extmmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX)? true : false;
    105 #else
    106 		info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false;
    107 #endif
    108 	}
    109 #else
    110 	info->use_asm = false;
    111 #endif
    112 #elif defined FLAC__CPU_PPC
    113 	info->type = FLAC__CPUINFO_TYPE_PPC;
    114 #if !defined FLAC__NO_ASM
    115 	info->use_asm = true;
    116 #ifdef FLAC__USE_ALTIVEC
    117 #if defined FLAC__SYS_DARWIN
    118 	{
    119 		int selectors[2] = { CTL_HW, HW_VECTORUNIT };
    120 		int result = 0;
    121 		size_t length = sizeof(result);
    122 		int error = sysctl(selectors, 2, &result, &length, 0, 0);
    123 
    124 		info->data.ppc.altivec = error==0 ? result!=0 : 0;
    125 	}
    126 	{
    127 		host_basic_info_data_t hostInfo;
    128 		mach_msg_type_number_t infoCount;
    129 
    130 		infoCount = HOST_BASIC_INFO_COUNT;
    131 		host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
    132 
    133 		info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
    134 	}
    135 #else /* FLAC__SYS_DARWIN */
    136 	{
    137 		/* no Darwin, do it the brute-force way */
    138 		/* this is borrowed from MPlayer from the libmpeg2 library */
    139 		info->data.ppc.altivec = 0;
    140 		info->data.ppc.ppc64 = 0;
    141 
    142 		signal (SIGILL, sigill_handler);
    143 		if (!sigsetjmp (jmpbuf, 1)) {
    144 			canjump = 1;
    145 
    146 			asm volatile (
    147 				"mtspr 256, %0\n\t"
    148 				"vand %%v0, %%v0, %%v0"
    149 				:
    150 				: "r" (-1)
    151 			);
    152 
    153 			info->data.ppc.altivec = 1;
    154 		}
    155 		canjump = 0;
    156 		if (!sigsetjmp (jmpbuf, 1)) {
    157 			int x = 0;
    158 			canjump = 1;
    159 
    160 			/* PPC64 hardware implements the cntlzd instruction */
    161 			asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) );
    162 
    163 			info->data.ppc.ppc64 = 1;
    164 		}
    165 		signal (SIGILL, SIG_DFL);
    166 	}
    167 #endif /* FLAC__SYS_DARWIN */
    168 #else /* FLAC__USE_ALTIVEC */
    169 	info->data.ppc.altivec = 0;
    170 	info->data.ppc.ppc64 = 0;
    171 #endif /* FLAC__USE_ALTIVEC */
    172 #else /* FLAC__NO_ASM */
    173 	info->use_asm = false;
    174 #endif /* FLAC__NO_ASM */
    175 #else
    176 	info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
    177 	info->use_asm = false;
    178 #endif
    179 }