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 % 25 25
Test Date: 2026-04-07 14:16:30 Functions: 100.0 % 4 4
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              : #ifdef _MSC_VER
      21              : #include <intrin.h>
      22              : #else
      23              : #include <cpuid.h>
      24              : #endif
      25              : 
      26              : #ifdef HAVE_XSAVE_INTRINSICS
      27              : #include <immintrin.h>
      28              : #endif
      29              : 
      30              : #include "port/pg_cpu.h"
      31              : 
      32              : /*
      33              :  * XSAVE state component bits that we need
      34              :  *
      35              :  * https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf
      36              :  * Chapter "MANAGING STATE USING THE XSAVE FEATURE SET"
      37              :  */
      38              : #define XMM         (1<<1)
      39              : #define YMM         (1<<2)
      40              : #define OPMASK      (1<<5)
      41              : #define ZMM0_15     (1<<6)
      42              : #define ZMM16_31    (1<<7)
      43              : 
      44              : 
      45              : /* array indexed by enum X86FeatureId */
      46              : bool        X86Features[X86FeaturesSize] = {0};
      47              : 
      48              : static bool
      49         3306 : mask_available(uint32 value, uint32 mask)
      50              : {
      51         3306 :     return (value & mask) == mask;
      52              : }
      53              : 
      54              : /* Named indexes for CPUID register array */
      55              : #define EAX 0
      56              : #define EBX 1
      57              : #define ECX 2
      58              : #define EDX 3
      59              : 
      60              : /*
      61              :  * Request CPUID information for the specified leaf.
      62              :  */
      63              : static inline void
      64         1653 : pg_cpuid(int leaf, unsigned int *reg)
      65              : {
      66              : #if defined(HAVE__GET_CPUID)
      67         1653 :     __get_cpuid(leaf, &reg[EAX], &reg[EBX], &reg[ECX], &reg[EDX]);
      68              : #elif defined(HAVE__CPUID)
      69              :     __cpuid((int *) reg, leaf);
      70              : #else
      71              : #error cpuid instruction not available
      72              : #endif
      73         1653 : }
      74              : 
      75              : /*
      76              :  * Request CPUID information for the specified leaf and subleaf.
      77              :  *
      78              :  * Returns true if the CPUID leaf/subleaf is supported, false otherwise.
      79              :  */
      80              : static inline bool
      81         1653 : pg_cpuid_subleaf(int leaf, int subleaf, unsigned int *reg)
      82              : {
      83              : #if defined(HAVE__GET_CPUID_COUNT)
      84         1653 :     return __get_cpuid_count(leaf, subleaf, &reg[EAX], &reg[EBX], &reg[ECX], &reg[EDX]) == 1;
      85              : #elif defined(HAVE__CPUIDEX)
      86              :     __cpuidex((int *) reg, leaf, subleaf);
      87              :     return true;
      88              : #else
      89              :     memset(reg, 0, 4 * sizeof(unsigned int));
      90              :     return false;
      91              : #endif
      92              : }
      93              : 
      94              : /*
      95              :  * Parse the CPU ID info for runtime checks.
      96              :  */
      97              : #ifdef HAVE_XSAVE_INTRINSICS
      98              : pg_attribute_target("xsave")
      99              : #endif
     100              : void
     101         1653 : set_x86_features(void)
     102              : {
     103         1653 :     unsigned int reg[4] = {0};
     104              : 
     105         1653 :     pg_cpuid(0x01, reg);
     106              : 
     107         1653 :     X86Features[PG_SSE4_2] = reg[ECX] >> 20 & 1;
     108         1653 :     X86Features[PG_POPCNT] = reg[ECX] >> 23 & 1;
     109              : 
     110              :     /* leaf 7 features that depend on OSXSAVE */
     111         1653 :     if (reg[ECX] & (1 << 27))
     112              :     {
     113         1653 :         uint32      xcr0_val = 0;
     114              : 
     115         1653 :         pg_cpuid_subleaf(0x07, 0, reg);
     116              : 
     117              : #ifdef HAVE_XSAVE_INTRINSICS
     118              :         /* get value of Extended Control Register */
     119         1653 :         xcr0_val = _xgetbv(0);
     120              : #endif
     121              : 
     122              :         /* Are YMM registers enabled? */
     123         1653 :         if (mask_available(xcr0_val, XMM | YMM))
     124         1653 :             X86Features[PG_AVX2] = reg[EBX] >> 5 & 1;
     125              : 
     126              :         /* Are ZMM registers enabled? */
     127         1653 :         if (mask_available(xcr0_val, XMM | YMM |
     128              :                            OPMASK | ZMM0_15 | ZMM16_31))
     129              :         {
     130         1653 :             X86Features[PG_AVX512_BW] = reg[EBX] >> 30 & 1;
     131         1653 :             X86Features[PG_AVX512_VL] = reg[EBX] >> 31 & 1;
     132              : 
     133         1653 :             X86Features[PG_AVX512_VPCLMULQDQ] = reg[ECX] >> 10 & 1;
     134         1653 :             X86Features[PG_AVX512_VPOPCNTDQ] = reg[ECX] >> 14 & 1;
     135              :         }
     136              :     }
     137              : 
     138         1653 :     X86Features[INIT_PG_X86] = true;
     139         1653 : }
     140              : 
     141              : #endif                          /* defined(USE_SSE2) || defined(__i386__) */
        

Generated by: LCOV version 2.0-1