Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: src/trusted/cpu_features/arch/x86/cpu_x86.c

Issue 11864002: Move CPU features into its own static library. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Another go at Windows x64, with help from Noel. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include "native_client/src/trusted/validator/x86/nacl_cpuid.h" 7 #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h"
8 8
9 /* 9 /*
10 * nacl_cpuid.c 10 * cpu_x86.c
11 * Retrieve and decode CPU model specific feature mask. 11 * Retrieve and decode CPU model specific feature mask.
12 */ 12 */
13 #if NACL_WINDOWS 13 #if NACL_WINDOWS
14 #include <intrin.h> /* __cpuid intrinsic */ 14 #include <intrin.h> /* __cpuid intrinsic */
15 #endif /* NACL_WINDOWS */ 15 #endif /* NACL_WINDOWS */
16 16
17 #include <stdio.h> 17 #include <stdio.h>
18 #include <string.h> 18 #include <string.h>
19 #include <assert.h> 19 #include <assert.h>
20 #include <stdlib.h> 20 #include <stdlib.h>
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 static const char Cyrix_CPUID0[kVendorIDLength] = "CyrixInstead"; 237 static const char Cyrix_CPUID0[kVendorIDLength] = "CyrixInstead";
238 static const char NexGen_CPUID0[kVendorIDLength] = "NexGenDriven"; 238 static const char NexGen_CPUID0[kVendorIDLength] = "NexGenDriven";
239 static const char Cantaur_CPUID0[kVendorIDLength] = "CentaurHauls"; 239 static const char Cantaur_CPUID0[kVendorIDLength] = "CentaurHauls";
240 static const char Rise_CPUID0[kVendorIDLength] = "RiseRiseRise"; 240 static const char Rise_CPUID0[kVendorIDLength] = "RiseRiseRise";
241 static const char SiS_CPUID0[kVendorIDLength] = "SiS SiS SiS "; 241 static const char SiS_CPUID0[kVendorIDLength] = "SiS SiS SiS ";
242 static const char TM_CPUID0[kVendorIDLength] = "GenuineTMx86"; 242 static const char TM_CPUID0[kVendorIDLength] = "GenuineTMx86";
243 static const char NSC_CPUID0[kVendorIDLength] = "Geode by NSC"; 243 static const char NSC_CPUID0[kVendorIDLength] = "Geode by NSC";
244 #endif 244 #endif
245 245
246 static int asm_HasCPUID(void) { 246 static int asm_HasCPUID(void) {
247 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
247 volatile int before, after, result; 248 volatile int before, after, result;
248 #if NACL_BUILD_SUBARCH == 64 249 #if NACL_BUILD_SUBARCH == 64
249 /* Note: If we are running in x86-64, then cpuid must be defined, 250 /* Note: If we are running in x86-64, then cpuid must be defined,
250 * since CPUID dates from DX2 486, and x86-64 was added after this. 251 * since CPUID dates from DX2 486, and x86-64 was added after this.
251 */ 252 */
252 return 1; 253 return 1;
253 /* TODO(bradchen): split into separate Windows, etc., files */ 254 /* TODO(bradchen): split into separate Windows, etc., files */
254 #elif defined(__GNUC__) 255 #elif defined(__GNUC__)
255 __asm__ volatile("pushfl \n\t" /* save EFLAGS to eax */ 256 __asm__ volatile("pushfl \n\t" /* save EFLAGS to eax */
256 "pop %%eax \n\t" 257 "pop %%eax \n\t"
(...skipping 21 matching lines...) Expand all
278 push eax 279 push eax
279 popfd 280 popfd
280 pushfd 281 pushfd
281 pop after 282 pop after
282 } 283 }
283 #else 284 #else
284 # error Unsupported platform 285 # error Unsupported platform
285 #endif 286 #endif
286 result = (before ^ after) & 0x0200000; 287 result = (before ^ after) & 0x0200000;
287 return result; 288 return result;
289 #else /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */
290 return 0;
291 #endif
288 } 292 }
289 293
290 static void asm_CPUID(uint32_t op, volatile uint32_t reg[4]) { 294 static void asm_CPUID(uint32_t op, volatile uint32_t reg[4]) {
295 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
291 #if defined(__GNUC__) 296 #if defined(__GNUC__)
292 #if NACL_BUILD_SUBARCH == 64 297 #if NACL_BUILD_SUBARCH == 64
293 __asm__ volatile("push %%rbx \n\t" /* save %ebx */ 298 __asm__ volatile("push %%rbx \n\t" /* save %ebx */
294 #else 299 #else
295 __asm__ volatile("pushl %%ebx \n\t" 300 __asm__ volatile("pushl %%ebx \n\t"
296 #endif 301 #endif
297 "cpuid \n\t" 302 "cpuid \n\t"
298 "movl %%ebx, %1 \n\t" 303 "movl %%ebx, %1 \n\t"
299 /* save what cpuid just put in %ebx */ 304 /* save what cpuid just put in %ebx */
300 #if NACL_BUILD_SUBARCH == 64 305 #if NACL_BUILD_SUBARCH == 64
301 "pop %%rbx \n\t" 306 "pop %%rbx \n\t"
302 #else 307 #else
303 "popl %%ebx \n\t" /* restore the old %ebx */ 308 "popl %%ebx \n\t" /* restore the old %ebx */
304 #endif 309 #endif
305 : "=a"(reg[0]), "=S"(reg[1]), "=c"(reg[2]), "=d"(reg[3]) 310 : "=a"(reg[0]), "=S"(reg[1]), "=c"(reg[2]), "=d"(reg[3])
306 : "a"(op) 311 : "a"(op)
307 : "cc"); 312 : "cc");
308 #elif NACL_WINDOWS 313 #elif NACL_WINDOWS
309 __cpuid((uint32_t*)reg, op); 314 __cpuid((uint32_t*)reg, op);
310 #else 315 #else
311 # error Unsupported platform 316 # error Unsupported platform
312 #endif 317 #endif
318 #else /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */
319 UNREFERENCED_PARAMETER(op);
320 reg[0] = 0;
321 reg[1] = 0;
322 reg[2] = 0;
323 reg[3] = 0;
324 return;
325 #endif
313 } 326 }
314 327
315 /* 328 /*
316 * Historically CPUID only used eax to select "CPUID function". Function 07h 329 * Historically CPUID only used eax to select "CPUID function". Function 07h
317 * broke this tradition: it's now required to specify "leaf" in ECX register. 330 * broke this tradition: it's now required to specify "leaf" in ECX register.
318 * 331 *
319 * We can specify leaf in all cases (older "CPUID functions" will just ignore 332 * We can specify leaf in all cases (older "CPUID functions" will just ignore
320 * it), but there is a catch: MSVC 2005 or below don't include __cpuidex 333 * it), but there is a catch: MSVC 2005 or below don't include __cpuidex
321 * intrinsic required to call CPUID with leaf support! 334 * intrinsic required to call CPUID with leaf support!
322 * 335 *
323 * Thus we have two functions: asm_CPUID (for "CPUID functions" without leaves) 336 * Thus we have two functions: asm_CPUID (for "CPUID functions" without leaves)
324 * and asm_CPUIDx (for "CPUID functions" with leaves). If code is compiled using 337 * and asm_CPUIDx (for "CPUID functions" with leaves). If code is compiled using
325 * MSVC 2005 or MSVC 2008 then features detected using function 07h will not be 338 * MSVC 2005 or MSVC 2008 then features detected using function 07h will not be
326 * available. 339 * available.
327 * 340 *
328 * Note: MSVC 2008 is particularly problematic: MSVC 2008 does not support 341 * Note: MSVC 2008 is particularly problematic: MSVC 2008 does not support
329 * __cpuidex while MSVC 2008 SP1 does. Unfortunatelly there are no easy way 342 * __cpuidex while MSVC 2008 SP1 does. Unfortunatelly there are no easy way
330 * to distinguish MSVC 2008 SP1 from MSVC 2008 using ifdef's thus we disable 343 * to distinguish MSVC 2008 SP1 from MSVC 2008 using ifdef's thus we disable
331 * __cpuidex for MSVC 2008 unconditionally. 344 * __cpuidex for MSVC 2008 unconditionally.
332 */ 345 */
333 static void asm_CPUIDx(uint32_t op, volatile uint32_t reg[4], uint32_t ecx) { 346 static void asm_CPUIDx(uint32_t op, volatile uint32_t reg[4], uint32_t ecx) {
347 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
334 #if defined(__GNUC__) 348 #if defined(__GNUC__)
335 #if NACL_BUILD_SUBARCH == 64 349 #if NACL_BUILD_SUBARCH == 64
336 __asm__ volatile("push %%rbx \n\t" /* save %ebx */ 350 __asm__ volatile("push %%rbx \n\t" /* save %ebx */
337 #else 351 #else
338 __asm__ volatile("pushl %%ebx \n\t" 352 __asm__ volatile("pushl %%ebx \n\t"
339 #endif 353 #endif
340 "cpuid \n\t" 354 "cpuid \n\t"
341 "movl %%ebx, %1 \n\t" 355 "movl %%ebx, %1 \n\t"
342 /* save what cpuid just put in %ebx */ 356 /* save what cpuid just put in %ebx */
343 #if NACL_BUILD_SUBARCH == 64 357 #if NACL_BUILD_SUBARCH == 64
(...skipping 14 matching lines...) Expand all
358 #else 372 #else
359 __cpuidex((uint32_t*)reg, op, ecx); 373 __cpuidex((uint32_t*)reg, op, ecx);
360 #endif 374 #endif
361 #else /* NACL_WINDOWS, but _MSC_VER is not defined */ 375 #else /* NACL_WINDOWS, but _MSC_VER is not defined */
362 /* This is Windows but not MSVC: who knows if __cpuidex is available? */ 376 /* This is Windows but not MSVC: who knows if __cpuidex is available? */
363 # error Unsupported compiler 377 # error Unsupported compiler
364 #endif 378 #endif
365 #else 379 #else
366 # error Unsupported platform 380 # error Unsupported platform
367 #endif 381 #endif
382 #else /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */
383 UNREFERENCED_PARAMETER(op);
384 UNREFERENCED_PARAMETER(ecx);
385 reg[0] = 0;
386 reg[1] = 0;
387 reg[2] = 0;
388 reg[3] = 0;
389 return;
390 #endif
368 } 391 }
369 392
370 static void CacheCPUVersionID(NaClCPUData* data) { 393 static void CacheCPUVersionID(NaClCPUData* data) {
371 uint32_t reg[4] = {0, 0, 0, 0 }; 394 uint32_t reg[4] = {0, 0, 0, 0 };
372 asm_CPUID(0, reg); 395 asm_CPUID(0, reg);
373 data->_vidwords[0] = reg[1]; 396 data->_vidwords[0] = reg[1];
374 data->_vidwords[1] = reg[3]; 397 data->_vidwords[1] = reg[3];
375 data->_vidwords[2] = reg[2]; 398 data->_vidwords[2] = reg[2];
376 data->_vidwords[3] = 0; 399 data->_vidwords[3] = 0;
377 } 400 }
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 651
629 void NaClCopyCPUFeaturesX86(NaClCPUFeaturesX86 *target, 652 void NaClCopyCPUFeaturesX86(NaClCPUFeaturesX86 *target,
630 const NaClCPUFeaturesX86 *source) { 653 const NaClCPUFeaturesX86 *source) {
631 memcpy(target, source, sizeof(*target)); 654 memcpy(target, source, sizeof(*target));
632 } 655 }
633 656
634 int NaClArchSupportedX86(const NaClCPUFeaturesX86 *f) { 657 int NaClArchSupportedX86(const NaClCPUFeaturesX86 *f) {
635 return (NaClGetCPUFeatureX86(f, NaClCPUFeatureX86_CPUIDSupported) && 658 return (NaClGetCPUFeatureX86(f, NaClCPUFeatureX86_CPUIDSupported) &&
636 NaClGetCPUFeatureX86(f, NaClCPUFeatureX86_CPUSupported)); 659 NaClGetCPUFeatureX86(f, NaClCPUFeatureX86_CPUSupported));
637 } 660 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698