Blame sysdeps/x86/cpu-features.c

Packit Service 82fcde
/* Initialize CPU feature data.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Copyright (C) 2008-2018 Free Software Foundation, Inc.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <cpuid.h>
Packit Service 82fcde
#include <cpu-features.h>
Packit Service 82fcde
#include <dl-hwcap.h>
Packit Service 82fcde
#include <libc-pointer-arith.h>
Packit Service 82fcde
Packit Service 82fcde
#if HAVE_TUNABLES
Packit Service 82fcde
# define TUNABLE_NAMESPACE tune
Packit Service 82fcde
# include <unistd.h>		/* Get STDOUT_FILENO for _dl_printf.  */
Packit Service 82fcde
# include <elf/dl-tunables.h>
Packit Service 82fcde
Packit Service 82fcde
extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
Packit Service 82fcde
  attribute_hidden;
Packit Service 82fcde
Packit Service 82fcde
# if CET_ENABLED
Packit Service 82fcde
extern void TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *)
Packit Service 82fcde
  attribute_hidden;
Packit Service 82fcde
extern void TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *)
Packit Service 82fcde
  attribute_hidden;
Packit Service 82fcde
# endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if CET_ENABLED
Packit Service 82fcde
# include <dl-cet.h>
Packit Service 82fcde
# include <cet-tunables.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
get_extended_indices (struct cpu_features *cpu_features)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int eax, ebx, ecx, edx;
Packit Service 82fcde
  __cpuid (0x80000000, eax, ebx, ecx, edx);
Packit Service 82fcde
  if (eax >= 0x80000001)
Packit Service 82fcde
    __cpuid (0x80000001,
Packit Service 82fcde
	     cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].eax,
Packit Service 82fcde
	     cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].ebx,
Packit Service 82fcde
	     cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].ecx,
Packit Service 82fcde
	     cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].edx);
Packit Service 82fcde
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
get_common_indeces (struct cpu_features *cpu_features,
Packit Service 82fcde
		    unsigned int *family, unsigned int *model,
Packit Service 82fcde
		    unsigned int *extended_model, unsigned int *stepping)
Packit Service 82fcde
{
Packit Service 82fcde
  if (family)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int eax;
Packit Service 82fcde
      __cpuid (1, eax, cpu_features->cpuid[COMMON_CPUID_INDEX_1].ebx,
Packit Service 82fcde
	       cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx,
Packit Service 82fcde
	       cpu_features->cpuid[COMMON_CPUID_INDEX_1].edx);
Packit Service 82fcde
      cpu_features->cpuid[COMMON_CPUID_INDEX_1].eax = eax;
Packit Service 82fcde
      *family = (eax >> 8) & 0x0f;
Packit Service 82fcde
      *model = (eax >> 4) & 0x0f;
Packit Service 82fcde
      *extended_model = (eax >> 12) & 0xf0;
Packit Service 82fcde
      *stepping = eax & 0x0f;
Packit Service 82fcde
      if (*family == 0x0f)
Packit Service 82fcde
	{
Packit Service 82fcde
	  *family += (eax >> 20) & 0xff;
Packit Service 82fcde
	  *model += *extended_model;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->max_cpuid >= 7)
Packit Service 82fcde
    __cpuid_count (7, 0,
Packit Service 82fcde
		   cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax,
Packit Service 82fcde
		   cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx,
Packit Service 82fcde
		   cpu_features->cpuid[COMMON_CPUID_INDEX_7].ecx,
Packit Service 82fcde
		   cpu_features->cpuid[COMMON_CPUID_INDEX_7].edx);
Packit Service 82fcde
Packit Service 82fcde
  /* Can we call xgetbv?  */
Packit Service 82fcde
  if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int xcrlow;
Packit Service 82fcde
      unsigned int xcrhigh;
Packit Service 82fcde
      asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0));
Packit Service 82fcde
      /* Is YMM and XMM state usable?  */
