Skip to content

Commit

Permalink
[Soft-Float] - Fixes VU add/sub regressions + partial U/O/I/D flag su…
Browse files Browse the repository at this point in the history
…pport for VU operations.

The flag support is not 100% accurate yet in FMAC methods (we need to carry mult flags to the add stage), but this is enough for Superman to work for now.
  • Loading branch information
GitHubProUser67 committed Jan 24, 2025
1 parent 8914229 commit 7efe187
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 246 deletions.
6 changes: 3 additions & 3 deletions pcsx2/PS2Float.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ u32 PS2Float::Abs()

PS2Float PS2Float::Negate()
{
return PS2Float(raw ^ 0x80000000);
return PS2Float(raw ^ SIGNMASK);
}

s32 PS2Float::CompareToSign(PS2Float other)
Expand All @@ -296,8 +296,8 @@ s32 PS2Float::CompareToSign(PS2Float other)

s32 PS2Float::CompareTo(PS2Float other)
{
s32 selfTwoComplementVal = (s32)Abs();
s32 otherTwoComplementVal = (s32)other.Abs();
u32 selfTwoComplementVal = Abs();
u32 otherTwoComplementVal = other.Abs();

if (selfTwoComplementVal < otherTwoComplementVal)
return -1;
Expand Down
44 changes: 23 additions & 21 deletions pcsx2/VUflags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,41 @@
/* NEW FLAGS */ //By asadr. Thnkx F|RES :p
/*****************************************/

static __ri u32 VU_MAC_UPDATE(int shift, VURegs* VU, u32 f)
static __ri u32 VU_MAC_UPDATE(int shift, VURegs* VU, PS2Float f)
{
PS2Float ps2f = PS2Float(f);

u32 exp = ps2f.Exponent();
u32 s = ps2f.raw & PS2Float::SIGNMASK;
u32 exp = f.Exponent();
u32 s = f.raw & PS2Float::SIGNMASK;

if (s)
VU->macflag |= 0x0010<<shift;
else
VU->macflag &= ~(0x0010<<shift);

if (ps2f.IsZero())
if (f.IsZero())
{
VU->macflag = (VU->macflag & ~(0x1100<<shift)) | (0x0001<<shift);
return f;
return f.raw;
}

switch(exp)
{
case 0:
VU->macflag = (VU->macflag&~(0x1000<<shift)) | (0x0101<<shift);
if (CHECK_VU_SOFT_ADDSUB((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_SQRT((VU == &VU1) ? 1 : 0))
{
if (f.uf) { VU->macflag = (VU->macflag & ~(0x1000 << shift)) | (0x0101 << shift); }
}
else
{
VU->macflag = (VU->macflag & ~(0x1000 << shift)) | (0x0101 << shift);
}

return s;
case 255:
if (CHECK_VU_SOFT_ADDSUB((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_SQRT((VU == &VU1) ? 1 : 0))
{
if (f == PS2Float::MAX_FLOATING_POINT_VALUE || f == PS2Float::MIN_FLOATING_POINT_VALUE)
{
VU->macflag = (VU->macflag & ~(0x0101 << shift)) | (0x1000 << shift);
return f;
}
else
return f;
if (f.of) { VU->macflag = (VU->macflag & ~(0x0101 << shift)) | (0x1000 << shift); }

return f.raw;
}
else if (CHECK_VU_OVERFLOW((VU == &VU1) ? 1 : 0))
{
Expand All @@ -54,30 +56,30 @@ static __ri u32 VU_MAC_UPDATE(int shift, VURegs* VU, u32 f)
else
{
VU->macflag = (VU->macflag & ~(0x0101 << shift)) | (0x1000 << shift);
return f;
return f.raw;
}
default:
VU->macflag = (VU->macflag & ~(0x1101<<shift));
return f;
return f.raw;
}
}

__fi u32 VU_MACx_UPDATE(VURegs* VU, u32 x)
__fi u32 VU_MACx_UPDATE(VURegs* VU, PS2Float x)
{
return VU_MAC_UPDATE(3, VU, x);
}

__fi u32 VU_MACy_UPDATE(VURegs* VU, u32 y)
__fi u32 VU_MACy_UPDATE(VURegs* VU, PS2Float y)
{
return VU_MAC_UPDATE(2, VU, y);
}

__fi u32 VU_MACz_UPDATE(VURegs* VU, u32 z)
__fi u32 VU_MACz_UPDATE(VURegs* VU, PS2Float z)
{
return VU_MAC_UPDATE(1, VU, z);
}

__fi u32 VU_MACw_UPDATE(VURegs* VU, u32 w)
__fi u32 VU_MACw_UPDATE(VURegs* VU, PS2Float w)
{
return VU_MAC_UPDATE(0, VU, w);
}
Expand Down
9 changes: 5 additions & 4 deletions pcsx2/VUflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

#pragma once
#include "VU.h"
#include "PS2Float.h"

extern u32 VU_MACx_UPDATE(VURegs* VU, u32 x);
extern u32 VU_MACy_UPDATE(VURegs* VU, u32 y);
extern u32 VU_MACz_UPDATE(VURegs* VU, u32 z);
extern u32 VU_MACw_UPDATE(VURegs* VU, u32 w);
extern u32 VU_MACx_UPDATE(VURegs* VU, PS2Float x);
extern u32 VU_MACy_UPDATE(VURegs* VU, PS2Float y);
extern u32 VU_MACz_UPDATE(VURegs* VU, PS2Float z);
extern u32 VU_MACw_UPDATE(VURegs* VU, PS2Float w);
extern void VU_MACx_CLEAR(VURegs* VU);
extern void VU_MACy_CLEAR(VURegs* VU);
extern void VU_MACz_CLEAR(VURegs* VU);
Expand Down
Loading

0 comments on commit 7efe187

Please sign in to comment.