diff --git a/src/core/cpu_core.h b/src/core/cpu_core.h index b9e31b553..b63b5e6aa 100644 --- a/src/core/cpu_core.h +++ b/src/core/cpu_core.h @@ -58,12 +58,13 @@ struct PGXP_value u32 value; u32 flags; - ALWAYS_INLINE void SetValidComp(u32 comp, bool valid) + ALWAYS_INLINE void SetValid(u32 comp, bool valid = true) { - flags = (flags & ~(1u << comp)) | (static_cast(valid) << comp); + const u32 mask = (1u << comp); + flags = valid ? (flags | mask) : (flags & ~mask); } - ALWAYS_INLINE bool GetValidComp(u32 comp) const { return ConvertToBoolUnchecked((flags >> comp) & 1); } + ALWAYS_INLINE bool HasValid(u32 comp) const { return ConvertToBoolUnchecked((flags >> comp) & 1); } }; struct State diff --git a/src/core/cpu_pgxp.cpp b/src/core/cpu_pgxp.cpp index d7993274b..449f70141 100644 --- a/src/core/cpu_pgxp.cpp +++ b/src/core/cpu_pgxp.cpp @@ -20,6 +20,8 @@ Log_SetChannel(CPU::PGXP); // #define LOG_VALUES 1 // #define LOG_LOOKUPS 1 +// TODO: Get rid of all the rs/rt subscripting. + namespace CPU::PGXP { namespace { @@ -29,17 +31,27 @@ enum : u32 VERTEX_CACHE_HEIGHT = 0x800 * 2, VERTEX_CACHE_SIZE = VERTEX_CACHE_WIDTH * VERTEX_CACHE_HEIGHT, PGXP_MEM_SIZE = (static_cast(Bus::RAM_8MB_SIZE) + static_cast(CPU::SCRATCHPAD_SIZE)) / 4, - PGXP_MEM_SCRATCH_OFFSET = Bus::RAM_8MB_SIZE / 4 + PGXP_MEM_SCRATCH_OFFSET = Bus::RAM_8MB_SIZE / 4, }; -#define ALL 0xFFFFFFFF -#define VALID_0 (1 << 0) -#define VALID_1 (1 << 1) -#define VALID_2 (1 << 2) -#define VALID_01 (VALID_0 | VALID_1) -#define VALID_012 (VALID_0 | VALID_1 | VALID_2) -#define VALID_ALL (VALID_0 | VALID_1 | VALID_2) -#define INV_VALID_ALL (ALL ^ VALID_ALL) +enum : u32 +{ + COMP_X, + COMP_Y, + COMP_Z, +}; + +enum : u32 +{ + ALL = 0xFFFFFFFFu, + VALID_X = (1u << 0), + VALID_Y = (1u << 1), + VALID_Z = (1u << 2), + VALID_XY = (VALID_X | VALID_Y), + VALID_XYZ = (VALID_X | VALID_Y | VALID_Z), + VALID_ALL = (VALID_X | VALID_Y | VALID_Z), + INV_VALID_ALL = (ALL ^ VALID_ALL), +}; union psx_value { @@ -107,8 +119,8 @@ static void LogValueStr(SmallStringBase& str, const char* name, u32 rval, const #endif // clang-format on -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 constexpr PGXP_value PGXP_value_invalid = {0.f, 0.f, 0.f, 0, 0}; +static constexpr 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; @@ -200,13 +212,13 @@ void CPU::PGXP::Shutdown() ALWAYS_INLINE_RELEASE void CPU::PGXP::MakeValid(PGXP_value* pV, u32 psxV) { - if ((pV->flags & VALID_01) == VALID_01) + if ((pV->flags & VALID_XY) == VALID_XY) return; pV->x = static_cast(static_cast(Truncate16(psxV))); pV->y = static_cast(static_cast(Truncate16(psxV >> 16))); pV->z = 0.0f; - pV->flags = VALID_01; + pV->flags = VALID_XY; pV->value = psxV; } @@ -286,13 +298,13 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::ValidateAndCopyMem16(PGXP_value* dest, u32 { val.w.h = static_cast(value); mask.w.h = 0xFFFF; - valid_mask = VALID_1; + valid_mask = VALID_Y; } else { val.w.l = static_cast(value); mask.w.l = 0xFFFF; - valid_mask = VALID_0; + valid_mask = VALID_X; } // validate and copy whole value @@ -303,19 +315,19 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::ValidateAndCopyMem16(PGXP_value* dest, u32 if (hiword) { dest->x = dest->y; - dest->SetValidComp(0, dest->GetValidComp(1)); + dest->SetValid(COMP_X, dest->HasValid(COMP_Y)); } // only set y as valid if x is also valid.. don't want to make fake values - if (dest->GetValidComp(0)) + if (dest->HasValid(COMP_X)) { dest->y = (dest->x < 0) ? -1.f * sign : 0.f; - dest->SetValidComp(1, true); + dest->SetValid(COMP_Y); } else { dest->y = 0.0f; - dest->SetValidComp(1, false); + dest->SetValid(COMP_Y, false); } dest->value = value; @@ -340,37 +352,38 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::WriteMem16(const PGXP_value* src, u32 addr if (hiword) { dest->y = src->x; - dest->SetValidComp(1, src->GetValidComp(0)); + dest->SetValid(COMP_Y, src->HasValid(COMP_X)); dest->value = (dest->value & UINT32_C(0x0000FFFF)) | (src->value << 16); } else { dest->x = src->x; - dest->SetValidComp(0, src->GetValidComp(0)); + dest->SetValid(COMP_X, src->HasValid(COMP_X)); dest->value = (dest->value & UINT32_C(0xFFFF0000)) | (src->value & UINT32_C(0x0000FFFF)); } // overwrite z/w if valid - if (src->GetValidComp(2)) + // TODO: Check modified + if (src->HasValid(COMP_Z)) { dest->z = src->z; - dest->SetValidComp(2, true); + dest->SetValid(COMP_Z); } } ALWAYS_INLINE_RELEASE void CPU::PGXP::CopyZIfMissing(PGXP_value& dst, const PGXP_value& src) { - if (dst.GetValidComp(2)) + if (dst.HasValid(COMP_Z)) return; dst.z = src.z; - dst.flags |= (src.flags & VALID_2); + dst.flags |= (src.flags & VALID_Z); } ALWAYS_INLINE_RELEASE void CPU::PGXP::SelectZ(PGXP_value& dst, const PGXP_value& src1, const PGXP_value& src2) { - dst.z = src1.GetValidComp(2) ? src1.z : src2.z; - dst.flags |= ((src1.flags | src2.flags) & VALID_2); + dst.z = src1.HasValid(COMP_Z) ? src1.z : src2.z; + dst.flags |= ((src1.flags | src2.flags) & VALID_Z); } #ifdef LOG_VALUES @@ -418,11 +431,11 @@ void CPU::PGXP::LogValueStr(SmallStringBase& str, const char* name, u32 rval, co if (val->flags != 0) { str.append(", valid="); - if (val->flags & VALID_0) + if (val->flags & VALID_X) str.append('X'); - if (val->flags & VALID_1) + if (val->flags & VALID_Y) str.append('Y'); - if (val->flags & VALID_2) + if (val->flags & VALID_Z) str.append('Z'); } @@ -459,7 +472,7 @@ int CPU::PGXP::GTE_NCLIP_valid(u32 sxy0, u32 sxy1, u32 sxy2) Validate(&SXY2, sxy2); // Don't use accurate clipping for game-constructed values, which don't have a valid Z. - return (((SXY0.flags & SXY1.flags & SXY2.flags & VALID_012) == VALID_012)); + return (((SXY0.flags & SXY1.flags & SXY2.flags & VALID_XYZ) == VALID_XYZ)); } float CPU::PGXP::GTE_NCLIP() @@ -595,7 +608,7 @@ bool CPU::PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, i float* out_w) { const PGXP_value* vert = GetPtr(addr); - if (vert && ((vert->flags & VALID_01) == VALID_01) && (vert->value == value)) + if (vert && ((vert->flags & VALID_XY) == VALID_XY) && (vert->value == value)) { // There is a value here with valid X and Y coordinates *out_x = TruncateVertexPosition(vert->x) + static_cast(xOffs); @@ -611,7 +624,7 @@ bool CPU::PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, i if (IsWithinTolerance(*out_x, *out_y, x, y)) { // check validity of z component - return ((vert->flags & VALID_2) == VALID_2); + return ((vert->flags & VALID_Z) == VALID_Z); } } @@ -622,7 +635,7 @@ bool CPU::PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, i // Look in cache for valid vertex vert = GetCachedVertex(psx_x, psx_y); - if (vert && (vert->flags & VALID_01) == VALID_01) + if (vert && (vert->flags & VALID_XY) == VALID_XY) { *out_x = TruncateVertexPosition(vert->x) + static_cast(xOffs); *out_y = TruncateVertexPosition(vert->y) + static_cast(yOffs); @@ -723,29 +736,31 @@ void CPU::PGXP::CPU_ADDI(u32 instr, u32 rsVal) LOG_VALUES_C1(rs(instr), rsVal); // Rt = Rs + Imm (signed) - Validate(&g_state.pgxp_gpr[rs(instr)], rsVal); - PGXP_value ret = g_state.pgxp_gpr[rs(instr)]; + PGXP_value& prsVal = g_state.pgxp_gpr[rs(instr)]; + Validate(&prsVal, rsVal); psx_value tempImm; tempImm.d = SignExtend32(static_cast(imm(instr))); - if (tempImm.d != 0) - { - ret.x = (float)f16Unsign(ret.x); - ret.x += (float)tempImm.w.l; + PGXP_value& prtVal = g_state.pgxp_gpr[rt(instr)]; + prtVal = prsVal; - // carry on over/underflow - float of = (ret.x > USHRT_MAX) ? 1.f : (ret.x < 0) ? -1.f : 0.f; - ret.x = (float)f16Sign(ret.x); - // ret.x -= of * (USHRT_MAX + 1); - ret.y += tempImm.sw.h + of; + if (tempImm.d == 0) + return; - // truncate on overflow/underflow - ret.y += (ret.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (ret.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f; - } + prtVal.x = (float)f16Unsign(prtVal.x); + prtVal.x += (float)tempImm.w.l; - g_state.pgxp_gpr[rt(instr)] = ret; - g_state.pgxp_gpr[rt(instr)].value = rsVal + imm_sext(instr); + // carry on over/underflow + float of = (prtVal.x > USHRT_MAX) ? 1.f : (prtVal.x < 0) ? -1.f : 0.f; + prtVal.x = (float)f16Sign(prtVal.x); + // ret.x -= of * (USHRT_MAX + 1); + prtVal.y += tempImm.sw.h + of; + + // truncate on overflow/underflow + prtVal.y += (prtVal.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (prtVal.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f; + + prtVal.value = rsVal + tempImm.d; } void CPU::PGXP::CPU_ANDI(u32 instr, u32 rsVal) @@ -754,33 +769,35 @@ void CPU::PGXP::CPU_ANDI(u32 instr, u32 rsVal) // Rt = Rs & Imm const u32 rtVal = rsVal & imm(instr); - Validate(&g_state.pgxp_gpr[rs(instr)], rsVal); - PGXP_value ret = g_state.pgxp_gpr[rs(instr)]; + PGXP_value& prsVal = g_state.pgxp_gpr[rs(instr)]; + Validate(&prsVal, rsVal); psx_value vRt; vRt.d = rtVal; - ret.y = 0.f; // remove upper 16-bits + PGXP_value& prtVal = g_state.pgxp_gpr[rt(instr)]; + prtVal = prsVal; + + prtVal.value = rtVal; + prtVal.y = 0.f; // remove upper 16-bits + prtVal.SetValid(COMP_Y); switch (imm(instr)) { case 0: // if 0 then x == 0 - ret.x = 0.f; + // TODO: x should be valid here + prtVal.x = 0.f; break; case 0xFFFF: // if saturated then x == x break; default: // otherwise x is low precision value - ret.x = vRt.sw.l; - ret.flags |= VALID_0; + prtVal.x = vRt.sw.l; + prtVal.SetValid(COMP_X); + break; } - - ret.flags |= VALID_1; - - g_state.pgxp_gpr[rt(instr)] = ret; - g_state.pgxp_gpr[rt(instr)].value = rtVal; } void CPU::PGXP::CPU_ORI(u32 instr, u32 rsVal) @@ -804,7 +821,8 @@ void CPU::PGXP::CPU_ORI(u32 instr, u32 rsVal) default: // otherwise x is low precision value ret.x = vRt.sw.l; - ret.flags |= VALID_0; + ret.SetValid(COMP_X); + break; } ret.value = rtVal; @@ -832,7 +850,8 @@ void CPU::PGXP::CPU_XORI(u32 instr, u32 rsVal) default: // otherwise x is low precision value ret.x = vRt.sw.l; - ret.flags |= VALID_0; + ret.SetValid(COMP_X); + break; } ret.value = rtVal; @@ -851,7 +870,7 @@ void CPU::PGXP::CPU_SLTI(u32 instr, u32 rsVal) tempImm.w.h = imm(instr); ret.y = 0.f; ret.x = (g_state.pgxp_gpr[rs(instr)].x < tempImm.sw.h) ? 1.f : 0.f; - ret.flags |= VALID_1; + ret.SetValid(COMP_Y); ret.value = BoolToUInt32(static_cast(rsVal) < imm_sext(instr)); g_state.pgxp_gpr[rt(instr)] = ret; @@ -869,7 +888,7 @@ void CPU::PGXP::CPU_SLTIU(u32 instr, u32 rsVal) tempImm.w.h = imm(instr); ret.y = 0.f; ret.x = (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < tempImm.w.h) ? 1.f : 0.f; - ret.flags |= VALID_1; + ret.SetValid(COMP_Y); ret.value = BoolToUInt32(rsVal < imm(instr)); g_state.pgxp_gpr[rt(instr)] = ret; @@ -886,7 +905,7 @@ void CPU::PGXP::CPU_LUI(u32 instr) g_state.pgxp_gpr[rt(instr)] = PGXP_value_zero; g_state.pgxp_gpr[rt(instr)].y = (float)(s16)imm(instr); g_state.pgxp_gpr[rt(instr)].value = static_cast(imm(instr)) << 16; - g_state.pgxp_gpr[rt(instr)].flags = VALID_01; + g_state.pgxp_gpr[rt(instr)].flags = VALID_XY; } //////////////////////////////////// @@ -913,8 +932,8 @@ void CPU::PGXP::CPU_ADD(u32 instr, u32 rsVal, u32 rtVal) else { // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -936,13 +955,13 @@ void CPU::PGXP::CPU_ADD(u32 instr, u32 rsVal, u32 rtVal) // TODO: decide which "z/w" component to use - ret.flags &= (g_state.pgxp_gpr[rt(instr)].flags & VALID_01); + ret.flags &= (g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) | ~VALID_XY; } - if (!(ret.flags & VALID_2) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_2)) + if (!(ret.flags & VALID_Z) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_Z)) { ret.z = g_state.pgxp_gpr[rt(instr)].z; - ret.SetValidComp(2, true); + ret.SetValid(COMP_Z); } ret.value = rsVal + rtVal; @@ -959,8 +978,8 @@ void CPU::PGXP::CPU_SUB(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -980,14 +999,14 @@ void CPU::PGXP::CPU_SUB(u32 instr, u32 rsVal, u32 rtVal) // truncate on overflow/underflow ret.y += (ret.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (ret.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f; - ret.flags &= (g_state.pgxp_gpr[rt(instr)].flags & VALID_01); + ret.flags &= (g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) | ~VALID_XY; ret.value = rsVal - rtVal; - if (!(ret.flags & VALID_2) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_2)) + if (!(ret.flags & VALID_Z) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_Z)) { ret.z = g_state.pgxp_gpr[rt(instr)].z; - ret.flags |= VALID_2; + ret.SetValid(COMP_Z); } g_state.pgxp_gpr[rd(instr)] = ret; @@ -1003,8 +1022,8 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVa Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1016,7 +1035,7 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVa valt.d = rtVal; PGXP_value ret; - ret.flags = VALID_01; + ret.flags = VALID_XY; if (vald.w.l == 0) { @@ -1025,17 +1044,17 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVa else if (vald.w.l == vals.w.l) { ret.x = g_state.pgxp_gpr[rs(instr)].x; - ret.SetValidComp(0, g_state.pgxp_gpr[rs(instr)].GetValidComp(0)); + ret.SetValid(COMP_X, g_state.pgxp_gpr[rs(instr)].HasValid(COMP_X)); } else if (vald.w.l == valt.w.l) { ret.x = g_state.pgxp_gpr[rt(instr)].x; - ret.SetValidComp(0, g_state.pgxp_gpr[rt(instr)].GetValidComp(0)); + ret.SetValid(COMP_X, g_state.pgxp_gpr[rt(instr)].HasValid(COMP_X)); } else { ret.x = (float)vald.sw.l; - ret.SetValidComp(0, true); + ret.SetValid(COMP_X); } if (vald.w.h == 0) @@ -1045,17 +1064,17 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVa else if (vald.w.h == vals.w.h) { ret.y = g_state.pgxp_gpr[rs(instr)].y; - ret.SetValidComp(1, g_state.pgxp_gpr[rs(instr)].GetValidComp(1)); + ret.SetValid(COMP_Y, g_state.pgxp_gpr[rs(instr)].HasValid(COMP_Y)); } else if (vald.w.h == valt.w.h) { ret.y = g_state.pgxp_gpr[rt(instr)].y; - ret.SetValidComp(1, g_state.pgxp_gpr[rt(instr)].GetValidComp(1)); + ret.SetValid(COMP_Y, g_state.pgxp_gpr[rt(instr)].HasValid(COMP_Y)); } else { ret.y = (float)vald.sw.h; - ret.SetValidComp(1, true); + ret.SetValid(COMP_Y); } // iCB Hack: Force validity if even one half is valid @@ -1064,20 +1083,20 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVa // /iCB Hack // Get a valid W - if (g_state.pgxp_gpr[rs(instr)].GetValidComp(2)) + if (g_state.pgxp_gpr[rs(instr)].HasValid(COMP_Z)) { ret.z = g_state.pgxp_gpr[rs(instr)].z; - ret.SetValidComp(2, true); + ret.SetValid(COMP_Z); } - else if (g_state.pgxp_gpr[rt(instr)].GetValidComp(2)) + else if (g_state.pgxp_gpr[rt(instr)].HasValid(COMP_Z)) { ret.z = g_state.pgxp_gpr[rt(instr)].z; - ret.SetValidComp(2, true); + ret.SetValid(COMP_Z); } else { ret.z = 0.0f; - ret.SetValidComp(2, false); + ret.SetValid(COMP_Z, false); } ret.value = rdVal; @@ -1129,8 +1148,8 @@ void CPU::PGXP::CPU_SLT(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1138,7 +1157,7 @@ void CPU::PGXP::CPU_SLT(u32 instr, u32 rsVal, u32 rtVal) PGXP_value ret = g_state.pgxp_gpr[rs(instr)]; ret.y = 0.f; - ret.SetValidComp(1, true); + ret.SetValid(COMP_Y); ret.x = (g_state.pgxp_gpr[rs(instr)].y < g_state.pgxp_gpr[rt(instr)].y) ? 1.f : (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < f16Unsign(g_state.pgxp_gpr[rt(instr)].x)) ? 1.f : @@ -1157,8 +1176,8 @@ void CPU::PGXP::CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1166,7 +1185,7 @@ void CPU::PGXP::CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal) PGXP_value ret = g_state.pgxp_gpr[rs(instr)]; ret.y = 0.f; - ret.SetValidComp(1, true); + ret.SetValid(COMP_Y); ret.x = (f16Unsign(g_state.pgxp_gpr[rs(instr)].y) < f16Unsign(g_state.pgxp_gpr[rt(instr)].y)) ? 1.f : (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < f16Unsign(g_state.pgxp_gpr[rt(instr)].x)) ? 1.f : @@ -1189,8 +1208,8 @@ void CPU::PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1242,8 +1261,8 @@ void CPU::PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); // iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1296,8 +1315,8 @@ void CPU::PGXP::CPU_DIV(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); //// iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1353,8 +1372,8 @@ void CPU::PGXP::CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal) Validate(&g_state.pgxp_gpr[rt(instr)], rtVal); //// iCB: Only require one valid input - if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) != - ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01)) + if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_XY) != VALID_XY) != + ((g_state.pgxp_gpr[rs(instr)].flags & VALID_XY) != VALID_XY)) { MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal); MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal); @@ -1566,7 +1585,7 @@ void CPU::PGXP::CPU_SRA(u32 instr, u32 rtVal) // and it's not originally from a 3D value. Too many false positives in P2/etc. // What we probably should do is not set the valid flag on non-3D values to begin // with, only letting them become valid when used in another expression. - if (!(ret.flags & VALID_2) && sh < 16) + if (!(ret.flags & VALID_Z) && sh < 16) { ret.flags = 0; MakeValid(&ret, rdVal);