Misc: Combine some redundant functions

This commit is contained in:
Stenzek
2023-12-13 20:56:24 +10:00
parent 68d3cb5b4a
commit bc2c334370
6 changed files with 329 additions and 264 deletions

View File

@ -79,8 +79,8 @@ static void CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
static void WriteMem(const PGXP_value* value, u32 addr);
static void WriteMem16(const PGXP_value* src, u32 addr);
static const PGXP_value PGXP_value_invalid = {0.f, 0.f, 0.f, {0}, 0};
static const PGXP_value PGXP_value_zero = {0.f, 0.f, 0.f, {VALID_ALL}, 0};
static const PGXP_value PGXP_value_invalid = {0.f, 0.f, 0.f, 0, {0}};
static const PGXP_value PGXP_value_zero = {0.f, 0.f, 0.f, 0, {VALID_ALL}};
static PGXP_value* s_mem = nullptr;
static PGXP_value* s_vertex_cache = nullptr;
@ -568,11 +568,17 @@ void CPU::PGXP::CPU_SW(u32 instr, u32 addr, u32 rtVal)
WriteMem(val, addr);
}
void CPU::PGXP::CPU_MOVE(u32 rd_and_rs, u32 rsVal)
void CPU::PGXP::CPU_MOVE_Packed(u32 rd_and_rs, u32 rsVal)
{
const u32 Rs = (rd_and_rs & 0xFFu);
const u32 Rd = (rd_and_rs >> 8);
CPU_MOVE(Rd, Rs, rsVal);
}
void CPU::PGXP::CPU_MOVE(u32 Rd, u32 Rs, u32 rsVal)
{
Validate(&g_state.pgxp_gpr[Rs], rsVal);
g_state.pgxp_gpr[(rd_and_rs >> 8)] = g_state.pgxp_gpr[Rs];
g_state.pgxp_gpr[Rd] = g_state.pgxp_gpr[Rs];
}
void CPU::PGXP::CPU_ADDI(u32 instr, u32 rsVal)
@ -1031,9 +1037,9 @@ void CPU::PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal)
MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)] = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].halfFlags[0] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].halfFlags[0] =
(g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double xx, xy, yx, yy;
@ -1056,15 +1062,15 @@ void CPU::PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal)
hy = f16Overflow(hx);
g_state.pgxp_lo.x = (float)f16Sign(lx);
g_state.pgxp_lo.y = (float)f16Sign(ly);
g_state.pgxp_hi.x = (float)f16Sign(hx);
g_state.pgxp_hi.y = (float)f16Sign(hy);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].x = (float)f16Sign(lx);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].y = (float)f16Sign(ly);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].x = (float)f16Sign(hx);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].y = (float)f16Sign(hy);
// compute PSX value
const u64 result = static_cast<u64>(static_cast<s64>(SignExtend64(rsVal)) * static_cast<s64>(SignExtend64(rtVal)));
g_state.pgxp_hi.value = Truncate32(result >> 32);
g_state.pgxp_lo.value = Truncate32(result);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = Truncate32(result >> 32);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value = Truncate32(result);
}
void CPU::PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
@ -1081,9 +1087,9 @@ void CPU::PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)] = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].halfFlags[0] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].halfFlags[0] =
(g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double xx, xy, yx, yy;
@ -1106,15 +1112,15 @@ void CPU::PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
hy = f16Overflow(hx);
g_state.pgxp_lo.x = (float)f16Sign(lx);
g_state.pgxp_lo.y = (float)f16Sign(ly);
g_state.pgxp_hi.x = (float)f16Sign(hx);
g_state.pgxp_hi.y = (float)f16Sign(hy);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].x = (float)f16Sign(lx);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].y = (float)f16Sign(ly);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].x = (float)f16Sign(hx);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].y = (float)f16Sign(hy);
// compute PSX value
const u64 result = ZeroExtend64(rsVal) * ZeroExtend64(rtVal);
g_state.pgxp_hi.value = Truncate32(result >> 32);
g_state.pgxp_lo.value = Truncate32(result);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = Truncate32(result >> 32);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value = Truncate32(result);
}
void CPU::PGXP::CPU_DIV(u32 instr, u32 rsVal, u32 rtVal)
@ -1132,39 +1138,42 @@ void CPU::PGXP::CPU_DIV(u32 instr, u32 rsVal, u32 rtVal)
MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)] = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].halfFlags[0] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].halfFlags[0] =
(g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double vs = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) + (g_state.pgxp_gpr[rs(instr)].y) * (double)(1 << 16);
double vt = f16Unsign(g_state.pgxp_gpr[rt(instr)].x) + (g_state.pgxp_gpr[rt(instr)].y) * (double)(1 << 16);
double lo = vs / vt;
g_state.pgxp_lo.y = (float)f16Sign(f16Overflow(lo));
g_state.pgxp_lo.x = (float)f16Sign(lo);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].y = (float)f16Sign(f16Overflow(lo));
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].x = (float)f16Sign(lo);
double hi = fmod(vs, vt);
g_state.pgxp_hi.y = (float)f16Sign(f16Overflow(hi));
g_state.pgxp_hi.x = (float)f16Sign(hi);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].y = (float)f16Sign(f16Overflow(hi));
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].x = (float)f16Sign(hi);
// compute PSX value
if (static_cast<s32>(rtVal) == 0)
{
// divide by zero
g_state.pgxp_lo.value = (static_cast<s32>(rsVal) >= 0) ? UINT32_C(0xFFFFFFFF) : UINT32_C(1);
g_state.pgxp_hi.value = static_cast<u32>(static_cast<s32>(rsVal));
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value =
(static_cast<s32>(rsVal) >= 0) ? UINT32_C(0xFFFFFFFF) : UINT32_C(1);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = static_cast<u32>(static_cast<s32>(rsVal));
}
else if (rsVal == UINT32_C(0x80000000) && static_cast<s32>(rtVal) == -1)
{
// unrepresentable
g_state.pgxp_lo.value = UINT32_C(0x80000000);
g_state.pgxp_hi.value = 0;
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value = UINT32_C(0x80000000);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = 0;
}
else
{
g_state.pgxp_lo.value = static_cast<u32>(static_cast<s32>(rsVal) / static_cast<s32>(rtVal));
g_state.pgxp_hi.value = static_cast<u32>(static_cast<s32>(rsVal) % static_cast<s32>(rtVal));
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value =
static_cast<u32>(static_cast<s32>(rsVal) / static_cast<s32>(rtVal));
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value =
static_cast<u32>(static_cast<s32>(rsVal) % static_cast<s32>(rtVal));
}
}
@ -1183,32 +1192,32 @@ void CPU::PGXP::CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal)
MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)] = g_state.pgxp_gpr[rs(instr)];
g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].halfFlags[0] = g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].halfFlags[0] =
(g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double vs = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) + f16Unsign(g_state.pgxp_gpr[rs(instr)].y) * (double)(1 << 16);
double vt = f16Unsign(g_state.pgxp_gpr[rt(instr)].x) + f16Unsign(g_state.pgxp_gpr[rt(instr)].y) * (double)(1 << 16);
double lo = vs / vt;
g_state.pgxp_lo.y = (float)f16Sign(f16Overflow(lo));
g_state.pgxp_lo.x = (float)f16Sign(lo);
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].y = (float)f16Sign(f16Overflow(lo));
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].x = (float)f16Sign(lo);
double hi = fmod(vs, vt);
g_state.pgxp_hi.y = (float)f16Sign(f16Overflow(hi));
g_state.pgxp_hi.x = (float)f16Sign(hi);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].y = (float)f16Sign(f16Overflow(hi));
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].x = (float)f16Sign(hi);
if (rtVal == 0)
{
// divide by zero
g_state.pgxp_lo.value = UINT32_C(0xFFFFFFFF);
g_state.pgxp_hi.value = rsVal;
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value = UINT32_C(0xFFFFFFFF);
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = rsVal;
}
else
{
g_state.pgxp_lo.value = rsVal / rtVal;
g_state.pgxp_hi.value = rsVal % rtVal;
g_state.pgxp_gpr[static_cast<u8>(Reg::lo)].value = rsVal / rtVal;
g_state.pgxp_gpr[static_cast<u8>(Reg::hi)].value = rsVal % rtVal;
}
}
@ -1575,38 +1584,6 @@ void CPU::PGXP::CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
g_state.pgxp_gpr[rd(instr)] = ret;
}
void CPU::PGXP::CPU_MFHI(u32 instr, u32 hiVal)
{
// Rd = Hi
Validate(&g_state.pgxp_hi, hiVal);
g_state.pgxp_gpr[rd(instr)] = g_state.pgxp_hi;
}
void CPU::PGXP::CPU_MTHI(u32 instr, u32 rsVal)
{
// Hi = Rd
Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
g_state.pgxp_hi = g_state.pgxp_gpr[rd(instr)];
}
void CPU::PGXP::CPU_MFLO(u32 instr, u32 loVal)
{
// Rd = Lo
Validate(&g_state.pgxp_lo, loVal);
g_state.pgxp_gpr[rd(instr)] = g_state.pgxp_lo;
}
void CPU::PGXP::CPU_MTLO(u32 instr, u32 rsVal)
{
// Lo = Rd
Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
g_state.pgxp_lo = g_state.pgxp_gpr[rd(instr)];
}
void CPU::PGXP::CPU_MFC0(u32 instr, u32 rdVal)
{
// CPU[Rt] = CP0[Rd]