This commit is contained in:
qurious-pixel 2026-07-06 09:18:06 +02:00 committed by GitHub
commit 5f52082a90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 514 additions and 402 deletions

View File

@ -128,7 +128,16 @@ jobs:
path: artifacts
build-windows:
runs-on: windows-2022
strategy:
fail-fast: false
matrix:
include:
- os: windows-2022
arch: x64
- os: windows-11-arm
arch: arm64
name: build-windows-${{ matrix.arch }}
runs-on: ${{ matrix.os }}
steps:
- name: "Checkout repo"
uses: actions/checkout@v6
@ -190,19 +199,19 @@ jobs:
shell: cmd
run: |
cd src\resource
makensis /DPRODUCT_VERSION=${{ inputs.next_version_major }}.${{ inputs.next_version_minor }} installer.nsi
makensis /DPRODUCT_VERSION=${{ inputs.next_version_major }}.${{ inputs.next_version_minor }} /DARCH=${{ matrix.arch }} installer.nsi
- name: Upload artifact
uses: actions/upload-artifact@v6
with:
name: cemu-bin-windows-x64
name: cemu-bin-windows-${{ matrix.arch }}
path: ./bin/Cemu.exe
- name: Upload NSIS Installer
uses: actions/upload-artifact@v6
with:
name: cemu-installer-windows-x64
path: ./src/resource/cemu-${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}-windows-x64-installer.exe
name: cemu-installer-windows-${{ matrix.arch }}
path: ./src/resource/cemu-${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}-windows-${{ matrix.arch }}-installer.exe
build-macos:
runs-on: macos-14

View File

