Showing the changes to codec/encoder/core/src/cpu.cpp (1 of 225 files). Show all
Unified · Split
| @@ -1,213 +1,196 @@ | |||
| 1 | /*! | 1 | /*! |
| 2 | * \copy | 2 | * \copy |
| 3 | * Copyright (c) 2009-2013, Cisco Systems | 3 | * Copyright (c) 2009-2013, Cisco Systems |
| 4 | * All rights reserved. | 4 | * All rights reserved. |
| 5 | * | 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: | 8 | * are met: |
| 9 | * | 9 | * |
| 10 | * * Redistributions of source code must retain the above copyright | 10 | * * Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * | 12 | * |
| 13 | * * Redistributions in binary form must reproduce the above copyright | 13 | * * Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in | 14 | * notice, this list of conditions and the following disclaimer in |
| 15 | * the documentation and/or other materials provided with the | 15 | * the documentation and/or other materials provided with the |
| 16 | * distribution. | 16 | * distribution. |
| 17 | * | 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. |
| 30 | * | 30 | * |
| 31 | * | 31 | * |
| 32 | * \file cpu.c | 32 | * \file cpu.c |
| 33 | * | 33 | * |
| 34 | * \brief CPU compatibility detection | 34 | * \brief CPU compatibility detection |
| 35 | * | 35 | * |
| 36 | * \date 04/29/2009 Created | 36 | * \date 04/29/2009 Created |
| 37 | * | 37 | * |
| 38 | ************************************************************************************* | 38 | ************************************************************************************* |
| 39 | */ | 39 | */ |
| 40 | 40 | ||
| 41 | #include <string.h> | 41 | #include <string.h> |
| 42 | 42 | ||
| 43 | #include "cpu.h" | 43 | #include "cpu.h" |
| 44 | #include "cpu_core.h" | 44 | #include "cpu_core.h" |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | namespace WelsSVCEnc { | 47 | namespace WelsSVCEnc { |
| 48 | #define CPU_Vender_AMD "AuthenticAMD" | 48 | #define CPU_Vender_AMD "AuthenticAMD" |
| 49 | #define CPU_Vender_INTEL "GenuineIntel" | 49 | #define CPU_Vender_INTEL "GenuineIntel" |
| 50 | #define CPU_Vender_CYRIX "CyrixInstead" | 50 | #define CPU_Vender_CYRIX "CyrixInstead" |
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | #if defined(X86_ASM) | 53 | #if defined(X86_ASM) |
| 54 | 54 | ||
| 55 | uint32_t WelsCPUFeatureDetect( int32_t *pNumberOfLogicProcessors ) | 55 | uint32_t WelsCPUFeatureDetect (int32_t* pNumberOfLogicProcessors) { |
| 56 | { | 56 | uint32_t uiCPU = 0; |
| 57 | uint32_t uiCPU = 0; | 57 | uint32_t uiFeatureA = 0, uiFeatureB = 0, uiFeatureC = 0, uiFeatureD = 0; |
| 58 | uint32_t uiFeatureA = 0, uiFeatureB = 0, uiFeatureC = 0, uiFeatureD = 0; | 58 | int32_t CacheLineSize = 0; |
| 59 | int32_t CacheLineSize = 0; | 59 | int8_t chVenderName[16] = { 0 }; |
| 60 | int8_t chVenderName[16] = { 0 }; | 60 | |
| 61 | 61 | if (!WelsCPUIdVerify()) { | |
| 62 | if( !WelsCPUIdVerify() ) | 62 | /* cpuid is not supported in cpu */ |
| 63 | { | 63 | return 0; |
| 64 | /* cpuid is not supported in cpu */ | 64 | } |
| 65 | return 0; | 65 | |
| 66 | } | 66 | WelsCPUId (0, &uiFeatureA, (uint32_t*)&chVenderName[0], (uint32_t*)&chVenderName[8], (uint32_t*)&chVenderName[4]); |
| 67 | 67 | if (uiFeatureA == 0) { | |
| 68 | WelsCPUId( 0, &uiFeatureA, (uint32_t*)&chVenderName[0],(uint32_t*)&chVenderName[8],(uint32_t*)&chVenderName[4] ); | 68 | /* maximum input value for basic cpuid information */ |
| 69 | if( uiFeatureA == 0 ) | 69 | return 0; |
| 70 | { | 70 | } |
| 71 | /* maximum input value for basic cpuid information */ | 71 | |
| 72 | return 0; | 72 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); |
| 73 | } | 73 | if ((uiFeatureD & 0x00800000) == 0) { |
| 74 | 74 | /* Basic MMX technology is not support in cpu, mean nothing for us so return here */ | |
| 75 | WelsCPUId( 1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD ); | 75 | return 0; |
| 76 | if( (uiFeatureD & 0x00800000) == 0 ) | 76 | } |
| 77 | { | 77 | |
| 78 | /* Basic MMX technology is not support in cpu, mean nothing for us so return here */ | 78 | uiCPU = WELS_CPU_MMX; |
| 79 | return 0; | 79 | if (uiFeatureD & 0x02000000) { |
| 80 | } | 80 | /* SSE technology is identical to AMD MMX extensions */ |
| 81 | 81 | uiCPU |= WELS_CPU_MMXEXT | WELS_CPU_SSE; | |
| 82 | uiCPU = WELS_CPU_MMX; | 82 | } |
| 83 | if( uiFeatureD & 0x02000000 ) | 83 | if (uiFeatureD & 0x04000000) { |
| 84 | { | 84 | /* SSE2 support here */ |
| 85 | /* SSE technology is identical to AMD MMX extensions */ | 85 | uiCPU |= WELS_CPU_SSE2; |
| 86 | uiCPU |= WELS_CPU_MMXEXT|WELS_CPU_SSE; | 86 | } |
| 87 | } | 87 | if (uiFeatureD & 0x00000001) { |
| 88 | if( uiFeatureD & 0x04000000 ) | 88 | /* x87 FPU on-chip checking */ |
| 89 | { | 89 | uiCPU |= WELS_CPU_FPU; |
| 90 | /* SSE2 support here */ | 90 | } |
| 91 | uiCPU |= WELS_CPU_SSE2; | 91 | if (uiFeatureD & 0x00008000) { |
| 92 | } | 92 | /* CMOV instruction checking */ |
| 93 | if ( uiFeatureD & 0x00000001 ) | 93 | uiCPU |= WELS_CPU_CMOV; |
| 94 | { | 94 | } |
| 95 | /* x87 FPU on-chip checking */ | 95 | if (!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) { // confirmed_safe_unsafe_usage |
| 96 | uiCPU |= WELS_CPU_FPU; | 96 | if (uiFeatureD & 0x10000000) { |
| 97 | } | 97 | /* Multi-Threading checking: contains of multiple logic processors */ |
| 98 | if ( uiFeatureD & 0x00008000 ) | 98 | uiCPU |= WELS_CPU_HTT; |
| 99 | { | 99 | } |
| 100 | /* CMOV instruction checking */ | 100 | } |
| 101 | uiCPU |= WELS_CPU_CMOV; | 101 | |
| 102 | } | 102 | if (uiFeatureC & 0x00000001) { |
| 103 | if ( !strcmp((const str_t*)chVenderName,CPU_Vender_INTEL) ) // confirmed_safe_unsafe_usage | 103 | /* SSE3 support here */ |
| 104 | { | 104 | uiCPU |= WELS_CPU_SSE3; |
| 105 | if ( uiFeatureD & 0x10000000 ) | 105 | } |
| 106 | { | 106 | if (uiFeatureC & 0x00000200) { |
| 107 | /* Multi-Threading checking: contains of multiple logic processors */ | 107 | /* SSSE3 support here */ |
| 108 | uiCPU |= WELS_CPU_HTT; | 108 | uiCPU |= WELS_CPU_SSSE3; |
| 109 | } | 109 | } |
| 110 | } | 110 | if (uiFeatureC & 0x00080000) { |
| 111 | 111 | /* SSE4.1 support here, 45nm Penryn processor */ | |
| 112 | if( uiFeatureC & 0x00000001 ){ | 112 | uiCPU |= WELS_CPU_SSE41; |
| 113 | /* SSE3 support here */ | 113 | } |
| 114 | uiCPU |= WELS_CPU_SSE3; | 114 | if (uiFeatureC & 0x00100000) { |
| 115 | } | 115 | /* SSE4.2 support here, next generation Nehalem processor */ |
| 116 | if( uiFeatureC & 0x00000200 ){ | 116 | uiCPU |= WELS_CPU_SSE42; |
| 117 | /* SSSE3 support here */ | 117 | } |
| 118 | uiCPU |= WELS_CPU_SSSE3; | 118 | if (WelsCPUSupportAVX (uiFeatureA, uiFeatureC)) { // |
| 119 | } | 119 | /* AVX supported */ |
| 120 | if( uiFeatureC & 0x00080000 ){ | 120 | uiCPU |= WELS_CPU_AVX; |
| 121 | /* SSE4.1 support here, 45nm Penryn processor */ | 121 | } |
| 122 | uiCPU |= WELS_CPU_SSE41; | 122 | if (WelsCPUSupportFMA (uiFeatureA, uiFeatureC)) { // |
| 123 | } | 123 | /* AVX FMA supported */ |
| 124 | if( uiFeatureC & 0x00100000 ){ | 124 | uiCPU |= WELS_CPU_FMA; |
| 125 | /* SSE4.2 support here, next generation Nehalem processor */ | 125 | } |
| 126 | uiCPU |= WELS_CPU_SSE42; | 126 | if (uiFeatureC & 0x02000000) { |
| 127 | } | 127 | /* AES checking */ |
| 128 | if ( WelsCPUSupportAVX( uiFeatureA, uiFeatureC ) ) // | 128 | uiCPU |= WELS_CPU_AES; |
| 129 | { | 129 | } |
| 130 | /* AVX supported */ | 130 | if (uiFeatureC & 0x00400000) { |
| 131 | uiCPU |= WELS_CPU_AVX; | 131 | /* MOVBE checking */ |
| 132 | } | 132 | uiCPU |= WELS_CPU_MOVBE; |
| 133 | if ( WelsCPUSupportFMA( uiFeatureA, uiFeatureC ) ) // | 133 | } |
| 134 | { | 134 | |
| 135 | /* AVX FMA supported */ | 135 | if (pNumberOfLogicProcessors != NULL) { |
| 136 | uiCPU |= WELS_CPU_FMA; | 136 | // HTT enabled on chip |
| 137 | } | 137 | *pNumberOfLogicProcessors = (uiFeatureB & 0x00ff0000) >> 16; // feature bits: 23-16 on returned EBX |
| 138 | if ( uiFeatureC & 0x02000000 ) | 138 | } |
| 139 | { | 139 | |
| 140 | /* AES checking */ | 140 | WelsCPUId (0x80000000, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); |
| 141 | uiCPU |= WELS_CPU_AES; | 141 | |
| 142 | } | 142 | if ((!strcmp ((const str_t*)chVenderName, CPU_Vender_AMD)) |
| 143 | if ( uiFeatureC & 0x00400000 ) | 143 | && (uiFeatureA >= 0x80000001)) { // confirmed_safe_unsafe_usage |
| 144 | { | 144 | WelsCPUId (0x80000001, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); |
| 145 | /* MOVBE checking */ | 145 | if (uiFeatureD & 0x00400000) { |
| 146 | uiCPU |= WELS_CPU_MOVBE; | 146 | uiCPU |= WELS_CPU_MMXEXT; |
| 147 | } | 147 | } |
| 148 | 148 | if (uiFeatureD & 0x80000000) { | |
| 149 | if ( pNumberOfLogicProcessors != NULL ) | 149 | uiCPU |= WELS_CPU_3DNOW; |
| 150 | { | 150 | } |
| 151 | // HTT enabled on chip | 151 | } |
| 152 | *pNumberOfLogicProcessors = (uiFeatureB & 0x00ff0000) >> 16; // feature bits: 23-16 on returned EBX | 152 | |
| 153 | } | 153 | if (!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) { // confirmed_safe_unsafe_usage |
| 154 | 154 | int32_t family, model; | |
| 155 | WelsCPUId( 0x80000000, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD ); | 155 | |
| 156 | 156 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | |
| 157 | if( (!strcmp((const str_t*)chVenderName,CPU_Vender_AMD)) && (uiFeatureA>=0x80000001) ){ // confirmed_safe_unsafe_usage | 157 | family = ((uiFeatureA >> 8) & 0xf) + ((uiFeatureA >> 20) & 0xff); |
| 158 | WelsCPUId(0x80000001, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD ); | 158 | model = ((uiFeatureA >> 4) & 0xf) + ((uiFeatureA >> 12) & 0xf0); |
| 159 | if( uiFeatureD&0x00400000 ){ | 159 | |
| 160 | uiCPU |= WELS_CPU_MMXEXT; | 160 | if ((family == 6) && (model == 9 || model == 13 || model == 14)) { |
| 161 | } | 161 | uiCPU &= ~ (WELS_CPU_SSE2 | WELS_CPU_SSE3); |
| 162 | if( uiFeatureD&0x80000000 ){ | 162 | } |
| 163 | uiCPU |= WELS_CPU_3DNOW; | 163 | } |
| 164 | } | 164 | |
| 165 | } | 165 | // get cache line size |
| 166 | 166 | if ((!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) | |
| 167 | if( !strcmp((const str_t*)chVenderName,CPU_Vender_INTEL) ){ // confirmed_safe_unsafe_usage | 167 | || ! (strcmp ((const str_t*)chVenderName, CPU_Vender_CYRIX))) { // confirmed_safe_unsafe_usage |
| 168 | int32_t family, model; | 168 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); |
| 169 | 169 | ||
| 170 | WelsCPUId(1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | 170 | CacheLineSize = (uiFeatureB & 0xff00) >> |
| 171 | family = ((uiFeatureA>>8)&0xf) + ((uiFeatureA>>20)&0xff); | 171 | 5; // ((clflush_line_size >> 8) << 3), CLFLUSH_line_size * 8 = CacheLineSize_in_byte |
| 172 | model = ((uiFeatureA>>4)&0xf) + ((uiFeatureA>>12)&0xf0); | 172 | |
| 173 | 173 | if (CacheLineSize == 128) { | |
| 174 | if( (family==6) && (model==9 || model==13 || model==14) ){ | 174 | uiCPU |= WELS_CPU_CACHELINE_128; |
| 175 | uiCPU &= ~(WELS_CPU_SSE2|WELS_CPU_SSE3); | 175 | } else if (CacheLineSize == 64) { |
| 176 | } | 176 | uiCPU |= WELS_CPU_CACHELINE_64; |
| 177 | } | 177 | } else if (CacheLineSize == 32) { |
| 178 | 178 | uiCPU |= WELS_CPU_CACHELINE_32; | |
| 179 | // get cache line size | 179 | } else if (CacheLineSize == 16) { |
| 180 | if( (!strcmp((const str_t*)chVenderName,CPU_Vender_INTEL)) || !(strcmp((const str_t*)chVenderName,CPU_Vender_CYRIX)) ){ // confirmed_safe_unsafe_usage | 180 | uiCPU |= WELS_CPU_CACHELINE_16; |
| 181 | WelsCPUId(1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | 181 | } |
| 182 | 182 | } | |
| 183 | CacheLineSize = (uiFeatureB&0xff00)>>5; // ((clflush_line_size >> 8) << 3), CLFLUSH_line_size * 8 = CacheLineSize_in_byte | 183 | |
| 184 | 184 | return uiCPU; | |
| 185 | if( CacheLineSize == 128 ){ | 185 | } |
| 186 | uiCPU |= WELS_CPU_CACHELINE_128; | 186 | |
| 187 | } | 187 | |
| 188 | else if( CacheLineSize == 64 ){ | 188 | void WelsCPURestore (const uint32_t kuiCPU) { |
| 189 | uiCPU |= WELS_CPU_CACHELINE_64; | 189 | if (kuiCPU & (WELS_CPU_MMX | WELS_CPU_MMXEXT | WELS_CPU_3DNOW | WELS_CPU_3DNOWEXT)) { |
| 190 | } | 190 | WelsEmms(); |
| 191 | else if( CacheLineSize == 32 ){ | 191 | } |
| 192 | uiCPU |= WELS_CPU_CACHELINE_32; | 192 | } |
| 193 | } | 193 | |
| 194 | else if( CacheLineSize == 16 ){ | 194 | #endif |
| 195 | uiCPU |= WELS_CPU_CACHELINE_16; | 195 | |
| 196 | } | 196 | } |
| 197 | } | ||
| 198 | |||
| 199 | return uiCPU; | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 203 | void WelsCPURestore( const uint32_t kuiCPU ) | ||
| 204 | { | ||
| 205 | if( kuiCPU & (WELS_CPU_MMX|WELS_CPU_MMXEXT|WELS_CPU_3DNOW|WELS_CPU_3DNOWEXT) ) | ||
| 206 | { | ||
| 207 | WelsEmms(); | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | #endif | ||
| 212 | |||
| 213 | } | ||