CPU/PGXP: Purge psx_value from shifts

This commit is contained in:
Stenzek 2024-08-20 16:42:51 +10:00
parent 302652df22
commit fc375d76b5
No known key found for this signature in database
1 changed files with 45 additions and 71 deletions

View File

@ -59,6 +59,8 @@ enum : u32
#define HIWORD_U16(val) (static_cast<u16>(static_cast<u32>(val) >> 16)) #define HIWORD_U16(val) (static_cast<u16>(static_cast<u32>(val) >> 16))
#define LOWORD_S16(val) (static_cast<s16>(static_cast<u16>(val))) #define LOWORD_S16(val) (static_cast<s16>(static_cast<u16>(val)))
#define HIWORD_S16(val) (static_cast<s16>(static_cast<u16>(static_cast<u32>(val) >> 16))) #define HIWORD_S16(val) (static_cast<s16>(static_cast<u16>(static_cast<u32>(val) >> 16)))
#define SET_LOWORD(val, loword) ((static_cast<u32>(val) & 0xFFFF0000u) | static_cast<u32>(static_cast<u16>(loword)))
#define SET_HIWORD(val, hiword) ((static_cast<u32>(val) & 0x0000FFFFu) | (static_cast<u32>(hiword) << 16))
union psx_value union psx_value
{ {
@ -1376,14 +1378,14 @@ void CPU::PGXP::CPU_SLL(Instruction instr, u32 rtVal)
} }
else if (sh >= 16) else if (sh >= 16)
{ {
y = x * (1 << (sh - 16)); y = x * static_cast<float>(1 << (sh - 16));
y = f16Sign(y); y = f16Sign(y);
x = 0.f; x = 0.f;
} }
else else
{ {
x = x * (1 << sh); x = x * static_cast<float>(1 << sh);
y = y * (1 << sh); y = y * static_cast<float>(1 << sh);
y += f16Overflow(x); y += f16Overflow(x);
x = f16Sign(x); x = f16Sign(x);
y = f16Sign(y); y = f16Sign(y);
@ -1409,26 +1411,19 @@ void CPU::PGXP::CPU_SRL(Instruction instr, u32 rtVal)
double x = prtVal.x; double x = prtVal.x;
double y = f16Unsign(prtVal.y); double y = f16Unsign(prtVal.y);
psx_value iX; const u32 iX = SignExtend32(LOWORD_S16(rtVal)); // remove Y
iX.d = rtVal; const u32 iY = SET_LOWORD(rtVal, HIWORD_U16(iX)); // overwrite x with sign(x)
psx_value iY;
iY.d = rtVal;
iX.sd = (iX.sd << 16) >> 16; // remove Y
iY.sw.l = iX.sw.h; // overwrite x with sign(x)
// Shift test values // Shift test values
psx_value dX; const u32 dX = static_cast<u32>(static_cast<s32>(iX) >> sh);
dX.sd = iX.sd >> sh; const u32 dY = iY >> sh;
psx_value dY;
dY.d = iY.d >> sh;
if (dX.sw.l != iX.sw.h) if (LOWORD_S16(dX) != HIWORD_S16(iX))
x = x / (1 << sh); x = x / (1 << sh);
else else
x = dX.sw.l; // only sign bits left x = LOWORD_S16(dX); // only sign bits left
if (dY.sw.l != iX.sw.h) if (LOWORD_S16(dY) != HIWORD_S16(iX))
{ {
if (sh == 16) if (sh == 16)
{ {
@ -1436,20 +1431,20 @@ void CPU::PGXP::CPU_SRL(Instruction instr, u32 rtVal)
} }
else if (sh < 16) else if (sh < 16)
{ {
x += y * (1 << (16 - sh)); x += y * static_cast<float>(1 << (16 - sh));
if (GetRtValue(instr).x < 0) if (GetRtValue(instr).x < 0)
x += 1 << (16 - sh); x += static_cast<float>(1 << (16 - sh));
} }
else else
{ {
x += y / (1 << (sh - 16)); x += y / static_cast<float>(1 << (sh - 16));
} }
} }
if ((dY.sw.h == 0) || (dY.sw.h == -1)) if ((HIWORD_S16(dY) == 0) || (HIWORD_S16(dY) == -1))
y = dY.sw.h; y = HIWORD_S16(dY);
else else
y = y / (1 << sh); y = y / static_cast<float>(1 << sh);
x = f16Sign(x); x = f16Sign(x);
y = f16Sign(y); y = f16Sign(y);
@ -1474,26 +1469,19 @@ void CPU::PGXP::CPU_SRA(Instruction instr, u32 rtVal)
double x = prtVal.x; double x = prtVal.x;
double y = prtVal.y; double y = prtVal.y;
psx_value iX; const u32 iX = SignExtend32(LOWORD_S16(rtVal)); // remove Y
iX.d = rtVal; const u32 iY = SET_LOWORD(rtVal, HIWORD_U16(iX)); // overwrite x with sign(x)
psx_value iY;
iY.d = rtVal;
iX.sd = (iX.sd << 16) >> 16; // remove Y
iY.sw.l = iX.sw.h; // overwrite x with sign(x)
// Shift test values // Shift test values
psx_value dX; const u32 dX = static_cast<u32>(static_cast<s32>(iX) >> sh);
dX.sd = iX.sd >> sh; const u32 dY = static_cast<u32>(static_cast<s32>(iY) >> sh);
psx_value dY;
dY.sd = iY.sd >> sh;
if (dX.sw.l != iX.sw.h) if (LOWORD_S16(dX) != HIWORD_S16(iX))
x = x / (1 << sh); x = x / (1 << sh);
else else
x = dX.sw.l; // only sign bits left x = LOWORD_S16(dX); // only sign bits left
if (dY.sw.l != iX.sw.h) if (LOWORD_S16(dY) != HIWORD_S16(iX))
{ {
if (sh == 16) if (sh == 16)
{ {
@ -1511,8 +1499,8 @@ void CPU::PGXP::CPU_SRA(Instruction instr, u32 rtVal)
} }
} }
if ((dY.sw.h == 0) || (dY.sw.h == -1)) if ((HIWORD_S16(dY) == 0) || (HIWORD_S16(dY) == -1))
y = dY.sw.h; y = HIWORD_S16(dY);
else else
y = y / (1 << sh); y = y / (1 << sh);
@ -1598,26 +1586,19 @@ void CPU::PGXP::CPU_SRLV(Instruction instr, u32 rtVal, u32 rsVal)
double x = prtVal.x; double x = prtVal.x;
double y = f16Unsign(prtVal.y); double y = f16Unsign(prtVal.y);
psx_value iX; const u32 iX = SignExtend32(LOWORD_S16(rtVal)); // remove Y
iX.d = rtVal; const u32 iY = SET_LOWORD(rtVal, HIWORD_U16(iX)); // overwrite x with sign(x)
psx_value iY;
iY.d = rtVal;
iX.sd = (iX.sd << 16) >> 16; // remove Y
iY.sw.l = iX.sw.h; // overwrite x with sign(x)
// Shift test values // Shift test values
psx_value dX; const u32 dX = static_cast<u32>(static_cast<s32>(iX) >> sh);
dX.sd = iX.sd >> sh; const u32 dY = iY >> sh;
psx_value dY;
dY.d = iY.d >> sh;
if (dX.sw.l != iX.sw.h) if (LOWORD_S16(dX) != HIWORD_S16(iX))
x = x / (1 << sh); x = x / (1 << sh);
else else
x = dX.sw.l; // only sign bits left x = LOWORD_S16(dX); // only sign bits left
if (dY.sw.l != iX.sw.h) if (LOWORD_S16(dY) != HIWORD_S16(iX))
{ {
if (sh == 16) if (sh == 16)
{ {
@ -1635,8 +1616,8 @@ void CPU::PGXP::CPU_SRLV(Instruction instr, u32 rtVal, u32 rsVal)
} }
} }
if ((dY.sw.h == 0) || (dY.sw.h == -1)) if ((HIWORD_S16(dY) == 0) || (HIWORD_S16(dY) == -1))
y = dY.sw.h; y = HIWORD_S16(dY);
else else
y = y / (1 << sh); y = y / (1 << sh);
@ -1661,26 +1642,19 @@ void CPU::PGXP::CPU_SRAV(Instruction instr, u32 rtVal, u32 rsVal)
double x = prtVal.x; double x = prtVal.x;
double y = prtVal.y; double y = prtVal.y;
psx_value iX; const u32 iX = SignExtend32(LOWORD_S16(rtVal)); // remove Y
iX.d = rtVal; const u32 iY = SET_LOWORD(rtVal, HIWORD_U16(iX)); // overwrite x with sign(x)
psx_value iY;
iY.d = rtVal;
iX.sd = (iX.sd << 16) >> 16; // remove Y
iY.sw.l = iX.sw.h; // overwrite x with sign(x)
// Shift test values // Shift test values
psx_value dX; const u32 dX = static_cast<u32>(static_cast<s32>(iX) >> sh);
dX.sd = iX.sd >> sh; const u32 dY = static_cast<u32>(static_cast<s32>(iY) >> sh);
psx_value dY;
dY.sd = iY.sd >> sh;
if (dX.sw.l != iX.sw.h) if (LOWORD_S16(dX) != HIWORD_S16(iX))
x = x / (1 << sh); x = x / (1 << sh);
else else
x = dX.sw.l; // only sign bits left x = LOWORD_S16(dX); // only sign bits left
if (dY.sw.l != iX.sw.h) if (LOWORD_S16(dY) != HIWORD_S16(iX))
{ {
if (sh == 16) if (sh == 16)
{ {
@ -1698,8 +1672,8 @@ void CPU::PGXP::CPU_SRAV(Instruction instr, u32 rtVal, u32 rsVal)
} }
} }
if ((dY.sw.h == 0) || (dY.sw.h == -1)) if ((HIWORD_S16(dY) == 0) || (HIWORD_S16(dY) == -1))
y = dY.sw.h; y = HIWORD_S16(dY);
else else
y = y / (1 << sh); y = y / (1 << sh);