| 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 | } | 
|---|