blob: 64f3da335b5be86853ae34af7bb6585f3f63061c [file] [log] [blame]
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <algorithm>
#include <string>
#include <vector>
#include "cpu_features_macros.h"
#include "cpuinfo_aarch64.h"
#include "cpuinfo_arm.h"
#include "cpuinfo_mips.h"
#include "cpuinfo_x86.h"
namespace cpu_features {
// Prints a named numeric value in both decimal and hexadecimal.
void PrintN(const char* field, int value) {
printf("%-15s : %3d (0x%02X)\n", field, value, value);
}
// Prints a named string.
void PrintS(const char* field, const char* value) {
printf("%-15s : %s\n", field, value);
}
template <typename HasFeatureFun, typename FeatureNameFun, typename FeatureType,
typename EnumType>
std::string GetFlags(const HasFeatureFun HasFeature,
const FeatureNameFun FeatureName,
const FeatureType* features, const EnumType last) {
std::vector<std::string> flags;
for (int i = 0; i < last; ++i) {
const EnumType enum_value = static_cast<EnumType>(i);
if (HasFeature(features, enum_value)) {
flags.push_back(FeatureName(enum_value));
}
}
std::sort(flags.begin(), flags.end());
std::string buffer;
for (const auto& flag : flags) {
if (!buffer.empty()) buffer += ' ';
buffer += flag;
}
return buffer;
}
void Main() {
#if defined(CPU_FEATURES_ARCH_X86)
char brand_string[49];
const X86Info info = GetX86Info();
const auto flags = GetFlags(&GetX86FeaturesEnumValue, &GetX86FeaturesEnumName,
&info.features, X86FeaturesEnum::X86_LAST_);
FillX86BrandString(brand_string);
PrintS("arch", "x86");
PrintS("brand", brand_string);
PrintN("family", info.family);
PrintN("model", info.model);
PrintN("stepping", info.stepping);
PrintS("uarch", GetX86MicroarchitectureName(GetX86Microarchitecture(&info)));
PrintS("flags", flags.c_str());
#elif defined(CPU_FEATURES_ARCH_ARM)
const ArmInfo info = GetArmInfo();
const auto flags = GetFlags(&GetArmFeaturesEnumValue, &GetArmFeaturesEnumName,
&info.features, ArmFeaturesEnum::ARM_LAST_);
PrintS("arch", "ARM");
PrintN("implementer", info.implementer);
PrintN("architecture", info.architecture);
PrintN("variant", info.variant);
PrintN("part", info.part);
PrintN("revision", info.revision);
PrintS("flags", flags.c_str());
#elif defined(CPU_FEATURES_ARCH_AARCH64)
const Aarch64Info info = GetAarch64Info();
const auto flags =
GetFlags(&GetAarch64FeaturesEnumValue, &GetAarch64FeaturesEnumName,
&info.features, Aarch64FeaturesEnum::AARCH64_LAST_);
PrintS("arch", "aarch64");
PrintN("implementer", info.implementer);
PrintN("variant", info.variant);
PrintN("part", info.part);
PrintN("revision", info.revision);
PrintS("flags", flags.c_str());
#elif defined(CPU_FEATURES_ARCH_MIPS)
const MipsInfo info = GetMipsInfo();
const auto flags =
GetFlags(&GetMipsFeaturesEnumValue, &GetMipsFeaturesEnumName,
&info.features, MipsFeaturesEnum::MIPS_LAST_);
PrintS("arch", "mips");
PrintS("flags", flags.c_str());
#endif
}
} // namespace cpu_features
int main(int argc, char** argv) {
cpu_features::Main();
return 0;
}