VU_STAT_UPDATE assigned the bare ZSUO cause nibble to statusflag, throwing
the sticky field away, and _vuFMACflush re-derived the stickies from that
cause nibble on every pipeline entry it retired. That is idempotent right
up until an FSSET clears the sticky field: the stale cause then
regenerates the bit FSSET just cleared.
Traced on VUSTICKY_MICRO_FSSET_ASSIGNS_NOT_ORS. The FSSET merge itself is
correct -- it produces VI=801 -- and the bit comes back one entry later:
[FSSET] imm=800 sf 001 -> 801
[FLUSH] pipe[2] flagreg=10000 entry.sf=801 VI=041 -> VI=801 (FSSET arm)
[ADD] pipe[3] lower VIwrite=8 snap.sf=801
[FLUSH] pipe[3] flagreg=8 entry.sf=801 VI=801 -> VI=841 (FMAC arm)
pipe[3] is not an FMAC at all; flagreg=8 is a lower op writing integer
register VI[3]. It took the non-FSSET arm only because every retired entry
rewrites STATUS, and (sf & 0xF) << 6 turned the long-dead Z cause back
into sticky Z.
So the sticky OR moves to VU_STAT_UPDATE, where the flags are produced,
and both flush sites take the sticky field from the snapshot instead of
re-deriving it. statusflag is seeded from the whole STATUS register in
vu0ExecMicro, so carrying the sticky field in it is the documented intent
-- VU_STAT_UPDATE's original comment claimed exactly this preservation
while the code did the opposite.
Both halves are load-bearing: reverting VU_STAT_UPDATE alone fails the
Vu0AluUpper suite, reverting the flush arms alone leaves the FSSET rows
diverging.
Graduates VUSTICKY_MICRO_FSSET_CLEARS and
VUSTICKY_MICRO_FSSET_ASSIGNS_NOT_ORS from kMicroDivergences, which no
longer holds any interp-only row.
Idea by pstef.
Two mask defects in the COP2 macro flag merge, both against the console
and against the arm64 recompiler:
SYNCMSFLAGS preserved only 0xFC0, so every macro FMAC cleared the D/I
cause pair (0x30) that belongs to the div unit. VU_STAT_UPDATE assigns
statusflag outright, so those bits have to be carried from VI -- arm64
does the equivalent, keeping its denormalized bits 18-19 across
cop2EmitFlagUpdate, which EeVu0Cop2MacroLazyStatus.DivCurrentDIBitsSurviveFmac
already pinned.
SYNCFDIV preserved only 0x3CF, clearing sticky IS/DS and re-deriving them
from the current cause, so sticky D/I could never accumulate across two
div ops nor outlive a clean one.
Graduates eight interp rows from kMacroStatusDivergences:
VUSTICKY_DIV_DI_ACCUMULATE, VUSTICKY_FMAC_KEEPS_DI,
VUSTICKY_DI_ACCUMULATE_SQRT_DIV and VUSTICKY_DI_CAUSE_REPLACED_STICKY_KEPT,
slots 2 and 3 of each.
VUSTICKY_CLEAN_DIV_KEEPS_STICKY_DI stays recorded for both engines: its
slot-1 VRSQRT of -0 raises only D where hardware raises D and I, and
slots 2-3 are that missing bit carried forward -- a different defect that
happened to share the old reason text, now corrected.
Also drops VU_STAT_UPDATE's comment claiming it saves the sticky flags
and D/I settings; it assigns and saves neither, which is precisely why
the merge masks have to.
Idea by pstef.
* Added __fi and __ri, which are abbreviations for __forceinline and __releaseinline.
* Added some static qualifiers to functions in mVU, MMI ops, and others where appropriate.
* Removed some unnecessary __fastcall qualifiers (since GCC gets funny sometimes when you combine __fastcall and inlining).
* Made _1mb, _16mb, _1gb values common to all emulation code (moved from newVif/mvu to Common.h) -- they're useful! :)
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3624 96395faa-99c1-11dd-bbfe-3dabce05a288
Added interface.cpp (plugin/pcsx2 interface) and savestate.cpp to SPU2ghz, to help clean up SPU2.cpp.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@463 96395faa-99c1-11dd-bbfe-3dabce05a288