Packit Service 82fcde
      if ((xcrlow & (bit_YMM_state | bit_XMM_state)) ==
Packit Service 82fcde
	  (bit_YMM_state | bit_XMM_state))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Determine if AVX is usable.  */
Packit Service 82fcde
	  if (CPU_FEATURES_CPU_P (cpu_features, AVX))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      cpu_features->feature[index_arch_AVX_Usable]
Packit Service 82fcde
		|= bit_arch_AVX_Usable;
Packit Service 82fcde
	      /* The following features depend on AVX being usable.  */
Packit Service 82fcde
	      /* Determine if AVX2 is usable.  */
Packit Service 82fcde
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX2))
Packit Service 82fcde
	      {
Packit Service 82fcde
		cpu_features->feature[index_arch_AVX2_Usable]
Packit Service 82fcde
		  |= bit_arch_AVX2_Usable;
Packit Service 82fcde
Packit Service 82fcde
	        /* Unaligned load with 256-bit AVX registers are faster on
Packit Service 82fcde
	           Intel/AMD processors with AVX2.  */
Packit Service 82fcde
	        cpu_features->feature[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 82fcde
		  |= bit_arch_AVX_Fast_Unaligned_Load;
Packit Service 82fcde
	      }
Packit Service 82fcde
	      /* Determine if FMA is usable.  */
Packit Service 82fcde
	      if (CPU_FEATURES_CPU_P (cpu_features, FMA))
Packit Service 82fcde
		cpu_features->feature[index_arch_FMA_Usable]
Packit Service 82fcde
		  |= bit_arch_FMA_Usable;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Check if OPMASK state, upper 256-bit of ZMM0-ZMM15 and
Packit Service 82fcde
	     ZMM16-ZMM31 state are enabled.  */
Packit Service 82fcde
	  if ((xcrlow & (bit_Opmask_state | bit_ZMM0_15_state
Packit Service 82fcde
			 | bit_ZMM16_31_state)) ==
Packit Service 82fcde
	      (bit_Opmask_state | bit_ZMM0_15_state | bit_ZMM16_31_state))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Determine if AVX512F is usable.  */
Packit Service 82fcde
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX512F))
Packit Service 82fcde
		{
Packit Service 82fcde
		  cpu_features->feature[index_arch_AVX512F_Usable]
Packit Service 82fcde
		    |= bit_arch_AVX512F_Usable;
Packit Service 82fcde
		  /* Determine if AVX512DQ is usable.  */
Packit Service 82fcde
		  if (CPU_FEATURES_CPU_P (cpu_features, AVX512DQ))
Packit Service 82fcde
		    cpu_features->feature[index_arch_AVX512DQ_Usable]
Packit Service 82fcde
		      |= bit_arch_AVX512DQ_Usable;
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* For _dl_runtime_resolve, set xsave_state_size to xsave area
Packit Service 82fcde
	 size + integer register save size and align it to 64 bytes.  */
Packit Service 82fcde
      if (cpu_features->max_cpuid >= 0xd)
Packit Service 82fcde
	{
Packit Service 82fcde
	  unsigned int eax, ebx, ecx, edx;
Packit Service 82fcde
Packit Service 82fcde
	  __cpuid_count (0xd, 0, eax, ebx, ecx, edx);
Packit Service 82fcde
	  if (ebx != 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      unsigned int xsave_state_full_size
Packit Service 82fcde
		= ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64);
Packit Service 82fcde
Packit Service 82fcde
	      cpu_features->xsave_state_size
Packit Service 82fcde
		= xsave_state_full_size;
Packit Service 82fcde
	      cpu_features->xsave_state_full_size
Packit Service 82fcde
		= xsave_state_full_size;
Packit Service 82fcde
Packit Service 82fcde
	      __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
	      /* Check if XSAVEC is available.  */
Packit Service 82fcde
	      if ((eax & (1 << 1)) != 0)
Packit Service 82fcde
		{
Packit Service 82fcde
		  unsigned int xstate_comp_offsets[32];
Packit Service 82fcde
		  unsigned int xstate_comp_sizes[32];
Packit Service 82fcde
		  unsigned int i;
Packit Service 82fcde
Packit Service 82fcde
		  xstate_comp_offsets[0] = 0;
Packit Service 82fcde
		  xstate_comp_offsets[1] = 160;
Packit Service 82fcde
		  xstate_comp_offsets[2] = 576;
Packit Service 82fcde
		  xstate_comp_sizes[0] = 160;
Packit Service 82fcde
		  xstate_comp_sizes[1] = 256;
Packit Service 82fcde
Packit Service 82fcde
		  for (i = 2; i < 32; i++)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      if ((STATE_SAVE_MASK & (1 << i)) != 0)
Packit Service 82fcde
			{
Packit Service 82fcde
			  __cpuid_count (0xd, i, eax, ebx, ecx, edx);
Packit Service 82fcde
			  xstate_comp_sizes[i] = eax;
Packit Service 82fcde
			}
Packit Service 82fcde
		      else
Packit Service 82fcde
			{
Packit Service 82fcde
			  ecx = 0;
Packit Service 82fcde
			  xstate_comp_sizes[i] = 0;
Packit Service 82fcde
			}
Packit Service 82fcde
Packit Service 82fcde
		      if (i > 2)
Packit Service 82fcde
			{
Packit Service 82fcde
			  xstate_comp_offsets[i]
Packit Service 82fcde
			    = (xstate_comp_offsets[i - 1]
Packit Service 82fcde
			       + xstate_comp_sizes[i -1]);
Packit Service 82fcde
			  if ((ecx & (1 << 1)) != 0)
Packit Service 82fcde
			    xstate_comp_offsets[i]
Packit Service 82fcde
			      = ALIGN_UP (xstate_comp_offsets[i], 64);
Packit Service 82fcde
			}
Packit Service 82fcde
		    }
Packit Service 82fcde
Packit Service 82fcde
		  /* Use XSAVEC.  */
Packit Service 82fcde
		  unsigned int size
Packit Service 82fcde
		    = xstate_comp_offsets[31] + xstate_comp_sizes[31];
Packit Service 82fcde
		  if (size)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      cpu_features->xsave_state_size
Packit Service 82fcde
			= ALIGN_UP (size + STATE_SAVE_OFFSET, 64);
Packit Service 82fcde
		      cpu_features->feature[index_arch_XSAVEC_Usable]
Packit Service 82fcde
			|= bit_arch_XSAVEC_Usable;
Packit Service 82fcde
		    }
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static inline void
Packit Service 82fcde
init_cpu_features (struct cpu_features *cpu_features)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int ebx, ecx, edx;
Packit Service 82fcde
  unsigned int family = 0;
Packit Service 82fcde
  unsigned int model = 0;
Packit Service 82fcde
  enum cpu_features_kind kind;
Packit Service 82fcde
Packit Service 82fcde
#if !HAS_CPUID
Packit Service 82fcde
  if (__get_cpuid_max (0, 0) == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      kind = arch_kind_other;
Packit Service 82fcde
      goto no_cpuid;
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  __cpuid (0, cpu_features->max_cpuid, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
  /* This spells out "GenuineIntel".  */
Packit Service 82fcde
  if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int extended_model, stepping;
Packit Service 82fcde
Packit Service 82fcde
      kind = arch_kind_intel;
Packit Service 82fcde
Packit Service 82fcde
      get_common_indeces (cpu_features, &family, &model, &extended_model,
Packit Service 82fcde
			  &stepping);
Packit Service 82fcde
Packit Service 82fcde
      get_extended_indices (cpu_features);
Packit Service 82fcde
Packit Service 82fcde
      if (family == 0x06)
Packit Service 82fcde
	{
Packit Service 82fcde
	  model += extended_model;
Packit Service 82fcde
	  switch (model)
Packit Service 82fcde
	    {
Packit Service 82fcde
	    case 0x1c:
Packit Service 82fcde
	    case 0x26:
Packit Service 82fcde
	      /* BSF is slow on Atom.  */
Packit Service 82fcde
	      cpu_features->feature[index_arch_Slow_BSF]
Packit Service 82fcde
		|= bit_arch_Slow_BSF;
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	    case 0x57:
Packit Service 82fcde
	      /* Knights Landing.  Enable Silvermont optimizations.  */
Packit Service 82fcde
Packit Service 82fcde
	    case 0x5c:
Packit Service 82fcde
	    case 0x5f:
Packit Service 82fcde
	      /* Unaligned load versions are faster than SSSE3
Packit Service 82fcde
		 on Goldmont.  */
Packit Service 82fcde
Packit Service 82fcde
	    case 0x4c:
Packit Service 82fcde
	      /* Airmont is a die shrink of Silvermont.  */
Packit Service 82fcde
Packit Service 82fcde
	    case 0x37:
Packit Service 82fcde
	    case 0x4a:
Packit Service 82fcde
	    case 0x4d:
Packit Service 82fcde
	    case 0x5a:
Packit Service 82fcde
	    case 0x5d:
Packit Service 82fcde
	      /* Unaligned load versions are faster than SSSE3
Packit Service 82fcde
		 on Silvermont.  */
Packit Service 82fcde
#if index_arch_Fast_Unaligned_Load != index_arch_Prefer_PMINUB_for_stringop
Packit Service 82fcde
# error index_arch_Fast_Unaligned_Load != index_arch_Prefer_PMINUB_for_stringop
Packit Service 82fcde
#endif
Packit Service 82fcde
#if index_arch_Fast_Unaligned_Load != index_arch_Slow_SSE4_2
Packit Service 82fcde
# error index_arch_Fast_Unaligned_Load != index_arch_Slow_SSE4_2
Packit Service 82fcde
#endif
Packit Service 82fcde
#if index_arch_Fast_Unaligned_Load != index_arch_Fast_Unaligned_Copy
Packit Service 82fcde
# error index_arch_Fast_Unaligned_Load != index_arch_Fast_Unaligned_Copy
Packit Service 82fcde
#endif
Packit Service 82fcde
	      cpu_features->feature[index_arch_Fast_Unaligned_Load]
Packit Service 82fcde
		|= (bit_arch_Fast_Unaligned_Load
Packit Service 82fcde
		    | bit_arch_Fast_Unaligned_Copy
Packit Service 82fcde
		    | bit_arch_Prefer_PMINUB_for_stringop
Packit Service 82fcde
		    | bit_arch_Slow_SSE4_2);
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	    default:
Packit Service 82fcde
	      /* Unknown family 0x06 processors.  Assuming this is one
Packit Service 82fcde
		 of Core i3/i5/i7 processors if AVX is available.  */
Packit Service 82fcde
	      if (!CPU_FEATURES_CPU_P (cpu_features, AVX))
Packit Service 82fcde
		break;
Packit Service 82fcde
Packit Service 82fcde
	    case 0x1a:
Packit Service 82fcde
	    case 0x1e:
Packit Service 82fcde
	    case 0x1f:
Packit Service 82fcde
	    case 0x25:
Packit Service 82fcde
	    case 0x2c:
Packit Service 82fcde
	    case 0x2e:
Packit Service 82fcde
	    case 0x2f:
Packit Service 82fcde
	      /* Rep string instructions, unaligned load, unaligned copy,
Packit Service 82fcde
		 and pminub are fast on Intel Core i3, i5 and i7.  */
Packit Service 82fcde
#if index_arch_Fast_Rep_String != index_arch_Fast_Unaligned_Load
Packit Service 82fcde
# error index_arch_Fast_Rep_String != index_arch_Fast_Unaligned_Load
Packit Service 82fcde
#endif
Packit Service 82fcde
#if index_arch_Fast_Rep_String != index_arch_Prefer_PMINUB_for_stringop
Packit Service 82fcde
# error index_arch_Fast_Rep_String != index_arch_Prefer_PMINUB_for_stringop
Packit Service 82fcde
#endif
Packit Service 82fcde
#if index_arch_Fast_Rep_String != index_arch_Fast_Unaligned_Copy
Packit Service 82fcde
# error index_arch_Fast_Rep_String != index_arch_Fast_Unaligned_Copy
Packit Service 82fcde
#endif
Packit Service 82fcde
	      cpu_features->feature[index_arch_Fast_Rep_String]
Packit Service 82fcde
		|= (bit_arch_Fast_Rep_String
Packit Service 82fcde
		    | bit_arch_Fast_Unaligned_Load
Packit Service 82fcde
		    | bit_arch_Fast_Unaligned_Copy
Packit Service 82fcde
		    | bit_arch_Prefer_PMINUB_for_stringop);
Packit Service 82fcde
	      break;
Packit Service 9ddf77
	    }
Packit Service 82fcde
Packit Service 9ddf77
	 /* Disable TSX on some Haswell processors to avoid TSX on kernels that
Packit Service 9ddf77
	    weren't updated with the latest microcode package (which disables
Packit Service 9ddf77
	    broken feature by default).  */
Packit Service 9ddf77
	 switch (model)
Packit Service 9ddf77
	    {
Packit Service 82fcde
	    case 0x3f:
Packit Service 82fcde
	      /* Xeon E7 v3 with stepping >= 4 has working TSX.  */
Packit Service 82fcde
	      if (stepping >= 4)
Packit Service 82fcde
		break;
Packit Service 82fcde
	    case 0x3c:
Packit Service 82fcde
	    case 0x45:
Packit Service 82fcde
	    case 0x46:
Packit Service 82fcde
	      /* Disable Intel TSX on Haswell processors (except Xeon E7 v3
Packit Service 82fcde
		 with stepping >= 4) to avoid TSX on kernels that weren't
Packit Service 82fcde
		 updated with the latest microcode package (which disables
Packit Service 82fcde
		 broken feature by default).  */
Packit Service 82fcde
	      cpu_features->cpuid[index_cpu_RTM].reg_RTM &= ~bit_cpu_RTM;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
      /* Since AVX512ER is unique to Xeon Phi, set Prefer_No_VZEROUPPER
Packit Service 82fcde
         if AVX512ER is available.  Don't use AVX512 to avoid lower CPU
Packit Service 82fcde
	 frequency if AVX512ER isn't available.  */
Packit Service 82fcde
      if (CPU_FEATURES_CPU_P (cpu_features, AVX512ER))
Packit Service 82fcde
	cpu_features->feature[index_arch_Prefer_No_VZEROUPPER]
Packit Service 82fcde
	  |= bit_arch_Prefer_No_VZEROUPPER;
Packit Service 82fcde
      else
Packit Service 82fcde
	cpu_features->feature[index_arch_Prefer_No_AVX512]
Packit Service 82fcde
	  |= bit_arch_Prefer_No_AVX512;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* This spells out "AuthenticAMD".  */
Packit Service 82fcde
  else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int extended_model, stepping;
Packit Service 82fcde
Packit Service 82fcde
      kind = arch_kind_amd;
Packit Service 82fcde
Packit Service 82fcde
      get_common_indeces (cpu_features, &family, &model, &extended_model,
Packit Service 82fcde
			  &stepping);
Packit Service 82fcde
Packit Service 82fcde
      get_extended_indices (cpu_features);
Packit Service 82fcde
Packit Service 82fcde
      ecx = cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx;
Packit Service 82fcde
Packit Service 82fcde
      if (HAS_ARCH_FEATURE (AVX_Usable))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Since the FMA4 bit is in COMMON_CPUID_INDEX_80000001 and
Packit Service 82fcde
	     FMA4 requires AVX, determine if FMA4 is usable here.  */
Packit Service 82fcde
	  if (CPU_FEATURES_CPU_P (cpu_features, FMA4))
Packit Service 82fcde
	    cpu_features->feature[index_arch_FMA4_Usable]
Packit Service 82fcde
	      |= bit_arch_FMA4_Usable;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (family == 0x15)
Packit Service 82fcde
	{
Packit Service 82fcde
#if index_arch_Fast_Unaligned_Load != index_arch_Fast_Copy_Backward
Packit Service 82fcde
# error index_arch_Fast_Unaligned_Load != index_arch_Fast_Copy_Backward
Packit Service 82fcde
#endif
Packit Service 82fcde
	  /* "Excavator"   */
Packit Service 82fcde
	  if (model >= 0x60 && model <= 0x7f)
Packit Service 82fcde
	  {
Packit Service 82fcde
	    cpu_features->feature[index_arch_Fast_Unaligned_Load]
Packit Service 82fcde
	      |= (bit_arch_Fast_Unaligned_Load
Packit Service 82fcde
		  | bit_arch_Fast_Copy_Backward);
Packit Service 82fcde
Packit Service 82fcde
	    /* Unaligned AVX loads are slower.*/
Packit Service 82fcde
	    cpu_features->feature[index_arch_AVX_Fast_Unaligned_Load]
Packit Service 82fcde
		  &= ~bit_arch_AVX_Fast_Unaligned_Load;
Packit Service 82fcde
	  }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      kind = arch_kind_other;
Packit Service 82fcde
      get_common_indeces (cpu_features, NULL, NULL, NULL, NULL);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Support i586 if CX8 is available.  */
Packit Service 82fcde
  if (CPU_FEATURES_CPU_P (cpu_features, CX8))
Packit Service 82fcde
    cpu_features->feature[index_arch_I586] |= bit_arch_I586;
Packit Service 82fcde
Packit Service 82fcde
  /* Support i686 if CMOV is available.  */
Packit Service 82fcde
  if (CPU_FEATURES_CPU_P (cpu_features, CMOV))
Packit Service 82fcde
    cpu_features->feature[index_arch_I686] |= bit_arch_I686;
Packit Service 82fcde
Packit Service 82fcde
#if !HAS_CPUID
Packit Service 82fcde
no_cpuid:
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  cpu_features->family = family;
Packit Service 82fcde
  cpu_features->model = model;
Packit Service 82fcde
  cpu_features->kind = kind;
Packit Service 82fcde
Packit Service 82fcde
#if HAVE_TUNABLES
Packit Service 82fcde
  TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
Packit Service 82fcde
  cpu_features->non_temporal_threshold
Packit Service 82fcde
    = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL);
Packit Service 82fcde
  cpu_features->data_cache_size
Packit Service 82fcde
    = TUNABLE_GET (x86_data_cache_size, long int, NULL);
Packit Service 82fcde
  cpu_features->shared_cache_size
Packit Service 82fcde
    = TUNABLE_GET (x86_shared_cache_size, long int, NULL);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86.  */
Packit Service 82fcde
#if !HAVE_TUNABLES && defined SHARED
Packit Service 82fcde
  /* The glibc.tune.hwcap_mask tunable is initialized already, so no need to do
Packit Service 82fcde
     this.  */
Packit Service 82fcde
  GLRO(dl_hwcap_mask) = HWCAP_IMPORTANT;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef __x86_64__
Packit Service 82fcde
  GLRO(dl_hwcap) = HWCAP_X86_64;
Packit Service 82fcde
  if (cpu_features->kind == arch_kind_intel)
Packit Service 82fcde
    {
Packit Service 82fcde
      const char *platform = NULL;
Packit Service 82fcde
Packit Service 82fcde
      if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, AVX512CD))
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (CPU_FEATURES_CPU_P (cpu_features, AVX512ER))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX512PF))
Packit Service 82fcde
		platform = "xeon_phi";
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (CPU_FEATURES_CPU_P (cpu_features, AVX512BW)
Packit Service 82fcde
		  && CPU_FEATURES_CPU_P (cpu_features, AVX512DQ)
Packit Service 82fcde
		  && CPU_FEATURES_CPU_P (cpu_features, AVX512VL))
Packit Service 82fcde
		GLRO(dl_hwcap) |= HWCAP_X86_AVX512_1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (platform == NULL
Packit Service 82fcde
	  && CPU_FEATURES_ARCH_P (cpu_features, AVX2_Usable)
Packit Service 82fcde
	  && CPU_FEATURES_ARCH_P (cpu_features, FMA_Usable)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, BMI1)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, BMI2)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, LZCNT)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, MOVBE)
