| OLD | NEW |
| 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 /* | 7 /* |
| 8 * vcpuid.c | 8 * vcpuid.c |
| 9 * | 9 * |
| 10 * Verify correctness of CPUID implementation. | 10 * Verify correctness of CPUID implementation. |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 return 0; | 483 return 0; |
| 484 } else { | 484 } else { |
| 485 printf("no %s\n", s); | 485 printf("no %s\n", s); |
| 486 return 1; | 486 return 1; |
| 487 } | 487 } |
| 488 } | 488 } |
| 489 #else | 489 #else |
| 490 # error Please specify platform as NACL_LINUX, NACL_OSX or NACL_WINDOWS | 490 # error Please specify platform as NACL_LINUX, NACL_OSX or NACL_WINDOWS |
| 491 #endif | 491 #endif |
| 492 | 492 |
| 493 #if NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64) |
| 494 static int CheckCPUFeatureDetection(NaClCPUFeaturesX86* cpuf) { |
| 495 /* Unfortunately the asm_ tests will not work on 64-bit Windows */ |
| 496 return 0; |
| 497 } |
| 498 #else |
| 493 static int DoCPUFeatureTest(NaClCPUFeaturesX86 *features, | 499 static int DoCPUFeatureTest(NaClCPUFeaturesX86 *features, |
| 494 NaClCPUFeatureX86ID id, | 500 NaClCPUFeatureX86ID id, |
| 495 int (*thetest)(void)) { | 501 int (*thetest)(void)) { |
| 496 if (NaClGetCPUFeatureX86(features, id)) | 502 if (NaClGetCPUFeatureX86(features, id)) |
| 497 return DoTest(thetest, NaClGetCPUFeatureX86Name(id)); | 503 return DoTest(thetest, NaClGetCPUFeatureX86Name(id)); |
| 498 else | 504 else |
| 499 return 0; | 505 return 0; |
| 500 } | 506 } |
| 501 | 507 |
| 508 /* |
| 509 * Check if CPU feature detection is self-consistent. |
| 510 * Returns 0 on success and non-0 else. |
| 511 */ |
| 512 static int CheckCPUFeatureDetection(NaClCPUFeaturesX86* cpuf) { |
| 513 int rcode = 0; |
| 514 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_x87, asm_HasX87); |
| 515 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_MMX, asm_HasMMX); |
| 516 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSE, asm_HasSSE); |
| 517 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSE2, asm_HasSSE2); |
| 518 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_3DNOW, asm_Has3DNow); |
| 519 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSE3, asm_HasSSE3); |
| 520 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSSE3, asm_HasSSSE3); |
| 521 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSE41, asm_HasSSE41); |
| 522 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_SSE42, asm_HasSSE42); |
| 523 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_POPCNT, asm_HasPOPCNT); |
| 524 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_CMOV, asm_HasCMOV); |
| 525 rcode |= DoCPUFeatureTest(cpuf, NaClCPUFeatureX86_TSC, asm_HasTSC); |
| 526 |
| 527 #define TEST_NEGATIVE_CASE 0 |
| 528 #if TEST_NEGATIVE_CASE |
| 529 printf("TESTING: simulating invalid CPUID implementation\n"); |
| 530 rcode |= DoTest(asm_HasSSSE3, "SSSE3"); |
| 531 rcode |= DoTest(asm_HasSSE41, "SSE41"); |
| 532 rcode |= DoTest(asm_HasSSE42, "SSE42"); |
| 533 rcode |= DoTest(asm_HasPOPCNT, "POPCNT"); |
| 534 rcode |= DoTest(asm_HasCMOV, "CMOV"); |
| 535 #endif |
| 536 /* |
| 537 * TODO(brad): implement the rest of these tests |
| 538 * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX8, asm_HasCX8); |
| 539 * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX16, asm_HasCX16); |
| 540 * DoTest(asm_HasSSE4a, "SSE4a"); |
| 541 * DoTest(asm_HasEMMX, "EMMX"); |
| 542 * DoTest(asm_HasE3DNow, "E3DNow"); |
| 543 * what about LZCNT? |
| 544 */ |
| 545 return rcode; |
| 546 } |
| 547 #endif /* 64-bit Windows */ |
| 548 |
| 502 static void PrintFail(const char *why) { | 549 static void PrintFail(const char *why) { |
| 503 fprintf(stderr, "ERROR: %s.\n", why); | 550 fprintf(stderr, "ERROR: %s.\n", why); |
| 504 fprintf(stderr, "Google Native Client cannot continue.\n"); | 551 fprintf(stderr, "Google Native Client cannot continue.\n"); |
| 505 } | 552 } |
| 506 | 553 |
| 507 #define TEST_NEGATIVE_CASE 0 | |
| 508 int CPUIDImplIsValid(void) { | 554 int CPUIDImplIsValid(void) { |
| 509 NaClCPUFeaturesX86 cpuf; | 555 NaClCPUFeaturesX86 cpuf; |
| 510 NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &cpuf); | 556 NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &cpuf); |
| 511 | 557 |
| 512 if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUIDSupported)) { | 558 if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUIDSupported)) { |
| 513 PrintFail("CPUID not implemented"); | 559 PrintFail("CPUID not implemented"); |
| 514 return 0; | 560 return 0; |
| 515 } | 561 } |
| 516 if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUSupported)) { | 562 if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUSupported)) { |
| 517 PrintFail("CPU not supported"); | 563 PrintFail("CPU not supported"); |
| 518 return 0; | 564 return 0; |
| 519 } | 565 } |
| 520 | 566 if (CheckCPUFeatureDetection(&cpuf) != 0) { |
| 521 /* Unfortunately the asm_ tests will not work on 64-bit Windows */ | 567 PrintFail("CPUID not implemented correctly."); |
| 522 #if !(NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64)) | 568 return 0; |
| 523 { | |
| 524 int rcode = 0; | |
| 525 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_x87, asm_HasX87); | |
| 526 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_MMX, asm_HasMMX); | |
| 527 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE, asm_HasSSE); | |
| 528 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE2, asm_HasSSE2); | |
| 529 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_3DNOW, asm_Has3DNow); | |
| 530 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE3, asm_HasSSE3); | |
| 531 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSSE3, asm_HasSSSE3); | |
| 532 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE41, asm_HasSSE41); | |
| 533 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE42, asm_HasSSE42); | |
| 534 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_POPCNT, asm_HasPOPCNT); | |
| 535 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CMOV, asm_HasCMOV); | |
| 536 rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_TSC, asm_HasTSC); | |
| 537 | |
| 538 #if TEST_NEGATIVE_CASE | |
| 539 printf("TESTING: simulating invalid CPUID implementation\n"); | |
| 540 rcode |= DoTest(asm_HasSSSE3, "SSSE3"); | |
| 541 rcode |= DoTest(asm_HasSSE41, "SSE41"); | |
| 542 rcode |= DoTest(asm_HasSSE42, "SSE42"); | |
| 543 rcode |= DoTest(asm_HasPOPCNT, "POPCNT"); | |
| 544 rcode |= DoTest(asm_HasCMOV, "CMOV"); | |
| 545 #endif | |
| 546 /* | |
| 547 * TODO(brad): implement the rest of these tests | |
| 548 * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX8, asm_HasCX8); | |
| 549 * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX16, asm_HasCX16); | |
| 550 * DoTest(asm_HasSSE4a, "SSE4a"); | |
| 551 * DoTest(asm_HasEMMX, "EMMX"); | |
| 552 * DoTest(asm_HasE3DNow, "E3DNow"); | |
| 553 * what about LZCNT? | |
| 554 */ | |
| 555 if (rcode != 0) { | |
| 556 PrintFail("CPUID not implemented correctly."); | |
| 557 return 0; | |
| 558 } | |
| 559 } | 569 } |
| 560 #endif /* 64-bit Windows */ | |
| 561 | 570 |
| 562 printf("[CPUID implementation looks okay]\n"); | 571 printf("[CPUID implementation looks okay]\n"); |
| 563 return 1; | 572 return 1; |
| 564 } | 573 } |
| OLD | NEW |