summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-01-13 16:41:53 -0800
committerAndreas Gampe <agampe@google.com>2015-01-13 20:19:56 -0800
commitc5a3ea7522b59c18daa4325d69703a6f7f743378 (patch)
tree22aced955bae73c2f032e7cd0fc970218a908419
parentd277efe59cc922f6070056dc130e29281cc4955a (diff)
downloadart-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.cc9
-rw-r--r--patchoat/patchoat.cc11
-rw-r--r--runtime/arch/mips/instruction_set_features_mips.cc92
-rw-r--r--runtime/arch/mips/instruction_set_features_mips.h12
-rw-r--r--runtime/elf_file.cc5
-rw-r--r--runtime/elf_utils.h1
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