summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lifang Xia <lifang_xia@linux.alibaba.com> 2023-01-25 15:55:55 +0000
committer Ulya Trofimovich <skvadrik@google.com> 2023-02-10 11:45:20 +0000
commit910c95fe2dd57bc0d70c78bdc0c6cdf4d21ce700 (patch)
treef075185c2f65183a6f579c759348260d7043f6a2
parentc137762c96cb8329ea95e1dda27b0a2d9c1f3228 (diff)
riscv64: define instruction set features.
At the moment we assume the basic extension set G (IMAFD) plus the C extension (compression). V extension (vector) is also defined, but not assumed by default. Test: lunch aosp_riscv64-userdebug && m dist Co-authored-by: Ulya Trafimovich <skvadrik@google.com> Change-Id: Ie3e7c1d5ad8e720d8bcab28a82fc602005efbb7f
-rw-r--r--runtime/Android.bp4
-rw-r--r--runtime/arch/instruction_set_features.cc30
-rw-r--r--runtime/arch/instruction_set_features.h4
-rw-r--r--runtime/arch/riscv64/instruction_set_features_riscv64.cc99
-rw-r--r--runtime/arch/riscv64/instruction_set_features_riscv64.h84
-rw-r--r--runtime/arch/riscv64/instruction_set_features_riscv64_test.cc38
6 files changed, 252 insertions, 7 deletions
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 18b7252c6c..c4fb600397 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -310,8 +310,9 @@ libart_cc_defaults {
"arch/arm/registers_arm.cc",
"arch/arm64/instruction_set_features_arm64.cc",
"arch/arm64/registers_arm64.cc",
- "arch/x86/instruction_set_features_x86.cc",
+ "arch/riscv64/instruction_set_features_riscv64.cc",
"arch/riscv64/registers_riscv64.cc",
+ "arch/x86/instruction_set_features_x86.cc",
"arch/x86/registers_x86.cc",
"arch/x86_64/registers_x86_64.cc",
"entrypoints/entrypoint_utils.cc",
@@ -821,6 +822,7 @@ art_cc_defaults {
"arch/instruction_set_features_test.cc",
"arch/memcmp16_test.cc",
"arch/stub_test.cc",
+ "arch/riscv64/instruction_set_features_riscv64_test.cc",
"arch/x86/instruction_set_features_x86_test.cc",
"arch/x86_64/instruction_set_features_x86_64_test.cc",
"art_method_test.cc",
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index 7a1e6b05ad..d88c544b35 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -14,20 +14,17 @@
* limitations under the License.
*/
-#include <algorithm>
-
#include "instruction_set_features.h"
#include <algorithm>
#include <ostream>
#include "android-base/strings.h"
-
-#include "base/casts.h"
-#include "base/utils.h"
-
#include "arm/instruction_set_features_arm.h"
#include "arm64/instruction_set_features_arm64.h"
+#include "base/casts.h"
+#include "base/utils.h"
+#include "riscv64/instruction_set_features_riscv64.h"
#include "x86/instruction_set_features_x86.h"
#include "x86_64/instruction_set_features_x86_64.h"
@@ -41,6 +38,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromVarian
return ArmInstructionSetFeatures::FromVariant(variant, error_msg);
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromVariant(variant, error_msg);
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromVariant(variant, error_msg);
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromVariant(variant, error_msg);
case InstructionSet::kX86_64:
@@ -91,6 +90,9 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromBitmap
case InstructionSet::kArm64:
result = Arm64InstructionSetFeatures::FromBitmap(bitmap);
break;
+ case InstructionSet::kRiscv64:
+ result = Riscv64InstructionSetFeatures::FromBitmap(bitmap);
+ break;
case InstructionSet::kX86:
result = X86InstructionSetFeatures::FromBitmap(bitmap);
break;
@@ -113,6 +115,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCppDef
return ArmInstructionSetFeatures::FromCppDefines();
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromCppDefines();
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromCppDefines();
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromCppDefines();
case InstructionSet::kX86_64:
@@ -143,6 +147,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuInf
return ArmInstructionSetFeatures::FromCpuInfo();
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromCpuInfo();
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromCpuInfo();
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromCpuInfo();
case InstructionSet::kX86_64:
@@ -162,6 +168,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromHwcap(
return ArmInstructionSetFeatures::FromHwcap();
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromHwcap();
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromHwcap();
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromHwcap();
case InstructionSet::kX86_64:
@@ -181,6 +189,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromAssemb
return ArmInstructionSetFeatures::FromAssembly();
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromAssembly();
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromAssembly();
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromAssembly();
case InstructionSet::kX86_64:
@@ -200,6 +210,8 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuFea
return ArmInstructionSetFeatures::FromCpuFeatures();
case InstructionSet::kArm64:
return Arm64InstructionSetFeatures::FromCpuFeatures();
+ case InstructionSet::kRiscv64:
+ return Riscv64InstructionSetFeatures::FromCpuFeatures();
case InstructionSet::kX86:
return X86InstructionSetFeatures::FromCpuFeatures();
case InstructionSet::kX86_64:
@@ -276,6 +288,12 @@ const Arm64InstructionSetFeatures* InstructionSetFeatures::AsArm64InstructionSet
return down_cast<const Arm64InstructionSetFeatures*>(this);
}
+const Riscv64InstructionSetFeatures* InstructionSetFeatures::AsRiscv64InstructionSetFeatures()
+ const {
+ DCHECK_EQ(InstructionSet::kRiscv64, GetInstructionSet());
+ return down_cast<const Riscv64InstructionSetFeatures*>(this);
+}
+
const X86InstructionSetFeatures* InstructionSetFeatures::AsX86InstructionSetFeatures() const {
DCHECK(InstructionSet::kX86 == GetInstructionSet() ||
InstructionSet::kX86_64 == GetInstructionSet());
diff --git a/runtime/arch/instruction_set_features.h b/runtime/arch/instruction_set_features.h
index cee8c5d42f..1f41b39023 100644
--- a/runtime/arch/instruction_set_features.h
+++ b/runtime/arch/instruction_set_features.h
@@ -28,6 +28,7 @@ namespace art {
class ArmInstructionSetFeatures;
class Arm64InstructionSetFeatures;
+class Riscv64InstructionSetFeatures;
class X86InstructionSetFeatures;
class X86_64InstructionSetFeatures;
@@ -121,6 +122,9 @@ class InstructionSetFeatures {
// Down cast this Arm64InstructionFeatures.
const Arm64InstructionSetFeatures* AsArm64InstructionSetFeatures() const;
+ // Down cast this Riscv64InstructionFeatures.
+ const Riscv64InstructionSetFeatures* AsRiscv64InstructionSetFeatures() const;
+
// Down cast this X86InstructionFeatures.
const X86InstructionSetFeatures* AsX86InstructionSetFeatures() const;
diff --git a/runtime/arch/riscv64/instruction_set_features_riscv64.cc b/runtime/arch/riscv64/instruction_set_features_riscv64.cc
new file mode 100644
index 0000000000..2ef4f8493d
--- /dev/null
+++ b/runtime/arch/riscv64/instruction_set_features_riscv64.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 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_riscv64.h"
+
+#include <fstream>
+#include <sstream>
+
+#include "android-base/strings.h"
+#include "base/logging.h"
+
+namespace art {
+
+// Basic feature set is rv64gc, aka rv64imafdc.
+constexpr uint32_t BasicFeatures() {
+ return Riscv64InstructionSetFeatures::kExtGeneric | Riscv64InstructionSetFeatures::kExtCompressed;
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromVariant(
+ const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
+ if (variant != "generic") {
+ LOG(WARNING) << "Unexpected CPU variant for Riscv64 using defaults: " << variant;
+ }
+ return Riscv64FeaturesUniquePtr(new Riscv64InstructionSetFeatures(BasicFeatures()));
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
+ return Riscv64FeaturesUniquePtr(new Riscv64InstructionSetFeatures(bitmap));
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromCppDefines() {
+ return Riscv64FeaturesUniquePtr(new Riscv64InstructionSetFeatures(BasicFeatures()));
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromCpuInfo() {
+ UNIMPLEMENTED(WARNING);
+ return FromCppDefines();
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromHwcap() {
+ UNIMPLEMENTED(WARNING);
+ return FromCppDefines();
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromAssembly() {
+ UNIMPLEMENTED(WARNING);
+ return FromCppDefines();
+}
+
+Riscv64FeaturesUniquePtr Riscv64InstructionSetFeatures::FromCpuFeatures() {
+ UNIMPLEMENTED(WARNING);
+ return FromCppDefines();
+}
+
+bool Riscv64InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const {
+ if (InstructionSet::kRiscv64 != other->GetInstructionSet()) {
+ return false;
+ }
+ return bits_ == other->AsRiscv64InstructionSetFeatures()->bits_;
+}
+
+uint32_t Riscv64InstructionSetFeatures::AsBitmap() const { return bits_; }
+
+std::string Riscv64InstructionSetFeatures::GetFeatureString() const {
+ std::string result = "rv64";
+ if (bits_ & kExtGeneric) {
+ result += "g";
+ }
+ if (bits_ & kExtCompressed) {
+ result += "c";
+ }
+ if (bits_ & kExtVector) {
+ result += "v";
+ }
+ return result;
+}
+
+std::unique_ptr<const InstructionSetFeatures>
+Riscv64InstructionSetFeatures::AddFeaturesFromSplitString(
+ const std::vector<std::string>& features ATTRIBUTE_UNUSED,
+ std::string* error_msg ATTRIBUTE_UNUSED) const {
+ UNIMPLEMENTED(WARNING);
+ return std::unique_ptr<const InstructionSetFeatures>(new Riscv64InstructionSetFeatures(bits_));
+}
+
+} // namespace art
diff --git a/runtime/arch/riscv64/instruction_set_features_riscv64.h b/runtime/arch/riscv64/instruction_set_features_riscv64.h
new file mode 100644
index 0000000000..1ad2ffd830
--- /dev/null
+++ b/runtime/arch/riscv64/instruction_set_features_riscv64.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 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_RISCV64_INSTRUCTION_SET_FEATURES_RISCV64_H_
+#define ART_RUNTIME_ARCH_RISCV64_INSTRUCTION_SET_FEATURES_RISCV64_H_
+
+#include "arch/instruction_set_features.h"
+
+namespace art {
+
+class Riscv64InstructionSetFeatures;
+using Riscv64FeaturesUniquePtr = std::unique_ptr<const Riscv64InstructionSetFeatures>;
+
+// Instruction set features relevant to the RISCV64 architecture.
+class Riscv64InstructionSetFeatures final : public InstructionSetFeatures {
+ public:
+ // Bitmap positions for encoding features as a bitmap.
+ enum {
+ kExtGeneric = (1 << 0), // G extension covers the basic set IMAFD
+ kExtCompressed = (1 << 1), // C extension adds compressed instructions
+ kExtVector = (1 << 2) // V extension adds vector instructions
+ };
+
+ static Riscv64FeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg);
+
+ // Parse a bitmap and create an InstructionSetFeatures.
+ static Riscv64FeaturesUniquePtr FromBitmap(uint32_t bitmap);
+
+ // Turn C pre-processor #defines into the equivalent instruction set features.
+ static Riscv64FeaturesUniquePtr FromCppDefines();
+
+ // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
+ static Riscv64FeaturesUniquePtr FromCpuInfo();
+
+ // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
+ // InstructionSetFeatures.
+ static Riscv64FeaturesUniquePtr 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 Riscv64FeaturesUniquePtr FromAssembly();
+
+ // Use external cpu_features library.
+ static Riscv64FeaturesUniquePtr FromCpuFeatures();
+
+ bool Equals(const InstructionSetFeatures* other) const override;
+
+ InstructionSet GetInstructionSet() const override { return InstructionSet::kRiscv64; }
+
+ uint32_t AsBitmap() const override;
+
+ std::string GetFeatureString() const override;
+
+ virtual ~Riscv64InstructionSetFeatures() {}
+
+ protected:
+ std::unique_ptr<const InstructionSetFeatures> AddFeaturesFromSplitString(
+ const std::vector<std::string>& features, std::string* error_msg) const override;
+
+ private:
+ explicit Riscv64InstructionSetFeatures(uint32_t bits) : InstructionSetFeatures(), bits_(bits) {}
+
+ // Extension bitmap.
+ const uint32_t bits_;
+
+ DISALLOW_COPY_AND_ASSIGN(Riscv64InstructionSetFeatures);
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_ARCH_RISCV64_INSTRUCTION_SET_FEATURES_RISCV64_H_
diff --git a/runtime/arch/riscv64/instruction_set_features_riscv64_test.cc b/runtime/arch/riscv64/instruction_set_features_riscv64_test.cc
new file mode 100644
index 0000000000..aef3d67c00
--- /dev/null
+++ b/runtime/arch/riscv64/instruction_set_features_riscv64_test.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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_riscv64.h"
+
+#include <gtest/gtest.h>
+
+namespace art {
+
+TEST(Riscv64InstructionSetFeaturesTest, Riscv64FeaturesFromDefaultVariant) {
+ std::string error_msg;
+ std::unique_ptr<const InstructionSetFeatures> riscv64_features(
+ InstructionSetFeatures::FromVariant(InstructionSet::kRiscv64, "generic", &error_msg));
+ ASSERT_TRUE(riscv64_features.get() != nullptr) << error_msg;
+
+ EXPECT_EQ(riscv64_features->GetInstructionSet(), InstructionSet::kRiscv64);
+
+ EXPECT_TRUE(riscv64_features->Equals(riscv64_features.get()));
+
+ uint32_t expected_extensions =
+ Riscv64InstructionSetFeatures::kExtGeneric | Riscv64InstructionSetFeatures::kExtCompressed;
+ EXPECT_EQ(riscv64_features->AsBitmap(), expected_extensions); // rv64gc, aka rv64imafdc
+}
+
+} // namespace art