mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-08-09 14:06:50 -05:00
Merge acfe7db873 into daacdda0ba
This commit is contained in:
commit
d7da74dcec
78
.github/workflows/build.yml
vendored
78
.github/workflows/build.yml
vendored
|
|
@ -204,6 +204,84 @@ jobs:
|
|||
name: cemu-installer-windows-x64
|
||||
path: ./src/resource/cemu-${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}-windows-x64-installer.exe
|
||||
|
||||
build-windows-arm64:
|
||||
continue-on-error: true
|
||||
runs-on: windows-11-arm
|
||||
steps:
|
||||
- name: "Checkout repo"
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Setup release mode parameters
|
||||
run: |
|
||||
echo "BUILD_MODE=release" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "Build mode is release"
|
||||
|
||||
- name: Setup build flags for version
|
||||
if: ${{ inputs.next_version_major != '' }}
|
||||
run: |
|
||||
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: "Ensure clang-cl (LLVM) toolset is installed in Visual Studio"
|
||||
run: |
|
||||
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
$vsPath = & $vswhere -latest -products * -property installationPath
|
||||
$setup = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\setup.exe"
|
||||
$modifyArgs = "modify --installPath `"$vsPath`" --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset --quiet --norestart"
|
||||
Start-Process -FilePath $setup -Wait -ArgumentList $modifyArgs
|
||||
|
||||
- name: "Setup MSVC environment (arm64)"
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: arm64
|
||||
|
||||
- name: "Setup Ninja"
|
||||
run: choco install ninja -y
|
||||
|
||||
- name: "Setup cmake"
|
||||
uses: jwlawson/actions-setup-cmake@v2
|
||||
with:
|
||||
cmake-version: '3.29.0'
|
||||
|
||||
- name: "Bootstrap vcpkg"
|
||||
run: |
|
||||
./dependencies/vcpkg/bootstrap-vcpkg.bat
|
||||
|
||||
- name: 'Setup NuGet Credentials for vcpkg'
|
||||
shell: 'bash'
|
||||
run: |
|
||||
`./dependencies/vcpkg/vcpkg.exe fetch nuget | tail -n 1` \
|
||||
sources add \
|
||||
-source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
|
||||
-storepasswordincleartext \
|
||||
-name "GitHub" \
|
||||
-username "${{ github.repository_owner }}" \
|
||||
-password "${{ secrets.GITHUB_TOKEN }}"
|
||||
`./dependencies/vcpkg/vcpkg.exe fetch nuget | tail -n 1` \
|
||||
setapikey "${{ secrets.GITHUB_TOKEN }}" \
|
||||
-source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json"
|
||||
|
||||
- name: "cmake"
|
||||
run: |
|
||||
echo "[INFO] BUILD_FLAGS: ${{ env.BUILD_FLAGS }}"
|
||||
cmake -S . -B build -G Ninja ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_LINKER_TYPE=MSVC -DVCPKG_INSTALL_OPTIONS="--clean-after-build"
|
||||
|
||||
- name: "Build Cemu"
|
||||
run: |
|
||||
cmake --build build
|
||||
|
||||
- name: Prepare artifact
|
||||
run: Rename-Item bin/Cemu_release.exe Cemu.exe
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: cemu-bin-windows-arm64
|
||||
path: ./bin/Cemu.exe
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
|
|
|
|||
30
BUILD.md
30
BUILD.md
|
|
@ -42,6 +42,36 @@ Instructions for Visual Studio 2022:
|
|||
|
||||
Any other IDE should also work as long as it has CMake and MSVC support. CLion and Visual Studio Code have been confirmed to work.
|
||||
|
||||
### Windows on ARM64 (Snapdragon)
|
||||
|
||||
Native ARM64 builds are supported and use **clang-cl**. The recompiler uses the
|
||||
AArch64 backend (`xbyak_aarch64`), so it runs natively rather than under x64
|
||||
emulation.
|
||||
|
||||
Prerequisites (Visual Studio 2022 or Build Tools 2022 with these components):
|
||||
- MSVC v143 - ARM64/ARM64EC build tools
|
||||
- C++ Clang Compiler for Windows and *MSBuild support for LLVM (clang-cl) toolset*
|
||||
- C++ CMake tools for Windows (CMake 3.29 or newer)
|
||||
- Windows 11 SDK
|
||||
|
||||
The Visual Studio CMake generator cannot assemble the codebase, so build from the
|
||||
command line with Ninja. Open an **"ARM64 Native Tools Command Prompt for VS 2022"**
|
||||
(or run `vcvarsarm64.bat`), then:
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/cemu-project/Cemu
|
||||
cd Cemu
|
||||
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=release ^
|
||||
-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl ^
|
||||
-DCMAKE_LINKER_TYPE=MSVC
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
`-DCMAKE_LINKER_TYPE=MSVC` makes clang link with the MSVC `link.exe` (required so
|
||||
that vcpkg's static libraries link correctly). The resulting binary is
|
||||
`bin/Cemu_release.exe`. Note: on ARM64 the bundled H.264 decoder (ih264d) is built
|
||||
as portable C, and libusb is used via the standard vcpkg package.
|
||||
|
||||
## Linux
|
||||
|
||||
To compile Cemu, a recent enough compiler and STL with C++20 support is required! Clang-15 or higher is what we recommend.
|
||||
|
|
|
|||
|
|
@ -51,7 +51,17 @@ if (ENABLE_VCPKG)
|
|||
# CONFIG option
|
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
|
||||
if (WIN32)
|
||||
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
|
||||
# Auto-select the vcpkg triplet based on the target architecture.
|
||||
# Override on the command line with -DVCPKG_TARGET_TRIPLET=...
|
||||
if (NOT DEFINED VCPKG_TARGET_TRIPLET)
|
||||
if (CMAKE_GENERATOR_PLATFORM MATCHES "(ARM64|arm64)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "(ARM64|arm64|aarch64)" OR
|
||||
"$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "arm64")
|
||||
set(VCPKG_TARGET_TRIPLET "arm64-windows-static" CACHE STRING "")
|
||||
else()
|
||||
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -72,9 +82,13 @@ add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
|
|||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# enable link time optimization for release builds
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
|
||||
# enable link time optimization for release builds.
|
||||
# Skip it for clang-cl on Windows: IPO forces the LLVM linker (lld-link), which
|
||||
# cannot consume the MSVC /GL objects inside vcpkg static libraries.
|
||||
if(NOT (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)
|
||||
|
|
@ -256,11 +270,34 @@ add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL)
|
|||
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
set(CEMU_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
|
||||
elseif (WIN32 AND (CMAKE_GENERATOR_PLATFORM MATCHES "(ARM64|arm64)" OR "$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "arm64"))
|
||||
# Windows ARM64: the host toolchain / emulated shell can misreport the
|
||||
# processor, so trust the requested target platform instead.
|
||||
set(CEMU_ARCHITECTURE "aarch64")
|
||||
else()
|
||||
set(CEMU_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
|
||||
add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL)
|
||||
if(MSVC)
|
||||
# Match the static CRT used by the rest of the project (vcpkg static triplet)
|
||||
set_property(TARGET xbyak_aarch64 PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# clang-cl emits calls to compiler-rt builtins (e.g. __udivti3 for 128-bit
|
||||
# integer division) that lld-link does not link automatically. Link the
|
||||
# clang_rt.builtins library that ships next to the compiler.
|
||||
get_filename_component(_llvm_bin "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
||||
get_filename_component(_llvm_root "${_llvm_bin}" DIRECTORY)
|
||||
file(GLOB _clang_rt_builtins "${_llvm_root}/lib/clang/*/lib/windows/clang_rt.builtins-aarch64.lib")
|
||||
if(_clang_rt_builtins)
|
||||
list(GET _clang_rt_builtins 0 _clang_rt_builtins)
|
||||
link_libraries("${_clang_rt_builtins}")
|
||||
message(STATUS "Linking compiler-rt builtins: ${_clang_rt_builtins}")
|
||||
else()
|
||||
message(WARNING "clang_rt.builtins-aarch64.lib not found; link may fail with undefined __udivti3")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(ZArchive QUIET)
|
||||
|
|
|
|||
20
dependencies/ih264d/CMakeLists.txt
vendored
20
dependencies/ih264d/CMakeLists.txt
vendored
|
|
@ -123,7 +123,12 @@ else()
|
|||
set(IH264D_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (IH264D_ARCHITECTURE STREQUAL "x86_64" OR IH264D_ARCHITECTURE STREQUAL "amd64" OR IH264D_ARCHITECTURE STREQUAL "AMD64")
|
||||
# Normalize the architecture string so matching is case-insensitive.
|
||||
# MSVC/CMake reports "ARM64"/"AMD64" (uppercase) whereas the checks below use
|
||||
# the lowercase names emitted by GCC/Clang toolchains.
|
||||
string(TOLOWER "${IH264D_ARCHITECTURE}" IH264D_ARCHITECTURE)
|
||||
|
||||
if (IH264D_ARCHITECTURE STREQUAL "x86_64" OR IH264D_ARCHITECTURE STREQUAL "amd64")
|
||||
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
||||
target_sources(ih264d PRIVATE
|
||||
|
|
@ -147,6 +152,18 @@ target_sources(ih264d PRIVATE
|
|||
"decoder/x86/ih264d_function_selector_ssse3.c"
|
||||
)
|
||||
elseif(IH264D_ARCHITECTURE STREQUAL "aarch64" OR IH264D_ARCHITECTURE STREQUAL "arm64")
|
||||
if(MSVC)
|
||||
# Windows on ARM64: build the generic C decoder. The NEON .s files are GAS syntax
|
||||
# and use ELF-only ":got:" relocations that cannot be assembled for COFF targets,
|
||||
# so we fall back to portable C (only affects H.264/FMV decode performance).
|
||||
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
||||
target_sources(ih264d PRIVATE
|
||||
"common/armv8/ih264_platform_macros.h"
|
||||
"decoder/arm/ih264d_function_selector.c"
|
||||
)
|
||||
target_compile_definitions(ih264d PRIVATE ARMV8 DISABLE_NEON DEFAULT_ARCH=D_ARCH_ARM_NONEON)
|
||||
else()
|
||||
enable_language( C CXX ASM )
|
||||
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
||||
|
|
@ -189,6 +206,7 @@ endif()
|
|||
if(APPLE)
|
||||
target_sources(ih264d PRIVATE "common/armv8/macos_arm_symbol_aliases.s")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void ih264d_init_function_ptr(dec_struct_t *ps_codec)
|
|||
ih264d_init_function_ptr_generic(ps_codec);
|
||||
switch(e_proc_arch)
|
||||
{
|
||||
#if defined(ARMV8)
|
||||
#if defined(ARMV8) && !defined(DISABLE_NEON)
|
||||
case ARCH_ARMV8_GENERIC:
|
||||
default:
|
||||
ih264d_init_function_ptr_av8(ps_codec);
|
||||
|
|
|
|||
2
dist/windows/Cemu.manifest
vendored
2
dist/windows/Cemu.manifest
vendored
|
|
@ -2,7 +2,7 @@
|
|||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges>
|
||||
|
|
|
|||
|
|
@ -668,7 +668,12 @@ endif()
|
|||
if (ENABLE_LIBUSB)
|
||||
if (ENABLE_VCPKG)
|
||||
if(WIN32)
|
||||
set(PKG_CONFIG_EXECUTABLE "${VCPKG_INSTALLED_DIR}/x64-windows/tools/pkgconf/pkgconf.exe")
|
||||
# pkgconf is a host tool; locate it under whichever host triplet vcpkg
|
||||
# used (x64-windows on Intel hosts, arm64-windows on ARM64 hosts).
|
||||
file(GLOB _cemu_pkgconf "${VCPKG_INSTALLED_DIR}/*/tools/pkgconf/pkgconf.exe")
|
||||
if(_cemu_pkgconf)
|
||||
list(GET _cemu_pkgconf 0 PKG_CONFIG_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0)
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ void debugger_updateMemoryBreakpoint(DebuggerBreakpoint* bp)
|
|||
{
|
||||
std::vector<std::thread::native_handle_type> schedulerThreadHandles = coreinit::OSGetSchedulerThreads();
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
#if BOOST_OS_WINDOWS && defined(ARCH_X86_64)
|
||||
s_debuggerState.activeMemoryBreakpoint = bp;
|
||||
for (auto& hThreadNH : schedulerThreadHandles)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture)
|
|||
bool isCompressedFormat = hostTexture->IsCompressedFormat();
|
||||
if( isCompressedFormat == false )
|
||||
{
|
||||
#if BOOST_OS_WINDOWS
|
||||
#if BOOST_OS_WINDOWS && defined(ARCH_X86_64)
|
||||
if (g_CPUFeatures.x86.avx2)
|
||||
{
|
||||
__m256i h256 = { 0 };
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ void createCrashlog(EXCEPTION_POINTERS* e, PCONTEXT context)
|
|||
// register info
|
||||
sprintf(dumpLine, "\n");
|
||||
cemuLog_writePlainToLog(dumpLine);
|
||||
#if defined(ARCH_X86_64)
|
||||
sprintf(dumpLine, "RAX=%016I64x RBX=%016I64x RCX=%016I64x RDX=%016I64x\n", context->Rax, context->Rbx, context->Rcx, context->Rdx);
|
||||
cemuLog_writePlainToLog(dumpLine);
|
||||
sprintf(dumpLine, "RSP=%016I64x RBP=%016I64x RDI=%016I64x RSI=%016I64x\n", context->Rsp, context->Rbp, context->Rdi, context->Rsi);
|
||||
|
|
@ -217,6 +218,17 @@ void createCrashlog(EXCEPTION_POINTERS* e, PCONTEXT context)
|
|||
cemuLog_writePlainToLog(dumpLine);
|
||||
sprintf(dumpLine, "R12=%016I64x R13=%016I64x R14=%016I64x R15=%016I64x\n", context->R12, context->R13, context->R14, context->R15);
|
||||
cemuLog_writePlainToLog(dumpLine);
|
||||
#else // AArch64
|
||||
for (int i = 0; i < 28; i += 4)
|
||||
{
|
||||
sprintf(dumpLine, "X%-2d=%016I64x X%-2d=%016I64x X%-2d=%016I64x X%-2d=%016I64x\n",
|
||||
i, context->X[i], i + 1, context->X[i + 1], i + 2, context->X[i + 2], i + 3, context->X[i + 3]);
|
||||
cemuLog_writePlainToLog(dumpLine);
|
||||
}
|
||||
sprintf(dumpLine, "X28=%016I64x FP =%016I64x LR =%016I64x SP =%016I64x PC =%016I64x\n",
|
||||
context->X[28], context->Fp, context->Lr, context->Sp, context->Pc);
|
||||
cemuLog_writePlainToLog(dumpLine);
|
||||
#endif
|
||||
|
||||
CrashLog_SetOutputChannels(false, true);
|
||||
ExceptionHandler_LogGeneralInfo();
|
||||
|
|
@ -264,11 +276,15 @@ LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
|
|||
if (r != EXCEPTION_CONTINUE_SEARCH)
|
||||
return r;
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
if (GetBits(pExceptionInfo->ContextRecord->Dr6, 0, 1) || GetBits(pExceptionInfo->ContextRecord->Dr6, 1, 1))
|
||||
debugger_handleSingleStepException(pExceptionInfo->ContextRecord->Dr6);
|
||||
else if (GetBits(pExceptionInfo->ContextRecord->Dr6, 2, 1) || GetBits(pExceptionInfo->ContextRecord->Dr6, 3, 1))
|
||||
g_gdbstub->HandleAccessException(pExceptionInfo->ContextRecord->Dr6);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
#else // AArch64: hardware debug registers (Dr6) not available; debugger single-step unsupported for now
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
#endif
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,15 @@ typedef union _LARGE_INTEGER {
|
|||
inline T& operator^= (T& a, T b) { return reinterpret_cast<T&>( reinterpret_cast<std::underlying_type<T>::type&>(a) ^= static_cast<std::underlying_type<T>::type>(b) ); }
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM64)
|
||||
// _umul128 is an x86-64 intrinsic and is not provided by <intrin.h> on AArch64
|
||||
inline uint64 _umul128(uint64 multiplier, uint64 multiplicand, uint64 *highProduct) {
|
||||
unsigned __int128 x = (unsigned __int128)multiplier * (unsigned __int128)multiplicand;
|
||||
*highProduct = (uint64)(x >> 64);
|
||||
return (uint64)(x & 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline T GetBits(T value, uint32 index, uint32 numBits)
|
||||
{
|
||||
|
|
@ -343,10 +352,10 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor,
|
|||
|
||||
FORCE_INLINE int BSF(uint32 v) // returns index of first bit set, counting from LSB. If v is 0 then result is undefined
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_ctz(v); // clang-cl also defines _MSC_VER, so check this first
|
||||
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
|
||||
return _tzcnt_u32(v); // TZCNT requires BMI1. But if not supported it will execute as BSF
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_ctz(v);
|
||||
#else
|
||||
return std::countr_zero(v);
|
||||
#endif
|
||||
|
|
@ -610,12 +619,14 @@ inline uint32 GetTitleIdLow(uint64 titleId)
|
|||
return titleId & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define memcpy_dwords(__dest, __src, __numDwords) memcpy((__dest), (__src), (__numDwords) * sizeof(uint32))
|
||||
#define memcpy_qwords(__dest, __src, __numQwords) memcpy((__dest), (__src), (__numQwords) * sizeof(uint64))
|
||||
#else
|
||||
// __movsd/__movsq are x86-only MSVC intrinsics; use memcpy everywhere else
|
||||
// (clang-cl does not define __GNUC__, and AArch64 has no such intrinsics)
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && defined(ARCH_X86_64)
|
||||
#define memcpy_dwords(__dest, __src, __numDwords) __movsd((unsigned long*)(__dest), (const unsigned long*)(__src), __numDwords)
|
||||
#define memcpy_qwords(__dest, __src, __numQwords) __movsq((unsigned long long*)(__dest), (const unsigned long long*)(__src), __numQwords)
|
||||
#else
|
||||
#define memcpy_dwords(__dest, __src, __numDwords) memcpy((__dest), (__src), (__numDwords) * sizeof(uint32))
|
||||
#define memcpy_qwords(__dest, __src, __numQwords) memcpy((__dest), (__src), (__numQwords) * sizeof(uint64))
|
||||
#endif
|
||||
|
||||
// PPC context and memory functions
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user