@ -51,8 +51,16 @@ if (ENABLE_VCPKG)
# CONFIG option
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
if (WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
endif()
message(STATUS "CPU Arch is: $ENV{PROCESSOR_ARCHITECTURE}")
if($ENV{PROCESSOR_ARCHITECTURE} MATCHES "x86_64|amd64|AMD64")
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "" FORCE)
set(VCPKG_HOST_TRIPLET "x64-windows-static" CACHE STRING "" FORCE)
else()
set(VCPKG_TARGET_TRIPLET "arm64-windows-static" CACHE STRING "" FORCE)
set(VCPKG_HOST_TRIPLET "arm64-windows-static" CACHE STRING "" FORCE)
endif()
message(STATUS "Using VCPKG triplet: ${VCPKG_TARGET_TRIPLET}")
endif()
endif()
project(Cemu VERSION 2.0.0)
@ -79,6 +87,7 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
if (MSVC)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)
# floating point model: precise, fiber safe optimizations
add_compile_definitions(NOMINMAX)
add_compile_options(/EHsc /fp:precise)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Speeds up static linking (especially helpful in incremental compilation)
@ -173,6 +182,19 @@ if (NOT TARGET glslang::SPIRV AND TARGET SPIRV)
add_library(glslang::SPIRV ALIAS SPIRV)
endif()
if (UNIX AND NOT APPLE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(ARCH_TRIPLET "aarch64-linux-gnu")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
set(ARCH_TRIPLET "x86_64-linux-gnu")
else()
message(WARNING "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
if(ARCH_TRIPLET)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/share/pkgconfig:/usr/lib/${ARCH_TRIPLET}/pkgconfig:/usr/local/share/pkgconfig")
endif()
endif()
if (UNIX AND NOT APPLE)
find_package(X11 REQUIRED)
if (ENABLE_WAYLAND)
@ -253,6 +275,9 @@ if (ENABLE_CUBEB)
endif()
add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL)
if(MSVC)
target_compile_options(ih264d PRIVATE /wd4005)
endif()
if (CMAKE_OSX_ARCHITECTURES)
set(CEMU_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
@ -261,6 +286,9 @@ else()
endif()
if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL)
if(MSVC)
target_compile_options(xbyak_aarch64 PRIVATE "/wd4245" "/wd4458")
endif()
endif()
find_package(ZArchive QUIET)

View File

@ -1,4 +1,4 @@
{
{
"configurations": [
{
"name": "RelWithDebInfo",
@ -25,4 +25,4 @@
"installRoot": "${projectDir}\\out\\install\\${name}"
}
]
}
}

View File

@ -1,204 +1,148 @@
cmake_minimum_required (VERSION 3.8)
cmake_minimum_required(VERSION 3.10)
project ("ih264d")
project(ih264d LANGUAGES C)
add_library (ih264d
"common/ih264_buf_mgr.c"
"common/ih264_buf_mgr.h"
"common/ih264_cabac_tables.c"
"common/ih264_cabac_tables.h"
"common/ih264_cavlc_tables.c"
"common/ih264_cavlc_tables.h"
"common/ih264_chroma_intra_pred_filters.c"
"common/ih264_common_tables.c"
"common/ih264_common_tables.h"
"common/ih264_deblk_edge_filters.c"
"common/ih264_deblk_edge_filters.h"
"common/ih264_deblk_tables.c"
"common/ih264_deblk_tables.h"
"common/ih264_debug.h"
"common/ih264_defs.h"
"common/ih264_disp_mgr.c"
"common/ih264_disp_mgr.h"
"common/ih264_dpb_mgr.c"
"common/ih264_dpb_mgr.h"
"common/ih264_error.h"
"common/ih264_ihadamard_scaling.c"
"common/ih264_inter_pred_filters.c"
"common/ih264_inter_pred_filters.h"
"common/ih264_intra_pred_filters.h"
"common/ih264_iquant_itrans_recon.c"
"common/ih264_list.c"
"common/ih264_list.h"
"common/ih264_luma_intra_pred_filters.c"
"common/ih264_macros.h"
"common/ih264_mem_fns.c"
"common/ih264_mem_fns.h"
"common/ih264_padding.c"
"common/ih264_padding.h"
"common/ih264_resi_trans.h"
"common/ih264_resi_trans_quant.c"
"common/ih264_size_defs.h"
"common/ih264_structs.h"
"common/ih264_trans_data.c"
"common/ih264_trans_data.h"
"common/ih264_trans_macros.h"
"common/ih264_trans_quant_itrans_iquant.h"
"common/ih264_typedefs.h"
"common/ih264_weighted_pred.c"
"common/ih264_weighted_pred.h"
"common/ithread.c"
"common/ithread.h"
"decoder/ih264d.h"
"decoder/ih264d_api.c"
"decoder/ih264d_bitstrm.c"
"decoder/ih264d_bitstrm.h"
"decoder/ih264d_cabac.c"
"decoder/ih264d_cabac.h"
"decoder/ih264d_cabac_init_tables.c"
"decoder/ih264d_compute_bs.c"
"decoder/ih264d_deblocking.c"
"decoder/ih264d_deblocking.h"
"decoder/ih264d_debug.h"
"decoder/ih264d_defs.h"
"decoder/ih264d_dpb_manager.h"
"decoder/ih264d_dpb_mgr.c"
"decoder/ih264d_error_handler.h"
"decoder/ih264d_format_conv.c"
"decoder/ih264d_format_conv.h"
"decoder/ih264d_function_selector.h"
"decoder/ih264d_function_selector_generic.c"
"decoder/ih264d_inter_pred.c"
"decoder/ih264d_inter_pred.h"
"decoder/ih264d_mb_utils.c"
"decoder/ih264d_mb_utils.h"
"decoder/ih264d_mem_request.h"
"decoder/ih264d_mvpred.c"
"decoder/ih264d_mvpred.h"
"decoder/ih264d_nal.c"
"decoder/ih264d_nal.h"
"decoder/ih264d_parse_bslice.c"
"decoder/ih264d_parse_cabac.c"
"decoder/ih264d_parse_cabac.h"
"decoder/ih264d_parse_cavlc.c"
"decoder/ih264d_parse_cavlc.h"
"decoder/ih264d_parse_headers.c"
"decoder/ih264d_parse_headers.h"
"decoder/ih264d_parse_islice.c"
"decoder/ih264d_parse_islice.h"
"decoder/ih264d_parse_mb_header.c"
"decoder/ih264d_parse_mb_header.h"
"decoder/ih264d_parse_pslice.c"
"decoder/ih264d_parse_slice.c"
"decoder/ih264d_parse_slice.h"
"decoder/ih264d_process_bslice.c"
"decoder/ih264d_process_bslice.h"
"decoder/ih264d_process_intra_mb.c"
"decoder/ih264d_process_intra_mb.h"
"decoder/ih264d_process_pslice.c"
"decoder/ih264d_process_pslice.h"
"decoder/ih264d_quant_scaling.c"
"decoder/ih264d_quant_scaling.h"
"decoder/ih264d_sei.c"
"decoder/ih264d_sei.h"
"decoder/ih264d_structs.h"
"decoder/ih264d_tables.c"
"decoder/ih264d_tables.h"
"decoder/ih264d_thread_compute_bs.c"
"decoder/ih264d_thread_compute_bs.h"
"decoder/ih264d_thread_parse_decode.c"
"decoder/ih264d_thread_parse_decode.h"
"decoder/ih264d_transfer_address.h"
"decoder/ih264d_utils.c"
"decoder/ih264d_utils.h"
"decoder/ih264d_vui.c"
"decoder/ih264d_vui.h"
"decoder/iv.h"
"decoder/ivd.h"
add_library(ih264d STATIC
"common/ih264_buf_mgr.c"
"common/ih264_cabac_tables.c"
"common/ih264_cavlc_tables.c"
"common/ih264_chroma_intra_pred_filters.c"
"common/ih264_common_tables.c"
"common/ih264_deblk_edge_filters.c"
"common/ih264_deblk_tables.c"
"common/ih264_disp_mgr.c"
"common/ih264_dpb_mgr.c"
"common/ih264_ihadamard_scaling.c"
"common/ih264_inter_pred_filters.c"
"common/ih264_iquant_itrans_recon.c"
"common/ih264_list.c"
"common/ih264_luma_intra_pred_filters.c"
"common/ih264_mem_fns.c"
"common/ih264_padding.c"
"common/ih264_resi_trans_quant.c"
"common/ih264_trans_data.c"
"common/ih264_weighted_pred.c"
"common/ithread.c"
"decoder/ih264d_api.c"
"decoder/ih264d_bitstrm.c"
"decoder/ih264d_cabac.c"
"decoder/ih264d_cabac_init_tables.c"
"decoder/ih264d_compute_bs.c"
"decoder/ih264d_deblocking.c"
"decoder/ih264d_dpb_mgr.c"
"decoder/ih264d_format_conv.c"
"decoder/ih264d_function_selector_generic.c"
"decoder/ih264d_inter_pred.c"
"decoder/ih264d_mb_utils.c"
"decoder/ih264d_mvpred.c"
"decoder/ih264d_nal.c"
"decoder/ih264d_parse_bslice.c"
"decoder/ih264d_parse_cabac.c"
"decoder/ih264d_parse_cavlc.c"
"decoder/ih264d_parse_headers.c"
"decoder/ih264d_parse_islice.c"
"decoder/ih264d_parse_mb_header.c"
"decoder/ih264d_parse_pslice.c"
"decoder/ih264d_parse_slice.c"
"decoder/ih264d_process_bslice.c"
"decoder/ih264d_process_intra_mb.c"
"decoder/ih264d_process_pslice.c"
"decoder/ih264d_quant_scaling.c"
"decoder/ih264d_sei.c"
"decoder/ih264d_tables.c"
"decoder/ih264d_thread_compute_bs.c"
"decoder/ih264d_thread_parse_decode.c"
"decoder/ih264d_utils.c"
"decoder/ih264d_vui.c"
)
if (CMAKE_OSX_ARCHITECTURES)
set(IH264D_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
if(CMAKE_OSX_ARCHITECTURES)
set(IH264D_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
else()
set(IH264D_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set(IH264D_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
endif()
if (IH264D_ARCHITECTURE STREQUAL "x86_64" OR IH264D_ARCHITECTURE STREQUAL "amd64" OR IH264D_ARCHITECTURE STREQUAL "AMD64")
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
target_sources(ih264d PRIVATE
"common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
"common/x86/ih264_deblk_chroma_ssse3.c"
"common/x86/ih264_deblk_luma_ssse3.c"
"common/x86/ih264_ihadamard_scaling_sse42.c"
"common/x86/ih264_ihadamard_scaling_ssse3.c"
"common/x86/ih264_inter_pred_filters_ssse3.c"
"common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
"common/x86/ih264_iquant_itrans_recon_sse42.c"
"common/x86/ih264_iquant_itrans_recon_ssse3.c"
"common/x86/ih264_luma_intra_pred_filters_ssse3.c"
"common/x86/ih264_mem_fns_ssse3.c"
"common/x86/ih264_padding_ssse3.c"
"common/x86/ih264_platform_macros.h"
"common/x86/ih264_resi_trans_quant_sse42.c"
"common/x86/ih264_weighted_pred_sse42.c"
"decoder/x86/ih264d_function_selector.c"
"decoder/x86/ih264d_function_selector_sse42.c"
"decoder/x86/ih264d_function_selector_ssse3.c"
)
elseif(IH264D_ARCHITECTURE STREQUAL "aarch64" OR IH264D_ARCHITECTURE STREQUAL "arm64")
enable_language( C CXX ASM )
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
target_sources(ih264d PRIVATE
"common/armv8/ih264_deblk_chroma_av8.s"
"common/armv8/ih264_deblk_luma_av8.s"
"common/armv8/ih264_default_weighted_pred_av8.s"
"common/armv8/ih264_ihadamard_scaling_av8.s"
"common/armv8/ih264_inter_pred_chroma_av8.s"
"common/armv8/ih264_inter_pred_filters_luma_horz_av8.s"
"common/armv8/ih264_inter_pred_filters_luma_vert_av8.s"
"common/armv8/ih264_inter_pred_luma_copy_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_hpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_hpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_vert_qpel_av8.s"
"common/armv8/ih264_intra_pred_chroma_av8.s"
"common/armv8/ih264_intra_pred_luma_16x16_av8.s"
"common/armv8/ih264_intra_pred_luma_4x4_av8.s"
"common/armv8/ih264_intra_pred_luma_8x8_av8.s"
"common/armv8/ih264_iquant_itrans_recon_av8.s"
"common/armv8/ih264_iquant_itrans_recon_dc_av8.s"
"common/armv8/ih264_mem_fns_neon_av8.s"
"common/armv8/ih264_neon_macros.s"
"common/armv8/ih264_padding_neon_av8.s"
"common/armv8/ih264_platform_macros.h"
"common/armv8/ih264_resi_trans_quant_av8.s"
"common/armv8/ih264_weighted_bi_pred_av8.s"
"common/armv8/ih264_weighted_pred_av8.s"
"decoder/arm/ih264d_function_selector_a9q.c"
"decoder/arm/ih264d_function_selector_av8.c"
"decoder/arm/ih264d_function_selector.c"
)
target_compile_options(ih264d PRIVATE -DARMV8 $<$<COMPILE_LANGUAGE:ASM,Clang>:-Wno-unused-command-line-argument>)
if(NOT MSVC)
set(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
endif()
if(APPLE)
target_sources(ih264d PRIVATE "common/armv8/macos_arm_symbol_aliases.s")
endif()
message(STATUS "DEBUG: ih264d detected architecture is: ${IH264D_ARCHITECTURE}")
if(IH264D_ARCHITECTURE MATCHES "x86_64|amd64|AMD64|i386|i686")
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
target_sources(ih264d PRIVATE
"common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
"common/x86/ih264_deblk_chroma_ssse3.c"
"common/x86/ih264_deblk_luma_ssse3.c"
"common/x86/ih264_ihadamard_scaling_sse42.c"
"common/x86/ih264_ihadamard_scaling_ssse3.c"
"common/x86/ih264_inter_pred_filters_ssse3.c"
"common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
"common/x86/ih264_iquant_itrans_recon_sse42.c"
"common/x86/ih264_iquant_itrans_recon_ssse3.c"
"common/x86/ih264_luma_intra_pred_filters_ssse3.c"
"common/x86/ih264_mem_fns_ssse3.c"
"common/x86/ih264_padding_ssse3.c"
"common/x86/ih264_resi_trans_quant_sse42.c"
"common/x86/ih264_weighted_pred_sse42.c"
"decoder/x86/ih264d_function_selector.c"
"decoder/x86/ih264d_function_selector_sse42.c"
"decoder/x86/ih264d_function_selector_ssse3.c"
)
elseif(IH264D_ARCHITECTURE MATCHES "aarch64|arm64|ARM64")
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
if(MSVC)
message(STATUS "MSVC ARM64 detected: Forcing portable C implementation.")
target_sources(ih264d PRIVATE
"decoder/arm/ih264d_function_selector.c"
"decoder/arm/ih264d_function_selector_av8.c"
)
target_compile_definitions(ih264d PRIVATE PORTABLE_C ARCH_GENERIC DISABLE_NEON)
else()
enable_language(ASM)
message(STATUS "ARM64 Clang/GCC detected: Enabling assembly optimization.")
target_sources(ih264d PRIVATE
"common/armv8/ih264_deblk_chroma_av8.s"
"common/armv8/ih264_deblk_luma_av8.s"
"common/armv8/ih264_default_weighted_pred_av8.s"
"common/armv8/ih264_ihadamard_scaling_av8.s"
"common/armv8/ih264_inter_pred_chroma_av8.s"
"common/armv8/ih264_inter_pred_filters_luma_horz_av8.s"
"common/armv8/ih264_inter_pred_filters_luma_vert_av8.s"
"common/armv8/ih264_inter_pred_luma_copy_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_hpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_hpel_av8.s"
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_qpel_av8.s"
"common/armv8/ih264_inter_pred_luma_vert_qpel_av8.s"
"common/armv8/ih264_intra_pred_chroma_av8.s"
"common/armv8/ih264_intra_pred_luma_16x16_av8.s"
"common/armv8/ih264_intra_pred_luma_4x4_av8.s"
"common/armv8/ih264_intra_pred_luma_8x8_av8.s"
"common/armv8/ih264_iquant_itrans_recon_av8.s"
"common/armv8/ih264_iquant_itrans_recon_dc_av8.s"
"common/armv8/ih264_mem_fns_neon_av8.s"
"common/armv8/ih264_padding_neon_av8.s"
"common/armv8/ih264_resi_trans_quant_av8.s"
"common/armv8/ih264_weighted_bi_pred_av8.s"
"common/armv8/ih264_weighted_pred_av8.s"
"decoder/arm/ih264d_function_selector_av8.c"
"decoder/arm/ih264d_function_selector.c"
)
target_compile_definitions(ih264d PRIVATE ARMV8)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -x assembler-with-cpp")
endif()
if(APPLE)
target_sources(ih264d PRIVATE "common/armv8/macos_arm_symbol_aliases.s")
endif()
else()
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
endif()
if(MSVC)
set_property(TARGET ih264d PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# tune settings for slightly better performance
target_compile_options(ih264d PRIVATE $<$<CONFIG:Release,RelWithDebInfo>:/Oi>) # enable intrinsic functions
target_compile_options(ih264d PRIVATE $<$<CONFIG:Release,RelWithDebInfo>:/Ot>) # favor speed
target_compile_options(ih264d PRIVATE "/GS-") # disable runtime checks
set_property(TARGET ih264d PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_compile_options(ih264d PRIVATE $<$<CONFIG:Release,RelWithDebInfo>:/Oi> $<$<CONFIG:Release,RelWithDebInfo>:/Ot> "/GS-")
endif()

View File

@ -21,6 +21,17 @@
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ]
},
{
"name": "arm64-Release",
"generator": "Ninja",
"configurationType": "Release",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_arm64_x64" ]
}
]
}
}

View File

@ -38,144 +38,95 @@
#include <stdint.h>
#ifndef ARMV8
static __inline WORD32 CLIP_U8(WORD32 x)
{
asm("usat %0, #8, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_S8(WORD32 x)
{
asm("ssat %0, #8, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_U10(WORD32 x)
{
asm("usat %0, #10, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_S10(WORD32 x)
{
asm("ssat %0, #10, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_U11(WORD32 x)
{
asm("usat %0, #11, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_S11(WORD32 x)
{
asm("ssat %0, #11, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_U12(WORD32 x)
{
asm("usat %0, #12, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_S12(WORD32 x)
{
asm("ssat %0, #12, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_U16(WORD32 x)
{
asm("usat %0, #16, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline WORD32 CLIP_S16(WORD32 x)
{
asm("ssat %0, #16, %1" : "=r"(x) : "r"(x));
return x;
}
static __inline UWORD32 ITT_BIG_ENDIAN(UWORD32 x)
{
asm("rev %0, %1" : "=r"(x) : "r"(x));
return x;
}
#define NOP(nop_cnt) {UWORD32 nop_i; for (nop_i = 0; nop_i < nop_cnt; nop_i++) asm("nop");}
#else
#define CLIP_U8(x) CLIP3(0, UINT8_MAX, (x))
#define CLIP_S8(x) CLIP3(INT8_MIN, INT8_MAX, (x))
#define CLIP_U10(x) CLIP3(0, 1023, (x))
#define CLIP_S10(x) CLIP3(-512, 511, (x))
#define CLIP_U11(x) CLIP3(0, 2047, (x))
#define CLIP_S11(x) CLIP3(-1024, 1023, (x))
#define CLIP_U12(x) CLIP3(0, 4095, (x))
#define CLIP_S12(x) CLIP3(-2048, 2047, (x))
#define CLIP_U16(x) CLIP3(0, UINT16_MAX, (x))
#define CLIP_S16(x) CLIP3(INT16_MIN, INT16_MAX, (x))
#define ITT_BIG_ENDIAN(x) __asm__("rev %0, %1" : "=r"(x) : "r"(x));
#define NOP(nop_cnt) \
{ \
UWORD32 nop_i; \
for (nop_i = 0; nop_i < nop_cnt; nop_i++) \
__asm__ __volatile__("mov x0, x0"); \
}
#ifndef WORD32
typedef int32_t WORD32;
#endif
#ifndef UWORD32
typedef uint32_t UWORD32;
#endif
/*saturating instructions are not available for WORD64 in ARMv7, hence we cannot
* use inline assembly like other clips*/
#define CLIP_U32(x) CLIP3(0, UINT32_MAX, (x))
#define CLIP_S32(x) CLIP3(INT32_MIN, INT32_MAX, (x))
#include <arm_neon.h>
#define DATA_SYNC() __sync_synchronize()
#ifdef _MSC_VER
#include <intrin.h>
#if defined(_M_ARM64) && !defined(__arm64_intrinsics_h__)
#ifndef _ARM64_BARRIER_ISH
#define _ARM64_BARRIER_ISH 0xB
#endif
#endif
#define SHL(x,y) (((y) < 32) ? ((x) << (y)) : 0)
#define SHR(x,y) (((y) < 32) ? ((x) >> (y)) : 0)
#define INLINE __inline
#define MEM_ALIGN8 __declspec(align(8))
#define MEM_ALIGN16 __declspec(align(16))
#define MEM_ALIGN32 __declspec(align(32))
#define DATA_SYNC() __dmb(_ARM64_BARRIER_ISH)
#define NOP(nop_cnt) { for (int i = 0; i < (int)nop_cnt; i++) __nop(); }
#define ITT_BIG_ENDIAN(x) _byteswap_ulong(x)
#else
#define INLINE inline
#define MEM_ALIGN8 __attribute__ ((aligned (8)))
#define MEM_ALIGN16 __attribute__ ((aligned (16)))
#define MEM_ALIGN32 __attribute__ ((aligned (32)))
#define DATA_SYNC() __sync_synchronize()
#define NOP(nop_cnt) \
{ \
uint32_t nop_i; \
for (nop_i = 0; nop_i < nop_cnt; nop_i++) \
__asm__ __volatile__("mov x0, x0"); \
}
static INLINE uint32_t ITT_BIG_ENDIAN(uint32_t x) {
return __builtin_bswap32(x);
}
#endif
#ifndef CLIP3
#define CLIP3(min_val, max_val, x) (((x) < (min_val)) ? (min_val) : (((x) > (max_val)) ? (max_val) : (x)))
#endif
#define CLIP_U8(x) CLIP3(0, 255, (x))
#define CLIP_S8(x) CLIP3(-128, 127, (x))
#define CLIP_U10(x) CLIP3(0, 1023, (x))
#define CLIP_S10(x) CLIP3(-512, 511, (x))
#define CLIP_U11(x) CLIP3(0, 2047, (x))
#define CLIP_S11(x) CLIP3(-1024, 1023, (x))
#define CLIP_U12(x) CLIP3(0, 4095, (x))
#define CLIP_S12(x) CLIP3(-2048, 2047, (x))
#define CLIP_U16(x) CLIP3(0, 65535, (x))
#define CLIP_S16(x) CLIP3(-32768, 32767, (x))
#define CLIP_U32(x) CLIP3(0, 0xFFFFFFFF, (x))
#define CLIP_S32(x) CLIP3(-2147483647-1, 2147483647, (x))
static INLINE uint32_t CLZ(uint32_t u4_word) {
if (u4_word == 0) return 31;
#ifdef _MSC_VER
return (uint32_t)_CountLeadingZeros(u4_word);
#else
return (uint32_t)__builtin_clz(u4_word);
#endif
}
static INLINE uint32_t CTZ(uint32_t u4_word) {
if (u4_word == 0) return 31;
#ifdef _MSC_VER
unsigned long index;
_BitScanForward(&index, u4_word);
return (uint32_t)index;
#else
return (uint32_t)__builtin_ctz(u4_word);
#endif
}
#define SHL(x,y) (((y) < 32) ? ((uint32_t)(x) << (y)) : 0)
#define SHR(x,y) (((y) < 32) ? ((uint32_t)(x) >> (y)) : 0)
#define SHR_NEG(val,shift) ((shift>0)?(val>>shift):(val<<(-shift)))
#define SHL_NEG(val,shift) ((shift<0)?(val>>(-shift)):(val<<shift))
#define INLINE inline
/* In normal cases, 0 will not be passed as an argument to CLZ and CTZ.
As CLZ and CTZ outputs are used as a shift value in few places, these return
31 for u4_word == 0 case, just to handle error cases gracefully without any
undefined behaviour */
static INLINE UWORD32 CLZ(UWORD32 u4_word)
{
if(u4_word)
return (__builtin_clz(u4_word));
else
return 31;
}
static INLINE UWORD32 CTZ(UWORD32 u4_word)
{
if(0 == u4_word)
return 31;
else
{
unsigned int index;
index = __builtin_ctz(u4_word);
return (UWORD32)index;
}
}
#define MEM_ALIGN8 __attribute__ ((aligned (8)))
#define MEM_ALIGN16 __attribute__ ((aligned (16)))
#define MEM_ALIGN32 __attribute__ ((aligned (32)))
#endif /* _IH264_PLATFORM_MACROS_H_ */

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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>
@ -13,4 +13,4 @@
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
</windowsSettings>
</application>
</assembly>
</assembly>

View File

@ -70,10 +70,16 @@ add_executable(CemuBin
cemu_use_precompiled_header(CemuBin)
if(MSVC AND MSVC_VERSION EQUAL 1940)
if(MSVC)
set(CEMU_LINKER_FLAGS "/NODEFAULTLIB:MSVCRT")
if(MSVC_VERSION EQUAL 1940)
# workaround for an msvc issue on VS 17.10 where generated ILK files are too large
# see https://developercommunity.visualstudio.com/t/After-updating-to-VS-1710-the-size-of-/10665511
set_target_properties(CemuBin PROPERTIES LINK_FLAGS "/INCREMENTAL:NO")
string(APPEND CEMU_LINKER_FLAGS " /INCREMENTAL:NO")
endif()
set_target_properties(CemuBin PROPERTIES LINK_FLAGS "${CEMU_LINKER_FLAGS}")
endif()
if(WIN32)

View File

@ -83,13 +83,6 @@ add_library(CemuCafe
HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp
HW/Espresso/Recompiler/PPCRecompilerIml.h
HW/Espresso/Recompiler/PPCRecompilerIntermediate.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64AVX.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64BMI.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64FPU.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64Gen.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64GenFPU.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64.h
HW/Espresso/Recompiler/BackendX64/X64Emit.hpp
HW/Espresso/Recompiler/BackendX64/x86Emitter.h
HW/Latte/Common/RegisterSerializer.cpp
@ -618,12 +611,23 @@ if(ENABLE_METAL)
)
endif()
if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h
)
target_link_libraries(CemuCafe PRIVATE xbyak_aarch64)
if(CEMU_ARCHITECTURE MATCHES "(x86_64|amd64|AMD64)")
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendX64/BackendX64.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64.h
HW/Espresso/Recompiler/BackendX64/BackendX64AVX.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64BMI.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64FPU.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64Gen.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64GenFPU.cpp
)
else()
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h
)
target_link_libraries(CemuCafe PRIVATE xbyak_aarch64)
target_compile_definitions(ih264d PRIVATE ARCH_GENERIC DISABLE_NEON)
endif()
set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
@ -646,7 +650,7 @@ else()
endif()
target_link_libraries(CemuCafe PRIVATE
CemuCommon
CemuCommon
CemuGui
ZArchive::zarchive
imguiImpl
@ -668,7 +672,7 @@ endif()
if (ENABLE_LIBUSB)
if (ENABLE_VCPKG)
if(WIN32)
set(PKG_CONFIG_EXECUTABLE "${VCPKG_INSTALLED_DIR}/x64-windows/tools/pkgconf/pkgconf.exe")
set(PKG_CONFIG_EXECUTABLE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/pkgconf/pkgconf.exe")
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0)

View File

@ -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(_M_X64)
s_debuggerState.activeMemoryBreakpoint = bp;
for (auto& hThreadNH : schedulerThreadHandles)
{
@ -235,9 +235,51 @@ void debugger_updateMemoryBreakpoint(DebuggerBreakpoint* bp)
SetThreadContext(hThread, &ctx);
ResumeThread(hThread);
}
#else
#elif defined(_M_X64)
s_debuggerState.activeMemoryBreakpoint = bp;
for (auto& hThreadNH : schedulerThreadHandles)
{
HANDLE hThread = (HANDLE)hThreadNH;
CONTEXT ctx{};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
SuspendThread(hThread);
if (GetThreadContext(hThread, &ctx))
{
if (s_debuggerState.activeMemoryBreakpoint)
{
// ARM64 uses Bvr/Bcr pairs. We'll use slot 0.
ctx.Bvr[0] = (DWORD64)memory_getPointerFromVirtualOffset(bp->address);
// Construct the Control Register (BCR)
DWORD64 bcr = 0;
bcr |= 0x1; // Bit 0: Global Enable
bcr |= (0x3 << 1); // Bits 1-2: User and Privileged access
bcr |= (0xF << 5); // Bits 5-8: Byte address select (watch all 4 bytes)
// Map Cemu BP types to ARM64 Watchpoint types
if (bp->bpType == DEBUGGER_BP_T_MEMORY_READ)
bcr |= (0x1 << 21); // Bit 21-22: 1 = Load
else if (bp->bpType == DEBUGGER_BP_T_MEMORY_WRITE)
bcr |= (0x2 << 21); // Bit 21-22: 2 = Store
else
bcr |= (0x3 << 21); // Bit 21-22: 3 = Either
ctx.Bcr[0] = bcr;
}
else
{
// Disable breakpoint slot 0
ctx.Bvr[0] = 0;
ctx.Bcr[0] = 0;
}
SetThreadContext(hThread, &ctx);
}
ResumeThread(hThread);
}
#else
cemuLog_log(LogType::Force, "Debugger breakpoints are not supported");
#endif
#endif
}
void debugger_handleSingleStepException(uint64 dr6)

View File

@ -823,4 +823,4 @@ namespace IMLArchX86
{
static constexpr int PHYSREG_GPR_BASE = 0;
static constexpr int PHYSREG_FPR_BASE = 16;
};
};

View File

@ -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(_M_X64)
if (g_CPUFeatures.x86.avx2)
{
__m256i h256 = { 0 };
@ -430,4 +430,4 @@ void LatteTC_UnloadAllTextures()
LatteTexture_Delete(itr);
}
LatteRenderTarget_unloadAll();
}
}

View File

@ -1,3 +1,4 @@
#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "Cafe/HW/Latte/LatteAddrLib/LatteAddrLib.h"
#include "config/ActiveSettings.h"
@ -707,7 +708,7 @@ void optimizedLinearReadbackWriteLoop(LatteTextureLoaderCtx* textureLoader, uint
copyType* blockData = (copyType*)LatteTextureLoader_getInputLinearOptimized_(textureLoader, 0, y, 1, 1, sizeof(copyType) * 8, 0, 1, 0, textureLoader->pitch, textureLoader->height);
if constexpr (sizeof(copyType) == 4)
{
memcpy_dwords(blockData, rowPixelData, textureLoader->width);
SAFE_MOVSD(blockData, rowPixelData, textureLoader->width);
}
else
{

View File

@ -113,4 +113,41 @@ static void* _ppc_va_arg(ppc_va_list* vargs, ppc_va_type argType)
vargs->overflow_arg_area += 8;
return r;
}
}
}
#ifdef _WIN32
#include <intrin.h>
#else
#include <string.h>
#if defined(__x86_64__) || defined(__i386__)
#include <x86intrin.h>
#endif
#endif
#ifdef _WIN32
static inline void safe_memcpy_dwords(void* dest, const void* src, size_t count) {
#if defined(_M_ARM64) || defined(_M_ARM)
memcpy(dest, src, count * 4);
#else
__movsd((unsigned long*)dest, (const unsigned long*)src, (unsigned long)count);
#endif
}
static inline void safe_memcpy_qwords(void* dest, const void* src, size_t count) {
#if defined(_M_ARM64) || defined(_M_ARM)
memcpy(dest, src, count * 8);
#else
__movsq((unsigned __int64*)dest, (const unsigned __int64*)src, count);
#endif
}
#define SAFE_MOVSD(d, s, c) safe_memcpy_dwords((d), (s), (c))
#define SAFE_MOVSQ(d, s, c) safe_memcpy_qwords((d), (s), (c))
#else
static inline void safe_memcpy_dwords(void* dest, const void* src, size_t count) {
memcpy(dest, src, count * 4);
}
static inline void safe_memcpy_qwords(void* dest, const void* src, size_t count) {
memcpy(dest, src, count * 8);
}
#define SAFE_MOVSD(d, s, c) safe_memcpy_dwords((d), (s), (c))
#define SAFE_MOVSQ(d, s, c) safe_memcpy_qwords((d), (s), (c))
#endif

View File

@ -256,7 +256,7 @@ namespace coreinit
uint8* destPtr = memory_getPointerFromVirtualOffset(hCPU->gpr[3]);
uint8* srcPtr = memory_getPointerFromVirtualOffset(hCPU->gpr[4]);
// copy right away, we don't emulate the DMAQueue currently
memcpy_qwords(destPtr, srcPtr, numBlocks * (32 / sizeof(uint64)));
SAFE_MOVSQ(destPtr, srcPtr, (size_t)numBlocks * 4);
LatteBufferCache_notifyDCFlush(hCPU->gpr[3], numBlocks * 32);

View File

@ -42,7 +42,7 @@ void gx2WriteGather_submitU32AsLEArray(uint32* v, uint32 numValues)
uint32 coreIndex = PPCInterpreter_getCoreIndex(PPCInterpreter_getCurrentInstance());
if (GX2::s_perCoreCBState[coreIndex].currentWritePtr == nullptr)
return;
memcpy_dwords(GX2::s_perCoreCBState[coreIndex].currentWritePtr, v, numValues);
SAFE_MOVSD(GX2::s_perCoreCBState[coreIndex].currentWritePtr, v, numValues);
GX2::s_perCoreCBState[coreIndex].currentWritePtr += numValues;
cemu_assert_debug(GX2::s_perCoreCBState[coreIndex].currentWritePtr <= (GX2::s_perCoreCBState[coreIndex].bufferPtr + GX2::s_perCoreCBState[coreIndex].bufferSizeInU32s));
}

View File

@ -209,6 +209,20 @@ void createCrashlog(EXCEPTION_POINTERS* e, PCONTEXT context)
// register info
sprintf(dumpLine, "\n");
cemuLog_writePlainToLog(dumpLine);
#if defined(_M_ARM64)
// ARM64 Register Dump
sprintf(dumpLine, "X0 =%016I64x X1 =%016I64x X2 =%016I64x X3 =%016I64x\n", context->X0, context->X1, context->X2, context->X3);
cemuLog_writePlainToLog(dumpLine);
sprintf(dumpLine, "X4 =%016I64x X5 =%016I64x X6 =%016I64x X7 =%016I64x\n", context->X4, context->X5, context->X6, context->X7);
cemuLog_writePlainToLog(dumpLine);
sprintf(dumpLine, "X8 =%016I64x X9 =%016I64x X10=%016I64x X11=%016I64x\n", context->X8, context->X9, context->X10, context->X11);
cemuLog_writePlainToLog(dumpLine);
sprintf(dumpLine, "X12=%016I64x X13=%016I64x X14=%016I64x X15=%016I64x\n", context->X12, context->X13, context->X14, context->X15);
cemuLog_writePlainToLog(dumpLine);
sprintf(dumpLine, "SP =%016I64x PC =%016I64x\n", context->Sp, context->Pc);
cemuLog_writePlainToLog(dumpLine);
#else
// x86_64 Register Dump
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 +231,7 @@ 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);
#endif
CrashLog_SetOutputChannels(false, true);
ExceptionHandler_LogGeneralInfo();
@ -264,10 +279,13 @@ LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
if (r != EXCEPTION_CONTINUE_SEARCH)
return r;
#if !defined(_M_ARM64)
// Hardware breakpoints (Dr6) are x86-specific in the Windows CONTEXT struct
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);
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;

View File

@ -179,6 +179,12 @@ inline sint16 _swapEndianS16(sint16 v)
{
return (sint16)(((uint16)v >> 8) | ((uint16)v << 8));
}
#if defined(_M_ARM64)
inline uint64 _umul128(uint64 multiplier, uint64 multiplicand, uint64 *highProduct) {
*highProduct = __umulh(multiplier, multiplicand);
return multiplier * multiplicand;
}
#endif
#else
inline uint64 _swapEndianU64(uint64 v)
{
@ -290,6 +296,18 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor,
*remainder = (uint64)((dividend % divisor) & 0xFFFFFFFFFFFFFFFF);
return (uint64)((dividend / divisor) & 0xFFFFFFFFFFFFFFFF);
}
#elif defined(_M_ARM64)
inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor, uint64 *remainder)
{
uint64 high = highDividend;
uint64 low = lowDividend;
if (high >= divisor) {
high %= divisor;
}
unsigned __int128 dividend = (((unsigned __int128)highDividend) << 64) | lowDividend;
*remainder = (uint64)(dividend % divisor);
return (uint64)(dividend / divisor);
}
#endif
#if defined(_MSC_VER)
@ -341,48 +359,65 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor,
#define FORCE_INLINE inline
#endif
FORCE_INLINE int BSF(uint32 v) // returns index of first bit set, counting from LSB. If v is 0 then result is undefined
FORCE_INLINE int BSF(uint32 v) // returns index of first bit set, counting from LSB. If v is 0 then result is 32
{
#if defined(_MSC_VER)
return _tzcnt_u32(v); // TZCNT requires BMI1. But if not supported it will execute as BSF
#if defined(_M_ARM64) || defined(_M_ARM)
unsigned long index;
if (_BitScanForward(&index, (unsigned long)v))
return (int)index;
return 32;
#else
// This is the x86/x64 specific intrinsic that was causing ARM64 build failures
return (v == 0) ? 32 : (int)_tzcnt_u32(v);
#endif
#elif defined(__GNUC__) || defined(__clang__)
return __builtin_ctz(v);
return v == 0 ? 32 : __builtin_ctz(v);
#else
return std::countr_zero(v);
return (int)std::countr_zero(v);
#endif
}
// On aarch64 we handle some of the x86 intrinsics by implementing them as wrappers
#if defined(__aarch64__)
#if defined(__aarch64__) || defined(_M_ARM64)
inline void _mm_pause()
{
#if defined(_MSC_VER)
__yield();
#else
asm volatile("yield");
#endif
}
inline uint64 __rdtsc()
{
#if defined(_MSC_VER)
return (uint64)_ReadStatusReg(ARM64_CNTVCT_EL0);
#else
uint64 t;
asm volatile("mrs %0, cntvct_el0" : "=r" (t));
return t;
#endif
}
inline void _mm_mfence()
{
asm volatile("" ::: "memory");
std::atomic_thread_fence(std::memory_order_seq_cst);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, unsigned long long b, unsigned long long *result)
{
*result = a + b + (unsigned long long)carry;
if (*result < a)
return 1;
return 0;
#if !defined(_MSC_VER)
unsigned __int128 res = (unsigned __int128)a + b + carry;
*result = (unsigned long long)res;
return (res >> 64) ? 1 : 0;
#else
*result = a + b + carry;
return (*result < a || (*result == a && carry > 0)) ? 1 : 0;
#endif
}
#endif
// asserts

View File

@ -191,6 +191,7 @@ endif()
if(WIN32)
target_link_libraries(CemuWxGui PRIVATE bthprops)
target_compile_options(CemuWxGui PRIVATE /wd4312)
endif()
if(ALLOW_PORTABLE)

View File

@ -13,10 +13,10 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Neutral (Default) (unknown sub-lang: 0x8) resources
// Neutral (Default) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ZZZ)
LANGUAGE LANG_NEUTRAL, 0x8
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/////////////////////////////////////////////////////////////////////////////
//
@ -64,7 +64,6 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
@ -73,16 +72,25 @@ END
#define xstr(s) str(s)
#define str(s) #s
#if defined(_M_ARM64)
#define ARCH_DESC " (ARM64)"
#elif defined(_M_X64) || defined(_M_AMD64)
#define ARCH_DESC " (x64)"
#else
#define ARCH_DESC ""
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
PRODUCTVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
FILEVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
PRODUCTVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x0L
// VOS_NT_WINDOWS32 is used for both x64 and ARM64 NT-based systems
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
@ -90,12 +98,12 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Cemu Wii U emulator"
VALUE "FileDescription", "Cemu Wii U emulator" ARCH_DESC
VALUE "InternalName", "Cemu"
VALUE "LegalCopyright", "Team Cemu"
VALUE "OriginalFilename", "Cemu.exe"
VALUE "ProductName", "Cemu"
VALUE "ProductVersion", xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) "." xstr(EMULATOR_VERSION_PATCH) EMULATOR_VERSION_SUFFIX "\0"
VALUE "ProductVersion", xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) "." xstr(EMULATOR_VERSION_PATCH) EMULATOR_VERSION_SUFFIX "\0"
END
END
BLOCK "VarFileInfo"
@ -104,7 +112,6 @@ BEGIN
END
END
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
@ -112,10 +119,7 @@ END
IDR_FONTAWESOME RCDATA "resource\\fontawesome-webfont.ttf"
#endif // Neutral (Default) (unknown sub-lang: 0x8) resources
/////////////////////////////////////////////////////////////////////////////
#endif // Neutral resources
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -126,4 +130,3 @@ IDR_FONTAWESOME RCDATA "resource\\fontawesome-webfont.t
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -4,10 +4,17 @@
; Usage:
; get the latest nsis: https://nsis.sourceforge.io/Download
; probably also want vscode extension: https://marketplace.visualstudio.com/items?itemName=idleberg.nsis
; makensis.exe /DPRODUCT_VERSION=2.0 /DARCH=arm64 installer.nsi
; makensis.exe /DPRODUCT_VERSION=2.0 /DARCH=x64 installer.nsi
; Require /DPRODUCT_VERSION for makensis.
!ifndef PRODUCT_VERSION
!error "PRODUCT_VERSION must be defined"
!error "PRODUCT_VERSION must be defined (e.g. /DPRODUCT_VERSION=2.0)"
!endif
; Default to x64 if ARCH is not defined
!ifndef ARCH
!define ARCH "x64"
!endif
ManifestDPIAware true
@ -19,9 +26,9 @@ ManifestDPIAware true
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define BINARY_SOURCE_DIR "..\..\bin"
OutFile "cemu-${PRODUCT_VERSION}-windows-${ARCH}-installer.exe"
Name "${PRODUCT_NAME}"
OutFile "cemu-${PRODUCT_VERSION}-windows-x64-installer.exe"
Name "${PRODUCT_NAME} (${ARCH})"
SetCompressor /SOLID lzma
InstallDir "$LOCALAPPDATA\Cemu"
ShowInstDetails show
@ -30,6 +37,7 @@ ShowUnInstDetails show
!include "MUI2.nsh"
; Custom page plugin
!include "nsDialogs.nsh"
!include "x64.nsh"
; MUI Settings
!define MUI_ICON "logo_icon.ico"
@ -81,8 +89,19 @@ Var DesktopShortcut
; MUI end ------
Function .onInit
StrCpy $DesktopShortcut 1
; Block installation if trying to install x64 on ARM without emulation,
; or ensure the user is aware.
${If} "${ARCH}" == "arm64"
${Unless} ${IsNativeARM64}
MessageBox MB_OK|MB_ICONEXCLAMATION "This installer is for ARM64 systems. Your CPU does not appear to support it natively."
${EndUnless}
${Else}
${If} ${IsNativeARM64}
DetailPrint "Running x64 installer on ARM64 system via Prism/Emulation."
${EndIf}
${EndIf}
StrCpy $DesktopShortcut 1
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
@ -97,7 +116,6 @@ Function desktopShortcutPageCreate
${NSD_CreateCheckbox} 0u 0u 100% 12u "Create a desktop shortcut"
Pop $DesktopShortcutCheckbox
${NSD_SetState} $DesktopShortcutCheckbox $DesktopShortcut
nsDialogs::Show
FunctionEnd
@ -106,13 +124,14 @@ Function desktopShortcutPageLeave
FunctionEnd
Section "Base"
; Prevent running the uninstaller of a different arch in the same folder
; without cleaning up first
ExecWait '"$INSTDIR\uninst.exe" /S _?=$INSTDIR'
SectionIn RO
SetOutPath "$INSTDIR"
; The binplaced build output will be included verbatim.
; This will pull files from the directory defined at the top
File /r "${BINARY_SOURCE_DIR}\*"
; Create start menu and desktop shortcuts
@ -136,10 +155,12 @@ Section -Post
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKCU "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0"
; File Associations
WriteRegStr HKCU "Software\Classes\.wud" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\.wux" "" "$(^Name)"
WriteRegStr HKCU "Software\Classes\.wua" "" "$(^Name)"
@ -151,7 +172,7 @@ Section Uninstall
Delete "$DESKTOP\$(^Name).lnk"
Delete "$SMPROGRAMS\$(^Name).lnk"
; Be a bit careful to not delete files a user may have put into the install directory
; Be a bit careful to not delete files a user may have put into the install directory
Delete "$INSTDIR\Cemu.exe"
Delete "$INSTDIR\uninst.exe"
RMDir /r "$INSTDIR\gameProfiles"
@ -162,9 +183,9 @@ Section Uninstall
DeleteRegKey HKCU "Software\Classes\.wux"
DeleteRegKey HKCU "Software\Classes\.wua"
DeleteRegKey HKCU "Software\Classes\$(^Name)"
DeleteRegKey HKCU "Software\Classes\discord-460807638964371468"
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}"

View File

@ -67,7 +67,8 @@
"zip"
]
},
"libusb"
"libusb",
"pkgconf"
],
"overrides": [
{