| [17] | 1 | /*************************************************************************** | 
|---|
 | 2 |  *   Copyright (C) 2005 by Prakash Punnoor                                 * | 
|---|
 | 3 |  *   prakash@punnoor.de                                                    * | 
|---|
 | 4 |  *                                                                         * | 
|---|
 | 5 |  *   This program is free software; you can redistribute it and/or modify  * | 
|---|
 | 6 |  *   it under the terms of the GNU Library General Public License as       * | 
|---|
 | 7 |  *   published by the Free Software Foundation; either version 2 of the    * | 
|---|
 | 8 |  *   License, or (at your option) any later version.                       * | 
|---|
 | 9 |  *                                                                         * | 
|---|
 | 10 |  *   This program is distributed in the hope that it will be useful,       * | 
|---|
 | 11 |  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * | 
|---|
 | 12 |  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         * | 
|---|
 | 13 |  *   GNU General Public License for more details.                          * | 
|---|
 | 14 |  *                                                                         * | 
|---|
 | 15 |  *   You should have received a copy of the GNU Library General Public     * | 
|---|
 | 16 |  *   License along with this program; if not, write to the                 * | 
|---|
 | 17 |  *   Free Software Foundation, Inc.,                                       * | 
|---|
 | 18 |  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * | 
|---|
 | 19 |  ***************************************************************************/ | 
|---|
 | 20 | #include "al_siteconfig.h" | 
|---|
 | 21 | #include <string.h> | 
|---|
 | 22 | #include <stdlib.h> | 
|---|
 | 23 | #include "al_cpu_caps.h" | 
|---|
 | 24 | #include "al_debug.h" | 
|---|
 | 25 |  | 
|---|
 | 26 | typedef unsigned int uint; | 
|---|
 | 27 | int _alDetectx86CPUCaps(uint* caps1, uint* caps2, uint* caps3); | 
|---|
 | 28 |  | 
|---|
 | 29 |         /* caps1 */ | 
|---|
 | 30 | #define MMX_BIT             23 | 
|---|
 | 31 | #define SSE_BIT             25 | 
|---|
 | 32 | #define SSE2_BIT            26 | 
|---|
 | 33 |  | 
|---|
 | 34 |         /* caps2 */ | 
|---|
 | 35 | #define SSE3_BIT             0 | 
|---|
 | 36 |  | 
|---|
 | 37 |         /* caps3 */ | 
|---|
 | 38 | #define AMD_3DNOW_BIT       31 | 
|---|
 | 39 | #define AMD_3DNOWEXT_BIT    30 | 
|---|
 | 40 | #define AMD_SSE_MMX_BIT     22 | 
|---|
 | 41 | #define CYRIX_MMXEXT_BIT    24 | 
|---|
 | 42 |  | 
|---|
 | 43 |  | 
|---|
 | 44 | struct x86cpu_caps_s x86cpu_caps = { 0, 0, 0, 0, 0, 0, 0, 0}; | 
|---|
 | 45 | struct x86cpu_caps_s x86cpu_caps_use = { 1, 1, 1, 1, 1, 1, 1, 1}; | 
|---|
 | 46 |  | 
|---|
 | 47 | void _alDetectCPUCaps(void) | 