Packit Service 82fcde
	  && CPU_FEATURES_CPU_P (cpu_features, POPCNT))
Packit Service 82fcde
	platform = "haswell";
Packit Service 82fcde
Packit Service 82fcde
      if (platform != NULL)
Packit Service 82fcde
	GLRO(dl_platform) = platform;
Packit Service 82fcde
    }
Packit Service 82fcde
#else
Packit Service 82fcde
  GLRO(dl_hwcap) = 0;
Packit Service 82fcde
  if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
Packit Service 82fcde
    GLRO(dl_hwcap) |= HWCAP_X86_SSE2;
Packit Service 82fcde
Packit Service 82fcde
  if (CPU_FEATURES_ARCH_P (cpu_features, I686))
Packit Service 82fcde
    GLRO(dl_platform) = "i686";
Packit Service 82fcde
  else if (CPU_FEATURES_ARCH_P (cpu_features, I586))
Packit Service 82fcde
    GLRO(dl_platform) = "i586";
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if CET_ENABLED
Packit Service 82fcde
# if HAVE_TUNABLES
Packit Service 82fcde
  TUNABLE_GET (x86_ibt, tunable_val_t *,
Packit Service 82fcde
	       TUNABLE_CALLBACK (set_x86_ibt));
Packit Service 82fcde
  TUNABLE_GET (x86_shstk, tunable_val_t *,
Packit Service 82fcde
	       TUNABLE_CALLBACK (set_x86_shstk));
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
  /* Check CET status.  */
