LCOV - code coverage report
Current view: top level - src/port - pg_cpu_x86.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 19 19
Test Date: 2026-03-03 15:15:20 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * pg_cpu_x86.c
       4              :  *    Runtime CPU feature detection for x86
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/port/pg_cpu_x86.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : 
      16              : #include "c.h"
      17              : 
      18              : #if defined(USE_SSE2) || defined(__i386__)
      19              : 
      20              : #if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
      21              : #include <cpuid.h>
      22              : #endif
      23              : 
      24              : #if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
      25              : #include <intrin.h>
      26              : #endif
      27              : 
      28              : #ifdef HAVE_XSAVE_INTRINSICS
      29              : #include <immintrin.h>
      30              : #endif
      31              : 
      32              : #include "port/pg_cpu.h"
      33              : 
      34              : /*
      35              :  * XSAVE state component bits that we need
      36              :  *
      37              :  * https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf
      38              :  * Chapter "MANAGING STATE USING THE XSAVE FEATURE SET"
      39              :  */
      40              : #define XMM         (1<<1)
      41              : #define YMM         (1<<2)
      42              : #define OPMASK      (1<<5)
      43              : #define ZMM0_15     (1<<6)
      44              : #define ZMM16_31    (1<<7)
      45              : 
      46              : 
      47              : /* array indexed by enum X86FeatureId */
      48              : bool        X86Features[X86FeaturesSize] = {0};
      49              : 
      50              : static bool
      51         1501 : mask_available(uint32 value, uint32 mask)
      52              : {
      53         1501 :     return (value & mask) == mask;
      54              : }
      55              : 
      56              : /*
      57              :  * Parse the CPU ID info for runtime checks.
      58              :  */
      59              : #ifdef HAVE_XSAVE_INTRINSICS
      60              : pg_attribute_target("xsave")
      61              : #endif
      62              : void
      63         1501 : set_x86_features(void)
      64              : {
      65         1501 :     unsigned int exx[4] = {0, 0, 0, 0};
      66              : 
      67              : #if defined(HAVE__GET_CPUID)
      68         1501 :     __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
      69              : #elif defined(HAVE__CPUID)
      70              :     __cpuid(exx, 1);
      71              : #else
      72              : #error cpuid instruction not available
      73              : #endif
      74              : 
      75         1501 :     X86Features[PG_SSE4_2] = exx[2] >> 20 & 1;
      76         1501 :     X86Features[PG_POPCNT] = exx[2] >> 23 & 1;
      77              : 
      78              :     /* All these features depend on OSXSAVE */
      79         1501 :     if (exx[2] & (1 << 27))
      80              :     {
      81         1501 :         uint32      xcr0_val = 0;
      82              : 
      83              :         /* second cpuid call on leaf 7 to check extended AVX-512 support */
      84              : 
      85         1501 :         memset(exx, 0, 4 * sizeof(exx[0]));
      86              : 
      87              : #if defined(HAVE__GET_CPUID_COUNT)
      88         1501 :         __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]);
      89              : #elif defined(HAVE__CPUIDEX)
      90              :         __cpuidex(exx, 7, 0);
      91              : #endif
      92              : 
      93              : #ifdef HAVE_XSAVE_INTRINSICS
      94              :         /* get value of Extended Control Register */
      95         1501 :         xcr0_val = _xgetbv(0);
      96              : #endif
      97              : 
      98              :         /* Are ZMM registers enabled? */
      99         1501 :         if (mask_available(xcr0_val, XMM | YMM |
     100              :                            OPMASK | ZMM0_15 | ZMM16_31))
     101              :         {
     102         1501 :             X86Features[PG_AVX512_BW] = exx[1] >> 30 & 1;
     103         1501 :             X86Features[PG_AVX512_VL] = exx[1] >> 31 & 1;
     104              : 
     105         1501 :             X86Features[PG_AVX512_VPCLMULQDQ] = exx[2] >> 10 & 1;
     106         1501 :             X86Features[PG_AVX512_VPOPCNTDQ] = exx[2] >> 14 & 1;
     107              :         }
     108              :     }
     109              : 
     110         1501 :     X86Features[INIT_PG_X86] = true;
     111         1501 : }
     112              : 
     113              : #endif                          /* defined(USE_SSE2) || defined(__i386__) */
        

Generated by: LCOV version 2.0-1