ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
- // Assume all ARM processors are SMP.
- // TODO: set the SMP support based on variant.
- const bool smp = true;
-
// Look for variants that have divide support.
static const char* arm_variants_with_div[] = {
"cortex-a7", "cortex-a12", "cortex-a15", "cortex-a17", "cortex-a53", "cortex-a57",
<< ") using conservative defaults";
}
}
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_lpae));
}
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromBitmap(uint32_t bitmap) {
- bool smp = (bitmap & kSmpBitfield) != 0;
bool has_div = (bitmap & kDivBitfield) != 0;
bool has_atomic_ldrd_strd = (bitmap & kAtomicLdrdStrdBitfield) != 0;
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_atomic_ldrd_strd));
}
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromCppDefines() {
- const bool smp = true;
#if defined(__ARM_ARCH_EXT_IDIV__)
const bool has_div = true;
#else
#else
const bool has_lpae = false;
#endif
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_lpae));
}
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromCpuInfo() {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
- bool smp = false;
bool has_lpae = false;
bool has_div = false;
if (line.find("lpae") != std::string::npos) {
has_lpae = true;
}
- } else if (line.find("processor") != std::string::npos &&
- line.find(": 1") != std::string::npos) {
- smp = true;
}
}
}
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_lpae));
}
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromHwcap() {
- bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
-
bool has_div = false;
bool has_lpae = false;
}
#endif
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_lpae));
}
// A signal handler called by a fault for an illegal instruction. We record the fact in r0
}
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromAssembly() {
- const bool smp = true;
-
// See if have a sdiv instruction. Register a signal handler and try to execute an sdiv
// instruction. If we get a SIGILL then it's not supported.
struct sigaction sa, osa;
#else
const bool has_lpae = false;
#endif
- return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(has_div, has_lpae));
}
bool ArmInstructionSetFeatures::Equals(const InstructionSetFeatures* other) const {
return false;
}
const ArmInstructionSetFeatures* other_as_arm = other->AsArmInstructionSetFeatures();
- return IsSmp() == other_as_arm->IsSmp() &&
- has_div_ == other_as_arm->has_div_ &&
+ return has_div_ == other_as_arm->has_div_ &&
has_atomic_ldrd_strd_ == other_as_arm->has_atomic_ldrd_strd_;
}
uint32_t ArmInstructionSetFeatures::AsBitmap() const {
- return (IsSmp() ? kSmpBitfield : 0) |
- (has_div_ ? kDivBitfield : 0) |
+ return (has_div_ ? kDivBitfield : 0) |
(has_atomic_ldrd_strd_ ? kAtomicLdrdStrdBitfield : 0);
}
std::string ArmInstructionSetFeatures::GetFeatureString() const {
std::string result;
- if (IsSmp()) {
- result += "smp";
- } else {
- result += "-smp";
- }
if (has_div_) {
- result += ",div";
+ result += "div";
} else {
- result += ",-div";
+ result += "-div";
}
if (has_atomic_ldrd_strd_) {
result += ",atomic_ldrd_strd";
std::unique_ptr<const InstructionSetFeatures>
ArmInstructionSetFeatures::AddFeaturesFromSplitString(
- const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
+ const std::vector<std::string>& features, std::string* error_msg) const {
bool has_atomic_ldrd_strd = has_atomic_ldrd_strd_;
bool has_div = has_div_;
for (auto i = features.begin(); i != features.end(); i++) {
}
}
return std::unique_ptr<const InstructionSetFeatures>(
- new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd));
+ new ArmInstructionSetFeatures(has_div, has_atomic_ldrd_strd));
}
} // namespace art
protected:
// Parse a vector of the form "div", "lpae" adding these to a new ArmInstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
private:
- ArmInstructionSetFeatures(bool smp, bool has_div, bool has_atomic_ldrd_strd)
- : InstructionSetFeatures(smp),
+ ArmInstructionSetFeatures(bool has_div, bool has_atomic_ldrd_strd)
+ : InstructionSetFeatures(),
has_div_(has_div), has_atomic_ldrd_strd_(has_atomic_ldrd_strd) {
}
// Bitmap positions for encoding features as a bitmap.
enum {
- kSmpBitfield = 1,
- kDivBitfield = 2,
- kAtomicLdrdStrdBitfield = 4,
+ kDivBitfield = 1 << 0,
+ kAtomicLdrdStrdBitfield = 1 << 1,
};
const bool has_div_;
EXPECT_TRUE(krait_features->Equals(krait_features.get()));
EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
- EXPECT_EQ(krait_features->AsBitmap(), 7U);
+ EXPECT_STREQ("div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
+ EXPECT_EQ(krait_features->AsBitmap(), 3U);
// Build features for a 32-bit ARM denver processor.
std::unique_ptr<const InstructionSetFeatures> denver_features(
EXPECT_TRUE(krait_features->Equals(denver_features.get()));
EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
- EXPECT_EQ(denver_features->AsBitmap(), 7U);
+ EXPECT_STREQ("div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
+ EXPECT_EQ(denver_features->AsBitmap(), 3U);
// Build features for a 32-bit ARMv7 processor.
std::unique_ptr<const InstructionSetFeatures> arm7_features(
EXPECT_FALSE(krait_features->Equals(arm7_features.get()));
EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
- EXPECT_EQ(arm7_features->AsBitmap(), 1U);
+ EXPECT_STREQ("-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
+ EXPECT_EQ(arm7_features->AsBitmap(), 0U);
// ARM6 is not a supported architecture variant.
std::unique_ptr<const InstructionSetFeatures> arm6_features(
EXPECT_TRUE(krait_features->Equals(krait_features.get()));
EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
- EXPECT_EQ(krait_features->AsBitmap(), 7U);
+ EXPECT_STREQ("div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
+ EXPECT_EQ(krait_features->AsBitmap(), 3U);
// Build features for a 32-bit ARM processor with LPAE and div flipped.
std::unique_ptr<const InstructionSetFeatures> denver_features(
EXPECT_TRUE(krait_features->Equals(denver_features.get()));
EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
- EXPECT_EQ(denver_features->AsBitmap(), 7U);
+ EXPECT_STREQ("div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
+ EXPECT_EQ(denver_features->AsBitmap(), 3U);
// Build features for a 32-bit default ARM processor.
std::unique_ptr<const InstructionSetFeatures> arm7_features(
EXPECT_FALSE(krait_features->Equals(arm7_features.get()));
EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
- EXPECT_STREQ("smp,-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
- EXPECT_EQ(arm7_features->AsBitmap(), 1U);
+ EXPECT_STREQ("-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
+ EXPECT_EQ(arm7_features->AsBitmap(), 0U);
}
} // namespace art
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
- const bool smp = true; // Conservative default.
-
// Look for variants that need a fix for a53 erratum 835769.
static const char* arm64_variants_with_a53_835769_bug[] = {
"default", "generic", "cortex-a53" // Pessimistically assume all generic ARM64s are A53s.
bool needs_a53_843419_fix = needs_a53_835769_fix;
return Arm64FeaturesUniquePtr(
- new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix, needs_a53_843419_fix));
+ new Arm64InstructionSetFeatures(needs_a53_835769_fix, needs_a53_843419_fix));
}
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
- bool smp = (bitmap & kSmpBitfield) != 0;
bool is_a53 = (bitmap & kA53Bitfield) != 0;
- return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(is_a53, is_a53));
}
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromCppDefines() {
- const bool smp = true;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(is_a53, is_a53));
}
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromCpuInfo() {
- // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
- // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
- bool smp = false;
const bool is_a53 = true; // Conservative default.
-
- std::ifstream in("/proc/cpuinfo");
- if (!in.fail()) {
- while (!in.eof()) {
- std::string line;
- std::getline(in, line);
- if (!in.eof()) {
- LOG(INFO) << "cpuinfo line: " << line;
- if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) {
- smp = true;
- }
- }
- }
- in.close();
- } else {
- LOG(ERROR) << "Failed to open /proc/cpuinfo";
- }
- return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(is_a53, is_a53));
}
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromHwcap() {
- bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(is_a53, is_a53));
}
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromAssembly() {
if (kArm64 != other->GetInstructionSet()) {
return false;
}
- const Arm64InstructionSetFeatures* other_as_arm = other->AsArm64InstructionSetFeatures();
- return fix_cortex_a53_835769_ == other_as_arm->fix_cortex_a53_835769_;
+ const Arm64InstructionSetFeatures* other_as_arm64 = other->AsArm64InstructionSetFeatures();
+ return fix_cortex_a53_835769_ == other_as_arm64->fix_cortex_a53_835769_ &&
+ fix_cortex_a53_843419_ == other_as_arm64->fix_cortex_a53_843419_;
}
uint32_t Arm64InstructionSetFeatures::AsBitmap() const {
- return (IsSmp() ? kSmpBitfield : 0) | (fix_cortex_a53_835769_ ? kA53Bitfield : 0);
+ return (fix_cortex_a53_835769_ ? kA53Bitfield : 0);
}
std::string Arm64InstructionSetFeatures::GetFeatureString() const {
std::string result;
- if (IsSmp()) {
- result += "smp";
- } else {
- result += "-smp";
- }
if (fix_cortex_a53_835769_) {
- result += ",a53";
+ result += "a53";
} else {
- result += ",-a53";
+ result += "-a53";
}
return result;
}
std::unique_ptr<const InstructionSetFeatures>
Arm64InstructionSetFeatures::AddFeaturesFromSplitString(
- const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
+ const std::vector<std::string>& features, std::string* error_msg) const {
bool is_a53 = fix_cortex_a53_835769_;
for (auto i = features.begin(); i != features.end(); i++) {
std::string feature = android::base::Trim(*i);
}
}
return std::unique_ptr<const InstructionSetFeatures>(
- new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
+ new Arm64InstructionSetFeatures(is_a53, is_a53));
}
} // namespace art
protected:
// Parse a vector of the form "a53" adding these to a new ArmInstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
private:
- Arm64InstructionSetFeatures(bool smp, bool needs_a53_835769_fix, bool needs_a53_843419_fix)
- : InstructionSetFeatures(smp),
+ Arm64InstructionSetFeatures(bool needs_a53_835769_fix, bool needs_a53_843419_fix)
+ : InstructionSetFeatures(),
fix_cortex_a53_835769_(needs_a53_835769_fix),
fix_cortex_a53_843419_(needs_a53_843419_fix) {
}
// Bitmap positions for encoding features as a bitmap.
enum {
- kSmpBitfield = 1,
- kA53Bitfield = 2,
+ kA53Bitfield = 1 << 0,
};
const bool fix_cortex_a53_835769_;
ASSERT_TRUE(arm64_features.get() != nullptr) << error_msg;
EXPECT_EQ(arm64_features->GetInstructionSet(), kArm64);
EXPECT_TRUE(arm64_features->Equals(arm64_features.get()));
- EXPECT_STREQ("smp,a53", arm64_features->GetFeatureString().c_str());
- EXPECT_EQ(arm64_features->AsBitmap(), 3U);
+ EXPECT_STREQ("a53", arm64_features->GetFeatureString().c_str());
+ EXPECT_EQ(arm64_features->AsBitmap(), 1U);
}
} // namespace art
}
std::vector<std::string> features;
Split(feature_list, ',', &features);
- bool smp = smp_;
bool use_default = false; // Have we seen the 'default' feature?
bool first = false; // Is this first feature?
for (auto it = features.begin(); it != features.end();) {
*error_msg = "Unexpected instruction set features before 'default'";
return std::unique_ptr<const InstructionSetFeatures>();
}
- } else if (feature == "smp") {
- smp = true;
- erase = true;
- } else if (feature == "-smp") {
- smp = false;
- erase = true;
}
- // Erase the smp feature once processed.
if (!erase) {
++it;
} else {
first = true;
}
// Expectation: "default" is standalone, no other flags. But an empty features vector after
- // processing can also come along if the handled flags (at the moment only smp) are the only
- // ones in the list. So logically, we check "default -> features.empty."
+ // processing can also come along if the handled flags are the only ones in the list. So
+ // logically, we check "default -> features.empty."
DCHECK(!use_default || features.empty());
- return AddFeaturesFromSplitString(smp, features, error_msg);
+ return AddFeaturesFromSplitString(features, error_msg);
}
const ArmInstructionSetFeatures* InstructionSetFeatures::AsArmInstructionSetFeatures() const {
// Return a string of the form "div,lpae" or "none".
virtual std::string GetFeatureString() const = 0;
- // Does the instruction set variant require instructions for correctness with SMP?
- bool IsSmp() const {
- return smp_;
- }
-
// Down cast this ArmInstructionFeatures.
const ArmInstructionSetFeatures* AsArmInstructionSetFeatures() const;
virtual ~InstructionSetFeatures() {}
protected:
- explicit InstructionSetFeatures(bool smp) : smp_(smp) {}
+ InstructionSetFeatures() {}
// Returns true if variant appears in the array variants.
static bool FindVariantInArray(const char* const variants[], size_t num_variants,
// Add architecture specific features in sub-classes.
virtual std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const = 0;
private:
- const bool smp_;
-
DISALLOW_COPY_AND_ASSIGN(InstructionSetFeatures);
};
std::ostream& operator<<(std::ostream& os, const InstructionSetFeatures& rhs);
MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
- bool smp = true; // Conservative default.
-
// Override defaults based on compiler flags.
// This is needed when running ART test where the variant is not defined.
bool fpu_32bit;
fpu_32bit = (variant[kPrefixLength] < '5');
mips_isa_gte2 = (variant[kPrefixLength] >= '2');
} else if (variant == "default") {
- // Default variant is: smp = true, has FPU, is gte2. This is the traditional setting.
+ // Default variant has FPU, is gte2. This is the traditional setting.
//
// Note, we get FPU bitness and R6-ness from the build (using cpp defines, see above)
// and don't override them because many things depend on the "default" variant being
LOG(WARNING) << "Unexpected CPU variant for Mips32 using defaults: " << variant;
}
- return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(fpu_32bit, mips_isa_gte2, r6));
}
-MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromBitmap(
- uint32_t bitmap) {
- bool smp = (bitmap & kSmpBitfield) != 0;
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromBitmap(uint32_t bitmap) {
bool fpu_32bit = (bitmap & kFpu32Bitfield) != 0;
bool mips_isa_gte2 = (bitmap & kIsaRevGte2Bitfield) != 0;
bool r6 = (bitmap & kR6) != 0;
- return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(fpu_32bit, mips_isa_gte2, r6));
}
MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromCppDefines() {
- // Assume conservative defaults.
- const bool smp = true;
-
bool fpu_32bit;
bool mips_isa_gte2;
bool r6;
GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit);
- return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(fpu_32bit, mips_isa_gte2, r6));
}
MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromCpuInfo() {
- // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
- // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
- // Assume conservative defaults.
- bool smp = false;
-
bool fpu_32bit;
bool mips_isa_gte2;
bool r6;
GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit);
- std::ifstream in("/proc/cpuinfo");
- if (!in.fail()) {
- while (!in.eof()) {
- std::string line;
- std::getline(in, line);
- if (!in.eof()) {
- LOG(INFO) << "cpuinfo line: " << line;
- if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) {
- smp = true;
- }
- }
- }
- in.close();
- } else {
- LOG(ERROR) << "Failed to open /proc/cpuinfo";
- }
- return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(fpu_32bit, mips_isa_gte2, r6));
}
MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromHwcap() {
return false;
}
const MipsInstructionSetFeatures* other_as_mips = other->AsMipsInstructionSetFeatures();
- return (IsSmp() == other->IsSmp()) &&
- (fpu_32bit_ == other_as_mips->fpu_32bit_) &&
+ return (fpu_32bit_ == other_as_mips->fpu_32bit_) &&
(mips_isa_gte2_ == other_as_mips->mips_isa_gte2_) &&
(r6_ == other_as_mips->r6_);
}
uint32_t MipsInstructionSetFeatures::AsBitmap() const {
- return (IsSmp() ? kSmpBitfield : 0) |
- (fpu_32bit_ ? kFpu32Bitfield : 0) |
+ return (fpu_32bit_ ? kFpu32Bitfield : 0) |
(mips_isa_gte2_ ? kIsaRevGte2Bitfield : 0) |
(r6_ ? kR6 : 0);
}
std::string MipsInstructionSetFeatures::GetFeatureString() const {
std::string result;
- if (IsSmp()) {
- result += "smp";
- } else {
- result += "-smp";
- }
if (fpu_32bit_) {
- result += ",fpu32";
+ result += "fpu32";
} else {
- result += ",-fpu32";
+ result += "-fpu32";
}
if (mips_isa_gte2_) {
result += ",mips2";
std::unique_ptr<const InstructionSetFeatures>
MipsInstructionSetFeatures::AddFeaturesFromSplitString(
- const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
+ const std::vector<std::string>& features, std::string* error_msg) const {
bool fpu_32bit = fpu_32bit_;
bool mips_isa_gte2 = mips_isa_gte2_;
bool r6 = r6_;
}
}
return std::unique_ptr<const InstructionSetFeatures>(
- new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
+ new MipsInstructionSetFeatures(fpu_32bit, mips_isa_gte2, r6));
}
} // namespace art
protected:
// Parse a vector of the form "fpu32", "mips2" adding these to a new MipsInstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
private:
- MipsInstructionSetFeatures(bool smp, bool fpu_32bit, bool mips_isa_gte2, bool r6)
- : InstructionSetFeatures(smp),
+ MipsInstructionSetFeatures(bool fpu_32bit, bool mips_isa_gte2, bool r6)
+ : InstructionSetFeatures(),
fpu_32bit_(fpu_32bit),
mips_isa_gte2_(mips_isa_gte2),
r6_(r6) {
// Bitmap positions for encoding features as a bitmap.
enum {
- kSmpBitfield = 1,
- kFpu32Bitfield = 2,
- kIsaRevGte2Bitfield = 4,
- kR6 = 8,
+ kFpu32Bitfield = 1 << 0,
+ kIsaRevGte2Bitfield = 1 << 1,
+ kR6 = 1 << 2,
};
const bool fpu_32bit_;
ASSERT_TRUE(mips_features.get() != nullptr) << error_msg;
EXPECT_EQ(mips_features->GetInstructionSet(), kMips);
EXPECT_TRUE(mips_features->Equals(mips_features.get()));
- EXPECT_STREQ("smp,fpu32,mips2", mips_features->GetFeatureString().c_str());
- EXPECT_EQ(mips_features->AsBitmap(), 7U);
+ EXPECT_STREQ("fpu32,mips2", mips_features->GetFeatureString().c_str());
+ EXPECT_EQ(mips_features->AsBitmap(), 3U);
}
} // namespace art
if (variant != "default" && variant != "mips64r6") {
LOG(WARNING) << "Unexpected CPU variant for Mips64 using defaults: " << variant;
}
- bool smp = true; // Conservative default.
- return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures());
}
-Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
- bool smp = (bitmap & kSmpBitfield) != 0;
- return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap ATTRIBUTE_UNUSED) {
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures());
}
Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromCppDefines() {
- const bool smp = true;
-
- return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures());
}
Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromCpuInfo() {
- // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
- // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
- bool smp = false;
-
- std::ifstream in("/proc/cpuinfo");
- if (!in.fail()) {
- while (!in.eof()) {
- std::string line;
- std::getline(in, line);
- if (!in.eof()) {
- LOG(INFO) << "cpuinfo line: " << line;
- if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) {
- smp = true;
- }
- }
- }
- in.close();
- } else {
- LOG(ERROR) << "Failed to open /proc/cpuinfo";
- }
- return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures());
}
Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromHwcap() {
if (kMips64 != other->GetInstructionSet()) {
return false;
}
- return (IsSmp() == other->IsSmp());
+ return true;
}
uint32_t Mips64InstructionSetFeatures::AsBitmap() const {
- return (IsSmp() ? kSmpBitfield : 0);
+ return 0;
}
std::string Mips64InstructionSetFeatures::GetFeatureString() const {
- std::string result;
- if (IsSmp()) {
- result += "smp";
- } else {
- result += "-smp";
- }
- return result;
+ return "";
}
std::unique_ptr<const InstructionSetFeatures>
Mips64InstructionSetFeatures::AddFeaturesFromSplitString(
- const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
+ const std::vector<std::string>& features, std::string* error_msg) const {
auto i = features.begin();
if (i != features.end()) {
// We don't have any features.
*error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str());
return nullptr;
}
- return std::unique_ptr<const InstructionSetFeatures>(new Mips64InstructionSetFeatures(smp));
+ return std::unique_ptr<const InstructionSetFeatures>(new Mips64InstructionSetFeatures());
}
} // namespace art
public:
// Process a CPU variant string like "r4000" and create InstructionSetFeatures.
static Mips64FeaturesUniquePtr FromVariant(const std::string& variant,
- std::string* error_msg);
+ std::string* error_msg);
// Parse a bitmap and create an InstructionSetFeatures.
static Mips64FeaturesUniquePtr FromBitmap(uint32_t bitmap);
protected:
// Parse a vector of the form "fpu32", "mips2" adding these to a new Mips64InstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp,
- const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
private:
- explicit Mips64InstructionSetFeatures(bool smp) : InstructionSetFeatures(smp) {
+ Mips64InstructionSetFeatures() : InstructionSetFeatures() {
}
- // Bitmap positions for encoding features as a bitmap.
- enum {
- kSmpBitfield = 1,
- };
-
DISALLOW_COPY_AND_ASSIGN(Mips64InstructionSetFeatures);
};
ASSERT_TRUE(mips64_features.get() != nullptr) << error_msg;
EXPECT_EQ(mips64_features->GetInstructionSet(), kMips64);
EXPECT_TRUE(mips64_features->Equals(mips64_features.get()));
- EXPECT_STREQ("smp", mips64_features->GetFeatureString().c_str());
- EXPECT_EQ(mips64_features->AsBitmap(), 1U);
+ EXPECT_STREQ("", mips64_features->GetFeatureString().c_str());
+ EXPECT_EQ(mips64_features->AsBitmap(), 0U);
}
} // namespace art
};
X86FeaturesUniquePtr X86InstructionSetFeatures::Create(bool x86_64,
- bool smp,
bool has_SSSE3,
bool has_SSE4_1,
bool has_SSE4_2,
bool has_AVX2,
bool has_POPCNT) {
if (x86_64) {
- return X86FeaturesUniquePtr(new X86_64InstructionSetFeatures(smp,
- has_SSSE3,
+ return X86FeaturesUniquePtr(new X86_64InstructionSetFeatures(has_SSSE3,
has_SSE4_1,
has_SSE4_2,
has_AVX,
has_AVX2,
has_POPCNT));
} else {
- return X86FeaturesUniquePtr(new X86InstructionSetFeatures(smp,
- has_SSSE3,
+ return X86FeaturesUniquePtr(new X86InstructionSetFeatures(has_SSSE3,
has_SSE4_1,
has_SSE4_2,
has_AVX,
X86FeaturesUniquePtr X86InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED,
bool x86_64) {
- bool smp = true; // Conservative default.
bool has_SSSE3 = FindVariantInArray(x86_variants_with_ssse3, arraysize(x86_variants_with_ssse3),
variant);
bool has_SSE4_1 = FindVariantInArray(x86_variants_with_sse4_1,
LOG(WARNING) << "Unexpected CPU variant for X86 using defaults: " << variant;
}
- return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
+ return Create(x86_64, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
X86FeaturesUniquePtr X86InstructionSetFeatures::FromBitmap(uint32_t bitmap, bool x86_64) {
- bool smp = (bitmap & kSmpBitfield) != 0;
bool has_SSSE3 = (bitmap & kSsse3Bitfield) != 0;
bool has_SSE4_1 = (bitmap & kSse4_1Bitfield) != 0;
bool has_SSE4_2 = (bitmap & kSse4_2Bitfield) != 0;
bool has_AVX = (bitmap & kAvxBitfield) != 0;
bool has_AVX2 = (bitmap & kAvxBitfield) != 0;
bool has_POPCNT = (bitmap & kPopCntBitfield) != 0;
- return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
+ return Create(x86_64, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
X86FeaturesUniquePtr X86InstructionSetFeatures::FromCppDefines(bool x86_64) {
- const bool smp = true;
-
#ifndef __SSSE3__
const bool has_SSSE3 = false;
#else
const bool has_POPCNT = true;
#endif
- return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
+ return Create(x86_64, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
X86FeaturesUniquePtr X86InstructionSetFeatures::FromCpuInfo(bool x86_64) {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
- bool smp = false;
bool has_SSSE3 = false;
bool has_SSE4_1 = false;
bool has_SSE4_2 = false;
if (line.find("popcnt") != std::string::npos) {
has_POPCNT = true;
}
- } else if (line.find("processor") != std::string::npos &&
- line.find(": 1") != std::string::npos) {
- smp = true;
}
}
}
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
+ return Create(x86_64, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
X86FeaturesUniquePtr X86InstructionSetFeatures::FromHwcap(bool x86_64) {
return false;
}
const X86InstructionSetFeatures* other_as_x86 = other->AsX86InstructionSetFeatures();
- return (IsSmp() == other->IsSmp()) &&
- (has_SSSE3_ == other_as_x86->has_SSSE3_) &&
+ return (has_SSSE3_ == other_as_x86->has_SSSE3_) &&
(has_SSE4_1_ == other_as_x86->has_SSE4_1_) &&
(has_SSE4_2_ == other_as_x86->has_SSE4_2_) &&
(has_AVX_ == other_as_x86->has_AVX_) &&
}
uint32_t X86InstructionSetFeatures::AsBitmap() const {
- return (IsSmp() ? kSmpBitfield : 0) |
- (has_SSSE3_ ? kSsse3Bitfield : 0) |
+ return (has_SSSE3_ ? kSsse3Bitfield : 0) |
(has_SSE4_1_ ? kSse4_1Bitfield : 0) |
(has_SSE4_2_ ? kSse4_2Bitfield : 0) |
(has_AVX_ ? kAvxBitfield : 0) |
std::string X86InstructionSetFeatures::GetFeatureString() const {
std::string result;
- if (IsSmp()) {
- result += "smp";
- } else {
- result += "-smp";
- }
if (has_SSSE3_) {
- result += ",ssse3";
+ result += "ssse3";
} else {
- result += ",-ssse3";
+ result += "-ssse3";
}
if (has_SSE4_1_) {
result += ",sse4.1";
}
std::unique_ptr<const InstructionSetFeatures> X86InstructionSetFeatures::AddFeaturesFromSplitString(
- const bool smp, const std::vector<std::string>& features, bool x86_64,
+ const std::vector<std::string>& features, bool x86_64,
std::string* error_msg) const {
bool has_SSSE3 = has_SSSE3_;
bool has_SSE4_1 = has_SSE4_1_;
return nullptr;
}
}
- return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
+ return Create(x86_64, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
} // namespace art
protected:
// Parse a string of the form "ssse3" adding these to a new InstructionSetFeatures.
virtual std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE {
- return AddFeaturesFromSplitString(smp, features, false, error_msg);
+ return AddFeaturesFromSplitString(features, false, error_msg);
}
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
- bool x86_64, std::string* error_msg) const;
-
- X86InstructionSetFeatures(bool smp, bool has_SSSE3, bool has_SSE4_1, bool has_SSE4_2,
- bool has_AVX, bool has_AVX2, bool has_POPCNT)
- : InstructionSetFeatures(smp),
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
+ bool x86_64,
+ std::string* error_msg) const;
+
+ X86InstructionSetFeatures(bool has_SSSE3,
+ bool has_SSE4_1,
+ bool has_SSE4_2,
+ bool has_AVX,
+ bool has_AVX2,
+ bool has_POPCNT)
+ : InstructionSetFeatures(),
has_SSSE3_(has_SSSE3),
has_SSE4_1_(has_SSE4_1),
has_SSE4_2_(has_SSE4_2),
}
static X86FeaturesUniquePtr Create(bool x86_64,
- bool smp,
bool has_SSSE3,
bool has_SSE4_1,
bool has_SSE4_2,
private:
// Bitmap positions for encoding features as a bitmap.
enum {
- kSmpBitfield = 1,
- kSsse3Bitfield = 2,
- kSse4_1Bitfield = 4,
- kSse4_2Bitfield = 8,
- kAvxBitfield = 16,
- kAvx2Bitfield = 32,
- kPopCntBitfield = 64,
+ kSsse3Bitfield = 1 << 0,
+ kSse4_1Bitfield = 1 << 1,
+ kSse4_2Bitfield = 1 << 2,
+ kAvxBitfield = 1 << 3,
+ kAvx2Bitfield = 1 << 4,
+ kPopCntBitfield = 1 << 5,
};
const bool has_SSSE3_; // x86 128bit SIMD - Supplemental SSE.
ASSERT_TRUE(x86_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_features->GetInstructionSet(), kX86);
EXPECT_TRUE(x86_features->Equals(x86_features.get()));
- EXPECT_STREQ("smp,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_features->AsBitmap(), 1U);
+ EXPECT_EQ(x86_features->AsBitmap(), 0U);
}
TEST(X86InstructionSetFeaturesTest, X86FeaturesFromAtomVariant) {
ASSERT_TRUE(x86_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_features->GetInstructionSet(), kX86);
EXPECT_TRUE(x86_features->Equals(x86_features.get()));
- EXPECT_STREQ("smp,ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_features->AsBitmap(), 3U);
+ EXPECT_EQ(x86_features->AsBitmap(), 1U);
// Build features for a 32-bit x86 default processor.
std::unique_ptr<const InstructionSetFeatures> x86_default_features(
ASSERT_TRUE(x86_default_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_default_features->GetInstructionSet(), kX86);
EXPECT_TRUE(x86_default_features->Equals(x86_default_features.get()));
- EXPECT_STREQ("smp,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_default_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_default_features->AsBitmap(), 1U);
+ EXPECT_EQ(x86_default_features->AsBitmap(), 0U);
// Build features for a 64-bit x86-64 atom processor.
std::unique_ptr<const InstructionSetFeatures> x86_64_features(
ASSERT_TRUE(x86_64_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_64_features->GetInstructionSet(), kX86_64);
EXPECT_TRUE(x86_64_features->Equals(x86_64_features.get()));
- EXPECT_STREQ("smp,ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_64_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_64_features->AsBitmap(), 3U);
+ EXPECT_EQ(x86_64_features->AsBitmap(), 1U);
EXPECT_FALSE(x86_64_features->Equals(x86_features.get()));
EXPECT_FALSE(x86_64_features->Equals(x86_default_features.get()));
ASSERT_TRUE(x86_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_features->GetInstructionSet(), kX86);
EXPECT_TRUE(x86_features->Equals(x86_features.get()));
- EXPECT_STREQ("smp,ssse3,sse4.1,sse4.2,-avx,-avx2,popcnt",
+ EXPECT_STREQ("ssse3,sse4.1,sse4.2,-avx,-avx2,popcnt",
x86_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_features->AsBitmap(), 79U);
+ EXPECT_EQ(x86_features->AsBitmap(), 39U);
// Build features for a 32-bit x86 default processor.
std::unique_ptr<const InstructionSetFeatures> x86_default_features(
ASSERT_TRUE(x86_default_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_default_features->GetInstructionSet(), kX86);
EXPECT_TRUE(x86_default_features->Equals(x86_default_features.get()));
- EXPECT_STREQ("smp,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_default_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_default_features->AsBitmap(), 1U);
+ EXPECT_EQ(x86_default_features->AsBitmap(), 0U);
// Build features for a 64-bit x86-64 silvermont processor.
std::unique_ptr<const InstructionSetFeatures> x86_64_features(
ASSERT_TRUE(x86_64_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_64_features->GetInstructionSet(), kX86_64);
EXPECT_TRUE(x86_64_features->Equals(x86_64_features.get()));
- EXPECT_STREQ("smp,ssse3,sse4.1,sse4.2,-avx,-avx2,popcnt",
+ EXPECT_STREQ("ssse3,sse4.1,sse4.2,-avx,-avx2,popcnt",
x86_64_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_64_features->AsBitmap(), 79U);
+ EXPECT_EQ(x86_64_features->AsBitmap(), 39U);
EXPECT_FALSE(x86_64_features->Equals(x86_features.get()));
EXPECT_FALSE(x86_64_features->Equals(x86_default_features.get()));
protected:
// Parse a string of the form "ssse3" adding these to a new InstructionSetFeatures.
std::unique_ptr<const InstructionSetFeatures>
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ AddFeaturesFromSplitString(const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE {
- return X86InstructionSetFeatures::AddFeaturesFromSplitString(smp, features, true, error_msg);
+ return X86InstructionSetFeatures::AddFeaturesFromSplitString(features, true, error_msg);
}
private:
- X86_64InstructionSetFeatures(bool smp, bool has_SSSE3, bool has_SSE4_1, bool has_SSE4_2,
- bool has_AVX, bool has_AVX2, bool has_POPCNT)
- : X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
+ X86_64InstructionSetFeatures(bool has_SSSE3,
+ bool has_SSE4_1,
+ bool has_SSE4_2,
+ bool has_AVX,
+ bool has_AVX2,
+ bool has_POPCNT)
+ : X86InstructionSetFeatures(has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
has_AVX2, has_POPCNT) {
}
ASSERT_TRUE(x86_64_features.get() != nullptr) << error_msg;
EXPECT_EQ(x86_64_features->GetInstructionSet(), kX86_64);
EXPECT_TRUE(x86_64_features->Equals(x86_64_features.get()));
- EXPECT_STREQ("smp,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
+ EXPECT_STREQ("-ssse3,-sse4.1,-sse4.2,-avx,-avx2,-popcnt",
x86_64_features->GetFeatureString().c_str());
- EXPECT_EQ(x86_64_features->AsBitmap(), 1U);
+ EXPECT_EQ(x86_64_features->AsBitmap(), 0U);
}
} // namespace art