Compare commits

...

2 commits

Author SHA1 Message Date
Exverge
00ff5549d9
General aarch64 improvements & Apple Silicon support (#1255)
Some checks failed
Generate translation template / generate-pot (push) Failing after 1m1s
Build check / build (push) Has been cancelled
2025-06-18 10:36:05 +02:00
oltolm
c8ffff8f41
Replace basic_string<> of betype with std::vector (#1601) 2025-06-18 10:34:06 +02:00
24 changed files with 430 additions and 49 deletions

View file

@ -177,6 +177,9 @@ jobs:
build-macos: build-macos:
runs-on: macos-14 runs-on: macos-14
strategy:
matrix:
arch: [x86_64, arm64]
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -236,7 +239,7 @@ jobs:
cd build cd build
cmake .. ${{ env.BUILD_FLAGS }} \ cmake .. ${{ env.BUILD_FLAGS }} \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} \
-DCMAKE_OSX_ARCHITECTURES=x86_64 \ -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} \
-DMACOS_BUNDLE=ON \ -DMACOS_BUNDLE=ON \
-G Ninja -G Ninja
@ -259,5 +262,5 @@ jobs:
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: cemu-bin-macos-x64 name: cemu-bin-macos-${{ matrix.arch }}
path: ./bin/Cemu.dmg path: ./bin/Cemu.dmg

View file

@ -222,7 +222,12 @@ endif()
add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL) add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)") if (CMAKE_OSX_ARCHITECTURES)
set(CEMU_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
else()
set(CEMU_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL) add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL)
endif() endif()
@ -231,4 +236,4 @@ if (NOT ZArchive_FOUND)
add_subdirectory("dependencies/ZArchive" EXCLUDE_FROM_ALL) add_subdirectory("dependencies/ZArchive" EXCLUDE_FROM_ALL)
endif() endif()
add_subdirectory(src) add_subdirectory(src)

View file

@ -183,6 +183,9 @@ target_sources(ih264d PRIVATE
"decoder/arm/ih264d_function_selector.c" "decoder/arm/ih264d_function_selector.c"
) )
target_compile_options(ih264d PRIVATE -DARMV8) target_compile_options(ih264d PRIVATE -DARMV8)
if(APPLE)
target_sources(ih264d PRIVATE "common/armv8/macos_arm_symbol_aliases.s")
endif()
else() else()
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}") message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
endif() endif()

View file

@ -429,8 +429,13 @@ ih264_intra_pred_chroma_8x8_mode_plane_av8:
rev64 v7.4h, v2.4h rev64 v7.4h, v2.4h
ld1 {v3.2s}, [x10] ld1 {v3.2s}, [x10]
sub x5, x3, #8 sub x5, x3, #8
#ifdef __APPLE__
adrp x12, _ih264_gai1_intrapred_chroma_plane_coeffs1@GOTPAGE
ldr x12, [x12, _ih264_gai1_intrapred_chroma_plane_coeffs1@GOTPAGEOFF]
#else
adrp x12, :got:ih264_gai1_intrapred_chroma_plane_coeffs1 adrp x12, :got:ih264_gai1_intrapred_chroma_plane_coeffs1
ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_chroma_plane_coeffs1] ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_chroma_plane_coeffs1]
#endif
usubl v10.8h, v5.8b, v1.8b usubl v10.8h, v5.8b, v1.8b
ld1 {v8.8b, v9.8b}, [x12] // Load multiplication factors 1 to 8 into D3 ld1 {v8.8b, v9.8b}, [x12] // Load multiplication factors 1 to 8 into D3
mov v8.d[1], v9.d[0] mov v8.d[1], v9.d[0]
@ -484,10 +489,13 @@ ih264_intra_pred_chroma_8x8_mode_plane_av8:
zip1 v1.8h, v0.8h, v2.8h zip1 v1.8h, v0.8h, v2.8h
zip2 v2.8h, v0.8h, v2.8h zip2 v2.8h, v0.8h, v2.8h
mov v0.16b, v1.16b mov v0.16b, v1.16b
#ifdef __APPLE__
adrp x12, _ih264_gai1_intrapred_chroma_plane_coeffs2@GOTPAGE
ldr x12, [x12, _ih264_gai1_intrapred_chroma_plane_coeffs2@GOTPAGEOFF]
#else
adrp x12, :got:ih264_gai1_intrapred_chroma_plane_coeffs2 adrp x12, :got:ih264_gai1_intrapred_chroma_plane_coeffs2
ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_chroma_plane_coeffs2] ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_chroma_plane_coeffs2]
#endif
ld1 {v8.2s, v9.2s}, [x12] ld1 {v8.2s, v9.2s}, [x12]
mov v8.d[1], v9.d[0] mov v8.d[1], v9.d[0]
mov v10.16b, v8.16b mov v10.16b, v8.16b

View file

