about summary refs log tree commit diff
path: root/sysdeps/x86/dl-hwcap.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-05-03 13:42:42 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-05-03 13:44:35 -0700
commit1432d38ea04ab5e96f21a382101856db5b49ad8a (patch)
tree90330655c7751e3f10a9cecbd190fa50ab368bac /sysdeps/x86/dl-hwcap.h
parent3b5f801ddb838311b5b05c218caac3bdb00d7c95 (diff)
downloadglibc-1432d38ea04ab5e96f21a382101856db5b49ad8a.tar.gz
glibc-1432d38ea04ab5e96f21a382101856db5b49ad8a.tar.xz
glibc-1432d38ea04ab5e96f21a382101856db5b49ad8a.zip
x86: Set dl_platform and dl_hwcap from CPU features [BZ #21391]
dl_platform and dl_hwcap are set from AT_PLATFORM and AT_HWCAP very
early during startup.  They are used by dynamic linker to determine
platform and build an array of hardware capability names, which are
added to search path when loading shared object.  dl_platform and
dl_hwcap are unused on x86-64.  On i386, i386, i486, i586 and i686
platforms were supported and only SSE2 capability was used.

On x86, usage of AT_PLATFORM and AT_HWCAP to determine platform and
processor capabilities is obsolete since all information is available
in dl_x86_cpu_features.  This patch sets dl_platform and dl_hwcap from
dl_x86_cpu_features in dynamic linker.  On i386, the available plaforms
are changed to i586 and i686 since i386 has been deprecated.  On x86-64,
the available plaforms are haswell, which is for Haswell class processors
with BMI1, BMI2, LZCNT, MOVBE, POPCNT, AVX2 and FMA, and xeon_phi, which
is for Xeon Phi class processors with AVX512F, AVX512CD, AVX512ER and
AVX512PF.  A capability, avx512_1, is also added to x86-64 for AVX512
ISAs: AVX512F, AVX512CD, AVX512BW, AVX512DQ and AVX512VL.

	[BZ #21391]
	* sysdeps/i386/dl-machine.h (dl_platform_init) [IS_IN (rtld)]:
	Only call init_cpu_features.
	[!IS_IN (rtld)]: Only set GLRO(dl_platform) to NULL if needed.
	* sysdeps/x86_64/dl-machine.h (dl_platform_init): Likewise.
	* sysdeps/i386/dl-procinfo.h: Removed.
	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Don't include
	<sysdeps/i386/dl-procinfo.h> nor <ldsodefs.h>.  Include
	<sysdeps/x86/dl-procinfo.h>.
	(_dl_procinfo): Replace _DL_HWCAP_COUNT with 32.
	* sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h [!IS_IN (ldconfig)]:
	Include <sysdeps/x86/dl-procinfo.h> instead of
	 <sysdeps/generic/dl-procinfo.h>.
	* sysdeps/x86/cpu-features.c: Include <dl-hwcap.h>.
	(init_cpu_features): Set dl_platform, dl_hwcap and dl_hwcap_mask.
	* sysdeps/x86/cpu-features.h (bit_cpu_LZCNT): New.
	(bit_cpu_MOVBE): Likewise.
	(bit_cpu_BMI1): Likewise.
	(bit_cpu_BMI2): Likewise.
	(index_cpu_BMI1): Likewise.
	(index_cpu_BMI2): Likewise.
	(index_cpu_LZCNT): Likewise.
	(index_cpu_MOVBE): Likewise.
	(index_cpu_POPCNT): Likewise.
	(reg_BMI1): Likewise.
	(reg_BMI2): Likewise.
	(reg_LZCNT): Likewise.
	(reg_MOVBE): Likewise.
	(reg_POPCNT): Likewise.
	* sysdeps/x86/dl-hwcap.h: New file.
	* sysdeps/x86/dl-procinfo.h: Likewise.
	* sysdeps/x86/dl-procinfo.c (_dl_x86_hwcap_flags): New.
	(_dl_x86_platforms): Likewise.
Diffstat (limited to 'sysdeps/x86/dl-hwcap.h')
-rw-r--r--sysdeps/x86/dl-hwcap.h75
1 files changed, 75 insertions, 0 deletions
diff --git a/sysdeps/x86/dl-hwcap.h b/sysdeps/x86/dl-hwcap.h
new file mode 100644
index 0000000000..c95668415a
--- /dev/null
+++ b/sysdeps/x86/dl-hwcap.h
@@ -0,0 +1,75 @@
+/* x86 version of hardware capability information handling macros.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_HWCAP_H
+#define _DL_HWCAP_H
+
+#if IS_IN (ldconfig)
+/* Since ldconfig processes both i386 and x86-64 libraries, it needs
+   to cover all platforms and hardware capabilities.  */
+# define HWCAP_PLATFORMS_START	0
+# define HWCAP_PLATFORMS_COUNT	4
+# define HWCAP_START		0
+# define HWCAP_COUNT		2
+# define HWCAP_IMPORTANT	(HWCAP_X86_SSE2 | HWCAP_X86_AVX512_1)
+#elif defined __x86_64__
+/* For 64 bit, only cover x86-64 platforms and capabilities.  */
+# define HWCAP_PLATFORMS_START	2
+# define HWCAP_PLATFORMS_COUNT	4
+# define HWCAP_START		1
+# define HWCAP_COUNT		2
+# define HWCAP_IMPORTANT	(HWCAP_X86_AVX512_1)
+#else
+/* For 32 bit, only cover i586, i686 and SSE2.  */
+# define HWCAP_PLATFORMS_START	0
+# define HWCAP_PLATFORMS_COUNT	2
+# define HWCAP_START		0
+# define HWCAP_COUNT		1
+# define HWCAP_IMPORTANT	(HWCAP_X86_SSE2)
+#endif
+
+enum
+{
+  HWCAP_X86_SSE2		= 1 << 0,
+  HWCAP_X86_AVX512_1		= 1 << 1
+};
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+  return GLRO(dl_x86_hwcap_flags)[idx];
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_hwcap (const char *str)
+{
+  int i;
+
+  for (i = HWCAP_START; i < HWCAP_COUNT; i++)
+    {
+      if (strcmp (str, GLRO(dl_x86_hwcap_flags)[i]) == 0)
+	return i;
+    }
+  return -1;
+};
+
+/* We cannot provide a general printing function.  */
+#define _dl_procinfo(type, word) -1
+
+#endif /* dl-hwcap.h */