LCOV - code coverage report
Current view: directory - src/trusted/platform_qualify/arch/x86 - vcpuid.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 132 104 78.8 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       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
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * vcpuid.c
       9                 :  *
      10                 :  * Verify correctness of CPUID implementation.
      11                 :  *
      12                 :  * This uses shell status code to indicate its result; non-zero return
      13                 :  * code indicates the CPUID instruction is not implemented or not
      14                 :  * implemented correctly.
      15                 :  *
      16                 :  * The asm_ tests use inline assembler, which is not supported on
      17                 :  * 64-bit Windows. We use #if to prevent these routines from being
      18                 :  * provided on 64-bit Windows.
      19                 :  *
      20                 :  * TODO(bradchen): test on a machine with SSE4.
      21                 :  */
      22                 : #include "native_client/src/include/portability.h"
      23                 : #include <stdio.h>
      24                 : #include <string.h>
      25                 : #include <assert.h>
      26                 : #include <stdlib.h>
      27                 : #include <setjmp.h>
      28                 : #include <signal.h>
      29                 : #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h"
      30                 : #include "native_client/src/trusted/platform_qualify/nacl_cpuwhitelist.h"
      31                 : 
      32                 : /* MAGIC_CONST is a 32 bit constant, somewhat arbitrarily choosen. */
      33                 : /* The value should be a valid (i.e. not denormal single-precision */
      34                 : /* float; otherwise unexpected FP exceptions are possible.         */
      35                 : const int kMagicConst = 0xc01df00d;
      36                 : const int kMagicConst_ROUNDSS = 0xc0000000;
      37                 : const int kMagicConst_POPCNT = 13;
      38                 : const int kMagicConst_CRC32  = 0xb906c3ea;
      39                 : 
      40                 : #if !(NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64))
      41                 : static int asm_HasMMX(void) {
      42               1 :   volatile int before, after;
      43               1 :   before = kMagicConst;
      44                 : #if defined(__GNUC__)
      45               1 :   __asm__ volatile("mov %1, %%eax         \n\t"
      46                 :                    "xor %%ecx, %%ecx      \n\t"
      47                 :                    "movd %%eax, %%mm0     \n\t" /* copy eax into mm0 (MMX) */
      48                 :                    "movd %%mm0, %%ecx     \n\t" /* copy mm0 into ecx (MMX) */
      49                 :                    "mov %%ecx, %0         \n\t"
      50                 :                    : "=g" (after)
      51                 :                    : "m" (before)
      52                 :                    : "eax", "ecx", "mm0" );
      53                 : #elif NACL_WINDOWS
      54                 :   __asm {
      55                 :       mov eax, before
      56                 :       xor ecx, ecx
      57                 :       movd mm0, eax
      58                 :       movd ecx, mm0
      59                 :       mov after, ecx
      60                 :   }
      61                 : #else
      62                 : # error Unsupported platform
      63                 : #endif
      64               1 :   return (after == kMagicConst);
      65                 : }
      66                 : 
      67                 : /* TODO(brad): Test this routine on a machine with 3DNow */
      68                 : static int asm_Has3DNow(void) {
      69               0 :   volatile int before, after;
      70               0 :   before = kMagicConst;
      71                 : #if defined(__GNUC__)
      72               0 :   __asm__ volatile("mov %1, %%eax         \n\t"
      73                 :                    "movd %%eax, %%mm0     \n\t" /* copy eax into mm0 (MMX) */
      74                 :                    "pfadd %%mm0, %%mm0    \n\t" /* 3DNow! */
      75                 :                    "movd %%mm0, %%ecx     \n\t" /* copy mm0 into ecx (MMX) */
      76                 :                    "mov %%ecx, %0         \n\t"
      77                 :                    "emms                  \n\t"
      78                 :                    : "=g" (after)
      79                 :                    : "m" (before)
      80                 :                    : "%eax", "%ecx");
      81                 : #elif NACL_WINDOWS
      82                 :   __asm {
      83                 :       mov eax, before
      84                 :       movd mm0, eax
      85                 :       pfadd mm0, mm0
      86                 :       movd ecx, mm0
      87                 :       mov after, ecx
      88                 :       emms
      89                 :   }
      90                 : #else
      91                 : # error Unsupported platform
      92                 : #endif
      93               0 :   return (after == kMagicConst + 0x800000);
      94                 : }
      95                 : 
      96                 : 
      97                 : static int asm_HasSSE(void) {
      98               1 :   volatile int before, after;
      99               1 :   before = kMagicConst;
     100               1 :   after = 0;
     101                 : #if defined(__GNUC__)
     102               1 :   __asm__ volatile("movss  %1, %%xmm0     \n\t"
     103                 :                    /* copy before into xmm0 (SSE2) */
     104                 :                    "movss %%xmm0, %0      \n\t" /* copy xmm0 into after (SSE) */
     105                 :                    : "=g" (after)
     106                 :                    : "m" (before)
     107                 :                    : "xmm0" );
     108                 : #elif NACL_WINDOWS
     109                 :   __asm {
     110                 :     movss xmm0, before
     111                 :     movss after, xmm0
     112                 :   }
     113                 : #else
     114                 : # error Unsupported platform
     115                 : #endif
     116               1 :   return (after == kMagicConst);
     117                 : }
     118                 : 
     119                 : static int asm_HasSSE2(void) {
     120               1 :   volatile int before, after;
     121               1 :   before = kMagicConst;
     122                 : #if defined(__GNUC__)
     123               1 :   __asm__ volatile("mov %1, %%eax         \n\t"
     124                 :                    "xor %%ecx, %%ecx      \n\t"
     125                 :                    "movd %%eax, %%xmm0    \n\t" /* copy eax into xmm0 (SSE2) */
     126                 :                    "movd %%xmm0, %%ecx    \n\t" /* copy xmm0 into ecx (SSE2) */
     127                 :                    "mov %%ecx, %0         \n\t"
     128                 :                    : "=g" (after)
     129                 :                    : "m" (before)
     130                 :                    : "eax", "ecx", "xmm0");
     131                 : #elif NACL_WINDOWS
     132                 :   __asm {
     133                 :     mov eax, before
     134                 :     xor ecx, ecx
     135                 :     movd xmm0, eax
     136                 :     movd ecx, xmm0
     137                 :     mov after, ecx
     138                 :   }
     139                 : #else
     140                 : # error Unsupported platform
     141                 : #endif
     142               1 :   return (after == kMagicConst);
     143                 : }
     144                 : 
     145                 : static int asm_HasSSE3(void) {
     146               1 :   volatile int before, after;
     147               1 :   after = 0;
     148               1 :   before = kMagicConst;
     149                 : #if defined(__GNUC__)
     150               1 :   __asm__ volatile("mov %1, %%eax             \n\t"
     151                 :                    "movd %%eax, %%xmm0        \n\t"
     152                 :                    "movddup %%xmm0, %%xmm1    \n\t"
     153                 :                    "movd %%xmm1, %%ecx        \n\t"
     154                 :                    "mov %%ecx, %0             \n\t"
     155                 :                    : "=g" (after)
     156                 :                    : "m" (before)
     157                 :                    : "eax", "ecx", "xmm0", "xmm1" );
     158                 : #elif NACL_WINDOWS
     159                 :   __asm {
     160                 :     mov eax, before
     161                 :     movd xmm0, eax
     162                 :     movddup xmm1, xmm0
     163                 :     movd ecx, xmm1
     164                 :     mov after, ecx
     165                 :   }
     166                 : #else
     167                 : # error Unsupported platform
     168                 : #endif
     169               1 :   return (after == kMagicConst);
     170                 : }
     171                 : 
     172                 : static int asm_HasSSSE3(void) {
     173               1 :   volatile int after;
     174                 : #if defined(__GNUC__)
     175               1 :   __asm__ volatile("mov $0x0000ffff, %%eax  \n\t"
     176                 :                    "xor %%ecx, %%ecx        \n\t"
     177                 :                    "movd %%eax, %%mm0       \n\t" /* copy eax into mm0 (MMX) */
     178                 :                    /* pabsw will change 0x0000ffff to 0x00000001 */
     179                 :                    "pabsw %%mm0, %%mm0      \n\t"
     180                 :                    "movd %%mm0, %%ecx       \n\t" /* copy mm0 into ecx (MMX) */
     181                 :                    "mov %%ecx, %0           \n\t"
     182                 :                    "emms                    \n\t"
     183                 :                    : "=g" (after)
     184                 :                    :
     185                 :                    : "eax", "ecx", "mm0");
     186                 : #elif NACL_WINDOWS
     187                 :   __asm {
     188                 :     mov eax, 0x0000ffff
     189                 :     xor ecx, ecx
     190                 :     movd mm0, eax
     191                 :     pabsw mm0, mm0
     192                 :     movd ecx, mm0
     193                 :     mov after, ecx
     194                 :     emms
     195                 :   }
     196                 : #else
     197                 : # error Unsupported platform
     198                 : #endif
     199               1 :   return (after == 1);
     200                 : }
     201                 : 
     202                 : static int asm_HasSSE41(void) {
     203               1 :   volatile int before, after;
     204               1 :   before = kMagicConst;
     205                 : #if defined(__GNUC__)
     206               1 :   __asm__ volatile("mov %1, %%eax              \n\t"
     207                 :                    "movd %%eax, %%xmm0         \n\t"
     208                 :                    "roundss $0, %%xmm0, %%xmm0 \n\t"
     209                 :                    "movd %%xmm0, %%ecx         \n\t"
     210                 :                    "mov %%ecx, %0              \n\t"
     211                 :                    : "=g" (after)
     212                 :                    : "g" (before)
     213                 :                    : "eax", "ecx", "xmm0" );
     214                 : #elif NACL_WINDOWS
     215                 :   __asm {
     216                 :     mov eax, before
     217                 :     movd xmm0, eax
     218                 :     /*
     219                 :      * NOTE: Use _emit for older MSFT compilers that don't know of SSE4
     220                 :      * 66 0f 3a 0a c0 00      roundss $0, xmm0, xmm0
     221                 :      */
     222                 :     _emit 0x66
     223                 :     _emit 0x0f
     224                 :     _emit 0x3a
     225                 :     _emit 0x0a
     226                 :     _emit 0xc0
     227                 :     _emit 0x00
     228                 :     movd ecx, xmm0
     229                 :     mov after, ecx
     230                 :   }
     231                 : #else
     232                 : # error Unsupported platform
     233                 : #endif
     234               1 :   return (after == kMagicConst_ROUNDSS);
     235                 : }
     236                 : 
     237                 : static int asm_HasSSE42(void) {
     238               1 :   volatile int after;
     239                 : #if defined(__GNUC__)
     240               1 :   __asm__ volatile("mov $0x0000ffff, %%eax  \n\t"
     241                 :                    "xor %%ecx, %%ecx        \n\t"
     242                 :                    "crc32 %%eax, %%ecx      \n\t"
     243                 :                    "mov %%ecx, %0           \n\t"
     244                 :                    : "=g" (after)
     245                 :                    :
     246                 :                    : "eax", "ecx" );
     247                 : #elif NACL_WINDOWS
     248                 :   __asm {
     249                 :     mov eax, 0x0000ffff
     250                 :     xor ecx, ecx
     251                 :     /*
     252                 :      * NOTE: Use _emit for older MSFT compilers that don't know of SSE4
     253                 :      * f2 0f 38 f1 c8   crc32 ecx, eax
     254                 :      */
     255                 :     _emit 0xf2
     256                 :     _emit 0x0f
     257                 :     _emit 0x38
     258                 :     _emit 0xf1
     259                 :     _emit 0xc8
     260                 :     mov after, ecx
     261                 :   }
     262                 : #else
     263                 : # error Unsupported platform
     264                 : #endif
     265               1 :   return (after == kMagicConst_CRC32);
     266                 : }
     267                 : 
     268                 : static int asm_HasPOPCNT(void) {
     269               1 :   volatile int before, after;
     270               1 :   before = kMagicConst;
     271                 : #if defined(__GNUC__)
     272               1 :   __asm__ volatile("mov %1, %%eax         \n\t"
     273                 :                    "xor %%ecx, %%ecx      \n\t"
     274                 :                    "popcnt %%eax, %%ecx   \n\t"
     275                 :                    "mov %%ecx, %0         \n\t"
     276                 :                    : "=g" (after)
     277                 :                    : "m" (before)
     278                 :                    : "eax", "ecx");
     279                 : #elif NACL_WINDOWS
     280                 :   __asm {
     281                 :     mov eax, before
     282                 :     xor ecx, ecx
     283                 :     /*
     284                 :      * NOTE: Use _emit for older MSFT compilers that don't know of SSE4
     285                 :      * f3 0f b8 c8   popcnt ecx, eax
     286                 :      */
     287                 :     _emit 0xf3
     288                 :     _emit 0x0f
     289                 :     _emit 0xb8
     290                 :     _emit 0xc8
     291                 :     mov after, ecx
     292                 :   }
     293                 : #else
     294                 : # error Unsupported platform
     295                 : #endif
     296               1 :   return (after == kMagicConst_POPCNT);
     297                 : }
     298                 : 
     299                 : static int asm_HasCMOV(void) {
     300               1 :   volatile int before, after;
     301               1 :   before = kMagicConst;
     302                 : #if defined(__GNUC__)
     303               1 :   __asm__ volatile("mov %1, %%eax          \n\t"
     304                 :                    "xor %%ecx, %%ecx       \n\t"
     305                 :                    "add $0, %%eax          \n\t"  /* to set condition code */
     306                 :                    "cmovnz %%eax, %%ecx    \n\t"
     307                 :                    "mov %%ecx, %0          \n\t"
     308                 :                    : "=g" (after)
     309                 :                    : "m" (before)
     310                 :                    : "eax", "ecx");
     311                 : #elif NACL_WINDOWS
     312                 :   __asm {
     313                 :     mov eax, before
     314                 :     xor ecx, ecx
     315                 :     add eax, 0
     316                 :     cmovnz ecx, eax
     317                 :     mov after, ecx
     318                 :   }
     319                 : #else
     320                 : # error Unsupported platform
     321                 : #endif
     322               1 :   return (after == kMagicConst);
     323                 : }
     324                 : 
     325                 : static int asm_HasTSC(void) {
     326               1 :   uint32_t _eax, _edx;
     327               1 :   _eax = 0;
     328               1 :   _edx = 0;
     329                 : 
     330                 : #if defined(__GNUC__)
     331               1 :   __asm__ volatile("rdtsc"
     332                 :                    : "=a" (_eax), "=d" (_edx)
     333                 :                    );
     334                 : #elif NACL_WINDOWS
     335                 :   __asm {
     336                 :     rdtsc
     337                 :     mov _eax, eax
     338                 :     mov _edx, ecx
     339                 :   }
     340                 : #else
     341                 : # error Unsupported platform
     342                 : #endif
     343               1 :   return ((_eax | _edx) != 0);
     344                 : }
     345                 : 
     346                 : static int asm_HasX87(void) {
     347                 : #if defined(__GNUC__)
     348               1 :   __asm__ volatile("fld1          \n\t"
     349                 :                    "fstp %st(0)    \n\t");
     350               1 :   return 1;
     351                 : #elif NACL_WINDOWS
     352                 :   __asm {
     353                 :     fld1
     354                 :     fstp st(0)
     355                 :   }
     356                 :   return 1;
     357                 : #else
     358                 : # error Unsupported platform
     359                 : #endif
     360                 : }
     361                 : 
     362                 : #if 0
     363                 : /* I'm having some trouble with my cmpxchg8b instruction */
     364                 : static int asm_HasCX8(void) {
     365                 :   uint32_t _eax, _ebx, _ecx, _edx;
     366                 :   uint64_t foo64 = 0;
     367                 :   _eax = 0;
     368                 :   _edx = 0;
     369                 :   _ebx = 0;
     370                 :   _ecx = kMagicConst;
     371                 : 
     372                 : #if defined(__GNUC__)
     373                 :   __asm__ volatile("cmpxchg8b %0   \n\t"
     374                 :                    : "=g" (foo64), "=b" (_ebx), "=c" (_ecx)
     375                 :                    : "a" (_eax), "d" (_edx) );
     376                 : #elif NACL_WINDOWS
     377                 :   __asm {
     378                 :   }
     379                 : #else
     380                 : # error Unsupported platform
     381                 : #endif
     382                 :   printf("ebx == %x  ecx == %x\n", _ebx, _ecx);
     383                 :   return (foo64 == (uint64_t)kMagicConst);
     384                 : }
     385                 : #endif  /* 0 */
     386                 : #endif  /* 64-bit Windows */
     387                 : 
     388                 : #if (NACL_LINUX || NACL_OSX)
     389                 : /* Linux/MacOS signal handling code, for trapping illegal instruction faults */
     390                 : static int sawbadinstruction = 0;
     391                 : static struct sigaction crash_detect;
     392                 : static int signum;
     393                 : 
     394                 : sigjmp_buf crash_load;
     395                 : 
     396               0 : void  handler_load(int  signum) {
     397               0 :   siglongjmp(crash_load, signum);
     398               0 : }
     399                 : 
     400              11 : void  all_sigs(struct sigaction *new_action,
     401              11 :                struct sigaction *prev_action) {
     402              11 :   int               sig;
     403              11 :   struct sigaction  ign;
     404                 : 
     405             704 :   for (sig = SIGHUP; sig < NSIG; ++sig) {
     406             341 :     switch (sig) {
     407                 :       case SIGWINCH:
     408                 :       case SIGCHLD:
     409                 :       case SIGTSTP:
     410              33 :         break;
     411                 :       default:
     412             308 :         (void) sigaction(sig, new_action, prev_action);
     413             308 :         break;
     414                 :     }
     415             341 :   }
     416              11 :   ign.sa_handler = SIG_DFL;
     417              11 :   sigemptyset(&ign.sa_mask);
     418              11 :   ign.sa_flags = SA_ONSTACK;
     419              11 :   (void) sigaction(SIGWINCH, &ign, 0);
     420              11 :   (void) sigaction(SIGCHLD, &ign, 0);
     421              11 :   (void) sigaction(SIGTSTP, &ign, 0);
     422              11 : }
     423                 : 
     424                 : static void SignalInit(void) {
     425              11 :   sawbadinstruction = 0;
     426              11 :   crash_detect.sa_handler = handler_load;
     427              11 :   sigemptyset(&crash_detect.sa_mask);
     428              11 :   crash_detect.sa_flags = SA_RESETHAND;
     429              11 :   all_sigs(&crash_detect, 0);
     430              11 : }
     431                 : 
     432                 : static void SetSawBadInst(void) {
     433               0 :   sawbadinstruction = 1;
     434               0 : }
     435                 : 
     436                 : static int SawBadInst(void) {
     437              22 :   return sawbadinstruction != 0;
     438                 : }
     439                 : 
     440                 : /*
     441                 :  * DoTest tests for a particular CPU feature using thetest().
     442                 :  * It returns 0 if the feature is present, 1 if it is not.
     443                 :  */
     444              11 : static int DoTest(int (*thetest)(void), const char *s) {
     445              11 :   SignalInit();
     446              11 :   if (0 != (signum = sigsetjmp(crash_load, 1))) {
     447               0 :     SetSawBadInst();
     448               0 :     if (SIGILL == signum) {
     449               0 :       fprintf(stderr, "%s: illegal instruction\n", s);
     450               0 :     } else {
     451               0 :       fprintf(stderr, "%s: signal %d received\n", s, signum);
     452                 :     }
     453               0 :   }
     454              11 :   if (! SawBadInst()) {
     455              11 :     int hasfeature = thetest();
     456              22 :     if (hasfeature && (! SawBadInst())) {
     457              11 :       printf("[Has %s]\n", s);
     458              11 :       return 0;
     459                 :     }
     460               0 :   }
     461               0 :   printf("no %s\n", s);
     462               0 :   return 1;
     463              11 : }
     464                 : #elif NACL_WINDOWS
     465                 : /* Windows signal handling code, for trapping illegal instruction faults */
     466                 : /*
     467                 :  * DoTest tests for a particular CPU feature using thetest().
     468                 :  * It returns 0 if the feature is present, 1 if it is not.
     469                 :  */
     470                 : static int DoTest(int (*thetest)(void), const char *s) {
     471                 :   int hasfeature = 0;
     472                 : 
     473                 :   __try {
     474                 :     hasfeature = thetest();
     475                 :   } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION ?
     476                 :               EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
     477                 :     printf("Saw exception\n");
     478                 :     hasfeature = 0;
     479                 :   }
     480                 :   if (hasfeature) {
     481                 :     printf("[Has %s]\n", s);
     482                 :     return 0;
     483                 :   } else {
     484                 :     printf("no %s\n", s);
     485                 :     return 1;
     486                 :   }
     487                 : }
     488                 : #else
     489                 : # error Please specify platform as NACL_LINUX, NACL_OSX or NACL_WINDOWS
     490                 : #endif
     491                 : 
     492              12 : static int DoCPUFeatureTest(NaClCPUFeaturesX86 *features,
     493              12 :                             NaClCPUFeatureX86ID id,
     494              12 :                             int (*thetest)(void)) {
     495              12 :   if (NaClGetCPUFeatureX86(features, id))
     496              11 :     return DoTest(thetest, NaClGetCPUFeatureX86Name(id));
     497                 :   else
     498               1 :     return 0;
     499              12 : }
     500                 : 
     501               0 : static void PrintFail(const char *why) {
     502               0 :   fprintf(stderr, "ERROR: %s.\n", why);
     503               0 :   fprintf(stderr, "Google Native Client cannot continue.\n");
     504               0 : }
     505                 : 
     506                 : #define TEST_NEGATIVE_CASE 0
     507                 : int CPUIDImplIsValid(void) {
     508               2 :   int rcode = 0;
     509               1 :   NaClCPUFeaturesX86 cpuf;
     510               1 :   NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &cpuf);
     511                 : 
     512               1 :   if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUIDSupported)) {
     513               0 :     PrintFail("CPUID not implemented");
     514               0 :     return 0;
     515                 :   }
     516               1 :   if (!NaClGetCPUFeatureX86(&cpuf, NaClCPUFeatureX86_CPUSupported)) {
     517               0 :     PrintFail("CPU not supported");
     518               0 :     return 0;
     519                 :   }
     520                 : 
     521                 : #if (NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64))
     522                 :   /* Unfortunately the asm_ tests will not work on 64-bit Windows */
     523                 :   return 1;
     524                 : #else
     525               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_x87, asm_HasX87);
     526               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_MMX, asm_HasMMX);
     527               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE, asm_HasSSE);
     528               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE2, asm_HasSSE2);
     529               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_3DNOW, asm_Has3DNow);
     530               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE3, asm_HasSSE3);
     531               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSSE3, asm_HasSSSE3);
     532               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE41, asm_HasSSE41);
     533               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_SSE42, asm_HasSSE42);
     534               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_POPCNT, asm_HasPOPCNT);
     535               1 :   rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CMOV, asm_HasCMOV);
     536               1 :   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                 : #endif  /* 64-bit Windows */
     547                 :   /*
     548                 :    * TODO(brad): implement the rest of these tests
     549                 :    * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX8, asm_HasCX8);
     550                 :    * rcode |= DoCPUFeatureTest(&cpuf, NaClCPUFeatureX86_CX16, asm_HasCX16);
     551                 :    * DoTest(asm_HasSSE4a, "SSE4a");
     552                 :    * DoTest(asm_HasEMMX, "EMMX");
     553                 :    * DoTest(asm_HasE3DNow, "E3DNow");
     554                 :    * what about LZCNT?
     555                 :    */
     556               1 :   if (rcode != 0) {
     557               0 :     PrintFail("CPUID not implemented correctly.");
     558               0 :     return 0;
     559                 :   }
     560               1 :   printf("[CPUID implementation looks okay]\n");
     561               1 :   return 1;
     562               1 : }

Generated by: LCOV version 1.7