From 4324b262aada2a005465596cf7e14465beb00932 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sun, 31 Dec 2023 18:09:00 +0800 Subject: [PATCH] backend/rv64: Add biscuit as the assembler --- CMakeLists.txt | 5 +++ CMakeModules/dynarmicConfig.cmake.in | 4 ++ README.md | 17 ++++++++ externals/CMakeLists.txt | 8 ++++ externals/README.md | 3 ++ src/dynarmic/CMakeLists.txt | 3 +- src/dynarmic/backend/exception_handler.h | 4 +- .../backend/exception_handler_generic.cpp | 2 +- .../backend/exception_handler_posix.cpp | 4 +- src/dynarmic/backend/riscv64/code_block.h | 42 +++++++++++++++++++ .../backend/riscv64/dummy_code_block.h | 16 ------- 11 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 src/dynarmic/backend/riscv64/code_block.h delete mode 100644 src/dynarmic/backend/riscv64/dummy_code_block.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ebe9dbb5..a60b4ec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ message(STATUS "Target architecture: ${ARCHITECTURE}") # Forced use of individual bundled libraries for non-REQUIRED library is possible with e.g. cmake -DCMAKE_DISABLE_FIND_PACKAGE_fmt=ON ... if (DYNARMIC_USE_BUNDLED_EXTERNALS) + set(CMAKE_DISABLE_FIND_PACKAGE_biscuit ON) set(CMAKE_DISABLE_FIND_PACKAGE_Catch2 ON) set(CMAKE_DISABLE_FIND_PACKAGE_fmt ON) set(CMAKE_DISABLE_FIND_PACKAGE_mcl ON) @@ -148,6 +149,10 @@ if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS) find_package(oaknut 2.0.1 CONFIG) endif() +if ("riscv" IN_LIST ARCHITECTURE) + find_package(biscuit 0.9.1 QUIET) +endif() + if ("x86_64" IN_LIST ARCHITECTURE) find_package(xbyak 7 CONFIG) find_package(Zydis 4 CONFIG) diff --git a/CMakeModules/dynarmicConfig.cmake.in b/CMakeModules/dynarmicConfig.cmake.in index 02612391..6a5db016 100644 --- a/CMakeModules/dynarmicConfig.cmake.in +++ b/CMakeModules/dynarmicConfig.cmake.in @@ -14,6 +14,10 @@ if (NOT @BUILD_SHARED_LIBS@) find_dependency(oaknut 2.0.1) endif() + if ("riscv" IN_LIST ARCHITECTURE) + find_dependency(biscuit 0.9.1) + endif() + if ("x86_64" IN_LIST ARCHITECTURE) find_dependency(xbyak 7) find_dependency(Zydis 4) diff --git a/README.md b/README.md index 466032dc..1bb437d8 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,23 @@ dynarmic is under a 0BSD license. See LICENSE.txt for more details. dynarmic uses several other libraries, whose licenses are included below: +### biscuit + +``` +Copyright 2021 Lioncash/Lioncache + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +``` + ### catch ``` diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 129d6a41..f6b837bc 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -15,6 +15,14 @@ set(BUILD_TESTING OFF) # simply add the directory to that file as a subdirectory # to have CMake automatically recognize them. +# biscuit + +if (NOT TARGET biscuit::biscuit) + if ("riscv" IN_LIST ARCHITECTURE) + add_subdirectory(biscuit) + endif() +endif() + # catch if (NOT TARGET Catch2::Catch2WithMain) diff --git a/externals/README.md b/externals/README.md index d71d5ae0..6fa02f5e 100644 --- a/externals/README.md +++ b/externals/README.md @@ -3,6 +3,7 @@ This repository uses subtrees to manage some of its externals. ## Initial setup ``` +git remote add externals-biscuit https://github.com/lioncash/biscuit.git --no-tags git remote add externals-catch https://github.com/catchorg/Catch2.git --no-tags git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags git remote add externals-mcl https://github.com/merryhime/mcl.git --no-tags @@ -18,6 +19,7 @@ git remote add externals-zydis https://github.com/zyantific/zydis.git --no-tags Change `` to refer to the appropriate git reference. ``` +git fetch externals-biscuit git fetch externals-catch git fetch externals-fmt git fetch externals-mcl @@ -26,6 +28,7 @@ git fetch externals-robin-map git fetch externals-xbyak git fetch externals-zycore git fetch externals-zydis +git subtree pull --squash --prefix=externals/biscuit externals-biscuit git subtree pull --squash --prefix=externals/catch externals-catch git subtree pull --squash --prefix=externals/fmt externals-fmt git subtree pull --squash --prefix=externals/mcl externals-mcl diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt index bfd03de5..675669c9 100644 --- a/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/CMakeLists.txt @@ -400,6 +400,8 @@ if ("arm64" IN_LIST ARCHITECTURE) endif() if ("riscv" IN_LIST ARCHITECTURE) + target_link_libraries(dynarmic PRIVATE biscuit::biscuit) + if ("A32" IN_LIST DYNARMIC_FRONTENDS) target_sources(dynarmic PRIVATE backend/riscv64/a32_address_space.cpp @@ -408,7 +410,6 @@ if ("riscv" IN_LIST ARCHITECTURE) backend/riscv64/a32_interface.cpp backend/riscv64/a32_jitstate.cpp backend/riscv64/a32_jitstate.h - backend/riscv64/dummy_code_block.h ) endif() diff --git a/src/dynarmic/backend/exception_handler.h b/src/dynarmic/backend/exception_handler.h index 3e388a20..ed5c41c7 100644 --- a/src/dynarmic/backend/exception_handler.h +++ b/src/dynarmic/backend/exception_handler.h @@ -22,7 +22,7 @@ class CodeBlock; } // namespace oaknut #elif defined(MCL_ARCHITECTURE_RISCV) namespace Dynarmic::Backend::RV64 { -class DummyCodeBlock; +class CodeBlock; } // namespace Dynarmic::Backend::RV64 #else # error "Invalid architecture" @@ -56,7 +56,7 @@ public: #elif defined(MCL_ARCHITECTURE_ARM64) void Register(oaknut::CodeBlock& mem, std::size_t mem_size); #elif defined(MCL_ARCHITECTURE_RISCV) - void Register(RV64::DummyCodeBlock& mem, std::size_t mem_size); + void Register(RV64::CodeBlock& mem, std::size_t mem_size); #else # error "Invalid architecture" #endif diff --git a/src/dynarmic/backend/exception_handler_generic.cpp b/src/dynarmic/backend/exception_handler_generic.cpp index 6c86c1ee..ad7df25c 100644 --- a/src/dynarmic/backend/exception_handler_generic.cpp +++ b/src/dynarmic/backend/exception_handler_generic.cpp @@ -22,7 +22,7 @@ void ExceptionHandler::Register(oaknut::CodeBlock&, std::size_t) { // Do nothing } #elif defined(MCL_ARCHITECTURE_RISCV) -void ExceptionHandler::Register(RV64::DummyCodeBlock&, std::size_t) { +void ExceptionHandler::Register(RV64::CodeBlock&, std::size_t) { // Do nothing } #else diff --git a/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/backend/exception_handler_posix.cpp index 72a178f1..5b442196 100644 --- a/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/backend/exception_handler_posix.cpp @@ -33,7 +33,7 @@ # include "dynarmic/backend/arm64/abi.h" #elif defined(MCL_ARCHITECTURE_RISCV) -# include "dynarmic/backend/riscv64/dummy_code_block.h" +# include "dynarmic/backend/riscv64/code_block.h" #else # error "Invalid architecture" #endif @@ -313,7 +313,7 @@ void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { impl = std::make_unique(code_begin, code_end); } #elif defined(MCL_ARCHITECTURE_RISCV) -void ExceptionHandler::Register(RV64::DummyCodeBlock& mem, std::size_t size) { +void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) { const u64 code_begin = mcl::bit_cast(mem.ptr()); const u64 code_end = code_begin + size; impl = std::make_unique(code_begin, code_end); diff --git a/src/dynarmic/backend/riscv64/code_block.h b/src/dynarmic/backend/riscv64/code_block.h new file mode 100644 index 00000000..786030c0 --- /dev/null +++ b/src/dynarmic/backend/riscv64/code_block.h @@ -0,0 +1,42 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2024 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#pragma once + +#include +#include + +#include +#include + +namespace Dynarmic::Backend::RV64 { + +class CodeBlock { +public: + explicit CodeBlock(std::size_t size) + : memsize(size) { + mem = (std::uint32_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + + if (mem == nullptr) + throw std::bad_alloc{}; + } + + ~CodeBlock() { + if (mem == nullptr) + return; + + munmap(mem, memsize); + } + + std::uint32_t* ptr() const { + return mem; + } + +protected: + std::uint32_t* mem; + std::size_t memsize = 0; + biscuit::Assembler as; +}; +} // namespace Dynarmic::Backend::RV64 diff --git a/src/dynarmic/backend/riscv64/dummy_code_block.h b/src/dynarmic/backend/riscv64/dummy_code_block.h deleted file mode 100644 index 208c956f..00000000 --- a/src/dynarmic/backend/riscv64/dummy_code_block.h +++ /dev/null @@ -1,16 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2024 MerryMage - * SPDX-License-Identifier: 0BSD - */ - -#pragma once - -namespace Dynarmic::Backend::RV64 { - -class DummyCodeBlock { -public: - DummyCodeBlock() {} - - void* ptr() { return nullptr; } -}; -} // namespace Dynarmic::Backend::RV64