diff options
author | Andreas Gampe <agampe@google.com> | 2015-01-14 15:45:59 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-01-15 11:32:48 -0800 |
commit | 57b34294758e9c00993913ebe43c7ee4698a5cc6 (patch) | |
tree | 981821619027686f83fbe00445299b0522f1df05 /runtime/arch/mips64 | |
parent | 4945bfef00ac446d9c5458e55500229d463ab4c3 (diff) | |
download | art-57b34294758e9c00993913ebe43c7ee4698a5cc6.zip art-57b34294758e9c00993913ebe43c7ee4698a5cc6.tar.gz art-57b34294758e9c00993913ebe43c7ee4698a5cc6.tar.bz2 |
ART: Allow to compile interpret-only mips64 files
Include enough infrastructure to allow cross-compiling for mips64,
interpret-only. This includes the instruction-set-features, frame
size info and utils assembler.
Also add a disassembler for oatdump, and support in patchoat.
Note: the runtime cannot run mips64, yet.
Change-Id: Id106581fa76b478984741c62a8a03be0f370d992
Diffstat (limited to 'runtime/arch/mips64')
-rw-r--r-- | runtime/arch/mips64/instruction_set_features_mips64.cc | 116 | ||||
-rw-r--r-- | runtime/arch/mips64/instruction_set_features_mips64.h | 80 | ||||
-rw-r--r-- | runtime/arch/mips64/instruction_set_features_mips64_test.cc | 34 | ||||
-rw-r--r-- | runtime/arch/mips64/quick_method_frame_info_mips64.h | 75 | ||||
-rw-r--r-- | runtime/arch/mips64/registers_mips64.cc | 50 | ||||
-rw-r--r-- | runtime/arch/mips64/registers_mips64.h | 109 |
6 files changed, 464 insertions, 0 deletions
diff --git a/runtime/arch/mips64/instruction_set_features_mips64.cc b/runtime/arch/mips64/instruction_set_features_mips64.cc new file mode 100644 index 0000000..26478cb --- /dev/null +++ b/runtime/arch/mips64/instruction_set_features_mips64.cc @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "instruction_set_features_mips64.h" + +#include <fstream> +#include <sstream> + +#include "base/stringprintf.h" +#include "utils.h" // For Trim. + +namespace art { + +const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromVariant( + const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) { + // TODO: r6 variant. + if (variant != "default") { + std::ostringstream os; + LOG(WARNING) << "Unexpected CPU variant for Mips64 using defaults: " << variant; + } + bool smp = true; // Conservative default. + return new Mips64InstructionSetFeatures(smp); +} + +const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap) { + bool smp = (bitmap & kSmpBitfield) != 0; + return new Mips64InstructionSetFeatures(smp); +} + +const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromCppDefines() { + const bool smp = true; + + return new Mips64InstructionSetFeatures(smp); +} + +const Mips64InstructionSetFeatures* 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 new Mips64InstructionSetFeatures(smp); +} + +const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromHwcap() { + UNIMPLEMENTED(WARNING); + return FromCppDefines(); +} + +const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromAssembly() { + UNIMPLEMENTED(WARNING); + return FromCppDefines(); +} + +bool Mips64InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { + if (kMips64 != other->GetInstructionSet()) { + return false; + } + return (IsSmp() == other->IsSmp()); +} + +uint32_t Mips64InstructionSetFeatures::AsBitmap() const { + return (IsSmp() ? kSmpBitfield : 0); +} + +std::string Mips64InstructionSetFeatures::GetFeatureString() const { + std::string result; + if (IsSmp()) { + result += "smp"; + } else { + result += "-smp"; + } + return result; +} + +const InstructionSetFeatures* Mips64InstructionSetFeatures::AddFeaturesFromSplitString( + const bool smp, 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. + std::string feature = Trim(*i); + *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str()); + return nullptr; + } + return new Mips64InstructionSetFeatures(smp); +} + +} // namespace art diff --git a/runtime/arch/mips64/instruction_set_features_mips64.h b/runtime/arch/mips64/instruction_set_features_mips64.h new file mode 100644 index 0000000..d5d6012 --- /dev/null +++ b/runtime/arch/mips64/instruction_set_features_mips64.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_ARCH_MIPS64_INSTRUCTION_SET_FEATURES_MIPS64_H_ +#define ART_RUNTIME_ARCH_MIPS64_INSTRUCTION_SET_FEATURES_MIPS64_H_ + +#include "arch/instruction_set_features.h" + +namespace art { + +// Instruction set features relevant to the MIPS64 architecture. +class Mips64InstructionSetFeatures FINAL : public InstructionSetFeatures { + public: + // Process a CPU variant string like "r4000" and create InstructionSetFeatures. + static const Mips64InstructionSetFeatures* FromVariant(const std::string& variant, + std::string* error_msg); + + // Parse a bitmap and create an InstructionSetFeatures. + static const Mips64InstructionSetFeatures* FromBitmap(uint32_t bitmap); + + // Turn C pre-processor #defines into the equivalent instruction set features. + static const Mips64InstructionSetFeatures* FromCppDefines(); + + // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures. + static const Mips64InstructionSetFeatures* FromCpuInfo(); + + // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce + // InstructionSetFeatures. + static const Mips64InstructionSetFeatures* FromHwcap(); + + // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the + // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. + static const Mips64InstructionSetFeatures* FromAssembly(); + + bool Equals(const InstructionSetFeatures* other) const OVERRIDE; + + InstructionSet GetInstructionSet() const OVERRIDE { + return kMips64; + } + + uint32_t AsBitmap() const OVERRIDE; + + std::string GetFeatureString() const OVERRIDE; + + virtual ~Mips64InstructionSetFeatures() {} + + protected: + // Parse a vector of the form "fpu32", "mips2" adding these to a new Mips64InstructionSetFeatures. + virtual const InstructionSetFeatures* + AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features, + std::string* error_msg) const OVERRIDE; + + private: + explicit Mips64InstructionSetFeatures(bool smp) : InstructionSetFeatures(smp) { + } + + // Bitmap positions for encoding features as a bitmap. + enum { + kSmpBitfield = 1, + }; + + DISALLOW_COPY_AND_ASSIGN(Mips64InstructionSetFeatures); +}; + +} // namespace art + +#endif // ART_RUNTIME_ARCH_MIPS64_INSTRUCTION_SET_FEATURES_MIPS64_H_ diff --git a/runtime/arch/mips64/instruction_set_features_mips64_test.cc b/runtime/arch/mips64/instruction_set_features_mips64_test.cc new file mode 100644 index 0000000..dc34506 --- /dev/null +++ b/runtime/arch/mips64/instruction_set_features_mips64_test.cc @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "instruction_set_features_mips64.h" + +#include <gtest/gtest.h> + +namespace art { + +TEST(Mips64InstructionSetFeaturesTest, Mips64Features) { + std::string error_msg; + std::unique_ptr<const InstructionSetFeatures> mips64_features( + InstructionSetFeatures::FromVariant(kMips64, "default", &error_msg)); + 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); +} + +} // namespace art diff --git a/runtime/arch/mips64/quick_method_frame_info_mips64.h b/runtime/arch/mips64/quick_method_frame_info_mips64.h new file mode 100644 index 0000000..281d5e6 --- /dev/null +++ b/runtime/arch/mips64/quick_method_frame_info_mips64.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ +#define ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ + +#include "quick/quick_method_frame_info.h" +#include "registers_mips64.h" +#include "runtime.h" // for Runtime::CalleeSaveType. + +namespace art { +namespace mips64 { + +static constexpr uint32_t kMips64CalleeSaveRefSpills = + (1 << art::mips64::S2) | (1 << art::mips64::S3) | (1 << art::mips64::S4) | + (1 << art::mips64::S5) | (1 << art::mips64::S6) | (1 << art::mips64::S7) | + (1 << art::mips64::GP) | (1 << art::mips64::S8); +static constexpr uint32_t kMips64CalleeSaveArgSpills = + (1 << art::mips64::A1) | (1 << art::mips64::A2) | (1 << art::mips64::A3) | + (1 << art::mips64::A4) | (1 << art::mips64::A5) | (1 << art::mips64::A6) | + (1 << art::mips64::A7); +static constexpr uint32_t kMips64CalleeSaveAllSpills = + (1 << art::mips64::S0) | (1 << art::mips64::S1); + +static constexpr uint32_t kMips64CalleeSaveFpRefSpills = 0; +static constexpr uint32_t kMips64CalleeSaveFpArgSpills = + (1 << art::mips64::F12) | (1 << art::mips64::F13) | (1 << art::mips64::F14) | + (1 << art::mips64::F15) | (1 << art::mips64::F16) | (1 << art::mips64::F17) | + (1 << art::mips64::F18) | (1 << art::mips64::F19); +static constexpr uint32_t kMips64CalleeSaveFpAllSpills = + (1 << art::mips64::F24) | (1 << art::mips64::F25) | (1 << art::mips64::F26) | + (1 << art::mips64::F27) | (1 << art::mips64::F28) | (1 << art::mips64::F29) | + (1 << art::mips64::F30) | (1 << art::mips64::F31); + +constexpr uint32_t Mips64CalleeSaveCoreSpills(Runtime::CalleeSaveType type) { + return kMips64CalleeSaveRefSpills | + (type == Runtime::kRefsAndArgs ? kMips64CalleeSaveArgSpills : 0) | + (type == Runtime::kSaveAll ? kMips64CalleeSaveAllSpills : 0) | (1 << art::mips64::RA); +} + +constexpr uint32_t Mips64CalleeSaveFpSpills(Runtime::CalleeSaveType type) { + return kMips64CalleeSaveFpRefSpills | + (type == Runtime::kRefsAndArgs ? kMips64CalleeSaveFpArgSpills: 0) | + (type == Runtime::kSaveAll ? kMips64CalleeSaveFpAllSpills : 0); +} + +constexpr uint32_t Mips64CalleeSaveFrameSize(Runtime::CalleeSaveType type) { + return RoundUp((POPCOUNT(Mips64CalleeSaveCoreSpills(type)) /* gprs */ + + POPCOUNT(Mips64CalleeSaveFpSpills(type)) /* fprs */ + + + 1 /* Method* */) * kMips64PointerSize, kStackAlignment); +} + +constexpr QuickMethodFrameInfo Mips64CalleeSaveMethodFrameInfo(Runtime::CalleeSaveType type) { + return QuickMethodFrameInfo(Mips64CalleeSaveFrameSize(type), + Mips64CalleeSaveCoreSpills(type), + Mips64CalleeSaveFpSpills(type)); +} + +} // namespace mips64 +} // namespace art + +#endif // ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ diff --git a/runtime/arch/mips64/registers_mips64.cc b/runtime/arch/mips64/registers_mips64.cc new file mode 100644 index 0000000..4959208 --- /dev/null +++ b/runtime/arch/mips64/registers_mips64.cc @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "registers_mips64.h" + +#include <ostream> + +namespace art { +namespace mips64 { + +static const char* kRegisterNames[] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", +}; + +std::ostream& operator<<(std::ostream& os, const GpuRegister& rhs) { + if (rhs >= ZERO && rhs < kNumberOfGpuRegisters) { + os << kRegisterNames[rhs]; + } else { + os << "GpuRegister[" << static_cast<int>(rhs) << "]"; + } + return os; +} + +std::ostream& operator<<(std::ostream& os, const FpuRegister& rhs) { + if (rhs >= F0 && rhs < kNumberOfFpuRegisters) { + os << "f" << static_cast<int>(rhs); + } else { + os << "FpuRegister[" << static_cast<int>(rhs) << "]"; + } + return os; +} + +} // namespace mips64 +} // namespace art diff --git a/runtime/arch/mips64/registers_mips64.h b/runtime/arch/mips64/registers_mips64.h new file mode 100644 index 0000000..38bc8f2 --- /dev/null +++ b/runtime/arch/mips64/registers_mips64.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_ARCH_MIPS64_REGISTERS_MIPS64_H_ +#define ART_RUNTIME_ARCH_MIPS64_REGISTERS_MIPS64_H_ + +#include <iosfwd> + +#include "base/logging.h" +#include "base/macros.h" +#include "globals.h" + +namespace art { +namespace mips64 { + +enum GpuRegister { + ZERO = 0, + AT = 1, // Assembler temporary. + V0 = 2, // Values. + V1 = 3, + A0 = 4, // Arguments. + A1 = 5, + A2 = 6, + A3 = 7, + A4 = 8, + A5 = 9, + A6 = 10, + A7 = 11, + T0 = 12, // Temporaries. + T1 = 13, + T2 = 14, + T3 = 15, + S0 = 16, // Saved values. + S1 = 17, + S2 = 18, + S3 = 19, + S4 = 20, + S5 = 21, + S6 = 22, + S7 = 23, + T8 = 24, // More temporaries. + T9 = 25, + K0 = 26, // Reserved for trap handler. + K1 = 27, + GP = 28, // Global pointer. + SP = 29, // Stack pointer. + S8 = 30, // Saved value/frame pointer. + RA = 31, // Return address. + kNumberOfGpuRegisters = 32, + kNoGpuRegister = -1 // Signals an illegal register. +}; +std::ostream& operator<<(std::ostream& os, const GpuRegister& rhs); + +// Values for floating point registers. +enum FpuRegister { + F0 = 0, + F1 = 1, + F2 = 2, + F3 = 3, + F4 = 4, + F5 = 5, + F6 = 6, + F7 = 7, + F8 = 8, + F9 = 9, + F10 = 10, + F11 = 11, + F12 = 12, + F13 = 13, + F14 = 14, + F15 = 15, + F16 = 16, + F17 = 17, + F18 = 18, + F19 = 19, + F20 = 20, + F21 = 21, + F22 = 22, + F23 = 23, + F24 = 24, + F25 = 25, + F26 = 26, + F27 = 27, + F28 = 28, + F29 = 29, + F30 = 30, + F31 = 31, + kNumberOfFpuRegisters = 32, + kNoFpuRegister = -1, +}; +std::ostream& operator<<(std::ostream& os, const FpuRegister& rhs); + +} // namespace mips64 +} // namespace art + +#endif // ART_RUNTIME_ARCH_MIPS64_REGISTERS_MIPS64_H_ |