@ -431,10 +431,13 @@ ih264_intra_pred_luma_16x16_mode_plane_av8:
mov x10, x1 //top_left mov x10, x1 //top_left
mov x4, #-1 mov x4, #-1
ld1 {v2.2s}, [x1], x8 ld1 {v2.2s}, [x1], x8
#ifdef __APPLE__
adrp x7, _ih264_gai1_intrapred_luma_plane_coeffs@GOTPAGE
ldr x7, [x7, _ih264_gai1_intrapred_luma_plane_coeffs@GOTPAGEOFF]
#else
adrp x7, :got:ih264_gai1_intrapred_luma_plane_coeffs adrp x7, :got:ih264_gai1_intrapred_luma_plane_coeffs
ldr x7, [x7, #:got_lo12:ih264_gai1_intrapred_luma_plane_coeffs] ldr x7, [x7, #:got_lo12:ih264_gai1_intrapred_luma_plane_coeffs]
#endif
ld1 {v0.2s}, [x1] ld1 {v0.2s}, [x1]
rev64 v2.8b, v2.8b rev64 v2.8b, v2.8b
ld1 {v6.2s, v7.2s}, [x7] ld1 {v6.2s, v7.2s}, [x7]

View file

@ -1029,9 +1029,13 @@ ih264_intra_pred_luma_8x8_mode_horz_u_av8:
mov v3.d[0], v2.d[1] mov v3.d[0], v2.d[1]
ext v4.16b, v2.16b , v2.16b , #1 ext v4.16b, v2.16b , v2.16b , #1
mov v5.d[0], v4.d[1] mov v5.d[0], v4.d[1]
#ifdef __APPLE__
adrp x12, _ih264_gai1_intrapred_luma_8x8_horz_u@GOTPAGE
ldr x12, [x12, _ih264_gai1_intrapred_luma_8x8_horz_u@GOTPAGEOFF]
#else
adrp x12, :got:ih264_gai1_intrapred_luma_8x8_horz_u adrp x12, :got:ih264_gai1_intrapred_luma_8x8_horz_u
ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_luma_8x8_horz_u] ldr x12, [x12, #:got_lo12:ih264_gai1_intrapred_luma_8x8_horz_u]
#endif
uaddl v20.8h, v0.8b, v2.8b uaddl v20.8h, v0.8b, v2.8b
uaddl v22.8h, v1.8b, v3.8b uaddl v22.8h, v1.8b, v3.8b
uaddl v24.8h, v2.8b, v4.8b uaddl v24.8h, v2.8b, v4.8b

View file

@ -142,14 +142,22 @@ ih264_weighted_bi_pred_luma_av8:
sxtw x4, w4 sxtw x4, w4
sxtw x5, w5 sxtw x5, w5
stp x19, x20, [sp, #-16]! stp x19, x20, [sp, #-16]!
#ifndef __APPLE__
ldr w8, [sp, #80] //Load wt2 in w8 ldr w8, [sp, #80] //Load wt2 in w8
ldr w9, [sp, #88] //Load ofst1 in w9 ldr w9, [sp, #88] //Load ofst1 in w9
add w6, w6, #1 //w6 = log_WD + 1
neg w10, w6 //w10 = -(log_WD + 1)
dup v0.8h, w10 //Q0 = -(log_WD + 1) (32-bit)
ldr w10, [sp, #96] //Load ofst2 in w10 ldr w10, [sp, #96] //Load ofst2 in w10
ldr w11, [sp, #104] //Load ht in w11 ldr w11, [sp, #104] //Load ht in w11
ldr w12, [sp, #112] //Load wd in w12 ldr w12, [sp, #112] //Load wd in w12
#else
ldr w8, [sp, #80] //Load wt2 in w8
ldr w9, [sp, #84] //Load ofst1 in w9
ldr w10, [sp, #88] //Load ofst2 in w10
ldr w11, [sp, #92] //Load ht in w11
ldr w12, [sp, #96] //Load wd in w12
#endif
add w6, w6, #1 //w6 = log_WD + 1
neg w10, w6 //w10 = -(log_WD + 1)
dup v0.8h, w10 //Q0 = -(log_WD + 1) (32-bit)
add w9, w9, #1 //w9 = ofst1 + 1 add w9, w9, #1 //w9 = ofst1 + 1
add w9, w9, w10 //w9 = ofst1 + ofst2 + 1 add w9, w9, w10 //w9 = ofst1 + ofst2 + 1
mov v2.s[0], w7 mov v2.s[0], w7
@ -424,17 +432,24 @@ ih264_weighted_bi_pred_chroma_av8:
sxtw x5, w5 sxtw x5, w5
stp x19, x20, [sp, #-16]! stp x19, x20, [sp, #-16]!
#ifndef __APPLE__
ldr w8, [sp, #80] //Load wt2 in w8 ldr w8, [sp, #80] //Load wt2 in w8
ldr w9, [sp, #88] //Load ofst1 in w9
ldr w10, [sp, #96] //Load ofst2 in w10
ldr w11, [sp, #104] //Load ht in w11
ldr w12, [sp, #112] //Load wd in w12
#else
ldr w8, [sp, #80] //Load wt2 in w8
ldr w9, [sp, #84] //Load ofst1 in w9
ldr w10, [sp, #88] //Load ofst2 in w10
ldr w11, [sp, #92] //Load ht in w11
ldr w12, [sp, #96] //Load wd in w12
#endif
dup v4.4s, w8 //Q2 = (wt2_u, wt2_v) (32-bit) dup v4.4s, w8 //Q2 = (wt2_u, wt2_v) (32-bit)
dup v2.4s, w7 //Q1 = (wt1_u, wt1_v) (32-bit) dup v2.4s, w7 //Q1 = (wt1_u, wt1_v) (32-bit)
add w6, w6, #1 //w6 = log_WD + 1 add w6, w6, #1 //w6 = log_WD + 1
ldr w9, [sp, #88] //Load ofst1 in w9
ldr w10, [sp, #96] //Load ofst2 in w10
neg w20, w6 //w20 = -(log_WD + 1) neg w20, w6 //w20 = -(log_WD + 1)
dup v0.8h, w20 //Q0 = -(log_WD + 1) (16-bit) dup v0.8h, w20 //Q0 = -(log_WD + 1) (16-bit)
ldr w11, [sp, #104] //Load ht in x11
ldr w12, [sp, #112] //Load wd in x12
dup v20.8h, w9 //0ffset1 dup v20.8h, w9 //0ffset1
dup v21.8h, w10 //0ffset2 dup v21.8h, w10 //0ffset2
srhadd v6.8b, v20.8b, v21.8b srhadd v6.8b, v20.8b, v21.8b

View file

@ -0,0 +1,185 @@
// macOS clang compilers append preceding underscores to function names, this is to prevent
// mismatches with the assembly function names and the C functions as defined in the header.
.global _ih264_deblk_chroma_horz_bs4_av8
_ih264_deblk_chroma_horz_bs4_av8 = ih264_deblk_chroma_horz_bs4_av8
.global _ih264_deblk_chroma_horz_bslt4_av8
_ih264_deblk_chroma_horz_bslt4_av8 = ih264_deblk_chroma_horz_bslt4_av8
.global _ih264_deblk_chroma_vert_bs4_av8
_ih264_deblk_chroma_vert_bs4_av8 = ih264_deblk_chroma_vert_bs4_av8
.global _ih264_deblk_chroma_vert_bslt4_av8
_ih264_deblk_chroma_vert_bslt4_av8 = ih264_deblk_chroma_vert_bslt4_av8
.global _ih264_deblk_luma_horz_bs4_av8
_ih264_deblk_luma_horz_bs4_av8 = ih264_deblk_luma_horz_bs4_av8
.global _ih264_deblk_luma_horz_bslt4_av8
_ih264_deblk_luma_horz_bslt4_av8 = ih264_deblk_luma_horz_bslt4_av8
.global _ih264_deblk_luma_vert_bs4_av8
_ih264_deblk_luma_vert_bs4_av8 = ih264_deblk_luma_vert_bs4_av8
.global _ih264_deblk_luma_vert_bslt4_av8
_ih264_deblk_luma_vert_bslt4_av8 = ih264_deblk_luma_vert_bslt4_av8
.global _ih264_default_weighted_pred_chroma_av8
_ih264_default_weighted_pred_chroma_av8 = ih264_default_weighted_pred_chroma_av8
.global _ih264_default_weighted_pred_luma_av8
_ih264_default_weighted_pred_luma_av8 = ih264_default_weighted_pred_luma_av8
.global _ih264_ihadamard_scaling_4x4_av8
_ih264_ihadamard_scaling_4x4_av8 = ih264_ihadamard_scaling_4x4_av8
.global _ih264_inter_pred_chroma_av8
_ih264_inter_pred_chroma_av8 = ih264_inter_pred_chroma_av8
.global _ih264_inter_pred_luma_copy_av8
_ih264_inter_pred_luma_copy_av8 = ih264_inter_pred_luma_copy_av8
.global _ih264_inter_pred_luma_horz_av8
_ih264_inter_pred_luma_horz_av8 = ih264_inter_pred_luma_horz_av8
.global _ih264_inter_pred_luma_horz_hpel_vert_hpel_av8
_ih264_inter_pred_luma_horz_hpel_vert_hpel_av8 = ih264_inter_pred_luma_horz_hpel_vert_hpel_av8
.global _ih264_inter_pred_luma_horz_hpel_vert_qpel_av8
_ih264_inter_pred_luma_horz_hpel_vert_qpel_av8 = ih264_inter_pred_luma_horz_hpel_vert_qpel_av8
.global _ih264_inter_pred_luma_horz_qpel_av8
_ih264_inter_pred_luma_horz_qpel_av8 = ih264_inter_pred_luma_horz_qpel_av8
.global _ih264_inter_pred_luma_horz_qpel_vert_hpel_av8
_ih264_inter_pred_luma_horz_qpel_vert_hpel_av8 = ih264_inter_pred_luma_horz_qpel_vert_hpel_av8
.global _ih264_inter_pred_luma_horz_qpel_vert_qpel_av8
_ih264_inter_pred_luma_horz_qpel_vert_qpel_av8 = ih264_inter_pred_luma_horz_qpel_vert_qpel_av8
.global _ih264_inter_pred_luma_vert_av8
_ih264_inter_pred_luma_vert_av8 = ih264_inter_pred_luma_vert_av8
.global _ih264_inter_pred_luma_vert_qpel_av8
_ih264_inter_pred_luma_vert_qpel_av8 = ih264_inter_pred_luma_vert_qpel_av8
.global _ih264_intra_pred_chroma_8x8_mode_horz_av8
_ih264_intra_pred_chroma_8x8_mode_horz_av8 = ih264_intra_pred_chroma_8x8_mode_horz_av8
.global _ih264_intra_pred_chroma_8x8_mode_plane_av8
_ih264_intra_pred_chroma_8x8_mode_plane_av8 = ih264_intra_pred_chroma_8x8_mode_plane_av8
.global _ih264_intra_pred_chroma_8x8_mode_vert_av8
_ih264_intra_pred_chroma_8x8_mode_vert_av8 = ih264_intra_pred_chroma_8x8_mode_vert_av8
.global _ih264_intra_pred_luma_16x16_mode_dc_av8
_ih264_intra_pred_luma_16x16_mode_dc_av8 = ih264_intra_pred_luma_16x16_mode_dc_av8
.global _ih264_intra_pred_luma_16x16_mode_horz_av8
_ih264_intra_pred_luma_16x16_mode_horz_av8 = ih264_intra_pred_luma_16x16_mode_horz_av8
.global _ih264_intra_pred_luma_16x16_mode_plane_av8
_ih264_intra_pred_luma_16x16_mode_plane_av8 = ih264_intra_pred_luma_16x16_mode_plane_av8
.global _ih264_intra_pred_luma_16x16_mode_vert_av8
_ih264_intra_pred_luma_16x16_mode_vert_av8 = ih264_intra_pred_luma_16x16_mode_vert_av8
.global _ih264_intra_pred_luma_4x4_mode_dc_av8
_ih264_intra_pred_luma_4x4_mode_dc_av8 = ih264_intra_pred_luma_4x4_mode_dc_av8
.global _ih264_intra_pred_luma_4x4_mode_diag_dl_av8
_ih264_intra_pred_luma_4x4_mode_diag_dl_av8 = ih264_intra_pred_luma_4x4_mode_diag_dl_av8
.global _ih264_intra_pred_luma_4x4_mode_diag_dr_av8
_ih264_intra_pred_luma_4x4_mode_diag_dr_av8 = ih264_intra_pred_luma_4x4_mode_diag_dr_av8
.global _ih264_intra_pred_luma_4x4_mode_horz_av8
_ih264_intra_pred_luma_4x4_mode_horz_av8 = ih264_intra_pred_luma_4x4_mode_horz_av8
.global _ih264_intra_pred_luma_4x4_mode_horz_d_av8
_ih264_intra_pred_luma_4x4_mode_horz_d_av8 = ih264_intra_pred_luma_4x4_mode_horz_d_av8
.global _ih264_intra_pred_luma_4x4_mode_horz_u_av8
_ih264_intra_pred_luma_4x4_mode_horz_u_av8 = ih264_intra_pred_luma_4x4_mode_horz_u_av8
.global _ih264_intra_pred_luma_4x4_mode_vert_av8
_ih264_intra_pred_luma_4x4_mode_vert_av8 = ih264_intra_pred_luma_4x4_mode_vert_av8
.global _ih264_intra_pred_luma_4x4_mode_vert_l_av8
_ih264_intra_pred_luma_4x4_mode_vert_l_av8 = ih264_intra_pred_luma_4x4_mode_vert_l_av8
.global _ih264_intra_pred_luma_4x4_mode_vert_r_av8
_ih264_intra_pred_luma_4x4_mode_vert_r_av8 = ih264_intra_pred_luma_4x4_mode_vert_r_av8
.global _ih264_intra_pred_luma_8x8_mode_dc_av8
_ih264_intra_pred_luma_8x8_mode_dc_av8 = ih264_intra_pred_luma_8x8_mode_dc_av8
.global _ih264_intra_pred_luma_8x8_mode_diag_dl_av8
_ih264_intra_pred_luma_8x8_mode_diag_dl_av8 = ih264_intra_pred_luma_8x8_mode_diag_dl_av8
.global _ih264_intra_pred_luma_8x8_mode_diag_dr_av8
_ih264_intra_pred_luma_8x8_mode_diag_dr_av8 = ih264_intra_pred_luma_8x8_mode_diag_dr_av8
.global _ih264_intra_pred_luma_8x8_mode_horz_av8
_ih264_intra_pred_luma_8x8_mode_horz_av8 = ih264_intra_pred_luma_8x8_mode_horz_av8
.global _ih264_intra_pred_luma_8x8_mode_horz_d_av8
_ih264_intra_pred_luma_8x8_mode_horz_d_av8 = ih264_intra_pred_luma_8x8_mode_horz_d_av8
.global _ih264_intra_pred_luma_8x8_mode_horz_u_av8
_ih264_intra_pred_luma_8x8_mode_horz_u_av8 = ih264_intra_pred_luma_8x8_mode_horz_u_av8
.global _ih264_intra_pred_luma_8x8_mode_vert_av8
_ih264_intra_pred_luma_8x8_mode_vert_av8 = ih264_intra_pred_luma_8x8_mode_vert_av8
.global _ih264_intra_pred_luma_8x8_mode_vert_l_av8
_ih264_intra_pred_luma_8x8_mode_vert_l_av8 = ih264_intra_pred_luma_8x8_mode_vert_l_av8
.global _ih264_intra_pred_luma_8x8_mode_vert_r_av8
_ih264_intra_pred_luma_8x8_mode_vert_r_av8 = ih264_intra_pred_luma_8x8_mode_vert_r_av8
.global _ih264_iquant_itrans_recon_4x4_av8
_ih264_iquant_itrans_recon_4x4_av8 = ih264_iquant_itrans_recon_4x4_av8
.global _ih264_iquant_itrans_recon_4x4_dc_av8
_ih264_iquant_itrans_recon_4x4_dc_av8 = ih264_iquant_itrans_recon_4x4_dc_av8
.global _ih264_iquant_itrans_recon_8x8_av8
_ih264_iquant_itrans_recon_8x8_av8 = ih264_iquant_itrans_recon_8x8_av8
.global _ih264_iquant_itrans_recon_8x8_dc_av8
_ih264_iquant_itrans_recon_8x8_dc_av8 = ih264_iquant_itrans_recon_8x8_dc_av8
.global _ih264_iquant_itrans_recon_chroma_4x4_av8
_ih264_iquant_itrans_recon_chroma_4x4_av8 = ih264_iquant_itrans_recon_chroma_4x4_av8
.global _ih264_iquant_itrans_recon_chroma_4x4_dc_av8
_ih264_iquant_itrans_recon_chroma_4x4_dc_av8 = ih264_iquant_itrans_recon_chroma_4x4_dc_av8
.global _ih264_pad_left_chroma_av8
_ih264_pad_left_chroma_av8 = ih264_pad_left_chroma_av8
.global _ih264_pad_left_luma_av8
_ih264_pad_left_luma_av8 = ih264_pad_left_luma_av8
.global _ih264_pad_right_chroma_av8
_ih264_pad_right_chroma_av8 = ih264_pad_right_chroma_av8
.global _ih264_pad_right_luma_av8
_ih264_pad_right_luma_av8 = ih264_pad_right_luma_av8
.global _ih264_pad_top_av8
_ih264_pad_top_av8 = ih264_pad_top_av8
.global _ih264_weighted_bi_pred_chroma_av8
_ih264_weighted_bi_pred_chroma_av8 = ih264_weighted_bi_pred_chroma_av8
.global _ih264_weighted_bi_pred_luma_av8
_ih264_weighted_bi_pred_luma_av8 = ih264_weighted_bi_pred_luma_av8
.global _ih264_weighted_pred_chroma_av8
_ih264_weighted_pred_chroma_av8 = ih264_weighted_pred_chroma_av8
.global _ih264_weighted_pred_luma_av8
_ih264_weighted_pred_luma_av8 = ih264_weighted_pred_luma_av8

View file

@ -101,13 +101,21 @@ if (MACOS_BUNDLE)
endforeach(folder) endforeach(folder)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/x64-osx/debug/lib/libusb-1.0.0.dylib") set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/debug/lib/libusb-1.0.0.dylib")
else() else()
set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/x64-osx/lib/libusb-1.0.0.dylib") set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/lib/libusb-1.0.0.dylib")
endif() endif()
if (EXISTS "/usr/local/lib/libMoltenVK.dylib")
set(MOLTENVK_PATH "/usr/local/lib/libMoltenVK.dylib")
elseif (EXISTS "/opt/homebrew/lib/libMoltenVK.dylib")
set(MOLTENVK_PATH "/opt/homebrew/lib/libMoltenVK.dylib")
else()
message(FATAL_ERROR "failed to find libMoltenVK.dylib")
endif ()
add_custom_command (TARGET CemuBin POST_BUILD add_custom_command (TARGET CemuBin POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy "/usr/local/lib/libMoltenVK.dylib" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libMoltenVK.dylib" COMMAND ${CMAKE_COMMAND} ARGS -E copy "${MOLTENVK_PATH}" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libMoltenVK.dylib"
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${LIBUSB_PATH}" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libusb-1.0.0.dylib" COMMAND ${CMAKE_COMMAND} ARGS -E copy "${LIBUSB_PATH}" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libusb-1.0.0.dylib"
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_SOURCE_DIR}/src/resource/update.sh" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/update.sh" COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_SOURCE_DIR}/src/resource/update.sh" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/update.sh"
COMMAND bash -c "install_name_tool -add_rpath @executable_path/../Frameworks ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}" COMMAND bash -c "install_name_tool -add_rpath @executable_path/../Frameworks ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}"

View file

@ -537,7 +537,7 @@ if(APPLE)
target_sources(CemuCafe PRIVATE "HW/Latte/Renderer/Vulkan/CocoaSurface.mm") target_sources(CemuCafe PRIVATE "HW/Latte/Renderer/Vulkan/CocoaSurface.mm")
endif() endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)") if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
target_sources(CemuCafe PRIVATE target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h

View file

@ -169,8 +169,10 @@ struct AArch64GenContext_t : CodeGenerator
bool processAllJumps() bool processAllJumps()
{ {
for (auto&& [jumpStart, jumpInfo] : jumps) for (auto jump : jumps)
{ {
auto jumpStart = jump.first;
auto jumpInfo = jump.second;
bool success = std::visit( bool success = std::visit(
[&, this](const auto& jump) { [&, this](const auto& jump) {
setSize(jumpStart); setSize(jumpStart);

View file

@ -6,6 +6,8 @@
#if defined(ARCH_X86_64) && defined(__GNUC__) #if defined(ARCH_X86_64) && defined(__GNUC__)
#include <immintrin.h> #include <immintrin.h>
#elif defined(__aarch64__)
#include <arm_neon.h>
#endif #endif
struct struct
@ -502,6 +504,114 @@ void LatteIndices_fastConvertU32_AVX2(const void* indexDataInput, void* indexDat
indexMax = std::max(indexMax, _maxIndex); indexMax = std::max(indexMax, _maxIndex);
indexMin = std::min(indexMin, _minIndex); indexMin = std::min(indexMin, _minIndex);
} }
#elif defined(__aarch64__)
void LatteIndices_fastConvertU16_NEON(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
{
const uint16* indicesU16BE = (const uint16*)indexDataInput;
uint16* indexOutput = (uint16*)indexDataOutput;
sint32 count8 = count >> 3;
sint32 countRemaining = count & 7;
if (count8)
{
uint16x8_t mMin = vdupq_n_u16(0xFFFF);
uint16x8_t mMax = vdupq_n_u16(0x0000);
uint16x8_t mTemp;
uint16x8_t* mRawIndices = (uint16x8_t*) indicesU16BE;
indicesU16BE += count8 * 8;
uint16x8_t* mOutputIndices = (uint16x8_t*) indexOutput;
indexOutput += count8 * 8;
while (count8--)
{
mTemp = vld1q_u16((uint16*)mRawIndices);
mRawIndices++;
mTemp = vrev16q_u8(mTemp);
mMin = vminq_u16(mMin, mTemp);
mMax = vmaxq_u16(mMax, mTemp);
vst1q_u16((uint16*)mOutputIndices, mTemp);
mOutputIndices++;
}
uint16* mMaxU16 = (uint16*)&mMax;
uint16* mMinU16 = (uint16*)&mMin;
for (int i = 0; i < 8; ++i) {
indexMax = std::max(indexMax, (uint32)mMaxU16[i]);
indexMin = std::min(indexMin, (uint32)mMinU16[i]);
}
}
// process remaining indices
uint32 _minIndex = 0xFFFFFFFF;
uint32 _maxIndex = 0;
for (sint32 i = countRemaining; (--i) >= 0;)
{
uint16 idx = _swapEndianU16(*indicesU16BE);
*indexOutput = idx;
indexOutput++;
indicesU16BE++;
_maxIndex = std::max(_maxIndex, (uint32)idx);
_minIndex = std::min(_minIndex, (uint32)idx);
}
// update min/max
indexMax = std::max(indexMax, _maxIndex);
indexMin = std::min(indexMin, _minIndex);
}
void LatteIndices_fastConvertU32_NEON(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
{
const uint32* indicesU32BE = (const uint32*)indexDataInput;
uint32* indexOutput = (uint32*)indexDataOutput;
sint32 count8 = count >> 2;
sint32 countRemaining = count & 3;
if (count8)
{
uint32x4_t mMin = vdupq_n_u32(0xFFFFFFFF);
uint32x4_t mMax = vdupq_n_u32(0x00000000);
uint32x4_t mTemp;
uint32x4_t* mRawIndices = (uint32x4_t*) indicesU32BE;
indicesU32BE += count8 * 4;
uint32x4_t* mOutputIndices = (uint32x4_t*) indexOutput;
indexOutput += count8 * 4;
while (count8--)
{
mTemp = vld1q_u32((uint32*)mRawIndices);
mRawIndices++;
mTemp = vrev32q_u8(mTemp);
mMin = vminq_u32(mMin, mTemp);
mMax = vmaxq_u32(mMax, mTemp);
vst1q_u32((uint32*)mOutputIndices, mTemp);
mOutputIndices++;
}
uint32* mMaxU32 = (uint32*)&mMax;
uint32* mMinU32 = (uint32*)&mMin;
for (int i = 0; i < 4; ++i) {
indexMax = std::max(indexMax, mMaxU32[i]);
indexMin = std::min(indexMin, mMinU32[i]);
}
}
// process remaining indices
uint32 _minIndex = 0xFFFFFFFF;
uint32 _maxIndex = 0;
for (sint32 i = countRemaining; (--i) >= 0;)
{
uint32 idx = _swapEndianU32(*indicesU32BE);
*indexOutput = idx;
indexOutput++;
indicesU32BE++;
_maxIndex = std::max(_maxIndex, idx);
_minIndex = std::min(_minIndex, idx);
}
// update min/max
indexMax = std::max(indexMax, _maxIndex);
indexMin = std::min(indexMin, _minIndex);
}
#endif #endif
template<typename T> template<typename T>
@ -688,27 +798,31 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
{ {
if (indexType == LatteIndexType::U16_BE) if (indexType == LatteIndexType::U16_BE)
{ {
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
if (g_CPUFeatures.x86.avx2) if (g_CPUFeatures.x86.avx2)
LatteIndices_fastConvertU16_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_fastConvertU16_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax);
else if (g_CPUFeatures.x86.sse4_1 && g_CPUFeatures.x86.ssse3) else if (g_CPUFeatures.x86.sse4_1 && g_CPUFeatures.x86.ssse3)
LatteIndices_fastConvertU16_SSE41(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_fastConvertU16_SSE41(indexData, indexOutputPtr, count, indexMin, indexMax);
else else
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
#else #elif defined(__aarch64__)
LatteIndices_fastConvertU16_NEON(indexData, indexOutputPtr, count, indexMin, indexMax);
#else
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
#endif #endif
} }
else if (indexType == LatteIndexType::U32_BE) else if (indexType == LatteIndexType::U32_BE)
{ {
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
if (g_CPUFeatures.x86.avx2) if (g_CPUFeatures.x86.avx2)
LatteIndices_fastConvertU32_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_fastConvertU32_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax);
else else
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
#else #elif defined(__aarch64__)
LatteIndices_fastConvertU32_NEON(indexData, indexOutputPtr, count, indexMin, indexMax);
#else
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax); LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
#endif #endif
} }
else if (indexType == LatteIndexType::U16_LE) else if (indexType == LatteIndexType::U16_LE)
{ {

View file

@ -132,7 +132,7 @@ namespace iosu
void convertMultiByteStringToBigEndianWidechar(const char* input, uint16be* output, sint32 maxOutputLength) void convertMultiByteStringToBigEndianWidechar(const char* input, uint16be* output, sint32 maxOutputLength)
{ {
std::basic_string<uint16be> beStr = StringHelpers::FromUtf8(input); std::vector<uint16be> beStr = StringHelpers::FromUtf8(input);
if (beStr.size() >= maxOutputLength - 1) if (beStr.size() >= maxOutputLength - 1)
beStr.resize(maxOutputLength-1); beStr.resize(maxOutputLength-1);
for (size_t i = 0; i < beStr.size(); i++) for (size_t i = 0; i < beStr.size(); i++)
@ -723,7 +723,7 @@ namespace iosu
{ {
if(numVecIn != 0 || numVecOut != 1) if(numVecIn != 0 || numVecOut != 1)
return FPResult_InvalidIPCParam; return FPResult_InvalidIPCParam;
std::basic_string<uint16be> myComment; std::vector<uint16be> myComment;
if(g_fpd.nexFriendSession) if(g_fpd.nexFriendSession)
{ {
if(vecOut->size != MY_COMMENT_LENGTH * sizeof(uint16be)) if(vecOut->size != MY_COMMENT_LENGTH * sizeof(uint16be))
@ -735,8 +735,8 @@ namespace iosu
g_fpd.nexFriendSession->getMyComment(myNexComment); g_fpd.nexFriendSession->getMyComment(myNexComment);
myComment = StringHelpers::FromUtf8(myNexComment.commentString); myComment = StringHelpers::FromUtf8(myNexComment.commentString);
} }
myComment.insert(0, 1, '\0'); myComment.insert(myComment.begin(), '\0');
memcpy(vecOut->basePhys.GetPtr(), myComment.c_str(), MY_COMMENT_LENGTH * sizeof(uint16be)); memcpy(vecOut->basePhys.GetPtr(), myComment.data(), MY_COMMENT_LENGTH * sizeof(uint16be));
return FPResult_Ok; return FPResult_Ok;
} }

View file

@ -25,7 +25,11 @@ void nnNfp_update();
namespace coreinit namespace coreinit
{ {
#ifdef __arm64__
void __OSFiberThreadEntry(uint32, uint32);
#else
void __OSFiberThreadEntry(void* thread); void __OSFiberThreadEntry(void* thread);
#endif
void __OSAddReadyThreadToRunQueue(OSThread_t* thread); void __OSAddReadyThreadToRunQueue(OSThread_t* thread);
void __OSRemoveThreadFromRunQueues(OSThread_t* thread); void __OSRemoveThreadFromRunQueues(OSThread_t* thread);
}; };
@ -49,7 +53,7 @@ namespace coreinit
struct OSHostThread struct OSHostThread
{ {
OSHostThread(OSThread_t* thread) : m_thread(thread), m_fiber(__OSFiberThreadEntry, this, this) OSHostThread(OSThread_t* thread) : m_thread(thread), m_fiber((void(*)(void*))__OSFiberThreadEntry, this, this)
{ {
} }
@ -1304,8 +1308,14 @@ namespace coreinit
__OSThreadStartTimeslice(hostThread->m_thread, &hostThread->ppcInstance); __OSThreadStartTimeslice(hostThread->m_thread, &hostThread->ppcInstance);
} }
#ifdef __arm64__
void __OSFiberThreadEntry(uint32 _high, uint32 _low)
{
uint64 _thread = (uint64) _high << 32 | _low;
#else
void __OSFiberThreadEntry(void* _thread) void __OSFiberThreadEntry(void* _thread)
{ {
#endif
OSHostThread* hostThread = (OSHostThread*)_thread; OSHostThread* hostThread = (OSHostThread*)_thread;
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)

View file

@ -145,7 +145,8 @@ namespace nn
if (name.size() != 0) if (name.size() != 0)
{ {
auto name_utf16 = StringHelpers::FromUtf8(name).substr(0, 128); auto name_utf16 = StringHelpers::FromUtf8(name);
name_utf16.resize(std::min<size_t>(name_utf16.size(), 128));
if (name_utf16.size() != 0) if (name_utf16.size() != 0)
{ {
for (int i = 0; i < name_utf16.size(); i++) for (int i = 0; i < name_utf16.size(); i++)
@ -160,7 +161,8 @@ namespace nn
if (description.size() != 0) if (description.size() != 0)
{ {
auto description_utf16 = StringHelpers::FromUtf8(description).substr(0, 256); auto description_utf16 = StringHelpers::FromUtf8(description);
description_utf16.resize(std::min<size_t>(description_utf16.size(), 256));
if (description_utf16.size() != 0) if (description_utf16.size() != 0)
{ {
for (int i = 0; i < description_utf16.size(); i++) for (int i = 0; i < description_utf16.size(); i++)
@ -206,7 +208,8 @@ namespace nn
if (screen_name.size() != 0) if (screen_name.size() != 0)
{ {
auto screen_name_utf16 = StringHelpers::FromUtf8(screen_name).substr(0, 32); auto screen_name_utf16 = StringHelpers::FromUtf8(screen_name);
screen_name_utf16.resize(std::min<size_t>(screen_name_utf16.size(), 32));
if (screen_name_utf16.size() != 0) if (screen_name_utf16.size() != 0)
{ {
for (int i = 0; i < screen_name_utf16.size(); i++) for (int i = 0; i < screen_name_utf16.size(); i++)

View file

@ -250,7 +250,8 @@ namespace nn
if (name.size() != 0) if (name.size() != 0)
{ {
auto name_utf16 = StringHelpers::FromUtf8(name).substr(0, 128); auto name_utf16 = StringHelpers::FromUtf8(name);
name_utf16.resize(std::min<size_t>(name_utf16.size(), 128));
if (name_utf16.size() != 0) if (name_utf16.size() != 0)
{ {
for (int i = 0; i < name_utf16.size(); i++) for (int i = 0; i < name_utf16.size(); i++)
@ -265,7 +266,8 @@ namespace nn
if (description.size() != 0) if (description.size() != 0)
{ {
auto description_utf16 = StringHelpers::FromUtf8(description).substr(0, 256); auto description_utf16 = StringHelpers::FromUtf8(description);
description_utf16.resize(std::min<size_t>(description_utf16.size(), 256));
if (description_utf16.size() != 0) if (description_utf16.size() != 0)
{ {
for (int i = 0; i < description_utf16.size(); i++) for (int i = 0; i < description_utf16.size(); i++)

View file

@ -1,5 +1,6 @@
#include "nn_olv_UploadFavoriteTypes.h" #include "nn_olv_UploadFavoriteTypes.h"
#include <algorithm> #include <algorithm>
#include <cstddef>
namespace nn namespace nn
{ {
@ -115,7 +116,8 @@ namespace nn
if (name.size() != 0) if (name.size() != 0)
{ {
auto name_utf16 = StringHelpers::FromUtf8(name).substr(0, 128); auto name_utf16 = StringHelpers::FromUtf8(name);
name_utf16.resize(std::min<size_t>(name_utf16.size(), 128));
if (name_utf16.size() != 0) if (name_utf16.size() != 0)
{ {
for (int i = 0; i < name_utf16.size(); i++) for (int i = 0; i < name_utf16.size(); i++)
@ -130,7 +132,8 @@ namespace nn
if (description.size() != 0) if (description.size() != 0)
{ {
auto description_utf16 = StringHelpers::FromUtf8(description).substr(0, 256); auto description_utf16 = StringHelpers::FromUtf8(description);
description_utf16.resize(std::min<size_t>(description_utf16.size(), 256));
if (description_utf16.size() != 0) if (description_utf16.size() != 0)
{ {
for (int i = 0; i < description_utf16.size(); i++) for (int i = 0; i < description_utf16.size(); i++)

View file

@ -51,15 +51,15 @@ class CafeWideString // fixed buffer size, null-terminated, PPC wchar_t (16bit b
bool assignFromUTF8(std::string_view sv) bool assignFromUTF8(std::string_view sv)
{ {
std::basic_string<uint16be> beStr = StringHelpers::FromUtf8(sv); std::vector<uint16be> beStr = StringHelpers::FromUtf8(sv);
if(beStr.length() > N-1) if(beStr.size() > N-1)
{ {
memcpy(data, beStr.data(), (N-1)*sizeof(uint16be)); memcpy(data, beStr.data(), (N-1)*sizeof(uint16be));
data[N-1] = 0; data[N-1] = 0;
return false; return false;
} }
memcpy(data, beStr.data(), beStr.length()*sizeof(uint16be)); memcpy(data, beStr.data(), beStr.size()*sizeof(uint16be));
data[beStr.length()] = '\0'; data[beStr.size()] = '\0';
return true; return true;
} }

View file

@ -310,7 +310,8 @@ inline uint64 __rdtsc()
inline void _mm_mfence() inline void _mm_mfence()
{ {
asm volatile("" ::: "memory");
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) inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, unsigned long long b, unsigned long long *result)

View file

@ -140,6 +140,7 @@ enum
MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS, MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS,
// debug->logging // debug->logging
MAINFRAME_MENU_ID_DEBUG_LOGGING_MESSAGE = 21499,
MAINFRAME_MENU_ID_DEBUG_LOGGING0 = 21500, MAINFRAME_MENU_ID_DEBUG_LOGGING0 = 21500,
MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO = 21599, MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO = 21599,
// debug->dump // debug->dump
@ -2234,7 +2235,7 @@ void MainWindow::RecreateMenu()
debugLoggingMenu->AppendSeparator(); debugLoggingMenu->AppendSeparator();
wxMenu* logCosModulesMenu = new wxMenu(); wxMenu* logCosModulesMenu = new wxMenu();
logCosModulesMenu->AppendCheckItem(0, _("&Options below are for experts. Leave off if unsure"), wxEmptyString)->Enable(false); logCosModulesMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING_MESSAGE, _("&Options below are for experts. Leave off if unsure"), wxEmptyString)->Enable(false);
logCosModulesMenu->AppendSeparator(); logCosModulesMenu->AppendSeparator();
logCosModulesMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::CoreinitFile), _("coreinit File-Access API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::CoreinitFile)); logCosModulesMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::CoreinitFile), _("coreinit File-Access API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::CoreinitFile));
logCosModulesMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::CoreinitThreadSync), _("coreinit Thread-Synchronization API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::CoreinitThreadSync)); logCosModulesMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::CoreinitThreadSync), _("coreinit Thread-Synchronization API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::CoreinitThreadSync));

View file

@ -15,7 +15,12 @@ Fiber::Fiber(void(*FiberEntryPoint)(void* userParam), void* userParam, void* pri
ctx->uc_stack.ss_sp = m_stackPtr; ctx->uc_stack.ss_sp = m_stackPtr;
ctx->uc_stack.ss_size = stackSize; ctx->uc_stack.ss_size = stackSize;
ctx->uc_link = &ctx[0]; ctx->uc_link = &ctx[0];
#ifdef __arm64__
// https://www.man7.org/linux/man-pages/man3/makecontext.3.html#NOTES
makecontext(ctx, (void(*)())FiberEntryPoint, 2, (uint64) userParam >> 32, userParam);
#else
makecontext(ctx, (void(*)())FiberEntryPoint, 1, userParam); makecontext(ctx, (void(*)())FiberEntryPoint, 1, userParam);
#endif
this->m_implData = (void*)ctx; this->m_implData = (void*)ctx;
} }

View file

@ -45,7 +45,11 @@ namespace MemMapper
void* r; void* r;
if(fromReservation) if(fromReservation)
{ {
if( mprotect(baseAddr, size, GetProt(permissionFlags)) == 0 ) uint64 page_size = sysconf(_SC_PAGESIZE);
void* page = baseAddr;
if ( (uint64) baseAddr % page_size != 0 )
page = (void*) ((uint64)baseAddr & ~(page_size - 1));
if( mprotect(page, size, GetProt(permissionFlags)) == 0 )
r = baseAddr; r = baseAddr;
else else
r = nullptr; r = nullptr;

View file

@ -111,9 +111,9 @@ namespace StringHelpers
} }
// convert utf8 string to Wii U big-endian wchar_t string // convert utf8 string to Wii U big-endian wchar_t string
static std::basic_string<uint16be> FromUtf8(std::string_view str) static std::vector<uint16be> FromUtf8(std::string_view str)
{ {
std::basic_string<uint16be> tmpStr; std::vector<uint16be> tmpStr;
std::wstring w = boost::nowide::widen(str.data(), str.size()); std::wstring w = boost::nowide::widen(str.data(), str.size());
for (auto& c : w) for (auto& c : w)
tmpStr.push_back((uint16)c); tmpStr.push_back((uint16)c);

View file

@ -27,6 +27,8 @@ uint64 HighResolutionTimer::m_freq = []() -> uint64 {
LARGE_INTEGER freq; LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq); QueryPerformanceFrequency(&freq);
return (uint64)(freq.QuadPart); return (uint64)(freq.QuadPart);
#elif BOOST_OS_MACOS
return 1000000000;
#else #else
timespec pc; timespec pc;
clock_getres(CLOCK_MONOTONIC_RAW, &pc); clock_getres(CLOCK_MONOTONIC_RAW, &pc);