diff options
-rw-r--r-- | build/art.go | 2 | ||||
-rw-r--r-- | compiler/debug/elf_debug_frame_writer.h | 4 | ||||
-rw-r--r-- | compiler/debug/elf_debug_line_writer.h | 1 | ||||
-rw-r--r-- | compiler/debug/elf_debug_loc_writer.h | 4 | ||||
-rw-r--r-- | libartbase/arch/instruction_set.cc | 7 | ||||
-rw-r--r-- | libartbase/arch/instruction_set.h | 35 | ||||
-rw-r--r-- | libelffile/dwarf/register.h | 2 | ||||
-rw-r--r-- | libelffile/elf/elf_builder.h | 7 | ||||
-rw-r--r-- | libelffile/elf/elf_utils.h | 9 | ||||
-rw-r--r-- | odrefresh/odr_config.h | 1 | ||||
-rw-r--r-- | runtime/metrics/statsd.cc | 2 |
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: |