summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/art.go2
-rw-r--r--compiler/debug/elf_debug_frame_writer.h4
-rw-r--r--compiler/debug/elf_debug_line_writer.h1
-rw-r--r--compiler/debug/elf_debug_loc_writer.h4
-rw-r--r--libartbase/arch/instruction_set.cc7
-rw-r--r--libartbase/arch/instruction_set.h35
-rw-r--r--libelffile/dwarf/register.h2
-rw-r--r--libelffile/elf/elf_builder.h7
-rw-r--r--libelffile/elf/elf_utils.h9
-rw-r--r--odrefresh/odr_config.h1
-rw-r--r--runtime/metrics/statsd.cc2
11 files changed, 70 insertions, 4 deletions
diff --git a/build/art.go b/build/art.go
index 7b06353ca1..970af8ab75 100644
--- a/build/art.go
+++ b/build/art.go
@@ -95,12 +95,14 @@ func globalFlags(ctx android.LoadHookContext) ([]string, []string) {
cflags = append(cflags,
"-DART_STACK_OVERFLOW_GAP_arm=16384",
"-DART_STACK_OVERFLOW_GAP_arm64=16384",
+ "-DART_STACK_OVERFLOW_GAP_riscv64=16384",
"-DART_STACK_OVERFLOW_GAP_x86=16384",
"-DART_STACK_OVERFLOW_GAP_x86_64=20480")
} else {
cflags = append(cflags,
"-DART_STACK_OVERFLOW_GAP_arm=8192",
"-DART_STACK_OVERFLOW_GAP_arm64=8192",
+ "-DART_STACK_OVERFLOW_GAP_riscv64=8192",
"-DART_STACK_OVERFLOW_GAP_x86=8192",
"-DART_STACK_OVERFLOW_GAP_x86_64=8192")
}
diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h
index 094e8871b9..269e3c6806 100644
--- a/compiler/debug/elf_debug_frame_writer.h
+++ b/compiler/debug/elf_debug_frame_writer.h
@@ -88,6 +88,10 @@ static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer)
WriteCIE(is64bit, return_reg, opcodes, buffer);
return;
}
+ case InstructionSet::kRiscv64: {
+ UNIMPLEMENTED(FATAL);
+ return;
+ }
case InstructionSet::kX86: {
// FIXME: Add fp registers once libunwind adds support for them. Bug: 20491296
constexpr bool generate_opcodes_for_x86_fp = false;
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index 8d62747c66..7df301af8d 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -73,6 +73,7 @@ class ElfDebugLineWriter {
code_factor_bits_ = 2; // 32-bit instructions
break;
case InstructionSet::kNone:
+ case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
break;
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h
index 9be1e2402d..374208187b 100644
--- a/compiler/debug/elf_debug_loc_writer.h
+++ b/compiler/debug/elf_debug_loc_writer.h
@@ -37,6 +37,8 @@ static Reg GetDwarfCoreReg(InstructionSet isa, int machine_reg) {
return Reg::ArmCore(machine_reg);
case InstructionSet::kArm64:
return Reg::Arm64Core(machine_reg);
+ case InstructionSet::kRiscv64:
+ return Reg::Riscv64Core(machine_reg);
case InstructionSet::kX86:
return Reg::X86Core(machine_reg);
case InstructionSet::kX86_64:
@@ -54,6 +56,8 @@ static Reg GetDwarfFpReg(InstructionSet isa, int machine_reg) {
return Reg::ArmFp(machine_reg);
case InstructionSet::kArm64:
return Reg::Arm64Fp(machine_reg);
+ case InstructionSet::kRiscv64:
+ return Reg::Riscv64Fp(machine_reg);
case InstructionSet::kX86:
return Reg::X86Fp(machine_reg);
case InstructionSet::kX86_64:
diff --git a/libartbase/arch/instruction_set.cc b/libartbase/arch/instruction_set.cc
index 7f1e4c7dd7..811e723e0e 100644
--- a/libartbase/arch/instruction_set.cc
+++ b/libartbase/arch/instruction_set.cc
@@ -29,6 +29,7 @@ void InstructionSetAbort(InstructionSet isa) {
case InstructionSet::kArm:
case InstructionSet::kThumb2:
case InstructionSet::kArm64:
+ case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
case InstructionSet::kNone:
@@ -46,6 +47,8 @@ const char* GetInstructionSetString(InstructionSet isa) {
return "arm";
case InstructionSet::kArm64:
return "arm64";
+ case InstructionSet::kRiscv64:
+ return "riscv64";
case InstructionSet::kX86:
return "x86";
case InstructionSet::kX86_64:
@@ -64,6 +67,8 @@ InstructionSet GetInstructionSetFromString(const char* isa_str) {
return InstructionSet::kArm;
} else if (strcmp("arm64", isa_str) == 0) {
return InstructionSet::kArm64;
+ } else if (strcmp("riscv64", isa_str) == 0) {
+ return InstructionSet::kRiscv64;
} else if (strcmp("x86", isa_str) == 0) {
return InstructionSet::kX86;
} else if (strcmp("x86_64", isa_str) == 0) {
@@ -93,6 +98,8 @@ std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg)
*error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
return {};
}
+ case InstructionSet::kRiscv64:
+ return {InstructionSet::kRiscv64};
case InstructionSet::kX86:
case InstructionSet::kX86_64:
if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
diff --git a/libartbase/arch/instruction_set.h b/libartbase/arch/instruction_set.h
index e68ff08c17..8d59f1b1e4 100644
--- a/libartbase/arch/instruction_set.h
+++ b/libartbase/arch/instruction_set.h
@@ -31,6 +31,7 @@ enum class InstructionSet {
kArm,
kArm64,
kThumb2,
+ kRiscv64,
kX86,
kX86_64,
kLast = kX86_64
@@ -41,6 +42,8 @@ std::ostream& operator<<(std::ostream& os, InstructionSet rhs);
static constexpr InstructionSet kRuntimeISA = InstructionSet::kArm;
#elif defined(__aarch64__)
static constexpr InstructionSet kRuntimeISA = InstructionSet::kArm64;
+#elif defined (__riscv)
+static constexpr InstructionSet kRuntimeISA = InstructionSet::kRiscv64;
#elif defined(__i386__)
static constexpr InstructionSet kRuntimeISA = InstructionSet::kX86;
#elif defined(__x86_64__)
@@ -52,6 +55,7 @@ static constexpr InstructionSet kRuntimeISA = InstructionSet::kNone;
// Architecture-specific pointer sizes
static constexpr PointerSize kArmPointerSize = PointerSize::k32;
static constexpr PointerSize kArm64PointerSize = PointerSize::k64;
+static constexpr PointerSize kRiscv64PointerSize = PointerSize::k64;
static constexpr PointerSize kX86PointerSize = PointerSize::k32;
static constexpr PointerSize kX86_64PointerSize = PointerSize::k64;
@@ -63,12 +67,17 @@ static constexpr size_t kArm64DefaultSVEVectorLength = 256;
// ARM processors require code to be 4-byte aligned, but ARM ELF requires 8.
static constexpr size_t kArmCodeAlignment = 8;
static constexpr size_t kArm64CodeAlignment = 16;
+static constexpr size_t kRiscv64CodeAlignment = 16;
static constexpr size_t kX86CodeAlignment = 16;
// Instruction alignment (every instruction must be aligned at this boundary). This differs from
// code alignment, which applies only to the first instruction of a subroutine.
+// Android requires the RISC-V compressed instruction extension, and that allows
+// *all* instructions (not just compressed ones) to be 2-byte aligned rather
+// than the usual 4-byte alignment requirement.
static constexpr size_t kThumb2InstructionAlignment = 2;
static constexpr size_t kArm64InstructionAlignment = 4;
+static constexpr size_t kRiscv64InstructionAlignment = 2;
static constexpr size_t kX86InstructionAlignment = 1;
static constexpr size_t kX86_64InstructionAlignment = 1;
@@ -88,6 +97,8 @@ constexpr PointerSize GetInstructionSetPointerSize(InstructionSet isa) {
return kArmPointerSize;
case InstructionSet::kArm64:
return kArm64PointerSize;
+ case InstructionSet::kRiscv64:
+ return kRiscv64PointerSize;
case InstructionSet::kX86:
return kX86PointerSize;
case InstructionSet::kX86_64:
@@ -104,6 +115,7 @@ constexpr bool IsValidInstructionSet(InstructionSet isa) {
case InstructionSet::kArm:
case InstructionSet::kThumb2:
case InstructionSet::kArm64:
+ case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
return true;
@@ -122,6 +134,8 @@ constexpr size_t GetInstructionSetInstructionAlignment(InstructionSet isa) {
return kThumb2InstructionAlignment;
case InstructionSet::kArm64:
return kArm64InstructionAlignment;
+ case InstructionSet::kRiscv64:
+ return kRiscv64InstructionAlignment;
case InstructionSet::kX86:
return kX86InstructionAlignment;
case InstructionSet::kX86_64:
@@ -141,6 +155,8 @@ constexpr size_t GetInstructionSetCodeAlignment(InstructionSet isa) {
return kArmCodeAlignment;
case InstructionSet::kArm64:
return kArm64CodeAlignment;
+ case InstructionSet::kRiscv64:
+ return kRiscv64CodeAlignment;
case InstructionSet::kX86:
// Fall-through.
case InstructionSet::kX86_64:
@@ -158,6 +174,7 @@ constexpr size_t GetInstructionSetEntryPointAdjustment(InstructionSet isa) {
switch (isa) {
case InstructionSet::kArm:
case InstructionSet::kArm64:
+ case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
return 0;
@@ -180,6 +197,7 @@ constexpr bool Is64BitInstructionSet(InstructionSet isa) {
return false;
case InstructionSet::kArm64:
+ case InstructionSet::kRiscv64:
case InstructionSet::kX86_64:
return true;
@@ -201,6 +219,8 @@ constexpr size_t GetBytesPerGprSpillLocation(InstructionSet isa) {
return 4;
case InstructionSet::kArm64:
return 8;
+ case InstructionSet::kRiscv64:
+ return 8;
case InstructionSet::kX86:
return 4;
case InstructionSet::kX86_64:
@@ -220,6 +240,8 @@ constexpr size_t GetBytesPerFprSpillLocation(InstructionSet isa) {
return 4;
case InstructionSet::kArm64:
return 8;
+ case InstructionSet::kRiscv64:
+ return 8;
case InstructionSet::kX86:
return 8;
case InstructionSet::kX86_64:
@@ -237,14 +259,16 @@ std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg);
namespace instruction_set_details {
#if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \
+ !defined(ART_STACK_OVERFLOW_GAP_riscv64) || \
!defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64)
#error "Missing defines for stack overflow gap"
#endif
-static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
-static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
-static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
-static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
+static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
+static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
+static constexpr size_t kRiscv64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_riscv64;
+static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
+static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
NO_RETURN void GetStackOverflowReservedBytesFailure(const char* error_msg);
@@ -260,6 +284,9 @@ constexpr size_t GetStackOverflowReservedBytes(InstructionSet isa) {
case InstructionSet::kArm64:
return instruction_set_details::kArm64StackOverflowReservedBytes;
+ case InstructionSet::kRiscv64:
+ return instruction_set_details::kRiscv64StackOverflowReservedBytes;
+
case InstructionSet::kX86:
return instruction_set_details::kX86StackOverflowReservedBytes;
diff --git a/libelffile/dwarf/register.h b/libelffile/dwarf/register.h
index 7742ec411e..33c67957d5 100644
--- a/libelffile/dwarf/register.h
+++ b/libelffile/dwarf/register.h
@@ -40,6 +40,8 @@ class Reg {
static Reg ArmDp(int num) { return Reg(256 + num); } // D0–D31.
static Reg Arm64Core(int num) { return Reg(num); } // X0-X31.
static Reg Arm64Fp(int num) { return Reg(64 + num); } // V0-V31.
+ static Reg Riscv64Core(int num) { return Reg(num); } // X0-X31
+ static Reg Riscv64Fp(int num) { return Reg(32 + num); } // F0-F31
static Reg X86Core(int num) { return Reg(num); }
static Reg X86Fp(int num) { return Reg(21 + num); }
static Reg X86_64Core(int num) {
diff --git a/libelffile/elf/elf_builder.h b/libelffile/elf/elf_builder.h
index 086bd41b6e..6720569aad 100644
--- a/libelffile/elf/elf_builder.h
+++ b/libelffile/elf/elf_builder.h
@@ -814,6 +814,8 @@ class ElfBuilder final {
return InstructionSet::kThumb2;
case EM_AARCH64:
return InstructionSet::kArm64;
+ case EM_RISCV:
+ return InstructionSet::kRiscv64;
case EM_386:
return InstructionSet::kX86;
case EM_X86_64:
@@ -839,6 +841,11 @@ class ElfBuilder final {
elf_header.e_flags = 0;
break;
}
+ case InstructionSet::kRiscv64: {
+ elf_header.e_machine = EM_RISCV;
+ elf_header.e_flags = EF_RISCV_RVC | EF_RISCV_FLOAT_ABI_DOUBLE;
+ break;
+ }
case InstructionSet::kX86: {
elf_header.e_machine = EM_386;
elf_header.e_flags = 0;
diff --git a/libelffile/elf/elf_utils.h b/libelffile/elf/elf_utils.h
index da67b8cc73..46b25b0a07 100644
--- a/libelffile/elf/elf_utils.h
+++ b/libelffile/elf/elf_utils.h
@@ -71,6 +71,15 @@ struct ElfTypes64 {
#define EM_AARCH64 183
+#ifndef EM_RISCV
+#define EM_RISCV 243
+#endif
+
+#ifndef EF_RISCV_RVC
+#define EF_RISCV_RVC 0x1
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x4
+#endif
+
#define DT_BIND_NOW 24
#define DT_INIT_ARRAY 25
#define DT_FINI_ARRAY 26
diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h
index b2621303e7..420f680f01 100644
--- a/odrefresh/odr_config.h
+++ b/odrefresh/odr_config.h
@@ -267,6 +267,7 @@ class OdrConfig final {
case art::InstructionSet::kX86:
case art::InstructionSet::kX86_64:
return std::make_pair(art::InstructionSet::kX86, art::InstructionSet::kX86_64);
+ case art::InstructionSet::kRiscv64:
case art::InstructionSet::kThumb2:
case art::InstructionSet::kNone:
LOG(FATAL) << "Invalid instruction set " << isa_;
diff --git a/runtime/metrics/statsd.cc b/runtime/metrics/statsd.cc
index 78c3622cbb..203b72e399 100644
--- a/runtime/metrics/statsd.cc
+++ b/runtime/metrics/statsd.cc
@@ -220,6 +220,8 @@ constexpr int32_t EncodeInstructionSet(InstructionSet isa) {
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM;
case InstructionSet::kArm64:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM64;
+ case InstructionSet::kRiscv64:
+ return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_RISCV64;
case InstructionSet::kX86:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_X86;
case InstructionSet::kX86_64: