Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, ANDROID_GLIBC, WOW64, ARM64-GCC-8]
platform: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, PPC64LE, ANDROID_GLIBC, WOW64, ARM64-GCC-8]
type: [Release, Trace, StaticBuild, Box32]
exclude:
- platform: ANDROID
Expand Down Expand Up @@ -64,6 +64,8 @@ jobs:
type: Trace
- platform: LARCH64
type: Trace
- platform: PPC64LE
type: Trace
include:
- platform: X64
os: ubuntu-latest
Expand All @@ -86,6 +88,9 @@ jobs:
- platform: LARCH64
os: ubuntu-latest

- platform: PPC64LE
os: ubuntu-latest

- platform: ANDROID_GLIBC
os: ubuntu-22.04-arm

Expand Down Expand Up @@ -122,7 +127,7 @@ jobs:
if: steps.changed-files-dir-names.outputs.all_modified_files == 'src/dynarec/arm64'
continue-on-error: true
run: |
if [[ ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' && ${{ matrix.platform }} != 'X64' ]]; then
if [[ ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' && ${{ matrix.platform }} != 'PPC64LE' && ${{ matrix.platform }} != 'X64' ]]; then
exit 1
fi

Expand All @@ -148,18 +153,29 @@ jobs:
exit 1
fi

- name: Early exit other jobs if this is a PPC64LE-only change
id: early-exit-ppc64le
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: steps.changed-files-dir-names.outputs.all_modified_files == 'src/dynarec/ppc64le'
continue-on-error: true
run: |
if [[ ${{ matrix.platform }} == 'PPC64LE' ]]; then
exit 1
fi

- name: Do not early exit otherwise
id: early-exit-never
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DIRS: ${{ steps.changed-files-dir-names.outputs.all_modified_files }}
if: env.DIRS != 'src/dynarec/arm64' && env.DIRS != 'src/dynarec/la64' && env.DIRS != 'src/dynarec/rv64'
if: env.DIRS != 'src/dynarec/arm64' && env.DIRS != 'src/dynarec/la64' && env.DIRS != 'src/dynarec/rv64' && env.DIRS != 'src/dynarec/ppc64le'
continue-on-error: true
run: exit 1

- name: Merge early exit conditions
id: early-exit
if: steps.early-exit-arm64.outcome == 'failure' || steps.early-exit-la64.outcome == 'failure' || steps.early-exit-rv64.outcome == 'failure' || steps.early-exit-never.outcome == 'failure'
if: steps.early-exit-arm64.outcome == 'failure' || steps.early-exit-la64.outcome == 'failure' || steps.early-exit-rv64.outcome == 'failure' || steps.early-exit-ppc64le.outcome == 'failure' || steps.early-exit-never.outcome == 'failure'
continue-on-error: true
run: exit 1

Expand All @@ -175,7 +191,7 @@ jobs:
sudo apt-get update
zydis_package=libzydis-dev
fi
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' ]]; then
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' && ${{ matrix.platform }} != 'PPC64LE' ]]; then
sudo apt-get -y install git cmake make python3 patchelf $zydis_package
if [[ ${{ matrix.platform }} == 'ANDROID' || ${{ matrix.platform }} == 'TERMUX' ]]; then
sudo apt-get -y install p7zip
Expand Down Expand Up @@ -253,6 +269,10 @@ jobs:
echo BOX64_PLATFORM_MARCRO="-DLARCH64=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=loongarch64-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git cmake make python3 libzydis-dev
elif [[ ${{ matrix.platform }} == 'PPC64LE' ]]; then
echo BOX64_PLATFORM_MARCRO="-DPPC64LE=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=powerpc64le-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git gcc-powerpc64le-linux-gnu cmake make python3 libzydis-dev
else
echo BOX64_PLATFORM_MARCRO="-DARM_DYNAREC=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
Expand Down Expand Up @@ -391,6 +411,14 @@ jobs:

BOX64_DYNAREC_TEST=1 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 BOX64_DYNAREC_NOHOSTEXT=1 ctest $CTEST_OPTIONS -E nocosim
elif [[ ${{ matrix.platform }} == 'PPC64LE' ]]; then
export INTERPRETER=qemu-ppc64le-static
export QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu/

ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS -E nocosim

BOX64_DYNAREC_TEST=1 ctest $CTEST_OPTIONS -E nocosim
elif [[ ${{ matrix.platform }} == 'ANDROID' ]]; then
export INTERPRETER=qemu-aarch64-static
export QEMU_LD_PREFIX=/system/lib64
Expand Down
78 changes: 76 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ if(LARCH64)
set(ARM_DYNAREC OFF CACHE BOOL "")
set(RV64_DYNAREC OFF CACHE BOOL "")
set(LARCH64_DYNAREC ON CACHE BOOL "")
set(PPC64LE_DYNAREC OFF CACHE BOOL "")
set(BAD_PKILL ON CACHE BOOL "")
if(LARCH64_ABI_1)
message(STATUS "Build for Loongarch64 ABI 1.0 system")
Expand All @@ -81,20 +82,23 @@ if(RV64)
set(ARM_DYNAREC OFF CACHE BOOL "")
set(RV64_DYNAREC ON CACHE BOOL "")
set(LARCH64_DYNAREC OFF CACHE BOOL "")
set(PPC64LE_DYNAREC OFF CACHE BOOL "")
endif()
if(PPC64LE)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC OFF CACHE BOOL "")
set(RV64_DYNAREC OFF CACHE BOOL "")
set(LARCH64_DYNAREC OFF CACHE BOOL "")
set(PPC64LE_DYNAREC ON CACHE BOOL "")
endif()
if(RK3399 OR RK3588 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RPI5ARM64 OR RK3326 OR TEGRAX1 OR TEGRA_T194 OR TEGRA_T234 OR NVIDIA_GB10 OR PHYTIUM OR SD845 OR SD865 OR SD888 OR SD8G2 OR SDORYON1 OR SD8EG5 OR LX2160A OR M1 OR ARM64 OR ADLINK)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC ON CACHE BOOL "")
set(RV64_DYNAREC OFF CACHE BOOL "")
set(LARCH64_DYNAREC OFF CACHE BOOL "")
set(PPC64LE_DYNAREC OFF CACHE BOOL "")
endif()
if(RK3399 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RPI5ARM64)
set(SAVE_MEM ON CACHE BOOL "")
Expand Down Expand Up @@ -122,6 +126,7 @@ option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NO
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation" ${ARM_DYNAREC})
option(RV64_DYNAREC "Set to ON to use RISC-V Dynamic Recompilation" ${RV64_DYNAREC})
option(LARCH64_DYNAREC "Set to ON to use LOONGARCH64 Dynamic Recompilation" ${LARCH64_DYNAREC})
option(PPC64LE_DYNAREC "Set to ON to use PPC64LE Dynamic Recompilation" ${PPC64LE_DYNAREC})
option(STATICBUILD "Set to ON to have a static build (Warning, not working)" ${STATICBUILD})
option(NO_LIB_INSTALL "Set ON to not install a few x86_64 libs that are used by many program" ${NO_LIB_INSTALL})
option(NO_CONF_INSTALL "Set ON to not install config files" ${NO_CONF_INSTALL})
Expand Down Expand Up @@ -251,6 +256,8 @@ elseif(RV64)
set(ASMFLAGS -pipe -march=rv64gc)
elseif(PPC64LE)
add_definitions(-DPPC64LE)
set(CFLAGS -pipe -mcpu=power9)
set(ASMFLAGS -pipe -mcpu=power9)
elseif(LX2160A)
add_definitions(-DLX2160A)
set(CFLAGS -pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto)
Expand Down Expand Up @@ -292,6 +299,9 @@ if(STATICBUILD)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS -static)
set(HAVE_TRACE OFF)
if(PPC64LE)
add_definitions(-fno-stack-protector)
endif()
endif()
if(BOX32)
add_definitions(-DBOX32)
Expand Down Expand Up @@ -348,6 +358,12 @@ elseif(LARCH64_DYNAREC)
enable_language(ASM)
include_directories("${BOX64_ROOT}/src/dynarec/la64")
set(DYNAREC ON)
elseif(PPC64LE_DYNAREC)
add_definitions(-DDYNAREC)
add_definitions(-DPPC64LE)
enable_language(ASM)
include_directories("${BOX64_ROOT}/src/dynarec/ppc64le")
set(DYNAREC ON)
else()
set(DYNAREC OFF)
endif()
Expand Down Expand Up @@ -848,7 +864,7 @@ if(NOT CI)
OUTPUT "${BOX64_ROOT}/src/wrapped/generated/functions_list.txt"
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/rebuild_wrappers.py"
"${BOX64_ROOT}"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "STATICBUILD" "LA64" "--"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "STATICBUILD" "LA64" "PPC64LE" "--"
${WRAPPEDS_HEAD}
MAIN_DEPENDENCY "${BOX64_ROOT}/rebuild_wrappers.py"
DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
Expand Down Expand Up @@ -1150,6 +1166,58 @@ if(LARCH64_DYNAREC)
)
endif()