|---|
 | 48 | { | 
|---|
 | 49 |         /* compile time detection */ | 
|---|
 | 50 | #ifdef __MMX__ | 
|---|
 | 51 |         x86cpu_caps.mmx = 1; | 
|---|
 | 52 | #endif | 
|---|
 | 53 | #ifdef __SSE__ | 
|---|
 | 54 |         x86cpu_caps.sse = 1; | 
|---|
 | 55 | #endif | 
|---|
 | 56 | #ifdef __SSE2__ | 
|---|
 | 57 |         x86cpu_caps.sse2 = 1; | 
|---|
 | 58 | #endif | 
|---|
 | 59 | #ifdef __SSE3__ | 
|---|
 | 60 |         x86cpu_caps.sse3 = 1; | 
|---|
 | 61 | #endif | 
|---|
 | 62 | #ifdef __3dNOW__ | 
|---|
 | 63 |         x86cpu_caps.amd_3dnow = 1; | 
|---|
 | 64 | #ifdef __athlon__ | 
|---|
 | 65 |         x86cpu_caps.amd_sse_mmx = 1; | 
|---|
 | 66 | #endif | 
|---|
 | 67 | #endif | 
|---|
 | 68 | #ifdef __3dNOW_A__ | 
|---|
 | 69 |         x86cpu_caps.amd_3dnowext = 1; | 
|---|
 | 70 | #endif | 
|---|
 | 71 |         /* end compile time detection */ | 
|---|
 | 72 |          | 
|---|
 | 73 |         /* runtime detection */ | 
|---|
 | 74 | #ifdef HAVE_CPU_CAPS_DETECTION | 
|---|
 | 75 |         { | 
|---|
 | 76 |                 uint caps1, caps2, caps3; | 
|---|
 | 77 |                  | 
|---|
 | 78 |                 if (_alDetectx86CPUCaps(&caps1, &caps2, &caps3)) { | 
|---|
 | 79 |                          | 
|---|
 | 80 |                         x86cpu_caps.mmx &= (caps1 >> MMX_BIT) & 1; | 
|---|
 | 81 |                         x86cpu_caps.sse &= (caps1 >> SSE_BIT) & 1; | 
|---|
 | 82 |                         x86cpu_caps.sse2 &= (caps1 >> SSE2_BIT) & 1; | 
|---|
 | 83 |                          | 
|---|
 | 84 |                         x86cpu_caps.sse3 &= (caps2 >> SSE3_BIT) & 1; | 
|---|
 | 85 |                          | 
|---|
 | 86 |                         x86cpu_caps.amd_3dnow &= (caps3 >> AMD_3DNOW_BIT) & 1; | 
|---|
 | 87 |                         x86cpu_caps.amd_3dnowext &= (caps3 >> AMD_3DNOWEXT_BIT) & 1; | 
|---|
 | 88 |                         x86cpu_caps.amd_sse_mmx &= (caps3 >> AMD_SSE_MMX_BIT) & 1; | 
|---|
 | 89 |                         /* FIXME: For Cyrix MMXEXT detect Cyrix CPU first! */ | 
|---|
 | 90 |                         /* | 
|---|
 | 91 |                         x86cpu_caps.cyrix_mmxext = (caps3 >> CYRIX_MMXEXT_BIT) & 1; | 
|---|
 | 92 |                         */ | 
|---|
 | 93 |                 } | 
|---|
 | 94 |         } | 
|---|
 | 95 | #endif /*HAVE_CPU_CAPS_DETECTION*/ | 
|---|
 | 96 |         /* end runtime detection */ | 
|---|
 | 97 |          | 
|---|
 | 98 |         /* check environment vars */ | 
|---|
 | 99 |         { | 
|---|
 | 100 |                 char *env; | 
|---|
 | 101 |                  | 
|---|
 | 102 |                 env = getenv("OPENAL_DISABLE_MMX"); | 
|---|
 | 103 |                 if (env) | 
|---|
 | 104 |                         x86cpu_caps_use.mmx = !atoi(env); | 
|---|
 | 105 |                  | 
|---|
 | 106 |                 env = getenv("OPENAL_DISABLE_SSE"); | 
|---|
 | 107 |                 if (env) | 
|---|
 | 108 |                         x86cpu_caps_use.sse = !atoi(env); | 
|---|
 | 109 |                  | 
|---|
 | 110 |                 env = getenv("OPENAL_DISABLE_SSE2"); | 
|---|
 | 111 |                 if (env) | 
|---|
 | 112 |                         x86cpu_caps_use.sse2 = !atoi(env); | 
|---|
 | 113 |                  | 
|---|
 | 114 |                 env = getenv("OPENAL_DISABLE_SSE3"); | 
|---|
 | 115 |                 if (env) | 
|---|
 | 116 |                         x86cpu_caps_use.sse3 = !atoi(env); | 
|---|
 | 117 |                  | 
|---|
 | 118 |                 env = getenv("OPENAL_DISABLE_3DNOW"); | 
|---|
 | 119 |                 if (env) | 
|---|
 | 120 |                         x86cpu_caps_use.amd_3dnow = !atoi(env); | 
|---|
 | 121 |                  | 
|---|
 | 122 |                 env = getenv("OPENAL_DISABLE_3DNOWEXT"); | 
|---|
 | 123 |                 if (env) | 
|---|
 | 124 |                         x86cpu_caps_use.amd_3dnowext = !atoi(env); | 
|---|
 | 125 |                  | 
|---|
 | 126 |                 env = getenv("OPENAL_DISABLE_SSE_MMX"); | 
|---|
 | 127 |                 if (env) | 
|---|
 | 128 |                         x86cpu_caps_use.amd_sse_mmx = !atoi(env); | 
|---|
 | 129 |                  | 
|---|
 | 130 |                 env = getenv("OPENAL_DISABLE_SIMD"); | 
|---|
 | 131 |                 if (env  &&  atoi(env)) | 
|---|
 | 132 |                         memset(&x86cpu_caps_use, 0, sizeof x86cpu_caps_use); | 
|---|
 | 133 |         } | 
|---|
 | 134 |         /* end check environment vars */ | 
|---|
 | 135 |  | 
|---|
 | 136 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"mmx found %i  use %i", | 
|---|
 | 137 |                  x86cpu_caps.mmx, x86cpu_caps_use.mmx); | 
|---|
 | 138 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"sse found %i  use %i", | 
|---|
 | 139 |                  x86cpu_caps.sse, x86cpu_caps_use.sse); | 
|---|
 | 140 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"sse2 found %i  use %i", | 
|---|
 | 141 |                  x86cpu_caps.sse2, x86cpu_caps_use.sse2); | 
|---|
 | 142 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"sse3 found %i  use %i", | 
|---|
 | 143 |                  x86cpu_caps.sse3, x86cpu_caps_use.sse3); | 
|---|
 | 144 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"amd_3dnow found %i  use %i", | 
|---|
 | 145 |                  x86cpu_caps.amd_3dnow, x86cpu_caps_use.amd_3dnow); | 
|---|
 | 146 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"amd_3dnowext found %i  use %i", | 
|---|
 | 147 |                  x86cpu_caps.amd_3dnowext, x86cpu_caps_use.amd_3dnowext); | 
|---|
 | 148 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"amd_sse_mmx found %i  use %i", | 
|---|
 | 149 |                  x86cpu_caps.amd_sse_mmx, x86cpu_caps_use.amd_sse_mmx); | 
|---|
 | 150 |         /* | 
|---|
 | 151 |         _alDebug(ALD_CONFIG, __FILE__, __LINE__,"cyrix_mmxext found %i  use %i", | 
|---|
 | 152 |                  x86cpu_caps.cyrix_mmxext, x86cpu_caps_use.cyrix_mmxext); | 
|---|
 | 153 |         */ | 
|---|
 | 154 |  | 
|---|
 | 155 | } | 
|---|