diff options
author | Andreas Gampe <agampe@google.com> | 2015-01-13 16:41:53 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-01-13 20:19:56 -0800 |
commit | c5a3ea7522b59c18daa4325d69703a6f7f743378 (patch) | |
tree | 22aced955bae73c2f032e7cd0fc970218a908419 | |
parent | d277efe59cc922f6070056dc130e29281cc4955a (diff) | |
download | art-c5a3ea7522b59c18daa4325d69703a6f7f743378.zip art-c5a3ea7522b59c18daa4325d69703a6f7f743378.tar.gz art-c5a3ea7522b59c18daa4325d69703a6f7f743378.tar.bz2 |
ART: Introduce Mips32 R6
Add an instruction-set feature for Mips R6. Currently restricted
to the interpreter.
Change-Id: Ic6d888e135bc87340229a0543dd94d0c1e863edd
-rw-r--r-- | dex2oat/dex2oat.cc | 9 | ||||
-rw-r--r-- | patchoat/patchoat.cc | 11 | ||||
-rw-r--r-- | runtime/arch/mips/instruction_set_features_mips.cc | 92 | ||||
-rw-r--r-- | runtime/arch/mips/instruction_set_features_mips.h | 12 | ||||
-rw-r--r-- | runtime/elf_file.cc | 5 | ||||
-rw-r--r-- | runtime/elf_utils.h | 1 |
6 files changed, 96 insertions, 34 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 4f279f2..4b4675b 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -34,6 +34,7 @@ #include <cutils/trace.h> #include "arch/instruction_set_features.h" +#include "arch/mips/instruction_set_features_mips.h" #include "base/dumpable.h" #include "base/stl_util.h" #include "base/stringpiece.h" @@ -852,7 +853,13 @@ class Dex2Oat FINAL { } if (compiler_filter_string == nullptr) { - if (instruction_set_ == kMips64) { + if (instruction_set_ == kMips && + reinterpret_cast<const MipsInstructionSetFeatures*>(instruction_set_features_.get())-> + IsR6()) { + // For R6, only interpreter mode is working. + // TODO: fix compiler for Mips32r6. + compiler_filter_string = "interpret-only"; + } else if (instruction_set_ == kMips64) { // TODO: fix compiler for Mips64. compiler_filter_string = "interpret-only"; } else if (image_) { diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index b6ec223..28f9668 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -48,7 +48,7 @@ namespace art { -static InstructionSet ElfISAToInstructionSet(Elf32_Word isa) { +static InstructionSet ElfISAToInstructionSet(Elf32_Word isa, Elf32_Word e_flags) { switch (isa) { case EM_ARM: return kArm; @@ -59,7 +59,12 @@ static InstructionSet ElfISAToInstructionSet(Elf32_Word isa) { case EM_X86_64: return kX86_64; case EM_MIPS: - return kMips; + if (((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R2) || + ((e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6)) { + return kMips; + } else { + return kNone; + } default: return kNone; } @@ -212,7 +217,7 @@ bool PatchOat::Patch(File* input_oat, const std::string& image_location, off_t d LOG(ERROR) << "unable to read elf header"; return false; } - isa = ElfISAToInstructionSet(elf_hdr.e_machine); + isa = ElfISAToInstructionSet(elf_hdr.e_machine, elf_hdr.e_flags); } const char* isa_name = GetInstructionSetString(isa); std::string image_filename; diff --git a/runtime/arch/mips/instruction_set_features_mips.cc b/runtime/arch/mips/instruction_set_features_mips.cc index 11be2a8..00ab613 100644 --- a/runtime/arch/mips/instruction_set_features_mips.cc +++ b/runtime/arch/mips/instruction_set_features_mips.cc @@ -25,52 +25,82 @@ namespace art { const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromVariant( - const std::string& variant ATTRIBUTE_UNUSED, std::string* error_msg ATTRIBUTE_UNUSED) { - if (variant != "default") { - std::ostringstream os; - LOG(WARNING) << "Unexpected CPU variant for Mips using defaults: " << variant; - } + const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) { + bool smp = true; // Conservative default. bool fpu_32bit = true; - bool mips_isa_gte2 = true; - return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); + bool mips_isa_gte2 = false; + bool r6 = false; + + // Override defaults based on variant string. + // Only care if it is R1, R2 or R6 and we assume all CPUs will have a FP unit. + constexpr const char* kMips32Prefix = "mips32r"; + const size_t kPrefixLength = strlen(kMips32Prefix); + if (variant.compare(0, kPrefixLength, kMips32Prefix, kPrefixLength) == 0 && + variant.size() > kPrefixLength) { + if (variant[kPrefixLength] >= '6') { + fpu_32bit = false; + r6 = true; + } + if (variant[kPrefixLength] >= '2') { + mips_isa_gte2 = true; + } + } else if (variant == "default") { + // Default variant is: smp = true, has fpu, is gte2, is not r6. This is the traditional + // setting. + mips_isa_gte2 = true; + } else { + LOG(WARNING) << "Unexpected CPU variant for Mips32 using defaults: " << variant; + } + + return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); } const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromBitmap(uint32_t bitmap) { bool smp = (bitmap & kSmpBitfield) != 0; bool fpu_32bit = (bitmap & kFpu32Bitfield) != 0; bool mips_isa_gte2 = (bitmap & kIsaRevGte2Bitfield) != 0; - return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); + bool r6 = (bitmap & kR6) != 0; + return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); } const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCppDefines() { + // Assume conservative defaults. const bool smp = true; + bool fpu_32bit = true; + bool mips_isa_gte2 = false; + bool r6 = false; - // TODO: here we assume the FPU is always 32-bit. - const bool fpu_32bit = true; + // Override defaults based on compiler flags. +#if (_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS32R5) || defined(_MIPS_ARCH_MIPS32R6) + mips_isa_gte2 = true; +#endif -#if __mips_isa_rev >= 2 - const bool mips_isa_gte2 = true; -#else - const bool mips_isa_gte2 = false; +#if defined(_MIPS_ARCH_MIPS32R6) + r6 = true; + fpu_32bit = false; #endif - return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); + return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); } const MipsInstructionSetFeatures* 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 = true; + bool mips_isa_gte2 = false; + bool r6 = false; - // TODO: here we assume the FPU is always 32-bit. - const bool fpu_32bit = true; + // Override defaults based on compiler flags. +#if (_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS32R5) || defined(_MIPS_ARCH_MIPS32R6) + mips_isa_gte2 = true; +#endif - // TODO: here we assume all MIPS processors are >= v2. -#if __mips_isa_rev >= 2 - const bool mips_isa_gte2 = true; -#else - const bool mips_isa_gte2 = false; +#if defined(_MIPS_ARCH_MIPS32R6) + r6 = true; + fpu_32bit = false; #endif std::ifstream in("/proc/cpuinfo"); @@ -89,7 +119,7 @@ const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCpuInfo() { } else { LOG(ERROR) << "Failed to open /proc/cpuinfo"; } - return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); + return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); } const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromHwcap() { @@ -109,13 +139,15 @@ bool MipsInstructionSetFeatures::Equals(const InstructionSetFeatures* other) con const MipsInstructionSetFeatures* other_as_mips = other->AsMipsInstructionSetFeatures(); return (IsSmp() == other->IsSmp()) && (fpu_32bit_ == other_as_mips->fpu_32bit_) && - (mips_isa_gte2_ == other_as_mips->mips_isa_gte2_); + (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) | - (mips_isa_gte2_ ? kIsaRevGte2Bitfield : 0); + (mips_isa_gte2_ ? kIsaRevGte2Bitfield : 0) | + (r6_ ? kR6 : 0); } std::string MipsInstructionSetFeatures::GetFeatureString() const { @@ -135,6 +167,9 @@ std::string MipsInstructionSetFeatures::GetFeatureString() const { } else { result += ",-mips2"; } + if (r6_) { + result += ",r6"; + } // Suppress non-r6. return result; } @@ -142,6 +177,7 @@ const InstructionSetFeatures* MipsInstructionSetFeatures::AddFeaturesFromSplitSt const bool smp, 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_; for (auto i = features.begin(); i != features.end(); i++) { std::string feature = Trim(*i); if (feature == "fpu32") { @@ -152,12 +188,16 @@ const InstructionSetFeatures* MipsInstructionSetFeatures::AddFeaturesFromSplitSt mips_isa_gte2 = true; } else if (feature == "-mips2") { mips_isa_gte2 = false; + } else if (feature == "r6") { + r6 = true; + } else if (feature == "-r6") { + r6 = false; } else { *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str()); return nullptr; } } - return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2); + return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6); } } // namespace art diff --git a/runtime/arch/mips/instruction_set_features_mips.h b/runtime/arch/mips/instruction_set_features_mips.h index f7c64fe..aac436e 100644 --- a/runtime/arch/mips/instruction_set_features_mips.h +++ b/runtime/arch/mips/instruction_set_features_mips.h @@ -67,6 +67,10 @@ class MipsInstructionSetFeatures FINAL : public InstructionSetFeatures { return fpu_32bit_; } + bool IsR6() const { + return r6_; + } + virtual ~MipsInstructionSetFeatures() {} protected: @@ -76,19 +80,21 @@ class MipsInstructionSetFeatures FINAL : public InstructionSetFeatures { std::string* error_msg) const OVERRIDE; private: - MipsInstructionSetFeatures(bool smp, bool fpu_32bit, bool mips_isa_gte2) - : InstructionSetFeatures(smp), fpu_32bit_(fpu_32bit), mips_isa_gte2_(mips_isa_gte2) { - } + MipsInstructionSetFeatures(bool smp, bool fpu_32bit, bool mips_isa_gte2, bool r6) + : InstructionSetFeatures(smp), 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, }; const bool fpu_32bit_; const bool mips_isa_gte2_; + const bool r6_; DISALLOW_COPY_AND_ASSIGN(MipsInstructionSetFeatures); }; diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index 4198905..b6df609 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -1332,7 +1332,10 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, break; } case EM_MIPS: { - elf_ISA = kMips; + if ((GetHeader().e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R2 || + (GetHeader().e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { + elf_ISA = kMips; + } break; } } diff --git a/runtime/elf_utils.h b/runtime/elf_utils.h index 7b00bad..3579e27 100644 --- a/runtime/elf_utils.h +++ b/runtime/elf_utils.h @@ -30,6 +30,7 @@ namespace art { #define EF_ARM_EABI_VER5 0x05000000 #define EF_MIPS_ABI_O32 0x00001000 #define EF_MIPS_ARCH_32R2 0x70000000 +#define EF_MIPS_ARCH_32R6 0x90000000 #define EI_ABIVERSION 8 #define EM_ARM 40 |