if(PPC64LE_DYNAREC)
set(DYNAREC_SRC
${DYNAREC_SRC}

"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_functions.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_arch.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/ppc64le_printer.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_jmpnext.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_consts.c"
)
set(DYNAREC_ASM
${DYNAREC_ASM}
"${BOX64_ROOT}/src/dynarec/ppc64le/ppc64le_prolog.S"
"${BOX64_ROOT}/src/dynarec/ppc64le/ppc64le_epilog.S"
"${BOX64_ROOT}/src/dynarec/ppc64le/ppc64le_next.S"
"${BOX64_ROOT}/src/dynarec/ppc64le/ppc64le_lock.S"
)

set(DYNAREC_PASS
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_helper.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_00.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_0f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_f0.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_f20f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_f30f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_66.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_660f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_66f0.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_66f20f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_66f30f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_d8.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_d9.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_da.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_db.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_dc.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_dd.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_de.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_df.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_0f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_0f38.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_66_0f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_66_0f38.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_66_0f3a.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_f2_0f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_f2_0f38.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_f2_0f3a.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_f3_0f.c"
"${BOX64_ROOT}/src/dynarec/ppc64le/dynarec_ppc64le_avx_f3_0f38.c"
)
endif()


if(GDBJIT)
set(GDBJITREADER "${BOX64_ROOT}/gdbjit/reader.c")
Expand Down Expand Up @@ -1291,8 +1359,12 @@ string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "i686" _x86)
string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "x86_64" _x86_64)
string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "aarch64" _aarch64)
string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "riscv64" _riscv64)
string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "ppc64le" _ppc64le)
if(NOT _ppc64le)
string(COMPARE EQUAL "${CMAKE_SYSTEM_PROCESSOR}" "powerpc64le" _ppc64le)
endif()

