From 72b828ef0de764aeb35a213eb3067b7041ef19e7 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Wed, 10 Jun 2015 10:11:06 +0100 Subject: [PATCH] Finish previous revert as TortoiseGit failed epicly at it. --- pcsx2/MMI.cpp | 30 +++++++++++++++++++++++------- pcsx2/x86/iMMI.cpp | 20 ++++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/pcsx2/MMI.cpp b/pcsx2/MMI.cpp index 9aa68670e6..6375405461 100644 --- a/pcsx2/MMI.cpp +++ b/pcsx2/MMI.cpp @@ -16,7 +16,6 @@ #include "PrecompiledHeader.h" #include "Common.h" -#include "Utilities/Math.h" namespace R5900 { namespace Interpreter { @@ -146,13 +145,30 @@ namespace MMI { //*****************MMI OPCODES********************************* -void PLZCW() { - if (!_Rd_) - return; +static __fi void _PLZCW(int n) +{ + // This function counts the number of "like" bits in the source register, starting + // with the MSB and working its way down, and returns the result MINUS ONE. + // So 0xff00 would return 7, not 8. - // Return the leading sign bits, excluding the original bit - cpuRegs.GPR.r[_Rd_].UL[0] = count_leading_sign_bits(cpuRegs.GPR.r[_Rs_].SL[0]) - 1; - cpuRegs.GPR.r[_Rd_].UL[1] = count_leading_sign_bits(cpuRegs.GPR.r[_Rs_].SL[1]) - 1; + int c = 0; + s32 i = cpuRegs.GPR.r[_Rs_].SL[n]; + + // Negate the source based on the sign bit. This allows us to use a simple + // unified bit test of the MSB for either condition. + if( i >= 0 ) i = ~i; + + // shift first, compare, then increment. This excludes the sign bit from our final count. + while( i <<= 1, i < 0 ) c++; + + cpuRegs.GPR.r[_Rd_].UL[n] = c; +} + +void PLZCW() { + if (!_Rd_) return; + + _PLZCW (0); + _PLZCW (1); } __fi void PMFHL_CLAMP(u16& dst, s32 src) diff --git a/pcsx2/x86/iMMI.cpp b/pcsx2/x86/iMMI.cpp index 0183c4e5b1..74ee3d7d49 100644 --- a/pcsx2/x86/iMMI.cpp +++ b/pcsx2/x86/iMMI.cpp @@ -25,7 +25,6 @@ #include "R5900OpcodeTables.h" #include "iR5900.h" #include "iMMI.h" -#include "Utilities/Math.h" using namespace x86Emitter; @@ -67,10 +66,23 @@ void recPLZCW() _deleteEEreg(_Rd_, 0); GPR_SET_CONST(_Rd_); - // Return the leading sign bits, excluding the original bit - g_cpuConstRegs[_Rd_].UL[0] = count_leading_sign_bits(g_cpuConstRegs[_Rs_].SL[0]) - 1; - g_cpuConstRegs[_Rd_].UL[1] = count_leading_sign_bits(g_cpuConstRegs[_Rs_].SL[1]) - 1; + for(regs = 0; regs < 2; ++regs) { + u32 val = g_cpuConstRegs[_Rs_].UL[regs]; + if( val != 0 ) { + u32 setbit = val&0x80000000; + g_cpuConstRegs[_Rd_].UL[regs] = 0; + val <<= 1; + + while((val & 0x80000000) == setbit) { + g_cpuConstRegs[_Rd_].UL[regs]++; + val <<= 1; + } + } + else { + g_cpuConstRegs[_Rd_].UL[regs] = 31; + } + } return; }