diff --git a/.gitignore b/.gitignore index c69ca20..3839ad4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ build # Now we can place the dump code here and test while expand the Runtime ps2xRuntime/include/ps2_recompiled_functions.h -ps2xRuntime/include/ps2_runtime_macros.h ps2xRuntime/include/ps2_recompiled_stubs.h ps2xRuntime/src/runner/ps2_recompiled_functions.cpp ps2xRuntime/src/runner/register_functions.cpp \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c857681..f57ce0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,7 @@ option(PS2X_RUNTIME OFF) add_subdirectory("ps2xRecomp") -if (PS2X_RUNTIME) - add_subdirectory("ps2xRuntime") -endif() +add_subdirectory("ps2xRuntime") add_subdirectory("ps2xAnalyzer") add_subdirectory("ps2xTest") diff --git a/ps2xAnalyzer/CMakeLists.txt b/ps2xAnalyzer/CMakeLists.txt index 2b8afdf..b076eeb 100644 --- a/ps2xAnalyzer/CMakeLists.txt +++ b/ps2xAnalyzer/CMakeLists.txt @@ -17,7 +17,7 @@ target_include_directories(ps2_analyzer PRIVATE target_link_libraries(ps2_analyzer PRIVATE fmt::fmt - ps2_recomp + ps2_recomp_lib ) install(TARGETS ps2_analyzer diff --git a/ps2xRecomp/CMakeLists.txt b/ps2xRecomp/CMakeLists.txt index 93f7e6e..b18cd37 100644 --- a/ps2xRecomp/CMakeLists.txt +++ b/ps2xRecomp/CMakeLists.txt @@ -29,45 +29,44 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(fmt) -file(GLOB_RECURSE PS2RECOMP_SOURCES - "src/*.cpp" +file(GLOB_RECURSE PS2RECOMP_LIB_SOURCES CONFIGURE_DEPENDS + src/lib/*.cpp ) -file(GLOB_RECURSE PS2RECOMP_HEADERS - "include/*.h" - "include/*.hpp" +file(GLOB_RECURSE PS2RECOMP_HEADERS CONFIGURE_DEPENDS + include/*.h + include/*.hpp ) -add_executable(ps2recomp ${PS2RECOMP_SOURCES}) +add_library(ps2_recomp_lib STATIC ${PS2RECOMP_LIB_SOURCES} ${PS2RECOMP_HEADERS}) -add_library(ps2_recomp STATIC ${PS2RECOMP_SOURCES}) - -target_include_directories(ps2recomp PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/../ps2xRuntime/include - ${elfio_SOURCE_DIR} -) - -target_include_directories(ps2_recomp PUBLIC +target_include_directories(ps2_recomp_lib +PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${elfio_SOURCE_DIR} -) -target_include_directories(ps2_recomp PRIVATE +PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ps2xRuntime/include ) -target_link_libraries(ps2recomp PRIVATE +target_link_libraries(ps2_recomp_lib +PUBLIC fmt::fmt toml11::toml11 ) -target_link_libraries(ps2_recomp PUBLIC - fmt::fmt - toml11::toml11 +file(GLOB_RECURSE PS2RECOMP_EXE_SOURCES CONFIGURE_DEPENDS + src/runner/*.cpp ) -install(TARGETS ps2recomp ps2_recomp +add_executable(ps2_recomp ${PS2RECOMP_EXE_SOURCES}) + +target_link_libraries(ps2_recomp +PRIVATE + ps2_recomp_lib +) + +install(TARGETS ps2_recomp ps2_recomp_lib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib diff --git a/ps2xRecomp/include/ps2recomp/code_generator.h b/ps2xRecomp/include/ps2recomp/code_generator.h index 5aa3280..2c950d8 100644 --- a/ps2xRecomp/include/ps2recomp/code_generator.h +++ b/ps2xRecomp/include/ps2recomp/code_generator.h @@ -33,7 +33,6 @@ namespace ps2recomp std::string generateFunction(const Function &function, const std::vector &instructions, const bool &useHeaders); std::string generateFunctionRegistration(const std::vector &functions, const std::map &stubs); - std::string generateMacroHeader(); std::string handleBranchDelaySlots(const Instruction &branchInst, const Instruction &delaySlot, const Function &function, const std::unordered_set &internalTargets); diff --git a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h index 89dc6d0..74e28d9 100644 --- a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h +++ b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h @@ -47,7 +47,6 @@ namespace ps2recomp void discoverAdditionalEntryPoints(); bool shouldSkipFunction(const std::string &name) const; bool isStubFunction(const std::string &name) const; - std::string generateRuntimeHeader() const; bool generateFunctionHeader(); bool generateStubHeader(); bool writeToFile(const std::string &path, const std::string &content); diff --git a/ps2xRecomp/src/code_generator.cpp b/ps2xRecomp/src/lib/code_generator.cpp similarity index 88% rename from ps2xRecomp/src/code_generator.cpp rename to ps2xRecomp/src/lib/code_generator.cpp index 1afb7ff..e082d85 100644 --- a/ps2xRecomp/src/code_generator.cpp +++ b/ps2xRecomp/src/lib/code_generator.cpp @@ -316,268 +316,6 @@ namespace ps2recomp CodeGenerator::~CodeGenerator() = default; - std::string CodeGenerator::generateMacroHeader() - { - std::stringstream ss; - - ss << "#ifndef PS2_RUNTIME_MACROS_H\n"; - ss << "#define PS2_RUNTIME_MACROS_H\n\n"; - ss << "#include \n"; - ss << "#include // For SSE/AVX intrinsics\n\n"; - ss << "#include \n\n"; - ss << "inline uint32_t ps2_clz32(uint32_t val) {\n"; - ss << "#if defined(_MSC_VER)\n"; - ss << " unsigned long idx;\n"; - ss << " if (_BitScanReverse(&idx, val)) {\n"; - ss << " return 31u - idx;\n"; - ss << " }\n"; - ss << " return 32u;\n"; - ss << "#else\n"; - ss << " return val == 0 ? 32u : (uint32_t)__builtin_clz(val);\n"; - ss << "#endif\n"; - ss << "}\n\n"; - - ss << "// Basic MIPS arithmetic operations\n"; - ss << "#define ADD32(a, b) ((uint32_t)((a) + (b)))\n"; - ss << "#define ADD32_OV(rs, rt, result32, overflow) \ - do { \ - int32_t _a = (int32_t)(rs); \ - int32_t _b = (int32_t)(rt); \ - int32_t _r = _a + _b; \ - overflow = (((_a ^ _b) >= 0) && ((_a ^ _r) < 0)); \ - result32 = (uint32_t)_r; \ - } while (0);\n"; - ss << "#define SUB32(a, b) ((uint32_t)((a) - (b)))\n"; - ss << "#define SUB32_OV(rs, rt, result32, overflow) \ - do { \ - int32_t _a = (int32_t)(rs); \ - int32_t _b = (int32_t)(rt); \ - int32_t _r = _a - _b; \ - overflow = (((_a ^ _b) < 0) && ((_a ^ _r) < 0)); \ - result32 = (uint32_t)_r; \ - } while (0);\n"; - ss << "#define MUL32(a, b) ((uint32_t)((a) * (b)))\n"; - ss << "#define DIV32(a, b) ((uint32_t)((a) / (b)))\n"; - ss << "#define AND32(a, b) ((uint32_t)((a) & (b)))\n"; - ss << "#define OR32(a, b) ((uint32_t)((a) | (b)))\n"; - ss << "#define XOR32(a, b) ((uint32_t)((a) ^ (b)))\n"; - ss << "#define NOR32(a, b) ((uint32_t)(~((a) | (b))))\n"; - ss << "#define SLL32(a, b) ((uint32_t)((a) << (b)))\n"; - ss << "#define SRL32(a, b) ((uint32_t)((a) >> (b)))\n"; - ss << "#define SRA32(a, b) ((uint32_t)((int32_t)(a) >> (b)))\n"; - ss << "#define SLT32(a, b) ((uint32_t)((int32_t)(a) < (int32_t)(b) ? 1 : 0))\n"; - ss << "#define SLTU32(a, b) ((uint32_t)((a) < (b) ? 1 : 0))\n\n"; - - ss << "// PS2-specific 128-bit MMI operations\n"; - ss << "#define PS2_PEXTLW(a, b) _mm_unpacklo_epi32((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PEXTUW(a, b) _mm_unpackhi_epi32((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PEXTLH(a, b) _mm_unpacklo_epi16((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PEXTUH(a, b) _mm_unpackhi_epi16((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PEXTLB(a, b) _mm_unpacklo_epi8((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PEXTUB(a, b) _mm_unpackhi_epi8((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PADDW(a, b) _mm_add_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PSUBW(a, b) _mm_sub_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PMAXW(a, b) _mm_max_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PMINW(a, b) _mm_min_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PADDH(a, b) _mm_add_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PSUBH(a, b) _mm_sub_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PMAXH(a, b) _mm_max_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PMINH(a, b) _mm_min_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PADDB(a, b) _mm_add_epi8((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PSUBB(a, b) _mm_sub_epi8((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PAND(a, b) _mm_and_si128((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_POR(a, b) _mm_or_si128((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PXOR(a, b) _mm_xor_si128((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PNOR(a, b) _mm_xor_si128(_mm_or_si128((__m128i)(a), (__m128i)(b)), _mm_set1_epi32(0xFFFFFFFF))\n\n"; - - ss << "// PS2 VU (Vector Unit) operations\n"; - ss << "#define PS2_VADD(a, b) _mm_add_ps((__m128)(a), (__m128)(b))\n"; - ss << "#define PS2_VSUB(a, b) _mm_sub_ps((__m128)(a), (__m128)(b))\n"; - ss << "#define PS2_VMUL(a, b) _mm_mul_ps((__m128)(a), (__m128)(b))\n"; - ss << "#define PS2_VDIV(a, b) _mm_div_ps((__m128)(a), (__m128)(b))\n"; - ss << "#define PS2_VMULQ(a, q) _mm_mul_ps((__m128)(a), _mm_set1_ps(q))\n\n"; - - ss << "// Memory access helpers\n"; - ss << "#define READ8(addr) (*(uint8_t*)((rdram) + ((addr) & PS2_RAM_MASK)))\n"; - ss << "#define READ16(addr) (*(uint16_t*)((rdram) + ((addr) & PS2_RAM_MASK)))\n"; - ss << "#define READ32(addr) (*(uint32_t*)((rdram) + ((addr) & PS2_RAM_MASK)))\n"; - ss << "#define READ64(addr) (*(uint64_t*)((rdram) + ((addr) & PS2_RAM_MASK)))\n"; - ss << "#define READ128(addr) (*((__m128i*)((rdram) + ((addr) & PS2_RAM_MASK))))\n"; - ss << "#define WRITE8(addr, val) (*(uint8_t*)((rdram) + ((addr) & PS2_RAM_MASK)) = (val))\n"; - ss << "#define WRITE16(addr, val) (*(uint16_t*)((rdram) + ((addr) & PS2_RAM_MASK)) = (val))\n"; - ss << "#define WRITE32(addr, val) (*(uint32_t*)((rdram) + ((addr) & PS2_RAM_MASK)) = (val))\n"; - ss << "#define WRITE64(addr, val) (*(uint64_t*)((rdram) + ((addr) & PS2_RAM_MASK)) = (val))\n"; - ss << "#define WRITE128(addr, val) (*((__m128i*)((rdram) + ((addr) & PS2_RAM_MASK))) = (val))\n\n"; - - // ss << "// Function lookup for indirect calls\n"; - // ss << "#define LOOKUP_FUNC(addr, runtime) runtime->lookupFunction(addr)\n\n"; - - // Packed Compare Greater Than (PCGT) - ss << "#define PS2_PCGTW(a, b) _mm_cmpgt_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PCGTH(a, b) _mm_cmpgt_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PCGTB(a, b) _mm_cmpgt_epi8((__m128i)(a), (__m128i)(b))\n"; - - // Packed Compare Equal (PCEQ) - ss << "#define PS2_PCEQW(a, b) _mm_cmpeq_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PCEQH(a, b) _mm_cmpeq_epi16((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PCEQB(a, b) _mm_cmpeq_epi8((__m128i)(a), (__m128i)(b))\n"; - - // Packed Absolute (PABS) - ss << "#define PS2_PABSW(a) _mm_abs_epi32((__m128i)(a))\n"; - ss << "#define PS2_PABSH(a) _mm_abs_epi16((__m128i)(a))\n"; - ss << "#define PS2_PABSB(a) _mm_abs_epi8((__m128i)(a))\n"; - - // Packed Pack (PPAC) - Packs larger elements into smaller ones - ss << "#define PS2_PPACW(a, b) _mm_packs_epi32((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PPACH(a, b) _mm_packs_epi16((__m128i)(b), (__m128i)(a))\n"; - ss << "#define PS2_PPACB(a, b) _mm_packus_epi16(_mm_packs_epi32((__m128i)(b), (__m128i)(a)), _mm_setzero_si128())\n"; - - // Packed Interleave (PINT) - ss << "#define PS2_PINTH(a, b) _mm_unpacklo_epi16(_mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0)))\n"; - ss << "#define PS2_PINTEH(a, b) _mm_unpackhi_epi16(_mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0)))\n"; - - // Packed Multiply-Add (PMADD) - ss << "#define PS2_PMADDW(a, b) _mm_add_epi32(_mm_mullo_epi32(_mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(1,0,3,2)), _mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(1,0,3,2))), _mm_mullo_epi32(_mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0))))\n"; - - // Packed Variable Shifts - ss << "#define PS2_PSLLVW(a, b) _mm_custom_sllv_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PSRLVW(a, b) _mm_custom_srlv_epi32((__m128i)(a), (__m128i)(b))\n"; - ss << "#define PS2_PSRAVW(a, b) _mm_custom_srav_epi32((__m128i)(a), (__m128i)(b))\n"; - - // Helper function declarations for custom variable shifts - ss << "inline __m128i _mm_custom_sllv_epi32(__m128i a, __m128i count) {\n"; - ss << " int32_t a_arr[4], count_arr[4], result[4];\n"; - ss << " _mm_storeu_si128((__m128i*)a_arr, a);\n"; - ss << " _mm_storeu_si128((__m128i*)count_arr, count);\n"; - ss << " for (int i = 0; i < 4; i++) {\n"; - ss << " result[i] = a_arr[i] << (count_arr[i] & 0x1F);\n"; - ss << " }\n"; - ss << " return _mm_loadu_si128((__m128i*)result);\n"; - ss << "}\n\n"; - - ss << "inline __m128i _mm_custom_srlv_epi32(__m128i a, __m128i count) {\n"; - ss << " int32_t a_arr[4], count_arr[4], result[4];\n"; - ss << " _mm_storeu_si128((__m128i*)a_arr, a);\n"; - ss << " _mm_storeu_si128((__m128i*)count_arr, count);\n"; - ss << " for (int i = 0; i < 4; i++) {\n"; - ss << " result[i] = (uint32_t)a_arr[i] >> (count_arr[i] & 0x1F);\n"; - ss << " }\n"; - ss << " return _mm_loadu_si128((__m128i*)result);\n"; - ss << "}\n\n"; - - ss << "inline __m128i _mm_custom_srav_epi32(__m128i a, __m128i count) {\n"; - ss << " int32_t a_arr[4], count_arr[4], result[4];\n"; - ss << " _mm_storeu_si128((__m128i*)a_arr, a);\n"; - ss << " _mm_storeu_si128((__m128i*)count_arr, count);\n"; - ss << " for (int i = 0; i < 4; i++) {\n"; - ss << " result[i] = a_arr[i] >> (count_arr[i] & 0x1F);\n"; - ss << " }\n"; - ss << " return _mm_loadu_si128((__m128i*)result);\n"; - ss << "}\n\n"; - - // PMFHL function implementations - ss << "#define PS2_PMFHL_LW(hi, lo) _mm_unpacklo_epi64(lo, hi)\n"; - ss << "#define PS2_PMFHL_UW(hi, lo) _mm_unpackhi_epi64(lo, hi)\n"; - ss << "#define PS2_PMFHL_SLW(hi, lo) _mm_packs_epi32(lo, hi)\n"; - ss << "#define PS2_PMFHL_LH(hi, lo) _mm_shuffle_epi32(_mm_packs_epi32(lo, hi), _MM_SHUFFLE(3,1,2,0))\n"; - ss << "#define PS2_PMFHL_SH(hi, lo) _mm_shufflehi_epi16(_mm_shufflelo_epi16(_mm_packs_epi32(lo, hi), _MM_SHUFFLE(3,1,2,0)), _MM_SHUFFLE(3,1,2,0))\n"; - - ss << "// FPU (COP1) operations\n"; - ss << "#define FPU_ADD_S(a, b) ((float)(a) + (float)(b))\n"; - ss << "#define FPU_SUB_S(a, b) ((float)(a) - (float)(b))\n"; - ss << "#define FPU_MUL_S(a, b) ((float)(a) * (float)(b))\n"; - ss << "#define FPU_DIV_S(a, b) ((float)(a) / (float)(b))\n"; - ss << "#define FPU_SQRT_S(a) sqrtf((float)(a))\n"; - ss << "#define FPU_ABS_S(a) fabsf((float)(a))\n"; - ss << "#define FPU_MOV_S(a) ((float)(a))\n"; - ss << "#define FPU_NEG_S(a) (-(float)(a))\n"; - ss << "#define FPU_ROUND_L_S(a) ((int64_t)roundf((float)(a)))\n"; - ss << "#define FPU_TRUNC_L_S(a) ((int64_t)(float)(a))\n"; - ss << "#define FPU_CEIL_L_S(a) ((int64_t)ceilf((float)(a)))\n"; - ss << "#define FPU_FLOOR_L_S(a) ((int64_t)floorf((float)(a)))\n"; - ss << "#define FPU_ROUND_W_S(a) ((int32_t)roundf((float)(a)))\n"; - ss << "#define FPU_TRUNC_W_S(a) ((int32_t)(float)(a))\n"; - ss << "#define FPU_CEIL_W_S(a) ((int32_t)ceilf((float)(a)))\n"; - ss << "#define FPU_FLOOR_W_S(a) ((int32_t)floorf((float)(a)))\n"; - ss << "#define FPU_CVT_S_W(a) ((float)(int32_t)(a))\n"; - ss << "#define FPU_CVT_S_L(a) ((float)(int64_t)(a))\n"; - ss << "#define FPU_CVT_W_S(a) ((int32_t)(float)(a))\n"; - ss << "#define FPU_CVT_L_S(a) ((int64_t)(float)(a))\n"; - ss << "#define FPU_C_F_S(a, b) (0)\n"; - ss << "#define FPU_C_UN_S(a, b) (isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_EQ_S(a, b) ((float)(a) == (float)(b))\n"; - ss << "#define FPU_C_UEQ_S(a, b) ((float)(a) == (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_OLT_S(a, b) ((float)(a) < (float)(b))\n"; - ss << "#define FPU_C_ULT_S(a, b) ((float)(a) < (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_OLE_S(a, b) ((float)(a) <= (float)(b))\n"; - ss << "#define FPU_C_ULE_S(a, b) ((float)(a) <= (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_SF_S(a, b) (0)\n"; - ss << "#define FPU_C_NGLE_S(a, b) (isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_SEQ_S(a, b) ((float)(a) == (float)(b))\n"; - ss << "#define FPU_C_NGL_S(a, b) ((float)(a) == (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_LT_S(a, b) ((float)(a) < (float)(b))\n"; - ss << "#define FPU_C_NGE_S(a, b) ((float)(a) < (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n"; - ss << "#define FPU_C_LE_S(a, b) ((float)(a) <= (float)(b))\n"; - ss << "#define FPU_C_NGT_S(a, b) ((float)(a) <= (float)(b) || isnan((float)(a)) || isnan((float)(b)))\n\n"; - - ss << "#define PS2_QFSRV(rs, rt, sa) _mm_or_si128(_mm_srl_epi32(rt, _mm_cvtsi32_si128(sa)), _mm_sll_epi32(rs, _mm_cvtsi32_si128(32 - sa)))\n"; - ss << "#define PS2_PCPYLD(rs, rt) _mm_unpacklo_epi64(rt, rs)\n"; - ss << "#define PS2_PEXEH(rs) _mm_shufflelo_epi16(_mm_shufflehi_epi16(rs, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1))\n"; - ss << "#define PS2_PEXEW(rs) _mm_shuffle_epi32(rs, _MM_SHUFFLE(2, 3, 0, 1))\n"; - ss << "#define PS2_PROT3W(rs) _mm_shuffle_epi32(rs, _MM_SHUFFLE(0, 3, 2, 1))\n"; - - ss << "// Additional VU0 operations\n"; - ss << "#define PS2_VSQRT(x) sqrtf(x)\n"; - ss << "#define PS2_VRSQRT(x) (1.0f / sqrtf(x))\n"; - ss << "#define PS2_VCALLMS(addr) // VU0 microprogram calls not supported directly\n"; - ss << "#define PS2_VCALLMSR(reg) // VU0 microprogram calls not supported directly\n"; - - ss << "#define GPR_U32(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0U : ctx_ptr->r[reg_idx].m128i_u32[0])\n"; - ss << "#define GPR_S32(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0 : ctx_ptr->r[reg_idx].m128i_i32[0])\n"; - ss << "#define GPR_U64(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0ULL : ctx_ptr->r[reg_idx].m128i_u64[0])\n"; - ss << "#define GPR_S64(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0LL : ctx_ptr->r[reg_idx].m128i_i64[0])\n"; - ss << "#define GPR_VEC(ctx_ptr, reg_idx) ((reg_idx == 0) ? _mm_setzero_si128() : ctx_ptr->r[reg_idx])\n"; - - ss << "#define SET_GPR_U32(ctx_ptr, reg_idx, val) \\\n"; - ss << " do \\\n"; - ss << " { \\\n"; - ss << " if (reg_idx != 0) \\\n"; - ss << " ctx_ptr->r[reg_idx] = _mm_set_epi32(0, 0, 0, (val)); \\\n"; - ss << " } while (0)\n"; - - ss << "#define SET_GPR_S32(ctx_ptr, reg_idx, val) \\\n"; - ss << " do \\\n"; - ss << " { \\\n"; - ss << " if (reg_idx != 0) \\\n"; - ss << " ctx_ptr->r[reg_idx] = _mm_set_epi32(0, 0, 0, (val)); \\\n"; - ss << " } while (0)\n"; - - ss << "#define SET_GPR_U64(ctx_ptr, reg_idx, val) \\\n"; - ss << " do \\\n"; - ss << " { \\\n"; - ss << " if (reg_idx != 0) \\\n"; - ss << " ctx_ptr->r[reg_idx] = _mm_set_epi64x(0, (val)); \\\n"; - ss << " } while (0)\n"; - - ss << "#define SET_GPR_S64(ctx_ptr, reg_idx, val) \\\n"; - ss << " do \\\n"; - ss << " { \\\n"; - ss << " if (reg_idx != 0) \\\n"; - ss << " ctx_ptr->r[reg_idx] = _mm_set_epi64x(0, (val)); \\\n"; - ss << " } while (0)\n"; - - ss << "#define SET_GPR_VEC(ctx_ptr, reg_idx, val) \\\n"; - ss << " do \\\n"; - ss << " { \\\n"; - ss << " if (reg_idx != 0) \\\n"; - ss << " ctx_ptr->r[reg_idx] = (val); \\\n"; - ss << " } while (0)\n"; - - ss << "#endif // PS2_RUNTIME_MACROS_H\n"; - - return ss.str(); - } - std::unordered_set CodeGenerator::collectInternalBranchTargets( const Function &function, const std::vector &instructions) { diff --git a/ps2xRecomp/src/config_manager.cpp b/ps2xRecomp/src/lib/config_manager.cpp similarity index 100% rename from ps2xRecomp/src/config_manager.cpp rename to ps2xRecomp/src/lib/config_manager.cpp diff --git a/ps2xRecomp/src/elf_parser.cpp b/ps2xRecomp/src/lib/elf_parser.cpp similarity index 100% rename from ps2xRecomp/src/elf_parser.cpp rename to ps2xRecomp/src/lib/elf_parser.cpp diff --git a/ps2xRecomp/src/ps2_recompiler.cpp b/ps2xRecomp/src/lib/ps2_recompiler.cpp similarity index 98% rename from ps2xRecomp/src/ps2_recompiler.cpp rename to ps2xRecomp/src/lib/ps2_recompiler.cpp index 81db3a8..cd817f5 100644 --- a/ps2xRecomp/src/ps2_recompiler.cpp +++ b/ps2xRecomp/src/lib/ps2_recompiler.cpp @@ -161,11 +161,6 @@ namespace ps2recomp { std::cout << "Recompiling " << m_functions.size() << " functions..." << std::endl; - std::string runtimeHeader = generateRuntimeHeader(); - fs::path runtimeHeaderPath = fs::path(m_config.outputPath) / "ps2_runtime_macros.h"; - - writeToFile(runtimeHeaderPath.string(), runtimeHeader); - size_t processedCount = 0; for (auto &function : m_functions) { @@ -677,11 +672,6 @@ namespace ps2recomp return ps2_runtime_calls::isStubName(name); } - std::string PS2Recompiler::generateRuntimeHeader() const - { - return m_codeGenerator->generateMacroHeader(); - } - bool PS2Recompiler::writeToFile(const std::string &path, const std::string &content) { std::ofstream file(path); diff --git a/ps2xRecomp/src/r5900_decoder.cpp b/ps2xRecomp/src/lib/r5900_decoder.cpp similarity index 100% rename from ps2xRecomp/src/r5900_decoder.cpp rename to ps2xRecomp/src/lib/r5900_decoder.cpp diff --git a/ps2xRecomp/src/main.cpp b/ps2xRecomp/src/runner/main.cpp similarity index 100% rename from ps2xRecomp/src/main.cpp rename to ps2xRecomp/src/runner/main.cpp diff --git a/ps2xRuntime/CMakeLists.txt b/ps2xRuntime/CMakeLists.txt index 4243de8..d2f4412 100644 --- a/ps2xRuntime/CMakeLists.txt +++ b/ps2xRuntime/CMakeLists.txt @@ -42,8 +42,11 @@ target_include_directories(ps2_runtime PUBLIC ) target_link_libraries(ps2_runtime PRIVATE raylib) -target_link_libraries(ps2EntryRunner PRIVATE raylib) -target_link_libraries(ps2EntryRunner PRIVATE ps2_runtime) +target_link_libraries(ps2EntryRunner +PRIVATE + ps2_runtime + raylib +) # Work around WinAPI vs raylib symbol clash for CloseWindow on x64 if (MSVC) diff --git a/ps2xRuntime/output/ps2_runtime_macros.h b/ps2xRuntime/include/ps2_runtime_macros.h similarity index 89% rename from ps2xRuntime/output/ps2_runtime_macros.h rename to ps2xRuntime/include/ps2_runtime_macros.h index bf02183..fd5f828 100644 --- a/ps2xRuntime/output/ps2_runtime_macros.h +++ b/ps2xRuntime/include/ps2_runtime_macros.h @@ -1,11 +1,8 @@ #ifndef PS2_RUNTIME_MACROS_H #define PS2_RUNTIME_MACROS_H - #include #include // For SSE/AVX intrinsics - #include - inline uint32_t ps2_clz32(uint32_t val) { #if defined(_MSC_VER) unsigned long idx; @@ -20,9 +17,23 @@ inline uint32_t ps2_clz32(uint32_t val) { // Basic MIPS arithmetic operations #define ADD32(a, b) ((uint32_t)((a) + (b))) -#define ADD32_OV(rs, rt, result32, overflow) do { int32_t _a = (int32_t)(rs); int32_t _b = (int32_t)(rt); int32_t _r = _a + _b; overflow = (((_a ^ _b) >= 0) && ((_a ^ _r) < 0)); result32 = (uint32_t)_r; } while (0); +#define ADD32_OV(rs, rt, result32, overflow) \ + do { \ + int32_t _a = (int32_t)(rs); \ + int32_t _b = (int32_t)(rt); \ + int32_t _r = _a + _b; \ + overflow = (((_a ^ _b) >= 0) && ((_a ^ _r) < 0)); \ + result32 = (uint32_t)_r; \ + } while (0); #define SUB32(a, b) ((uint32_t)((a) - (b))) -#define SUB32_OV(rs, rt, result32, overflow) do { int32_t _a = (int32_t)(rs); int32_t _b = (int32_t)(rt); int32_t _r = _a - _b; overflow = (((_a ^ _b) < 0) && ((_a ^ _r) < 0)); result32 = (uint32_t)_r; } while (0); +#define SUB32_OV(rs, rt, result32, overflow) \ + do { \ + int32_t _a = (int32_t)(rs); \ + int32_t _b = (int32_t)(rt); \ + int32_t _r = _a - _b; \ + overflow = (((_a ^ _b) < 0) && ((_a ^ _r) < 0)); \ + result32 = (uint32_t)_r; \ + } while (0); #define MUL32(a, b) ((uint32_t)((a) * (b))) #define DIV32(a, b) ((uint32_t)((a) / (b))) #define AND32(a, b) ((uint32_t)((a) & (b))) @@ -76,24 +87,39 @@ inline uint32_t ps2_clz32(uint32_t val) { #define WRITE64(addr, val) (*(uint64_t*)((rdram) + ((addr) & PS2_RAM_MASK)) = (val)) #define WRITE128(addr, val) (*((__m128i*)((rdram) + ((addr) & PS2_RAM_MASK))) = (val)) +// Packed Compare Greater Than (PCGT) #define PS2_PCGTW(a, b) _mm_cmpgt_epi32((__m128i)(a), (__m128i)(b)) #define PS2_PCGTH(a, b) _mm_cmpgt_epi16((__m128i)(a), (__m128i)(b)) #define PS2_PCGTB(a, b) _mm_cmpgt_epi8((__m128i)(a), (__m128i)(b)) + +// Packed Compare Equal (PCEQ) #define PS2_PCEQW(a, b) _mm_cmpeq_epi32((__m128i)(a), (__m128i)(b)) #define PS2_PCEQH(a, b) _mm_cmpeq_epi16((__m128i)(a), (__m128i)(b)) #define PS2_PCEQB(a, b) _mm_cmpeq_epi8((__m128i)(a), (__m128i)(b)) + +// Packed Absolute (PABS) #define PS2_PABSW(a) _mm_abs_epi32((__m128i)(a)) #define PS2_PABSH(a) _mm_abs_epi16((__m128i)(a)) #define PS2_PABSB(a) _mm_abs_epi8((__m128i)(a)) + +// Packed Pack (PPAC) - Packs larger elements into smaller ones #define PS2_PPACW(a, b) _mm_packs_epi32((__m128i)(b), (__m128i)(a)) #define PS2_PPACH(a, b) _mm_packs_epi16((__m128i)(b), (__m128i)(a)) #define PS2_PPACB(a, b) _mm_packus_epi16(_mm_packs_epi32((__m128i)(b), (__m128i)(a)), _mm_setzero_si128()) + +// Packed Interleave (PINT) #define PS2_PINTH(a, b) _mm_unpacklo_epi16(_mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0))) #define PS2_PINTEH(a, b) _mm_unpackhi_epi16(_mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0))) + +// Packed Multiply-Add (PMADD) #define PS2_PMADDW(a, b) _mm_add_epi32(_mm_mullo_epi32(_mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(1,0,3,2)), _mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(1,0,3,2))), _mm_mullo_epi32(_mm_shuffle_epi32((__m128i)(a), _MM_SHUFFLE(3,2,1,0)), _mm_shuffle_epi32((__m128i)(b), _MM_SHUFFLE(3,2,1,0)))) + +// Packed Variable Shifts #define PS2_PSLLVW(a, b) _mm_custom_sllv_epi32((__m128i)(a), (__m128i)(b)) #define PS2_PSRLVW(a, b) _mm_custom_srlv_epi32((__m128i)(a), (__m128i)(b)) #define PS2_PSRAVW(a, b) _mm_custom_srav_epi32((__m128i)(a), (__m128i)(b)) + +// Helper function declarations for custom variable shifts inline __m128i _mm_custom_sllv_epi32(__m128i a, __m128i count) { int32_t a_arr[4], count_arr[4], result[4]; _mm_storeu_si128((__m128i*)a_arr, a); @@ -124,11 +150,13 @@ inline __m128i _mm_custom_srav_epi32(__m128i a, __m128i count) { return _mm_loadu_si128((__m128i*)result); } +// PMFHL function implementations #define PS2_PMFHL_LW(hi, lo) _mm_unpacklo_epi64(lo, hi) #define PS2_PMFHL_UW(hi, lo) _mm_unpackhi_epi64(lo, hi) #define PS2_PMFHL_SLW(hi, lo) _mm_packs_epi32(lo, hi) #define PS2_PMFHL_LH(hi, lo) _mm_shuffle_epi32(_mm_packs_epi32(lo, hi), _MM_SHUFFLE(3,1,2,0)) #define PS2_PMFHL_SH(hi, lo) _mm_shufflehi_epi16(_mm_shufflelo_epi16(_mm_packs_epi32(lo, hi), _MM_SHUFFLE(3,1,2,0)), _MM_SHUFFLE(3,1,2,0)) + // FPU (COP1) operations #define FPU_ADD_S(a, b) ((float)(a) + (float)(b)) #define FPU_SUB_S(a, b) ((float)(a) - (float)(b)) @@ -172,44 +200,52 @@ inline __m128i _mm_custom_srav_epi32(__m128i a, __m128i count) { #define PS2_PEXEH(rs) _mm_shufflelo_epi16(_mm_shufflehi_epi16(rs, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)) #define PS2_PEXEW(rs) _mm_shuffle_epi32(rs, _MM_SHUFFLE(2, 3, 0, 1)) #define PS2_PROT3W(rs) _mm_shuffle_epi32(rs, _MM_SHUFFLE(0, 3, 2, 1)) + // Additional VU0 operations #define PS2_VSQRT(x) sqrtf(x) #define PS2_VRSQRT(x) (1.0f / sqrtf(x)) #define PS2_VCALLMS(addr) // VU0 microprogram calls not supported directly #define PS2_VCALLMSR(reg) // VU0 microprogram calls not supported directly + #define GPR_U32(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0U : ctx_ptr->r[reg_idx].m128i_u32[0]) #define GPR_S32(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0 : ctx_ptr->r[reg_idx].m128i_i32[0]) #define GPR_U64(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0ULL : ctx_ptr->r[reg_idx].m128i_u64[0]) #define GPR_S64(ctx_ptr, reg_idx) ((reg_idx == 0) ? 0LL : ctx_ptr->r[reg_idx].m128i_i64[0]) #define GPR_VEC(ctx_ptr, reg_idx) ((reg_idx == 0) ? _mm_setzero_si128() : ctx_ptr->r[reg_idx]) + #define SET_GPR_U32(ctx_ptr, reg_idx, val) \ do \ { \ if (reg_idx != 0) \ ctx_ptr->r[reg_idx] = _mm_set_epi32(0, 0, 0, (val)); \ } while (0) + #define SET_GPR_S32(ctx_ptr, reg_idx, val) \ do \ { \ if (reg_idx != 0) \ ctx_ptr->r[reg_idx] = _mm_set_epi32(0, 0, 0, (val)); \ } while (0) + #define SET_GPR_U64(ctx_ptr, reg_idx, val) \ do \ { \ if (reg_idx != 0) \ ctx_ptr->r[reg_idx] = _mm_set_epi64x(0, (val)); \ } while (0) + #define SET_GPR_S64(ctx_ptr, reg_idx, val) \ do \ { \ if (reg_idx != 0) \ ctx_ptr->r[reg_idx] = _mm_set_epi64x(0, (val)); \ } while (0) + #define SET_GPR_VEC(ctx_ptr, reg_idx, val) \ do \ { \ if (reg_idx != 0) \ ctx_ptr->r[reg_idx] = (val); \ } while (0) + #endif // PS2_RUNTIME_MACROS_H diff --git a/ps2xTest/CMakeLists.txt b/ps2xTest/CMakeLists.txt index cf35bde..18c9a96 100644 --- a/ps2xTest/CMakeLists.txt +++ b/ps2xTest/CMakeLists.txt @@ -17,5 +17,5 @@ target_include_directories(ps2x_tests PRIVATE ) target_link_libraries(ps2x_tests PRIVATE - ps2_recomp + ps2_recomp_lib )