mirror of
https://github.com/izzy2lost/PSX2.git
synced 2026-07-05 15:18:36 -07:00
Android project - Change calleesaved x86(rbp,rbx,r12,r13,r14,r15) => arm64(19,20,21,22,23,24)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,82 +30,86 @@ void _initX86regs()
|
||||
g_x86checknext = 0;
|
||||
}
|
||||
|
||||
std::array<int, 16> callee_saved_order{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
//std::array<int, 16> callee_saved_order{0, 1, 2, 19, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
//std::array<int, 16> 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<int>(i);
|
||||
bestcount = x86regs[i].counter;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (x86regs[i].counter < bestcount)
|
||||
{
|
||||
tempi = static_cast<int>(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;
|
||||
|
||||
@@ -370,7 +370,7 @@ void recCall(void (*func)())
|
||||
{
|
||||
iFlushCall(FLUSH_INTERPRETER);
|
||||
// xFastCall((void*)func);
|
||||
armEmitCall(reinterpret_cast<void*>(func), false);
|
||||
armEmitCall(reinterpret_cast<void*>(func));
|
||||
}
|
||||
|
||||
// =====================================================================================================
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user