From e5ce5614499233b27dcb25c34f98ce7e4442740d Mon Sep 17 00:00:00 2001 From: k2154 Date: Fri, 18 Jul 2025 22:17:04 +0900 Subject: [PATCH] Android project - Change calleesaved x86(rbp,rbx,r12,r13,r14,r15) => arm64(19,20,21,22,23,24) --- app/src/main/cpp/common/arm64/AsmHelpers.cpp | 36 ++--- app/src/main/cpp/common/arm64/AsmHelpers.h | 8 +- app/src/main/cpp/common/emitter/x86types.h | 4 + app/src/main/cpp/pcsx2/x86/iCore.cpp | 6 +- app/src/main/cpp/pcsx2/x86/iCore.h | 14 -- app/src/main/cpp/pcsx2/x86/ix86-32/iCore.cpp | 124 +++++++++--------- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 2 +- app/src/main/cpp/pcsx2/x86/microVU_IR.h | 10 +- app/src/main/cpp/pcsx2/x86/microVU_Misc.h | 5 - 9 files changed, 92 insertions(+), 117 deletions(-) diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.cpp b/app/src/main/cpp/common/arm64/AsmHelpers.cpp index e76cd69..38243a9 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.cpp +++ b/app/src/main/cpp/common/arm64/AsmHelpers.cpp @@ -170,21 +170,8 @@ void armEmitJmp(const void* ptr, bool force_inline) } } -//a64::RegList g_cpuList(a64::x3.GetBit() | a64::x5.GetBit() | a64::x12.GetBit() | a64::x13.GetBit() | a64::x14.GetBit() | a64::x15.GetBit()); -//a64::CPURegList g_caller_regs = a64::CPURegList(a64::CPURegister::kRegister, a64::kXRegSize, g_cpuList); - -void armEmitCall(const void* ptr, bool force_inline, bool reg_move) +void armEmitCall(const void* ptr, bool force_inline) { - if(reg_move) { -// armAsm->PushCPURegList(g_caller_regs); - armAsm->Mov(RSTATE_x19, a64::x3); - armAsm->Mov(RSTATE_x20, a64::x5); - armAsm->Mov(RSTATE_x21, a64::x12); - armAsm->Mov(RSTATE_x22, a64::x13); - armAsm->Mov(RSTATE_x23, a64::x14); - armAsm->Mov(RSTATE_x24, a64::x15); - } - s64 displacement = GetPCDisplacement(armGetCurrentCodePointer(), ptr); bool use_blr = !vixl::IsInt26(displacement); if (use_blr && armConstantPool && !force_inline) @@ -206,16 +193,6 @@ void armEmitCall(const void* ptr, bool force_inline, bool reg_move) a64::SingleEmissionCheckScope guard(armAsm); armAsm->bl(displacement); } - - if(reg_move) { -// armAsm->PopCPURegList(g_caller_regs); - armAsm->Mov(a64::x3, RSTATE_x19); - armAsm->Mov(a64::x5, RSTATE_x20); - armAsm->Mov(a64::x12, RSTATE_x21); - armAsm->Mov(a64::x13, RSTATE_x22); - armAsm->Mov(a64::x14, RSTATE_x23); - armAsm->Mov(a64::x15, RSTATE_x24); - } } void armEmitCbnz(const a64::Register& reg, const void* ptr) @@ -355,12 +332,17 @@ bool armIsCalleeSavedRegister(int reg) bool armIsCallerSaved(int id) { -#ifdef _WIN32 - // The x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile. - return (id <= 2 || (id >= 8 && id <= 11)); +#if defined(__ANDROID__) + // 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + return (id <= 15); #else + #ifdef _WIN32 + // The x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile. + return (id <= 2 || (id >= 8 && id <= 11)); + #else // rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 are scratch registers. return (id <= 2 || id == 6 || id == 7 || (id >= 8 && id <= 11)); + #endif #endif } diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.h b/app/src/main/cpp/common/arm64/AsmHelpers.h index 78b9191..6ed2ff7 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.h +++ b/app/src/main/cpp/common/arm64/AsmHelpers.h @@ -71,9 +71,9 @@ namespace a64 = vixl::aarch64; #define RSTATE_x23 a64::x23 #define RSTATE_x24 a64::x24 #define RFASTMEMBASE a64::x25 -#define RSTATE_FPU a64::x26 -#define RSTATE_PSX a64::x27 -#define RSTATE_CPU a64::x28 +#define RSTATE_FPU a64::x27 +#define RSTATE_PSX a64::x28 +#define RSTATE_CPU a64::x29 #define PTR_FPU(field) a64::MemOperand(RSTATE_FPU, offsetof(fpuRegisters, field)) #define PTR_PSX(field) a64::MemOperand(RSTATE_PSX, offsetof(psxRegisters, field)) @@ -121,7 +121,7 @@ u8* armEndBlock(); void armDisassembleAndDumpCode(const void* ptr, size_t size); void armEmitJmp(const void* ptr, bool force_inline = false); -void armEmitCall(const void* ptr, bool force_inline = false, bool reg_move = true); +void armEmitCall(const void* ptr, bool force_inline = false); void armEmitCbnz(const a64::Register& reg, const void* ptr); void armEmitCondBranch(a64::Condition cond, const void* ptr); void armMoveAddressToReg(const a64::Register& reg, const void* addr); diff --git a/app/src/main/cpp/common/emitter/x86types.h b/app/src/main/cpp/common/emitter/x86types.h index 8732641..12fe677 100644 --- a/app/src/main/cpp/common/emitter/x86types.h +++ b/app/src/main/cpp/common/emitter/x86types.h @@ -9,7 +9,11 @@ #include "common/arm64/AsmHelpers.h" static const uint iREGCNT_XMM = 16; +#if defined(__ANDROID__) +static const uint iREGCNT_GPR = 25; +#else static const uint iREGCNT_GPR = 16; +#endif enum XMMSSEType { diff --git a/app/src/main/cpp/pcsx2/x86/iCore.cpp b/app/src/main/cpp/pcsx2/x86/iCore.cpp index 278c5c0..71c2d02 100644 --- a/app/src/main/cpp/pcsx2/x86/iCore.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCore.cpp @@ -46,9 +46,9 @@ bool _isAllocatableX86reg(int x86reg) // if (x86reg == arg1reg.GetId() || x86reg == arg2reg.GetId()) // return false; - // arg3reg is also used for dispatching without fastmem - if (!CHECK_FASTMEM && x86reg == R8X.GetCode()) - return false; +// // arg3reg is also used for dispatching without fastmem +// if (!CHECK_FASTMEM && x86reg == R8X.GetCode()) +// return false; // rbp is used as the fastmem base if (CHECK_FASTMEM && x86reg == 5) diff --git a/app/src/main/cpp/pcsx2/x86/iCore.h b/app/src/main/cpp/pcsx2/x86/iCore.h index 7c690c9..a0bd63d 100644 --- a/app/src/main/cpp/pcsx2/x86/iCore.h +++ b/app/src/main/cpp/pcsx2/x86/iCore.h @@ -37,13 +37,6 @@ #define EEREC_HI (((info) >> 24) & 0xf) #define EEREC_ACC (((info) >> 20) & 0xf) -//#define EEREC_S (((info) >> 8) & 0x1f) -//#define EEREC_T (((info) >> 13) & 0x1f) -//#define EEREC_D (((info) >> 18) & 0x1f) -//#define EEREC_LO (((info) >> 20) & 0x1f) -//#define EEREC_HI (((info) >> 24) & 0x1f) -//#define EEREC_ACC (((info) >> 20) & 0x1f) - #define PROCESS_EE_SET_S(reg) (((reg) << 8) | PROCESS_EE_S) #define PROCESS_EE_SET_T(reg) (((reg) << 12) | PROCESS_EE_T) #define PROCESS_EE_SET_D(reg) (((reg) << 16) | PROCESS_EE_D) @@ -51,13 +44,6 @@ #define PROCESS_EE_SET_HI(reg) (((reg) << 24) | PROCESS_EE_HI) #define PROCESS_EE_SET_ACC(reg) (((reg) << 20) | PROCESS_EE_ACC) -//#define PROCESS_EE_SET_S(reg) (((reg) << 8) | PROCESS_EE_S) -//#define PROCESS_EE_SET_T(reg) (((reg) << 13) | PROCESS_EE_T) -//#define PROCESS_EE_SET_D(reg) (((reg) << 18) | PROCESS_EE_D) -//#define PROCESS_EE_SET_LO(reg) (((reg) << 20) | PROCESS_EE_LO) -//#define PROCESS_EE_SET_HI(reg) (((reg) << 24) | PROCESS_EE_HI) -//#define PROCESS_EE_SET_ACC(reg) (((reg) << 20) | PROCESS_EE_ACC) - // special info not related to above flags #define PROCESS_CONSTS 1 #define PROCESS_CONSTT 2 diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iCore.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iCore.cpp index c27d1b3..f369892 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iCore.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iCore.cpp @@ -30,82 +30,86 @@ void _initX86regs() g_x86checknext = 0; } -std::array callee_saved_order{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -//std::array callee_saved_order{0, 1, 2, 19, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -//std::array callee_saved_order{0, 1, 2, 19, 4, 20, 6, 7, 8, 9, 10, 11, 21, 22, 23, 24}; - int _getFreeX86reg(int mode) { - int tempi = -1; - u32 bestcount = 0x10000; + int i, tempi = -1; + u32 bestcount = 0x10000; - for (uint i = 0; i < iREGCNT_GPR; i++) -// for (uint i = 0; i < 16; i++) - { - const int reg = (g_x86checknext + i) % iREGCNT_GPR; -// const int ii = (g_x86checknext + i) % 16; -// int reg = callee_saved_order[ii]; + for (i = 0; i < iREGCNT_GPR; ++i) + { + const int reg = (g_x86checknext + i) % iREGCNT_GPR; + if (x86regs[reg].inuse || !_isAllocatableX86reg(reg)) + continue; - if (x86regs[reg].inuse || !_isAllocatableX86reg(reg)) - continue; +// if ((mode & MODE_CALLEESAVED) && xRegister32::IsCallerSaved(reg)) +// continue; - if ((mode & MODE_CALLEESAVED) && armIsCallerSaved(reg)) - continue; + if (mode & MODE_CALLEESAVED) { + if(!armIsCalleeSavedRegister(reg)) { + continue; + } + } else { + if(!armIsCallerSaved(reg)) { + continue; + } + } - if ((mode & MODE_COP2) && mVUIsReservedCOP2(reg)) - continue; + if ((mode & MODE_COP2) && mVUIsReservedCOP2(reg)) + continue; - if (x86regs[reg].inuse == 0) - { - g_x86checknext = (reg + 1) % iREGCNT_GPR; -// g_x86checknext = (ii + 1) % 16; -// if(reg == 23) { -// reg = reg; -// } - return reg; - } - } + if (x86regs[reg].inuse == 0) + { + g_x86checknext = (reg + 1) % iREGCNT_GPR; + return reg; + } + } - for (uint i = 0; i < iREGCNT_GPR; i++) -// for (uint i2 = 0; i2 < 16; i2++) - { -// int i = callee_saved_order[i2]; + for (i = 0; i < iREGCNT_GPR; ++i) + { + if (!_isAllocatableX86reg(i)) + continue; - if (!_isAllocatableX86reg(i)) - continue; +// if ((mode & MODE_CALLEESAVED) && xRegister32::IsCallerSaved(i)) +// continue; - if ((mode & MODE_CALLEESAVED) && armIsCallerSaved(i)) - continue; + if (mode & MODE_CALLEESAVED) { + if(!armIsCalleeSavedRegister(i)) { + continue; + } + } else { + if(!armIsCallerSaved(i)) { + continue; + } + } - if ((mode & MODE_COP2) && mVUIsReservedCOP2(i)) - continue; + if ((mode & MODE_COP2) && mVUIsReservedCOP2(i)) + continue; - // should have checked inuse in the previous loop. - pxAssert(x86regs[i].inuse); + // should have checked inuse in the previous loop. + pxAssert(x86regs[i].inuse); - if (x86regs[i].needed) - continue; + if (x86regs[i].needed) + continue; - if (x86regs[i].type != X86TYPE_TEMP) - { + if (x86regs[i].type != X86TYPE_TEMP) + { + if (x86regs[i].counter < bestcount) + { + tempi = static_cast(i); + bestcount = x86regs[i].counter; + } + continue; + } - if (x86regs[i].counter < bestcount) - { - tempi = static_cast(i); - bestcount = x86regs[i].counter; - } - continue; - } + _freeX86reg(i); + return i; + } - _freeX86reg(i); - return i; - } - - if (tempi != -1) - { - _freeX86reg(tempi); - return tempi; - } + if (tempi != -1) + { + _freeX86reg(tempi); + return tempi; + } pxFailRel("x86 register allocation error"); return -1; diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index 86e16cf..23bcc3b 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -370,7 +370,7 @@ void recCall(void (*func)()) { iFlushCall(FLUSH_INTERPRETER); // xFastCall((void*)func); - armEmitCall(reinterpret_cast(func), false); + armEmitCall(reinterpret_cast(func)); } // ===================================================================================================== diff --git a/app/src/main/cpp/pcsx2/x86/microVU_IR.h b/app/src/main/cpp/pcsx2/x86/microVU_IR.h index 4bf4d23..b6de977 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_IR.h +++ b/app/src/main/cpp/pcsx2/x86/microVU_IR.h @@ -347,15 +347,19 @@ public: // mark gpr registers as usable gprMap.fill({0, 0, false, false, false, false}); - for (int i = 0; i < gprTotal; i++) + for (uint i = 0; i < gprTotal; i++) { if (i == gprT1.GetCode() || i == gprT2.GetCode() || - i == gprF0.GetCode() || i == gprF1.GetCode() || i == gprF2.GetCode() || i == gprF3.GetCode() || - i == 4 //i == rsp.GetId() + i == gprF0.GetCode() || i == gprF1.GetCode() || i == gprF2.GetCode() || i == gprF3.GetCode() + || i == 4 //i == rsp.GetId() + || i == a64::x16.GetCode() || i == a64::x17.GetCode() || i == a64::x18.GetCode() + || i >= iREGCNT_GPR ) { continue; } + // 19,20,21,22,23,24 <= callee + gprMap[i].usable = true; } diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.h b/app/src/main/cpp/pcsx2/x86/microVU_Misc.h index 0926eff..98cbee5 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.h +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.h @@ -148,11 +148,6 @@ static const char branchSTR[16][8] = { #define gprF2 a64::w13 // Status Flag 2 #define gprF3 a64::w14 // Status Flag 3 -//#define gprF0 a64::w19 // Status Flag 0 -//#define gprF1 a64::w21 // Status Flag 1 -//#define gprF2 a64::w22 // Status Flag 2 -//#define gprF3 a64::w23 // Status Flag 3 - // Function Params #define mP microVU& mVU, int recPass #define mV microVU& mVU