Merge pull request #9198 from liamwhite/arm64

Initial ARM64 support
This commit is contained in:
bunnei 2022-11-10 17:11:27 -08:00 committed by GitHub
commit d05b183f21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 68 additions and 36 deletions

View file

@ -133,13 +133,13 @@ if (NOT ENABLE_GENERIC)
if (MSVC) if (MSVC)
detect_architecture("_M_AMD64" x86_64) detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86) detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM) detect_architecture("_M_ARM" arm)
detect_architecture("_M_ARM64" ARM64) detect_architecture("_M_ARM64" arm64)
else() else()
detect_architecture("__x86_64__" x86_64) detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86) detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM) detect_architecture("__arm__" arm)
detect_architecture("__aarch64__" ARM64) detect_architecture("__aarch64__" arm64)
endif() endif()
endif() endif()

View file

@ -7,15 +7,14 @@ include(DownloadExternals)
# xbyak # xbyak
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
add_library(xbyak INTERFACE) add_subdirectory(xbyak)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xbyak/xbyak DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_include_directories(xbyak SYSTEM INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
endif() endif()
# Dynarmic # Dynarmic
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
if (ARCHITECTURE_arm64)
set(DYNARMIC_FRONTENDS "A32")
endif()
set(DYNARMIC_NO_BUNDLED_FMT ON) set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE) set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
add_subdirectory(dynarmic) add_subdirectory(dynarmic)

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit 2d4602a6516c67d547000d4c80bcc5f74976abdd Subproject commit 424fdb5c5026ec5bdd7553271190397f63fb503e

2
externals/xbyak vendored

@ -1 +1 @@
Subproject commit c306b8e5786eeeb87b8925a8af5c3bf057ff5a90 Subproject commit 348e3e548ebac06d243e5881caec8440e249f65f

View file

@ -217,7 +217,7 @@ else()
endif() endif()
target_link_libraries(audio_core PUBLIC common core) target_link_libraries(audio_core PUBLIC common core)
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(audio_core PRIVATE dynarmic) target_link_libraries(audio_core PRIVATE dynarmic)
endif() endif()

View file

@ -31,8 +31,10 @@
#ifndef _MSC_VER #ifndef _MSC_VER
#ifdef ARCHITECTURE_x86_64 #if defined(ARCHITECTURE_x86_64)
#define Crash() __asm__ __volatile__("int $3") #define Crash() __asm__ __volatile__("int $3")
#elif defined(ARCHITECTURE_arm64)
#define Crash() __asm__ __volatile__("brk #0")
#else #else
#define Crash() exit(1) #define Crash() exit(1)
#endif #endif

View file

@ -359,6 +359,12 @@ public:
} }
}); });
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != 0x1000) {
LOG_CRITICAL(HW_Memory, "page size {:#x} is incompatible with 4K paging", page_size);
throw std::bad_alloc{};
}
// Backing memory initialization // Backing memory initialization
#if defined(__FreeBSD__) && __FreeBSD__ < 13 #if defined(__FreeBSD__) && __FreeBSD__ < 13
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30

View file

@ -497,10 +497,6 @@ add_library(core STATIC
hle/service/hid/irsensor/processor_base.h hle/service/hid/irsensor/processor_base.h
hle/service/hid/irsensor/tera_plugin_processor.cpp hle/service/hid/irsensor/tera_plugin_processor.cpp
hle/service/hid/irsensor/tera_plugin_processor.h hle/service/hid/irsensor/tera_plugin_processor.h
hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h
hle/service/jit/jit.cpp
hle/service/jit/jit.h
hle/service/lbl/lbl.cpp hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h hle/service/lbl/lbl.h
hle/service/ldn/lan_discovery.cpp hle/service/ldn/lan_discovery.cpp
@ -805,14 +801,18 @@ if (ENABLE_WEB_SERVICE)
target_link_libraries(core PRIVATE web_service) target_link_libraries(core PRIVATE web_service)
endif() endif()
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_sources(core PRIVATE target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic_32.cpp
arm/dynarmic/arm_dynarmic_32.h
arm/dynarmic/arm_dynarmic_64.cpp arm/dynarmic/arm_dynarmic_64.cpp
arm/dynarmic/arm_dynarmic_64.h arm/dynarmic/arm_dynarmic_64.h
arm/dynarmic/arm_dynarmic_32.cpp
arm/dynarmic/arm_dynarmic_32.h
arm/dynarmic/arm_dynarmic_cp15.cpp arm/dynarmic/arm_dynarmic_cp15.cpp
arm/dynarmic/arm_dynarmic_cp15.h arm/dynarmic/arm_dynarmic_cp15.h
hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h
hle/service/jit/jit.cpp
hle/service/jit/jit.h
) )
target_link_libraries(core PRIVATE dynarmic) target_link_libraries(core PRIVATE dynarmic)
endif() endif()

View file

@ -301,6 +301,11 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
} }
} }
#ifdef ARCHITECTURE_arm64
// TODO: remove when fixed in dynarmic
config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
#endif
return std::make_unique<Dynarmic::A32::Jit>(config); return std::make_unique<Dynarmic::A32::Jit>(config);
} }

View file