Packit Service 82fcde
  unsigned int cet_status = get_cet_status ();
Packit Service 82fcde
Packit Service 82fcde
  if (cet_status)
Packit Service 82fcde
    {
Packit Service 82fcde
      GL(dl_x86_feature_1)[0] = cet_status;
Packit Service 82fcde
Packit Service 82fcde
# ifndef SHARED
Packit Service 82fcde
      /* Check if IBT and SHSTK are enabled by kernel.  */
Packit Service 82fcde
      if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT)
Packit Service 82fcde
	  || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Disable IBT and/or SHSTK if they are enabled by kernel, but
Packit Service 82fcde
	     disabled by environment variable:
Packit Service 82fcde
Packit Service 82fcde
	     GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK
Packit Service 82fcde
	   */
Packit Service 82fcde
	  unsigned int cet_feature = 0;
Packit Service 82fcde
	  if (!HAS_CPU_FEATURE (IBT))
Packit Service 82fcde
	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
Packit Service 82fcde
	  if (!HAS_CPU_FEATURE (SHSTK))
Packit Service 82fcde
	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
Packit Service 82fcde
Packit Service 82fcde
	  if (cet_feature)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      int res = dl_cet_disable_cet (cet_feature);
Packit Service 82fcde
Packit Service 82fcde
	      /* Clear the disabled bits in dl_x86_feature_1.  */
Packit Service 82fcde
	      if (res == 0)
Packit Service 82fcde
		GL(dl_x86_feature_1)[0] &= ~cet_feature;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't
Packit Service 82fcde
	     lock CET if SHSTK is enabled permissively.  */
Packit Service 82fcde
	  if (((GL(dl_x86_feature_1)[1] >> CET_MAX)
Packit Service 82fcde
	       & ((1 << CET_MAX) - 1))
Packit Service 82fcde
	       != CET_PERMISSIVE)
Packit Service 82fcde
	    dl_cet_lock_cet ();
Packit Service 82fcde
	}
Packit Service 82fcde
# endif
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
}