1 /* Get x86 ISA level.
2    This file is part of the GNU C Library.
3    Copyright (C) 2020-2022 Free Software Foundation, Inc.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <elf.h>
20 #include <cpu-features.h>
21 
22 /* Get GNU_PROPERTY_X86_ISA_1_BASELINE and GNU_PROPERTY_X86_ISA_1_V[234]
23    ISA level.  */
24 
25 static unsigned int
get_isa_level(const struct cpu_features * cpu_features)26 get_isa_level (const struct cpu_features *cpu_features)
27 {
28   unsigned int isa_level = 0;
29 
30   if (CPU_FEATURE_USABLE_P (cpu_features, CMOV)
31       && CPU_FEATURE_USABLE_P (cpu_features, CX8)
32       && CPU_FEATURE_CPU_P (cpu_features, FPU)
33       && CPU_FEATURE_USABLE_P (cpu_features, FXSR)
34       && CPU_FEATURE_USABLE_P (cpu_features, MMX)
35       && CPU_FEATURE_USABLE_P (cpu_features, SSE)
36       && CPU_FEATURE_USABLE_P (cpu_features, SSE2))
37     {
38       isa_level = GNU_PROPERTY_X86_ISA_1_BASELINE;
39       if (CPU_FEATURE_USABLE_P (cpu_features, CMPXCHG16B)
40 	  && CPU_FEATURE_USABLE_P (cpu_features, LAHF64_SAHF64)
41 	  && CPU_FEATURE_USABLE_P (cpu_features, POPCNT)
42 	  && CPU_FEATURE_USABLE_P (cpu_features, SSE3)
43 	  && CPU_FEATURE_USABLE_P (cpu_features, SSSE3)
44 	  && CPU_FEATURE_USABLE_P (cpu_features, SSE4_1)
45 	  && CPU_FEATURE_USABLE_P (cpu_features, SSE4_2))
46 	{
47 	  isa_level |= GNU_PROPERTY_X86_ISA_1_V2;
48 	  if (CPU_FEATURE_USABLE_P (cpu_features, AVX)
49 	      && CPU_FEATURE_USABLE_P (cpu_features, AVX2)
50 	      && CPU_FEATURE_USABLE_P (cpu_features, F16C)
51 	      && CPU_FEATURE_USABLE_P (cpu_features, FMA)
52 	      && CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
53 	      && CPU_FEATURE_USABLE_P (cpu_features, MOVBE))
54 	    {
55 	      isa_level |= GNU_PROPERTY_X86_ISA_1_V3;
56 	      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F)
57 		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
58 		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512CD)
59 		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512DQ)
60 		  && CPU_FEATURE_USABLE_P (cpu_features, AVX512VL))
61 		isa_level |= GNU_PROPERTY_X86_ISA_1_V4;
62 	    }
63 	}
64     }
65 
66   return isa_level;
67 }
68