if(_x86_64 OR _aarch64)
if(_x86_64 OR _aarch64 OR _ppc64le)
add_definitions(-DCONFIG_64BIT)
endif()

Expand Down Expand Up @@ -1461,6 +1533,8 @@ if(_aarch64)
endif()
elseif(_riscv64)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "riscv64")
elseif(_ppc64le)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "ppc64el")
elseif(_x86_64)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "x86_64")
else()
Expand Down
4 changes: 3 additions & 1 deletion src/build_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#define __BUILD_INFO_H__


#if defined(DYNAREC) && (defined(ARM64) || defined(RV64) || defined(LA64))
#if defined(DYNAREC) && (defined(ARM64) || defined(RV64) || defined(LA64) || defined(PPC64LE))
#if defined(ARM64)
#define ARCH_STR " arm64"
#elif defined(RV64)
#define ARCH_STR " riscv64"
#elif defined(LA64)
#define ARCH_STR " loongarch64"
#elif defined(PPC64LE)
#define ARCH_STR " ppc64le"
#endif
#else
#define ARCH_STR ""
Expand Down
3 changes: 3 additions & 0 deletions src/dynarec/dynacache_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#elif defined(LA64)
#include "dynarec/la64/dynarec_la64_consts.h"
#define native_consts_t la64_consts_t
#elif defined(PPC64LE)
#include "dynarec/ppc64le/dynarec_ppc64le_consts.h"
#define native_consts_t ppc64le_consts_t
#else
#error Unsupported architecture
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/dynarec/dynarec.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,14 @@ void EmuRun(x64emu_t* emu, int use_dynarec)
JUMPBUFF jmpbuf[1] = {0};
int skip = 0;
JUMPBUFF *old_jmpbuf = emu->jmpbuf;
#ifdef RV64
#if defined(RV64) || defined(PPC64LE)
uintptr_t old_savesp = emu->xSPSave;
#endif
int is32bits = (emu->segs[_CS]==0x23);
while(!(emu->quit)) {
if(!emu->jmpbuf || (emu->flags.need_jmpbuf && emu->jmpbuf!=jmpbuf)) {
emu->jmpbuf = jmpbuf;
#ifdef RV64
#if defined(RV64) || defined(PPC64LE)
emu->old_savedsp = emu->xSPSave;
#endif
emu->flags.jmpbuf_ready = 1;
Expand Down Expand Up @@ -265,7 +265,7 @@ void EmuRun(x64emu_t* emu, int use_dynarec)
}
// clear the setjmp
emu->jmpbuf = old_jmpbuf;
#ifdef RV64
#if defined(RV64) || defined(PPC64LE)
emu->xSPSave = old_savesp;
#endif
}
Expand Down
39 changes: 39 additions & 0 deletions src/dynarec/dynarec_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,45 @@ extern uint32_t la64_crc(void* p, uint32_t len);
#define STOP_NATIVE_FLAGS(A, B) {}
#define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)
#define JMPNEXT_SIZE (4*sizeof(void*))

