Skip to content

Commit

Permalink
[X86] Combine to two feature variables in __cpu_indicator_init into a…
Browse files Browse the repository at this point in the history
…n array and pass them around as pointer we can treat as an array.

This simplifies the indexing code to set and test bits.
  • Loading branch information
topperc committed Jun 13, 2020
1 parent e424a35 commit 94ccb2a
Showing 1 changed file with 18 additions and 26 deletions.
44 changes: 18 additions & 26 deletions compiler-rt/lib/builtins/cpu_model.c
Expand Up @@ -271,9 +271,11 @@ static void detectX86FamilyModel(unsigned EAX, unsigned *Family,

static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
unsigned Brand_id,
unsigned Features,
unsigned Features2, unsigned *Type,
unsigned *Subtype) {
const unsigned *Features,
unsigned *Type, unsigned *Subtype) {
#define testFeature(F) \
(Features[F / 32] & (F % 32)) != 0

if (Brand_id != 0)
return;
switch (Family) {
Expand Down Expand Up @@ -354,7 +356,7 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
// Skylake Xeon:
case 0x55:
*Type = INTEL_COREI7;
if (Features2 & (1 << (FEATURE_AVX512VNNI - 32)))
if (testFeature(FEATURE_AVX512VNNI))
*Subtype = INTEL_COREI7_CASCADELAKE; // "cascadelake"
else
*Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
Expand Down Expand Up @@ -427,7 +429,7 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}

static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
unsigned Features, unsigned Features2,
const unsigned *Features,
unsigned *Type, unsigned *Subtype) {
// FIXME: this poorly matches the generated SubtargetFeatureKV table. There
// appears to be no way to generate the wide variety of AMD-specific targets
Expand Down Expand Up @@ -489,19 +491,13 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}

static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
unsigned *FeaturesOut,
unsigned *Features2Out) {
unsigned Features = 0;
unsigned Features2 = 0;
unsigned *Features) {
Features[0] = 0;
Features[1] = 0;
unsigned EAX, EBX;

#define setFeature(F) \
do { \
if (F < 32) \
Features |= 1U << (F & 0x1f); \
else if (F < 64) \
Features2 |= 1U << ((F - 32) & 0x1f); \
} while (0)
Features[F / 32] |= 1U << (F % 32)

if ((EDX >> 15) & 1)
setFeature(FEATURE_CMOV);
Expand Down Expand Up @@ -612,9 +608,6 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
setFeature(FEATURE_XOP);
if (HasExtLeaf1 && ((ECX >> 16) & 1))
setFeature(FEATURE_FMA4);

*FeaturesOut = Features;
*Features2Out = Features2;
#undef setFeature
}

Expand Down Expand Up @@ -659,8 +652,7 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) {
unsigned MaxLeaf = 5;
unsigned Vendor;
unsigned Model, Family, Brand_id;
unsigned Features = 0;
unsigned Features2 = 0;
unsigned Features[2];

// This function needs to run just once.
if (__cpu_model.__cpu_vendor)
Expand All @@ -679,19 +671,19 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) {
Brand_id = EBX & 0xff;

// Find available features.
getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
__cpu_model.__cpu_features[0] = Features;
__cpu_features2 = Features2;
getAvailableFeatures(ECX, EDX, MaxLeaf, &Features[0]);
__cpu_model.__cpu_features[0] = Features[0];
__cpu_features2 = Features[1];

if (Vendor == SIG_INTEL) {
// Get CPU type.
getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
Features2, &(__cpu_model.__cpu_type),
getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, &Features[0],
&(__cpu_model.__cpu_type),
&(__cpu_model.__cpu_subtype));
__cpu_model.__cpu_vendor = VENDOR_INTEL;
} else if (Vendor == SIG_AMD) {
// Get CPU type.
getAMDProcessorTypeAndSubtype(Family, Model, Features, Features2,
getAMDProcessorTypeAndSubtype(Family, Model, &Features[0],
&(__cpu_model.__cpu_type),
&(__cpu_model.__cpu_subtype));
__cpu_model.__cpu_vendor = VENDOR_AMD;
Expand Down

0 comments on commit 94ccb2a

Please sign in to comment.