1d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers/* 2d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Copyright (C) 2014 The Android Open Source Project 3d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 4d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 5d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * you may not use this file except in compliance with the License. 6d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * You may obtain a copy of the License at 7d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 8d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 9d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 10d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Unless required by applicable law or agreed to in writing, software 11d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 12d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * See the License for the specific language governing permissions and 14d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * limitations under the License. 15d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers */ 16d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 17d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "instruction_set_features_mips.h" 18d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 19d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <fstream> 20d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <sstream> 21d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 22d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "base/stringprintf.h" 23d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "utils.h" // For Trim. 24d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersnamespace art { 26d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 273d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung// An enum for the Mips revision. 283d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungenum class MipsLevel { 293d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung kBase, 303d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung kR2, 313d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung kR5, 323d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung kR6 333d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung}; 343d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 353d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung#if defined(_MIPS_ARCH_MIPS32R6) 363d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungstatic constexpr MipsLevel kRuntimeMipsLevel = MipsLevel::kR6; 373d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung#elif defined(_MIPS_ARCH_MIPS32R5) 383d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungstatic constexpr MipsLevel kRuntimeMipsLevel = MipsLevel::kR5; 393d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung#elif defined(_MIPS_ARCH_MIPS32R2) 403d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungstatic constexpr MipsLevel kRuntimeMipsLevel = MipsLevel::kR2; 413d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung#else 423d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungstatic constexpr MipsLevel kRuntimeMipsLevel = MipsLevel::kBase; 433d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung#endif 443d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 453d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leungstatic void GetFlagsFromCppDefined(bool* mips_isa_gte2, bool* r6, bool* fpu_32bit) { 463d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung // Override defaults based on compiler flags. 473d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung if (kRuntimeMipsLevel >= MipsLevel::kR2) { 483d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *mips_isa_gte2 = true; 493d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } else { 503d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *mips_isa_gte2 = false; 513d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } 523d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 533d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung if (kRuntimeMipsLevel >= MipsLevel::kR5) { 543d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *fpu_32bit = false; 553d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } else { 563d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *fpu_32bit = true; 573d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } 583d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 593d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung if (kRuntimeMipsLevel >= MipsLevel::kR6) { 603d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *r6 = true; 613d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } else { 623d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung *r6 = false; 633d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung } 643d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung} 653d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 66d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromVariant( 67c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) { 68c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe 69d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = true; // Conservative default. 703d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung 713d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung // Override defaults based on compiler flags. 723d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung // This is needed when running ART test where the variant is not defined. 733d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool fpu_32bit; 743d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool mips_isa_gte2; 753d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool r6; 763d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit); 77c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe 78c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // Override defaults based on variant string. 79c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // Only care if it is R1, R2 or R6 and we assume all CPUs will have a FP unit. 80c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe constexpr const char* kMips32Prefix = "mips32r"; 81c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe const size_t kPrefixLength = strlen(kMips32Prefix); 82c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe if (variant.compare(0, kPrefixLength, kMips32Prefix, kPrefixLength) == 0 && 83c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe variant.size() > kPrefixLength) { 84c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe if (variant[kPrefixLength] >= '6') { 85c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe fpu_32bit = false; 86c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe r6 = true; 87c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } 88c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe if (variant[kPrefixLength] >= '2') { 89c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe mips_isa_gte2 = true; 90c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } 91c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } else if (variant == "default") { 92c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // Default variant is: smp = true, has fpu, is gte2, is not r6. This is the traditional 93c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // setting. 94c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe mips_isa_gte2 = true; 95c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } else { 96c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe LOG(WARNING) << "Unexpected CPU variant for Mips32 using defaults: " << variant; 97c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } 98c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe 99c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); 100d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 101d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 102d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromBitmap(uint32_t bitmap) { 103d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = (bitmap & kSmpBitfield) != 0; 104d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool fpu_32bit = (bitmap & kFpu32Bitfield) != 0; 105d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool mips_isa_gte2 = (bitmap & kIsaRevGte2Bitfield) != 0; 106c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe bool r6 = (bitmap & kR6) != 0; 107c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); 108d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 109d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 110d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCppDefines() { 111c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // Assume conservative defaults. 112d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool smp = true; 113d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 1143d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool fpu_32bit; 1153d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool mips_isa_gte2; 1163d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool r6; 1173d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit); 118d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 119c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); 120d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 121d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 122d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCpuInfo() { 123d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that 124d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // the kernel puts the appropriate feature flags in here. Sometimes it doesn't. 125c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe // Assume conservative defaults. 126d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = false; 127d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 1283d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool fpu_32bit; 1293d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool mips_isa_gte2; 1303d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung bool r6; 1313d12eadf67e263ebc7e533f8daa65029feb41313Douglas Leung GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit); 132d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 133d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::ifstream in("/proc/cpuinfo"); 134d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (!in.fail()) { 135d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers while (!in.eof()) { 136d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string line; 137d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::getline(in, line); 138d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (!in.eof()) { 139d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(INFO) << "cpuinfo line: " << line; 140d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) { 141d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers smp = true; 142d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 143d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 144d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 145d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers in.close(); 146d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 147d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(ERROR) << "Failed to open /proc/cpuinfo"; 148d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 149c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); 150d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 151d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 152d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromHwcap() { 153d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNIMPLEMENTED(WARNING); 154d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return FromCppDefines(); 155d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 156d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 157d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromAssembly() { 158d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNIMPLEMENTED(WARNING); 159d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return FromCppDefines(); 160d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 161d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 162d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersbool MipsInstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { 163d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (kMips != other->GetInstructionSet()) { 164d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return false; 165d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 166d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const MipsInstructionSetFeatures* other_as_mips = other->AsMipsInstructionSetFeatures(); 167d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return (IsSmp() == other->IsSmp()) && 168d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (fpu_32bit_ == other_as_mips->fpu_32bit_) && 169c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe (mips_isa_gte2_ == other_as_mips->mips_isa_gte2_) && 170c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe (r6_ == other_as_mips->r6_); 171d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 172d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 173d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersuint32_t MipsInstructionSetFeatures::AsBitmap() const { 174d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return (IsSmp() ? kSmpBitfield : 0) | 175d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (fpu_32bit_ ? kFpu32Bitfield : 0) | 176c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe (mips_isa_gte2_ ? kIsaRevGte2Bitfield : 0) | 177c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe (r6_ ? kR6 : 0); 178d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 179d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 180d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstd::string MipsInstructionSetFeatures::GetFeatureString() const { 181d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string result; 182d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (IsSmp()) { 183d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += "smp"; 184d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 185d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += "-smp"; 186d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 187d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (fpu_32bit_) { 188d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",fpu32"; 189d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 190d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-fpu32"; 191d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 192d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (mips_isa_gte2_) { 193d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",mips2"; 194d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 195d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-mips2"; 196d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 197c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe if (r6_) { 198c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe result += ",r6"; 199c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } // Suppress non-r6. 200d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return result; 201d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 202d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 203d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst InstructionSetFeatures* MipsInstructionSetFeatures::AddFeaturesFromSplitString( 204d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool smp, const std::vector<std::string>& features, std::string* error_msg) const { 205d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool fpu_32bit = fpu_32bit_; 206d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool mips_isa_gte2 = mips_isa_gte2_; 207c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe bool r6 = r6_; 208d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers for (auto i = features.begin(); i != features.end(); i++) { 209d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string feature = Trim(*i); 210d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (feature == "fpu32") { 211d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers fpu_32bit = true; 212d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-fpu32") { 213d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers fpu_32bit = false; 214d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "mips2") { 215d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers mips_isa_gte2 = true; 216d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-mips2") { 217d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers mips_isa_gte2 = false; 218c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } else if (feature == "r6") { 219c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe r6 = true; 220c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe } else if (feature == "-r6") { 221c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe r6 = false; 222d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 223d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str()); 224d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return nullptr; 225d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 226d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 227c5a3ea7522b59c18daa4325d69703a6f7f743378Andreas Gampe return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); 228d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 229d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 230d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} // namespace art 231