This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: Add family and model to cpu_features
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 26 Jun 2009 15:29:38 -0700
- Subject: PATCH: Add family and model to cpu_features
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
We need to select different implementation not only on features, but
also on processor family/model. This patch adds family and model to
cpu_features.
Our upcoming SSSE3 strcpy/stpcpy patch needs it.
Thanks.
H.J.
---
2009-06-26 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/x86_64/multiarch/ifunc-defines.sym (FAMILIY_OFFSET): New.
(MODEL_OFFSET): Likewise.
* sysdeps/x86_64/multiarch/init-arch.h (cpu_features): Add
family and model.
* sysdeps/x86_64/multiarch/init-arch.c (__init_cpu_features): Set
family and model.
diff --git a/sysdeps/x86_64/multiarch/ifunc-defines.sym b/sysdeps/x86_64/multiarch/ifunc-defines.sym
index 48d1287..24b3aec 100644
--- a/sysdeps/x86_64/multiarch/ifunc-defines.sym
+++ b/sysdeps/x86_64/multiarch/ifunc-defines.sym
@@ -5,6 +5,8 @@
CPU_FEATURES_SIZE sizeof (struct cpu_features)
KIND_OFFSET offsetof (struct cpu_features, kind)
+FAMILIY_OFFSET offsetof (struct cpu_features, family)
+MODEL_OFFSET offsetof (struct cpu_features, model)
CPUID_OFFSET offsetof (struct cpu_features, cpuid)
CPUID_SIZE sizeof (struct cpuid_registers)
CPUID_EAX_OFFSET offsetof (struct cpuid_registers, eax)
diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c
index ec0eb29..1127e61 100644
--- a/sysdeps/x86_64/multiarch/init-arch.c
+++ b/sysdeps/x86_64/multiarch/init-arch.c
@@ -39,15 +39,39 @@ __init_cpu_features (void)
/* This spells out "GenuineIntel". */
if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
{
+ unsigned int eax;
+ unsigned int model, family;
+
__cpu_features.kind = arch_kind_intel;
get_common_cpuid:
asm volatile ("cpuid"
- : "=a" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax),
+ : "=a" (eax),
"=b" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx),
"=c" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx),
"=d" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx)
: "0" (1));
+
+ __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax = eax;
+
+ family = (eax >> 8) & 0x0f;
+ model = (eax >> 4) & 0x0f;
+ if (__cpu_features.kind == arch_kind_intel)
+ {
+ unsigned int extended_model, extended_family;
+
+ extended_family = (eax >> 20) & 0xff;
+ extended_model = (eax >> 12) & 0xf0;
+ if (family == 0x0f)
+ {
+ family += extended_family;
+ model += extended_model;
+ }
+ else if (family == 0x06)
+ model += extended_model;
+ }
+ __cpu_features.family = family;
+ __cpu_features.model = model;
}
/* This spells out "AuthenticAMD". */
else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h
index 5c4892d..48a2127 100644
--- a/sysdeps/x86_64/multiarch/init-arch.h
+++ b/sysdeps/x86_64/multiarch/init-arch.h
@@ -42,6 +42,8 @@ extern struct cpu_features
unsigned int ecx;
unsigned int edx;
} cpuid[COMMON_CPUID_INDEX_MAX];
+ unsigned int family;
+ unsigned int model;
} __cpu_features attribute_hidden;