cpu.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  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. #include "private/cpu.h"
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #ifdef HAVE_CONFIG_H
  35. #include <config.h>
  36. #endif
  37. #if defined FLAC__CPU_PPC
  38. #if !defined FLAC__NO_ASM
  39. #if defined FLAC__SYS_DARWIN
  40. #include <sys/sysctl.h>
  41. #include <mach/mach.h>
  42. #include <mach/mach_host.h>
  43. #include <mach/host_info.h>
  44. #include <mach/machine.h>
  45. #ifndef CPU_SUBTYPE_POWERPC_970
  46. #define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
  47. #endif
  48. #else /* FLAC__SYS_DARWIN */
  49. #include <signal.h>
  50. #include <setjmp.h>
  51. static sigjmp_buf jmpbuf;
  52. static volatile sig_atomic_t canjump = 0;
  53. static void sigill_handler (int sig)
  54. {
  55. if (!canjump) {
  56. signal (sig, SIG_DFL);
  57. raise (sig);
  58. }
  59. canjump = 0;
  60. siglongjmp (jmpbuf, 1);
  61. }
  62. #endif /* FLAC__SYS_DARWIN */
  63. #endif /* FLAC__NO_ASM */
  64. #endif /* FLAC__CPU_PPC */
  65. const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
  66. const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
  67. const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
  68. const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
  69. const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
  70. const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000;
  71. const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
  72. const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
  73. void FLAC__cpu_info(FLAC__CPUInfo *info)
  74. {
  75. #ifdef FLAC__CPU_IA32
  76. info->type = FLAC__CPUINFO_TYPE_IA32;
  77. #if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
  78. info->use_asm = true;
  79. {
  80. unsigned cpuid = FLAC__cpu_info_asm_ia32();
  81. info->data.ia32.cmov = (cpuid & FLAC__CPUINFO_IA32_CPUID_CMOV)? true : false;
  82. info->data.ia32.mmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_MMX)? true : false;
  83. info->data.ia32.fxsr = (cpuid & FLAC__CPUINFO_IA32_CPUID_FXSR)? true : false;
  84. info->data.ia32.sse = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE)? true : false;
  85. info->data.ia32.sse2 = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE2)? true : false;
  86. #ifndef FLAC__SSE_OS
  87. info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = false;
  88. #endif
  89. #ifdef FLAC__USE_3DNOW
  90. cpuid = FLAC__cpu_info_extended_amd_asm_ia32();
  91. info->data.ia32._3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW)? true : false;
  92. info->data.ia32.ext3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false;
  93. info->data.ia32.extmmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX)? true : false;
  94. #else
  95. info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false;
  96. #endif
  97. }
  98. #else
  99. info->use_asm = false;
  100. #endif
  101. #elif defined FLAC__CPU_PPC
  102. info->type = FLAC__CPUINFO_TYPE_PPC;
  103. #if !defined FLAC__NO_ASM
  104. info->use_asm = true;
  105. #ifdef FLAC__USE_ALTIVEC
  106. #if defined FLAC__SYS_DARWIN
  107. {
  108. int selectors[2] = { CTL_HW, HW_VECTORUNIT };
  109. int result = 0;
  110. size_t length = sizeof(result);
  111. int error = sysctl(selectors, 2, &result, &length, 0, 0);
  112. info->data.ppc.altivec = error==0 ? result!=0 : 0;
  113. }
  114. {
  115. host_basic_info_data_t hostInfo;
  116. mach_msg_type_number_t infoCount;
  117. infoCount = HOST_BASIC_INFO_COUNT;
  118. host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
  119. info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
  120. }
  121. #else /* FLAC__SYS_DARWIN */
  122. {
  123. /* no Darwin, do it the brute-force way */
  124. /* this is borrowed from MPlayer from the libmpeg2 library */
  125. info->data.ppc.altivec = 0;
  126. info->data.ppc.ppc64 = 0;
  127. signal (SIGILL, sigill_handler);
  128. if (!sigsetjmp (jmpbuf, 1)) {
  129. canjump = 1;
  130. asm volatile (
  131. "mtspr 256, %0nt"
  132. "vand %%v0, %%v0, %%v0"
  133. :
  134. : "r" (-1)
  135. );
  136. info->data.ppc.altivec = 1;
  137. }
  138. canjump = 0;
  139. if (!sigsetjmp (jmpbuf, 1)) {
  140. int x = 0;
  141. canjump = 1;
  142. /* PPC64 hardware implements the cntlzd instruction */
  143. asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) );
  144. info->data.ppc.ppc64 = 1;
  145. }
  146. signal (SIGILL, SIG_DFL);
  147. }
  148. #endif /* FLAC__SYS_DARWIN */
  149. #else /* FLAC__USE_ALTIVEC */
  150. info->data.ppc.altivec = 0;
  151. info->data.ppc.ppc64 = 0;
  152. #endif /* FLAC__USE_ALTIVEC */
  153. #else /* FLAC__NO_ASM */
  154. info->use_asm = false;
  155. #endif /* FLAC__NO_ASM */
  156. #else
  157. info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
  158. info->use_asm = false;
  159. #endif
  160. }