instruction_set_features_mips.cc revision d582fa4ea62083a7598dded5b82dc2198b3daac7
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "instruction_set_features_mips.h" 18 19#include <fstream> 20#include <sstream> 21 22#include "base/stringprintf.h" 23#include "utils.h" // For Trim. 24 25namespace art { 26 27const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromVariant( 28 const std::string& variant ATTRIBUTE_UNUSED, std::string* error_msg ATTRIBUTE_UNUSED) { 29 if (variant != "default") { 30 std::ostringstream os; 31 LOG(WARNING) << "Unexpected CPU variant for Mips using defaults: " << variant; 32 } 33 bool smp = true; // Conservative default. 34 bool fpu_32bit = true; 35 bool mips_isa_gte2 = true; 36 return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); 37} 38 39const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromBitmap(uint32_t bitmap) { 40 bool smp = (bitmap & kSmpBitfield) != 0; 41 bool fpu_32bit = (bitmap & kFpu32Bitfield) != 0; 42 bool mips_isa_gte2 = (bitmap & kIsaRevGte2Bitfield) != 0; 43 return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); 44} 45 46const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCppDefines() { 47#if defined(HAVE_ANDROID_OS) && (ANDROID_SMP == 0) 48 const bool smp = false; 49#else 50 const bool smp = true; 51#endif 52 53 // TODO: here we assume the FPU is always 32-bit. 54 const bool fpu_32bit = true; 55 56#if __mips_isa_rev >= 2 57 const bool mips_isa_gte2 = true; 58#else 59 const bool mips_isa_gte2 = false; 60#endif 61 62 return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); 63} 64 65const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCpuInfo() { 66 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that 67 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't. 68 bool smp = false; 69 70 // TODO: here we assume the FPU is always 32-bit. 71 const bool fpu_32bit = true; 72 73 // TODO: here we assume all MIPS processors are >= v2. 74#if __mips_isa_rev >= 2 75 const bool mips_isa_gte2 = true; 76#else 77 const bool mips_isa_gte2 = false; 78#endif 79 80 std::ifstream in("/proc/cpuinfo"); 81 if (!in.fail()) { 82 while (!in.eof()) { 83 std::string line; 84 std::getline(in, line); 85 if (!in.eof()) { 86 LOG(INFO) << "cpuinfo line: " << line; 87 if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) { 88 smp = true; 89 } 90 } 91 } 92 in.close(); 93 } else { 94 LOG(ERROR) << "Failed to open /proc/cpuinfo"; 95 } 96 return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); 97} 98 99const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromHwcap() { 100 UNIMPLEMENTED(WARNING); 101 return FromCppDefines(); 102} 103 104const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromAssembly() { 105 UNIMPLEMENTED(WARNING); 106 return FromCppDefines(); 107} 108 109bool MipsInstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { 110 if (kMips != other->GetInstructionSet()) { 111 return false; 112 } 113 const MipsInstructionSetFeatures* other_as_mips = other->AsMipsInstructionSetFeatures(); 114 return (IsSmp() == other->IsSmp()) && 115 (fpu_32bit_ == other_as_mips->fpu_32bit_) && 116 (mips_isa_gte2_ == other_as_mips->mips_isa_gte2_); 117} 118 119uint32_t MipsInstructionSetFeatures::AsBitmap() const { 120 return (IsSmp() ? kSmpBitfield : 0) | 121 (fpu_32bit_ ? kFpu32Bitfield : 0) | 122 (mips_isa_gte2_ ? kIsaRevGte2Bitfield : 0); 123} 124 125std::string MipsInstructionSetFeatures::GetFeatureString() const { 126 std::string result; 127 if (IsSmp()) { 128 result += "smp"; 129 } else { 130 result += "-smp"; 131 } 132 if (fpu_32bit_) { 133 result += ",fpu32"; 134 } else { 135 result += ",-fpu32"; 136 } 137 if (mips_isa_gte2_) { 138 result += ",mips2"; 139 } else { 140 result += ",-mips2"; 141 } 142 return result; 143} 144 145const InstructionSetFeatures* MipsInstructionSetFeatures::AddFeaturesFromSplitString( 146 const bool smp, const std::vector<std::string>& features, std::string* error_msg) const { 147 bool fpu_32bit = fpu_32bit_; 148 bool mips_isa_gte2 = mips_isa_gte2_; 149 for (auto i = features.begin(); i != features.end(); i++) { 150 std::string feature = Trim(*i); 151 if (feature == "fpu32") { 152 fpu_32bit = true; 153 } else if (feature == "-fpu32") { 154 fpu_32bit = false; 155 } else if (feature == "mips2") { 156 mips_isa_gte2 = true; 157 } else if (feature == "-mips2") { 158 mips_isa_gte2 = false; 159 } else { 160 *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str()); 161 return nullptr; 162 } 163 } 164 return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); 165} 166 167} // namespace art 168