summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/FileSystemGCWii.cpp
diff options
context:
space:
mode:
authorSintendo <bram.speeckaert@gmail.com>2021-01-09 22:52:18 +0100
committerSintendo <bram.speeckaert@gmail.com>2021-01-09 22:52:18 +0100
commit305cd31bd9eaa05b4453160afcdfaeaa9618c699 (patch)
treef27d010757c38d6908d6d904f501205d2afa0271 /Source/Core/DiscIO/FileSystemGCWii.cpp
parent0776263c5e1f205f77c4836c1489c7200da34763 (diff)
Jit64: Fix FinalizeCarryOverflow XER[OV/SO]
FinalizeCarryOverflow didn't maintain XER[OV/SO] properly due to an oversight. Here's the code it would generate: 0: 9c pushf 1: 80 65 3b fe and BYTE PTR [rbp+0x3b],0xfe 5: 71 04 jno b <jno> 7: c6 45 3b 03 mov BYTE PTR [rbp+0x3b],0x3 000000000000000b <jno>: b: 9d popf At first glance it seems reasonable. The host flags are carefully preserved with PUSHF. The AND instruction clears XER[OV]. Next, an conditional branch checks the host's overflow flag and, if needed, skips over a MOV that sets XER[OV/SO]. Finally, host flags are restored with POPF. However, the AND instruction also clears the host's overflow flag. As a result, the branch that follows it is always taken and the MOV is always skipped. The end result is that XER[OV] is always cleared while XER[SO] is left unchanged. Putting POPF immediately after the AND would fix this, but we already have GenerateOverflow doing it correctly (and without the PUSHF/POPF shenanigans too). So let's just use that instead.
Diffstat (limited to 'Source/Core/DiscIO/FileSystemGCWii.cpp')
0 files changed, 0 insertions, 0 deletions