#elif defined(PPC64LE)

#define instruction_native_t instruction_ppc64le_t
#define dynarec_native_t dynarec_ppc64le_t
#define extcache_native_t vmxcache_t

#define ADDITIONNAL_DEFINITION() \
int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst);

#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret |= 2;

#include "ppc64le/ppc64le_printer.h"
#include "ppc64le/dynarec_ppc64le_private.h"
#include "ppc64le/dynarec_ppc64le_functions.h"
#include "ppc64le/dynarec_ppc64le_arch.h"
// Limit here is unconditional branch (I-form), signed 26bits (24-bit field << 2), so ±32MB
#define MAXBLOCK_SIZE ((1 << 24) - 200)

#define RAZ_SPECIFIC(A, N)
#define UPDATE_SPECIFICS(A) propagateFpuBarrier(A)
#define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)
#define POSTUPDATE_SPECIFICS(A)

#define ARCH_SIZE(A) get_size_arch(A)
#define ARCH_FILL(A, B, C) populate_arch(A, B, C)
#define ARCH_ADJUST(A, B, C, D) adjust_arch(A, B, C, D)
#define STOP_NATIVE_FLAGS(A, B) {}
#define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)
extern uint32_t ppc64le_fast_hash(void* p, uint32_t len);
#define ARCH_CRC(A, B) return ppc64le_fast_hash(A, B)

#define ARCH_NOP 0x60000000 /* ori 0,0,0 */
#define ARCH_UDF 0x00000000 /* illegal instruction (all zeros) */
// PPC64LE CreateJmpNext needs 5 instructions (20 bytes) for PC-relative load + branch,
// so the jmpnext area needs 5 void* slots (40 bytes) instead of the default 4 (32 bytes).
#define JMPNEXT_SIZE (5*sizeof(void*))

#else
#error Unsupported platform
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/dynarec/dynarec_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ int is_addr_autosmc(uintptr_t addr);
#include "la64/dynarec_la64_helper.h"
#elif defined(RV64)
#include "rv64/dynarec_rv64_helper.h"
#elif defined(PPC64LE)
#include "ppc64le/dynarec_ppc64le_helper.h"
#else
#error Unsupported architecture
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/dynarec/dynarec_native_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
int jmp = dyn->insts[ninst].x64.jmp_insts;
if(jmp<0)
return 0;
#if defined(ARM64) || defined(LA64)
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
// df_none is now a defered information
if(dyn->insts[ninst].f_exit==dyn->insts[jmp].f_entry)
return 0;
Expand Down
Loading
Loading