diff options
| -rw-r--r-- | runtime/arch/riscv64/asm_support_riscv64.S | 27 | ||||
| -rw-r--r-- | runtime/arch/riscv64/asm_support_riscv64.h | 30 | ||||
| -rw-r--r-- | runtime/arch/riscv64/callee_save_frame_riscv64.h | 142 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/callee_save_frame.h | 21 |
4 files changed, 216 insertions, 4 deletions
diff --git a/runtime/arch/riscv64/asm_support_riscv64.S b/runtime/arch/riscv64/asm_support_riscv64.S new file mode 100644 index 0000000000..6a1f8872c8 --- /dev/null +++ b/runtime/arch/riscv64/asm_support_riscv64.S @@ -0,0 +1,27 @@ +/* + * 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_ASM_SUPPORT_RISCV64_S_ +#define ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_S_ + +#include "asm_support_riscv64.h" + +// Define special registers. + +// Register holding Thread::Current(). +#define xSELF s1 + +#endif // ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_S_ diff --git a/runtime/arch/riscv64/asm_support_riscv64.h b/runtime/arch/riscv64/asm_support_riscv64.h new file mode 100644 index 0000000000..8406a5366d --- /dev/null +++ b/runtime/arch/riscv64/asm_support_riscv64.h @@ -0,0 +1,30 @@ +/* + * 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_ASM_SUPPORT_RISCV64_H_ +#define ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_H_ + +#include "asm_support.h" + +// FS0 - FS11, S0 - S11, RA and ArtMethod*, total 8*(12 + 12 + 1 + 1) = 208 +#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVES 208 +// FA0 - FA7, A1 - A7, S0, S2 - S11, RA and ArtMethod* total 8*(8 + 7 + 11 + 1 + 1) = 224 +// A0 is excluded as the ArtMethod*, and S1 is excluded as the ART thread register TR. +#define FRAME_SIZE_SAVE_REFS_AND_ARGS 224 +// All 32 FPRs, 28 GPRs (no SP, Zero, TP, GP), ArtMethod*, padding, total 8*(32 + 28 + 1 + 1) = 496 +#define FRAME_SIZE_SAVE_EVERYTHING 496 + +#endif // ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_H_ diff --git a/runtime/arch/riscv64/callee_save_frame_riscv64.h b/runtime/arch/riscv64/callee_save_frame_riscv64.h new file mode 100644 index 0000000000..ac888814ce --- /dev/null +++ b/runtime/arch/riscv64/callee_save_frame_riscv64.h @@ -0,0 +1,142 @@ +/* + * 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_CALLEE_SAVE_FRAME_RISCV64_H_ +#define ART_RUNTIME_ARCH_RISCV64_CALLEE_SAVE_FRAME_RISCV64_H_ + +#include "arch/instruction_set.h" +#include "base/bit_utils.h" +#include "base/callee_save_type.h" +#include "base/enums.h" +#include "quick/quick_method_frame_info.h" +#include "registers_riscv64.h" +#include "runtime_globals.h" + +namespace art { +namespace riscv64 { + +static constexpr uint32_t kRiscv64CalleeSaveAlwaysSpills = + (1 << art::riscv64::RA); // Return address +// Callee-saved registers except for SP and S1 (SP is callee-saved according to RISC-V spec, but +// it cannot contain object reference, and S1(TR) is excluded as the ART thread register). +static constexpr uint32_t kRiscv64CalleeSaveRefSpills = + (1 << art::riscv64::S0) | (1 << art::riscv64::S2) | (1 << art::riscv64::S3) | + (1 << art::riscv64::S4) | (1 << art::riscv64::S5) | (1 << art::riscv64::S6) | + (1 << art::riscv64::S7) | (1 << art::riscv64::S8) | (1 << art::riscv64::S9) | + (1 << art::riscv64::S10) | (1 << art::riscv64::S11); +// S1(TR) is included because exception handler checks that the saved TR holds Thread::Current(). +// Stack pointer SP is excluded (although it is callee-saved by calling convention) because it is +// restored by the code logic and not from a stack frame. +static constexpr uint32_t kRiscv64CalleeSaveAllSpills = (1 << art::riscv64::S1); +// Argument registers except X10/A0 (which contains method pointer). +static constexpr uint32_t kRiscv64CalleeSaveArgSpills = + (1 << art::riscv64::A1) | (1 << art::riscv64::A2) | (1 << art::riscv64::A3) | + (1 << art::riscv64::A4) | (1 << art::riscv64::A5) | (1 << art::riscv64::A6) | + (1 << art::riscv64::A7); +// All registers except SP, immutable Zero, unallocatable thread pointer TP and global pointer GP. +static constexpr uint32_t kRiscv64CalleeSaveEverythingSpills = + (1 << art::riscv64::TR) | (1 << art::riscv64::T0) | (1 << art::riscv64::T1) | + (1 << art::riscv64::T2) | (1 << art::riscv64::T3) | (1 << art::riscv64::T4) | + (1 << art::riscv64::T5) | (1 << art::riscv64::T6) | (1 << art::riscv64::A0) | + (1 << art::riscv64::A1) | (1 << art::riscv64::A2) | (1 << art::riscv64::A3) | + (1 << art::riscv64::A4) | (1 << art::riscv64::A5) | (1 << art::riscv64::A6) | + (1 << art::riscv64::A7); + +// No references in floating-point registers. +static constexpr uint32_t kRiscv64CalleeSaveFpSpills = 0; +// Floating-point argument registers FA0 - FA7. +static constexpr uint32_t kRiscv64CalleeSaveFpArgSpills = + (1 << art::riscv64::FA0) | (1 << art::riscv64::FA1) | (1 << art::riscv64::FA2) | + (1 << art::riscv64::FA3) | (1 << art::riscv64::FA4) | (1 << art::riscv64::FA5) | + (1 << art::riscv64::FA6) | (1 << art::riscv64::FA7); +// Floating-point callee-saved registers FS0 - FS11. +static constexpr uint32_t kRiscv64CalleeSaveFpAllSpills = + (1 << art::riscv64::FS0) | (1 << art::riscv64::FS1) | (1 << art::riscv64::FS2) | + (1 << art::riscv64::FS3) | (1 << art::riscv64::FS4) | (1 << art::riscv64::FS5) | + (1 << art::riscv64::FS6) | (1 << art::riscv64::FS7) | (1 << art::riscv64::FS8) | + (1 << art::riscv64::FS9) | (1 << art::riscv64::FS10) | (1 << art::riscv64::FS11); +// All floating-point registers. +static constexpr uint32_t kRiscv64CalleeSaveFpEverythingSpills = + (1 << art::riscv64::FT0) | (1 << art::riscv64::FT1) | (1 << art::riscv64::FT2) | + (1 << art::riscv64::FT3) | (1 << art::riscv64::FT4) | (1 << art::riscv64::FT5) | + (1 << art::riscv64::FT6) | (1 << art::riscv64::FT7) | (1 << art::riscv64::FT8) | + (1 << art::riscv64::FT9) | (1 << art::riscv64::FT10) | (1 << art::riscv64::FT11) | + (1 << art::riscv64::FS0) | (1 << art::riscv64::FS1) | (1 << art::riscv64::FS2) | + (1 << art::riscv64::FS3) | (1 << art::riscv64::FS4) | (1 << art::riscv64::FS5) | + (1 << art::riscv64::FS6) | (1 << art::riscv64::FS7) | (1 << art::riscv64::FS8) | + (1 << art::riscv64::FS9) | (1 << art::riscv64::FS10) | (1 << art::riscv64::FS11) | + (1 << art::riscv64::FA0) | (1 << art::riscv64::FA1) | (1 << art::riscv64::FA2) | + (1 << art::riscv64::FA3) | (1 << art::riscv64::FA4) | (1 << art::riscv64::FA5) | + (1 << art::riscv64::FA6) | (1 << art::riscv64::FA7); + +class Riscv64CalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kRiscv64CalleeSaveAlwaysSpills | kRiscv64CalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kRiscv64CalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kRiscv64CalleeSaveAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kRiscv64CalleeSaveEverythingSpills : 0); + } + + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kRiscv64CalleeSaveFpSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kRiscv64CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kRiscv64CalleeSaveFpAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kRiscv64CalleeSaveFpEverythingSpills : 0); + } + + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + 1 /* Method* */) * + static_cast<size_t>(kRiscv64PointerSize), + kStackAlignment); + } + + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } + + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - (POPCOUNT(GetCoreSpills(type)) + POPCOUNT(GetFpSpills(type))) * + static_cast<size_t>(kRiscv64PointerSize); + } + + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kRiscv64PointerSize); + } + + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kRiscv64PointerSize); + } +}; + +// Assembly entrypoints rely on these constants. +static_assert(Riscv64CalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveRefsAndArgs) == 224); +static_assert(Riscv64CalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveAllCalleeSaves) == 208); +static_assert(Riscv64CalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveEverything) == 496); + +} // namespace riscv64 +} // namespace art + +#endif // ART_RUNTIME_ARCH_RISCV64_CALLEE_SAVE_FRAME_RISCV64_H_ diff --git a/runtime/entrypoints/quick/callee_save_frame.h b/runtime/entrypoints/quick/callee_save_frame.h index 1baccee4fc..7d9b844b0c 100644 --- a/runtime/entrypoints/quick/callee_save_frame.h +++ b/runtime/entrypoints/quick/callee_save_frame.h @@ -28,6 +28,7 @@ // specialize the code. #include "arch/arm/callee_save_frame_arm.h" #include "arch/arm64/callee_save_frame_arm64.h" +#include "arch/riscv64/callee_save_frame_riscv64.h" #include "arch/x86/callee_save_frame_x86.h" #include "arch/x86_64/callee_save_frame_x86_64.h" @@ -73,13 +74,25 @@ struct CSFSelector; // No definition for unspecialized callee save frame select // Note: kThumb2 is never the kRuntimeISA. template <> -struct CSFSelector<InstructionSet::kArm> { using type = arm::ArmCalleeSaveFrame; }; +struct CSFSelector<InstructionSet::kArm> { + using type = arm::ArmCalleeSaveFrame; +}; +template <> +struct CSFSelector<InstructionSet::kArm64> { + using type = arm64::Arm64CalleeSaveFrame; +}; template <> -struct CSFSelector<InstructionSet::kArm64> { using type = arm64::Arm64CalleeSaveFrame; }; +struct CSFSelector<InstructionSet::kRiscv64> { + using type = riscv64::Riscv64CalleeSaveFrame; +}; template <> -struct CSFSelector<InstructionSet::kX86> { using type = x86::X86CalleeSaveFrame; }; +struct CSFSelector<InstructionSet::kX86> { + using type = x86::X86CalleeSaveFrame; +}; template <> -struct CSFSelector<InstructionSet::kX86_64> { using type = x86_64::X86_64CalleeSaveFrame; }; +struct CSFSelector<InstructionSet::kX86_64> { + using type = x86_64::X86_64CalleeSaveFrame; +}; } // namespace detail |