@ -52,12 +52,16 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
case 4: case 4:
// CP15_DATA_SYNC_BARRIER // CP15_DATA_SYNC_BARRIER
return Callback{ return Callback{
[](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { [](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#ifdef _MSC_VER #if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
_mm_mfence(); _mm_mfence();
_mm_lfence(); _mm_lfence();
#else #elif defined(ARCHITECTURE_x86_64)
asm volatile("mfence\n\tlfence\n\t" : : : "memory"); asm volatile("mfence\n\tlfence\n\t" : : : "memory");
#elif defined(ARCHITECTURE_arm64)
asm volatile("dsb sy\n\t" : : : "memory");
#else
#error Unsupported architecture
#endif #endif
return 0; return 0;
}, },
@ -66,11 +70,15 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
case 5: case 5:
// CP15_DATA_MEMORY_BARRIER // CP15_DATA_MEMORY_BARRIER
return Callback{ return Callback{
[](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { [](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#ifdef _MSC_VER #if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
_mm_mfence(); _mm_mfence();
#else #elif defined(ARCHITECTURE_x86_64)
asm volatile("mfence\n\t" : : : "memory"); asm volatile("mfence\n\t" : : : "memory");
#elif defined(ARCHITECTURE_arm64)
asm volatile("dmb sy\n\t" : : : "memory");
#else
#error Unsupported architecture
#endif #endif
return 0; return 0;
}, },
@ -115,7 +123,7 @@ CallbackOrAccessOneWord DynarmicCP15::CompileGetOneWord(bool two, unsigned opc1,
CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) { CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) {
if (!two && opc == 0 && CRm == CoprocReg::C14) { if (!two && opc == 0 && CRm == CoprocReg::C14) {
// CNTPCT // CNTPCT
const auto callback = [](Dynarmic::A32::Jit*, void* arg, u32, u32) -> u64 { const auto callback = [](void* arg, u32, u32) -> u64 {
const auto& parent_arg = *static_cast<ARM_Dynarmic_32*>(arg); const auto& parent_arg = *static_cast<ARM_Dynarmic_32*>(arg);
return parent_arg.system.CoreTiming().GetClockTicks(); return parent_arg.system.CoreTiming().GetClockTicks();
}; };

View file

@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#ifdef ARCHITECTURE_x86_64 #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
#include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h"
#endif #endif
#include "core/arm/exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
@ -13,7 +13,7 @@ ExclusiveMonitor::~ExclusiveMonitor() = default;
std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor(Memory::Memory& memory, std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor(Memory::Memory& memory,
std::size_t num_cores) { std::size_t num_cores) {
#ifdef ARCHITECTURE_x86_64 #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
return std::make_unique<Core::DynarmicExclusiveMonitor>(memory, num_cores); return std::make_unique<Core::DynarmicExclusiveMonitor>(memory, num_cores);
#else #else
// TODO(merry): Passthrough exclusive monitor // TODO(merry): Passthrough exclusive monitor

View file

@ -12,7 +12,7 @@ namespace Kernel {
PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_) PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_)
: core_index{core_index_}, system{system_}, scheduler{scheduler_} { : core_index{core_index_}, system{system_}, scheduler{scheduler_} {
#ifdef ARCHITECTURE_x86_64 #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
// TODO(bunnei): Initialization relies on a core being available. We may later replace this with // TODO(bunnei): Initialization relies on a core being available. We may later replace this with
// a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager.
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
@ -26,7 +26,7 @@ PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KSche
PhysicalCore::~PhysicalCore() = default; PhysicalCore::~PhysicalCore() = default;
void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) { void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) {
#ifdef ARCHITECTURE_x86_64 #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
if (!is_64_bit) { if (!is_64_bit) {
// We already initialized a 64-bit core, replace with a 32-bit one. // We already initialized a 64-bit core, replace with a 32-bit one.

View file

@ -73,8 +73,6 @@ add_library(video_core STATIC
macro/macro_hle.h macro/macro_hle.h
macro/macro_interpreter.cpp macro/macro_interpreter.cpp
macro/macro_interpreter.h macro/macro_interpreter.h
macro/macro_jit_x64.cpp
macro/macro_jit_x64.h
fence_manager.h fence_manager.h
gpu.cpp gpu.cpp
gpu.h gpu.h
@ -245,7 +243,7 @@ add_library(video_core STATIC
create_target_directory_groups(video_core) create_target_directory_groups(video_core)
target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PUBLIC glad shader_recompiler xbyak) target_link_libraries(video_core PUBLIC glad shader_recompiler)
if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32) if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32)
add_dependencies(video_core ffmpeg-build) add_dependencies(video_core ffmpeg-build)
@ -282,8 +280,19 @@ else()
-Wno-sign-conversion -Wno-sign-conversion
) )
# xbyak
set_source_files_properties(macro/macro_jit_x64.cpp PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-shadow")
endif() endif()
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64)
target_sources(video_core PRIVATE
macro/macro_jit_x64.cpp
macro/macro_jit_x64.h
)
target_link_libraries(video_core PUBLIC xbyak)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(video_core PRIVATE dynarmic) target_link_libraries(video_core PRIVATE dynarmic)
endif() endif()

View file

@ -16,7 +16,10 @@
#include "video_core/macro/macro.h" #include "video_core/macro/macro.h"
#include "video_core/macro/macro_hle.h" #include "video_core/macro/macro_hle.h"
#include "video_core/macro/macro_interpreter.h" #include "video_core/macro/macro_interpreter.h"
#ifdef ARCHITECTURE_x86_64
#include "video_core/macro/macro_jit_x64.h" #include "video_core/macro/macro_jit_x64.h"
#endif
namespace Tegra { namespace Tegra {

View file

@ -385,6 +385,6 @@ if (NOT APPLE)
target_compile_definitions(yuzu PRIVATE HAS_OPENGL) target_compile_definitions(yuzu PRIVATE HAS_OPENGL)
endif() endif()
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(yuzu PRIVATE dynarmic) target_link_libraries(yuzu PRIVATE dynarmic)
endif() endif()