From e74ba82093dba66519a7369019d90142b556f9b5 Mon Sep 17 00:00:00 2001
From: TellowKrinkle <tellowkrinkle@gmail.com>
Date: Wed, 23 Sep 2020 03:49:02 -0500
Subject: [PATCH] iR5900: Move repeated code into functions

---
 pcsx2/x86/ix86-32/iR5900Arit.cpp    | 286 ++++++++++------------------
 pcsx2/x86/ix86-32/iR5900AritImm.cpp |  45 ++---
 pcsx2/x86/ix86-32/iR5900MultDiv.cpp | 221 +++++----------------
 pcsx2/x86/ix86-32/iR5900Shift.cpp   |  78 +++-----
 4 files changed, 201 insertions(+), 429 deletions(-)

diff --git a/pcsx2/x86/ix86-32/iR5900Arit.cpp b/pcsx2/x86/ix86-32/iR5900Arit.cpp
index a1d52dfcaa..3e5a05abbc 100644
--- a/pcsx2/x86/ix86-32/iR5900Arit.cpp
+++ b/pcsx2/x86/ix86-32/iR5900Arit.cpp
@@ -347,76 +347,141 @@ void recDSUBU(void)
 	recDSUB();
 }
 
-//// AND
-void recAND_const()
+enum class LogicalOp
 {
-	g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & g_cpuConstRegs[_Rt_].UD[0];
-}
+	AND,
+	OR,
+	XOR,
+	NOR
+};
 
-void recAND_constv(int info, int creg, u32 vreg)
+static void recLogicalOp_constv(LogicalOp op, int info, int creg, u32 vreg)
 {
 	pxAssert(!(info & PROCESS_EE_XMM));
 
+	xImpl_G1Logic bad{};
+	const xImpl_G1Logic& xOP = op == LogicalOp::AND ? xAND
+	                         : op == LogicalOp::OR  ? xOR
+	                         : op == LogicalOp::XOR ? xXOR
+	                         : op == LogicalOp::NOR ? xOR : bad;
+	s64 fixedInput, fixedOutput, identityInput;
+	bool hasFixed = true;
+	switch (op)
+	{
+		case LogicalOp::AND:
+			fixedInput = 0;
+			fixedOutput = 0;
+			identityInput = -1;
+			break;
+		case LogicalOp::OR:
+			fixedInput = -1;
+			fixedOutput = -1;
+			identityInput = 0;
+			break;
+		case LogicalOp::XOR:
+			hasFixed = false;
+			identityInput = 0;
+			break;
+		case LogicalOp::NOR:
+			fixedInput = -1;
+			fixedOutput = 0;
+			identityInput = 0;
+			break;
+		default:
+			pxAssert(0);
+	}
+
 	GPR_reg64 cval = g_cpuConstRegs[creg];
 
 	for (int i = 0; i < 2; i++)
 	{
-		if (!cval.UL[i])
+		if (hasFixed && cval.SL[i] == (s32)fixedInput)
 		{
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], 0);
+			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], (s32)fixedOutput);
 		}
 		else if (_Rd_ == vreg)
 		{
-			if (cval.SL[i] != -1)
-				xAND(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
+			if (cval.SL[i] != identityInput)
+				xOP(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
+			if (op == LogicalOp::NOR)
+				xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
 		}
 		else
 		{
 			xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
-			if (cval.SL[i] != -1)
-				xAND(eax, cval.UL[i]);
+			if (cval.SL[i] != identityInput)
+				xOP(eax, cval.UL[i]);
+			if (op == LogicalOp::NOR)
+				xNOT(eax);
 			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
 		}
 	}
 }
 
-void recAND_consts(int info)
-{
-	recAND_constv(info, _Rs_, _Rt_);
-}
-
-void recAND_constt(int info)
-{
-	recAND_constv(info, _Rt_, _Rs_);
-}
-
-void recAND_(int info)
+static void recLogicalOp(LogicalOp op, int info)
 {
 	pxAssert(!(info & PROCESS_EE_XMM));
 
+	xImpl_G1Logic bad{};
+	const xImpl_G1Logic& xOP = op == LogicalOp::AND ? xAND
+	                         : op == LogicalOp::OR  ? xOR
+	                         : op == LogicalOp::XOR ? xXOR
+	                         : op == LogicalOp::NOR ? xOR : bad;
+	pxAssert(&xOP != &bad);
+
 	u32 rs = _Rs_, rt = _Rt_;
 	if (_Rd_ == _Rt_)
 		rs = _Rt_, rt = _Rs_;
 
 	for (int i = 0; i < 2; i++)
 	{
-		if (_Rd_ == rs)
+		if (op == LogicalOp::XOR && rs == rt)
 		{
-			if (rs == rt)
-				continue;
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xAND(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
+			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], 0);
+		}
+		else if (_Rd_ == rs)
+		{
+			if (rs != rt)
+			{
+				xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
+				xOP(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
+			}
+			if (op == LogicalOp::NOR)
+				xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
 		}
 		else
 		{
 			xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
 			if (rs != rt)
-				xAND(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
+				xOP(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
+			if (op == LogicalOp::NOR)
+				xNOT(eax);
 			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
 		}
 	}
 }
 
+//// AND
+void recAND_const()
+{
+	g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & g_cpuConstRegs[_Rt_].UD[0];
+}
+
+void recAND_consts(int info)
+{
+	recLogicalOp_constv(LogicalOp::AND, info, _Rs_, _Rt_);
+}
+
+void recAND_constt(int info)
+{
+	recLogicalOp_constv(LogicalOp::AND, info, _Rt_, _Rs_);
+}
+
+void recAND_(int info)
+{
+	recLogicalOp(LogicalOp::AND, info);
+}
+
 EERECOMPILE_CODE0(AND, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
 
 //// OR
@@ -425,68 +490,19 @@ void recOR_const()
 	g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] | g_cpuConstRegs[_Rt_].UD[0];
 }
 
-void recOR_constv(int info, int creg, u32 vreg)
-{
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	GPR_reg64 cval = g_cpuConstRegs[creg];
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (cval.SL[i] == -1)
-		{
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], -1);
-		}
-		else if (_Rd_ == vreg)
-		{
-			if (cval.UL[i])
-				xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
-			if (cval.UL[i])
-				xOR(eax, cval.UL[i]);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
-}
-
 void recOR_consts(int info)
 {
-	recOR_constv(info, _Rs_, _Rt_);
+	recLogicalOp_constv(LogicalOp::OR, info, _Rs_, _Rt_);
 }
 
 void recOR_constt(int info)
 {
-	recOR_constv(info, _Rt_, _Rs_);
+	recLogicalOp_constv(LogicalOp::OR, info, _Rt_, _Rs_);
 }
 
 void recOR_(int info)
 {
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	u32 rs = _Rs_, rt = _Rt_;
-	if (_Rd_ == _Rt_)
-		rs = _Rt_, rt = _Rs_;
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (_Rd_ == rs)
-		{
-			if (rs == rt)
-				continue;
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
-			if (rs != rt)
-				xOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
+	recLogicalOp(LogicalOp::OR, info);
 }
 
 EERECOMPILE_CODE0(OR, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
@@ -497,65 +513,19 @@ void recXOR_const()
 	g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] ^ g_cpuConstRegs[_Rt_].UD[0];
 }
 
-void recXOR_constv(int info, int creg, u32 vreg)
-{
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	GPR_reg64 cval = g_cpuConstRegs[creg];
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (_Rd_ == vreg)
-		{
-			if (cval.UL[i])
-				xXOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
-			if (cval.UL[i])
-				xXOR(eax, cval.UL[i]);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
-}
-
 void recXOR_consts(int info)
 {
-	recXOR_constv(info, _Rs_, _Rt_);
+	recLogicalOp_constv(LogicalOp::XOR, info, _Rs_, _Rt_);
 }
 
 void recXOR_constt(int info)
 {
-	recXOR_constv(info, _Rt_, _Rs_);
+	recLogicalOp_constv(LogicalOp::XOR, info, _Rt_, _Rs_);
 }
 
 void recXOR_(int info)
 {
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	u32 rs = _Rs_, rt = _Rt_;
-	if (_Rd_ == _Rt_)
-		rs = _Rt_, rt = _Rs_;
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (rs == rt)
-		{
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], 0);
-		}
-		else if (_Rd_ == rs)
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xXOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
-			xXOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
+	recLogicalOp(LogicalOp::XOR, info);
 }
 
 EERECOMPILE_CODE0(XOR, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
@@ -566,71 +536,19 @@ void recNOR_const()
 	g_cpuConstRegs[_Rd_].UD[0] = ~(g_cpuConstRegs[_Rs_].UD[0] | g_cpuConstRegs[_Rt_].UD[0]);
 }
 
-void recNOR_constv(int info, int creg, u32 vreg)
-{
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	GPR_reg64 cval = g_cpuConstRegs[creg];
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (_Rd_ == vreg)
-		{
-			if (cval.UL[i])
-				xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
-			xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
-			if (cval.UL[i])
-				xOR(eax, cval.UL[i]);
-			xNOT(eax);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
-}
-
 void recNOR_consts(int info)
 {
-	recNOR_constv(info, _Rs_, _Rt_);
+	recLogicalOp_constv(LogicalOp::NOR, info, _Rs_, _Rt_);
 }
 
 void recNOR_constt(int info)
 {
-	recNOR_constv(info, _Rt_, _Rs_);
+	recLogicalOp_constv(LogicalOp::NOR, info, _Rt_, _Rs_);
 }
 
 void recNOR_(int info)
 {
-	pxAssert(!(info & PROCESS_EE_XMM));
-
-	u32 rs = _Rs_, rt = _Rt_;
-	if (_Rd_ == _Rt_)
-		rs = _Rt_, rt = _Rs_;
-
-	for (int i = 0; i < 2; i++)
-	{
-		if (_Rd_ == rs)
-		{
-			if (rs == rt)
-			{
-				xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
-				continue;
-			}
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-			xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
-		}
-		else
-		{
-			xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
-			if (rs != rt)
-				xOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
-			xNOT(eax);
-			xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
-		}
-	}
+	recLogicalOp(LogicalOp::NOR, info);
 }
 
 EERECOMPILE_CODE0(NOR, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
diff --git a/pcsx2/x86/ix86-32/iR5900AritImm.cpp b/pcsx2/x86/ix86-32/iR5900AritImm.cpp
index bbf3b484f2..871e01df4d 100644
--- a/pcsx2/x86/ix86-32/iR5900AritImm.cpp
+++ b/pcsx2/x86/ix86-32/iR5900AritImm.cpp
@@ -194,47 +194,48 @@ void recANDI_const()
 	g_cpuConstRegs[_Rt_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & (u64)_ImmU_; // Zero-extended Immediate
 }
 
-void recLogicalOpI(int info, int op)
+enum class LogicalOp
 {
+	AND,
+	OR,
+	XOR
+};
+
+static void recLogicalOpI(int info, LogicalOp op)
+{
+	xImpl_G1Logic bad{};
+	const xImpl_G1Logic& xOP = op == LogicalOp::AND ? xAND
+	                         : op == LogicalOp::OR  ? xOR
+	                         : op == LogicalOp::XOR ? xXOR : bad;
+	pxAssert(&xOP != &bad);
+
 	if (_ImmU_ != 0)
 	{
 		if (_Rt_ == _Rs_)
 		{
-			switch (op)
-			{
-				case 0: xAND(ptr32[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]], _ImmU_); break;
-				case 1: xOR(ptr32[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]], _ImmU_); break;
-				case 2: xXOR(ptr32[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]], _ImmU_); break;
-				default: pxAssert(0);
-			}
+			xOP(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], _ImmU_);
 		}
 		else
 		{
 			xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-			if (op != 0)
+			if (op != LogicalOp::AND)
 				xMOV(edx, ptr[&cpuRegs.GPR.r[_Rs_].UL[1]]);
 
-			switch (op)
-			{
-				case 0: xAND(eax, _ImmU_); break;
-				case 1: xOR(eax, _ImmU_); break;
-				case 2: xXOR(eax, _ImmU_); break;
-				default: pxAssert(0);
-			}
+			xOP(eax, _ImmU_);
 
-			if (op != 0)
+			if (op != LogicalOp::AND)
 				xMOV(ptr[&cpuRegs.GPR.r[_Rt_].UL[1]], edx);
 			xMOV(ptr[&cpuRegs.GPR.r[_Rt_].UL[0]], eax);
 		}
 
-		if (op == 0)
+		if (op == LogicalOp::AND)
 		{
 			xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[1]], 0);
 		}
 	}
 	else
 	{
-		if (op == 0)
+		if (op == LogicalOp::AND)
 		{
 			xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]], 0);
 			xMOV(ptr32[&cpuRegs.GPR.r[_Rt_].UL[1]], 0);
@@ -254,7 +255,7 @@ void recLogicalOpI(int info, int op)
 
 void recANDI_(int info)
 {
-	recLogicalOpI(info, 0);
+	recLogicalOpI(info, LogicalOp::AND);
 }
 
 EERECOMPILE_CODEX(eeRecompileCode1, ANDI);
@@ -267,7 +268,7 @@ void recORI_const()
 
 void recORI_(int info)
 {
-	recLogicalOpI(info, 1);
+	recLogicalOpI(info, LogicalOp::OR);
 }
 
 EERECOMPILE_CODEX(eeRecompileCode1, ORI);
@@ -280,7 +281,7 @@ void recXORI_const()
 
 void recXORI_(int info)
 {
-	recLogicalOpI(info, 2);
+	recLogicalOpI(info, LogicalOp::XOR);
 }
 
 EERECOMPILE_CODEX(eeRecompileCode1, XORI);
diff --git a/pcsx2/x86/ix86-32/iR5900MultDiv.cpp b/pcsx2/x86/ix86-32/iR5900MultDiv.cpp
index 2d05c68c12..6e744916c5 100644
--- a/pcsx2/x86/ix86-32/iR5900MultDiv.cpp
+++ b/pcsx2/x86/ix86-32/iR5900MultDiv.cpp
@@ -522,35 +522,53 @@ void recDIVU1_constt(int info)
 
 EERECOMPILE_CODE0(DIVU1, XMMINFO_READS | XMMINFO_READT);
 
+static void writeBackMAddToHiLoRd(int hiloID)
+{
+	// eax -> LO, ecx -> HI
+	xCDQ();
+	if (_Rd_)
+	{
+		_eeOnWriteReg(_Rd_, 1);
+		_deleteEEreg(_Rd_, 0);
+		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
+		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
+	}
+
+	xMOV(ptr[&cpuRegs.LO.UL[hiloID * 2]], eax);
+	xMOV(ptr[&cpuRegs.LO.UL[hiloID * 2 + 1]], edx);
+
+	xMOV(ptr[&cpuRegs.HI.UL[hiloID * 2]], ecx);
+	xMOV(eax, ecx);
+	xCDQ();
+	xMOV(ptr[&cpuRegs.HI.UL[hiloID * 2 + 1]], edx);
+}
+
+static void addConstantAndWriteBackToHiLoRd(int hiloID, u64 constant)
+{
+	_deleteEEreg(XMMGPR_LO, 1);
+	_deleteEEreg(XMMGPR_HI, 1);
+
+	xMOV(eax, ptr[&cpuRegs.LO.UL[hiloID * 2]]);
+	xMOV(ecx, ptr[&cpuRegs.HI.UL[hiloID * 2]]);
+	xADD(eax, (u32)(constant & 0xffffffff));
+	xADC(ecx, (u32)(constant >> 32));
+	writeBackMAddToHiLoRd(hiloID);
+}
+
+static void addEaxEdxAndWriteBackToHiLoRd(int hiloID)
+{
+	xMOV(ecx, edx);
+	xADD(eax, ptr[&cpuRegs.LO.UL[hiloID * 2]]);
+	xADC(ecx, ptr[&cpuRegs.HI.UL[hiloID * 2]]);
+	writeBackMAddToHiLoRd(hiloID);
+}
+
 void recMADD()
 {
 	if (GPR_IS_CONST2(_Rs_, _Rt_))
 	{
 		u64 result = ((s64)g_cpuConstRegs[_Rs_].SL[0] * (s64)g_cpuConstRegs[_Rt_].SL[0]);
-		_deleteEEreg(XMMGPR_LO, 1);
-		_deleteEEreg(XMMGPR_HI, 1);
-
-		// dadd
-		xMOV(eax, ptr[&cpuRegs.LO.UL[0]]);
-		xMOV(ecx, ptr[&cpuRegs.HI.UL[0]]);
-		xADD(eax, (u32)result & 0xffffffff);
-		xADC(ecx, (u32)(result >> 32));
-		xCDQ();
-		if (_Rd_)
-		{
-			_eeOnWriteReg(_Rd_, 1);
-			_deleteEEreg(_Rd_, 0);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-		}
-
-		xMOV(ptr[&cpuRegs.LO.UL[0]], eax);
-		xMOV(ptr[&cpuRegs.LO.UL[1]], edx);
-
-		xMOV(ptr[&cpuRegs.HI.UL[0]], ecx);
-		xMOV(eax, ecx);
-		xCDQ();
-		xMOV(ptr[&cpuRegs.HI.UL[1]], edx);
+		addConstantAndWriteBackToHiLoRd(0, result);
 		return;
 	}
 
@@ -575,25 +593,7 @@ void recMADD()
 		xMUL(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
 	}
 
-	xMOV(ecx, edx);
-	xADD(eax, ptr[&cpuRegs.LO.UL[0]]);
-	xADC(ecx, ptr[&cpuRegs.HI.UL[0]]);
-	xCDQ();
-	if (_Rd_)
-	{
-		_eeOnWriteReg(_Rd_, 1);
-		_deleteEEreg(_Rd_, 0);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-	}
-
-	xMOV(ptr[&cpuRegs.LO.UL[0]], eax);
-	xMOV(ptr[&cpuRegs.LO.UL[1]], edx);
-
-	xMOV(ptr[&cpuRegs.HI.UL[0]], ecx);
-	xMOV(eax, ecx);
-	xCDQ();
-	xMOV(ptr[&cpuRegs.HI.UL[1]], edx);
+	addEaxEdxAndWriteBackToHiLoRd(0);
 }
 
 void recMADDU()
@@ -601,30 +601,7 @@ void recMADDU()
 	if (GPR_IS_CONST2(_Rs_, _Rt_))
 	{
 		u64 result = ((u64)g_cpuConstRegs[_Rs_].UL[0] * (u64)g_cpuConstRegs[_Rt_].UL[0]);
-		_deleteEEreg(XMMGPR_LO, 1);
-		_deleteEEreg(XMMGPR_HI, 1);
-
-		// dadd
-		xMOV(eax, ptr[&cpuRegs.LO.UL[0]]);
-		xMOV(ecx, ptr[&cpuRegs.HI.UL[0]]);
-		xADD(eax, (u32)result & 0xffffffff);
-		xADC(ecx, (u32)(result >> 32));
-		xCDQ();
-		if (_Rd_)
-		{
-			_eeOnWriteReg(_Rd_, 1);
-			_deleteEEreg(_Rd_, 0);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-		}
-
-		xMOV(ptr[&cpuRegs.LO.UL[0]], eax);
-		xMOV(ptr[&cpuRegs.LO.UL[1]], edx);
-
-		xMOV(ptr[&cpuRegs.HI.UL[0]], ecx);
-		xMOV(eax, ecx);
-		xCDQ();
-		xMOV(ptr[&cpuRegs.HI.UL[1]], edx);
+		addConstantAndWriteBackToHiLoRd(0, result);
 		return;
 	}
 
@@ -649,25 +626,7 @@ void recMADDU()
 		xUMUL(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
 	}
 
-	xMOV(ecx, edx);
-	xADD(eax, ptr[&cpuRegs.LO.UL[0]]);
-	xADC(ecx, ptr[&cpuRegs.HI.UL[0]]);
-	xCDQ();
-	if (_Rd_)
-	{
-		_eeOnWriteReg(_Rd_, 1);
-		_deleteEEreg(_Rd_, 0);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-	}
-
-	xMOV(ptr[&cpuRegs.LO.UL[0]], eax);
-	xMOV(ptr[&cpuRegs.LO.UL[1]], edx);
-
-	xMOV(ptr[&cpuRegs.HI.UL[0]], ecx);
-	xMOV(eax, ecx);
-	xCDQ();
-	xMOV(ptr[&cpuRegs.HI.UL[1]], edx);
+	addEaxEdxAndWriteBackToHiLoRd(0);
 }
 
 void recMADD1()
@@ -675,30 +634,7 @@ void recMADD1()
 	if (GPR_IS_CONST2(_Rs_, _Rt_))
 	{
 		u64 result = ((s64)g_cpuConstRegs[_Rs_].SL[0] * (s64)g_cpuConstRegs[_Rt_].SL[0]);
-		_deleteEEreg(XMMGPR_LO, 1);
-		_deleteEEreg(XMMGPR_HI, 1);
-
-		// dadd
-		xMOV(eax, ptr[&cpuRegs.LO.UL[2]]);
-		xMOV(ecx, ptr[&cpuRegs.HI.UL[2]]);
-		xADD(eax, (u32)result & 0xffffffff);
-		xADC(ecx, (u32)(result >> 32));
-		xCDQ();
-		if (_Rd_)
-		{
-			_eeOnWriteReg(_Rd_, 1);
-			_deleteEEreg(_Rd_, 0);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-		}
-
-		xMOV(ptr[&cpuRegs.LO.UL[2]], eax);
-		xMOV(ptr[&cpuRegs.LO.UL[3]], edx);
-
-		xMOV(ptr[&cpuRegs.HI.UL[2]], ecx);
-		xMOV(eax, ecx);
-		xCDQ();
-		xMOV(ptr[&cpuRegs.HI.UL[3]], edx);
+		addConstantAndWriteBackToHiLoRd(1, result);
 		return;
 	}
 
@@ -723,25 +659,7 @@ void recMADD1()
 		xMUL(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
 	}
 
-	xMOV(ecx, edx);
-	xADD(eax, ptr[&cpuRegs.LO.UL[2]]);
-	xADC(ecx, ptr[&cpuRegs.HI.UL[2]]);
-	xCDQ();
-	if (_Rd_)
-	{
-		_eeOnWriteReg(_Rd_, 1);
-		_deleteEEreg(_Rd_, 0);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-	}
-
-	xMOV(ptr[&cpuRegs.LO.UL[2]], eax);
-	xMOV(ptr[&cpuRegs.LO.UL[3]], edx);
-
-	xMOV(ptr[&cpuRegs.HI.UL[2]], ecx);
-	xMOV(eax, ecx);
-	xCDQ();
-	xMOV(ptr[&cpuRegs.HI.UL[3]], edx);
+	addEaxEdxAndWriteBackToHiLoRd(1);
 }
 
 void recMADDU1()
@@ -749,30 +667,7 @@ void recMADDU1()
 	if (GPR_IS_CONST2(_Rs_, _Rt_))
 	{
 		u64 result = ((u64)g_cpuConstRegs[_Rs_].UL[0] * (u64)g_cpuConstRegs[_Rt_].UL[0]);
-		_deleteEEreg(XMMGPR_LO, 1);
-		_deleteEEreg(XMMGPR_HI, 1);
-
-		// dadd
-		xMOV(eax, ptr[&cpuRegs.LO.UL[2]]);
-		xMOV(ecx, ptr[&cpuRegs.HI.UL[2]]);
-		xADD(eax, (u32)result & 0xffffffff);
-		xADC(ecx, (u32)(result >> 32));
-		xCDQ();
-		if (_Rd_)
-		{
-			_eeOnWriteReg(_Rd_, 1);
-			_deleteEEreg(_Rd_, 0);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-			xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-		}
-
-		xMOV(ptr[&cpuRegs.LO.UL[2]], eax);
-		xMOV(ptr[&cpuRegs.LO.UL[3]], edx);
-
-		xMOV(ptr[&cpuRegs.HI.UL[2]], ecx);
-		xMOV(eax, ecx);
-		xCDQ();
-		xMOV(ptr[&cpuRegs.HI.UL[3]], edx);
+		addConstantAndWriteBackToHiLoRd(1, result);
 		return;
 	}
 
@@ -797,25 +692,7 @@ void recMADDU1()
 		xUMUL(ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
 	}
 
-	xMOV(ecx, edx);
-	xADD(eax, ptr[&cpuRegs.LO.UL[2]]);
-	xADC(ecx, ptr[&cpuRegs.HI.UL[2]]);
-	xCDQ();
-	if (_Rd_)
-	{
-		_eeOnWriteReg(_Rd_, 1);
-		_deleteEEreg(_Rd_, 0);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-		xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
-	}
-
-	xMOV(ptr[&cpuRegs.LO.UL[2]], eax);
-	xMOV(ptr[&cpuRegs.LO.UL[3]], edx);
-
-	xMOV(ptr[&cpuRegs.HI.UL[2]], ecx);
-	xMOV(eax, ecx);
-	xCDQ();
-	xMOV(ptr[&cpuRegs.HI.UL[3]], edx);
+	addEaxEdxAndWriteBackToHiLoRd(1);
 }
 
 
diff --git a/pcsx2/x86/ix86-32/iR5900Shift.cpp b/pcsx2/x86/ix86-32/iR5900Shift.cpp
index 4bafddf413..67c056fde4 100644
--- a/pcsx2/x86/ix86-32/iR5900Shift.cpp
+++ b/pcsx2/x86/ix86-32/iR5900Shift.cpp
@@ -341,6 +341,27 @@ EERECOMPILE_CODEX(eeRecompileCode2, DSRA32);
 * Format:  OP rd, rt, rs                                 *
 *********************************************************/
 
+static void recShiftV_constt(const xImpl_Group2& shift)
+{
+	xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
+
+	xMOV(eax, g_cpuConstRegs[_Rt_].UL[0]);
+	shift(eax, cl);
+
+	eeSignExtendTo(_Rd_);
+}
+
+static void recShiftV(const xImpl_Group2& shift)
+{
+	xMOV(eax, ptr[&cpuRegs.GPR.r[_Rt_].UL[0]]);
+	if (_Rs_ != 0)
+	{
+		xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
+		shift(eax, cl);
+	}
+	eeSignExtendTo(_Rd_);
+}
+
 __aligned16 u32 s_sa[4] = {0x1f, 0, 0x3f, 0};
 
 void recSetShiftV(int info, int* rsreg, int* rtreg, int* rdreg, int* rstemp)
@@ -395,27 +416,12 @@ void recSLLV_consts(int info)
 
 void recSLLV_constt(int info)
 {
-	xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-
-	xMOV(eax, g_cpuConstRegs[_Rt_].UL[0]);
-	xAND(ecx, 0x1f);
-	xSHL(eax, cl);
-
-	eeSignExtendTo(_Rd_);
+	recShiftV_constt(xSHL);
 }
 
 void recSLLV_(int info)
 {
-	xMOV(eax, ptr[&cpuRegs.GPR.r[_Rt_].UL[0]]);
-	if (_Rs_ != 0)
-	{
-		xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-		xAND(ecx, 0x1f);
-		xSHL(eax, cl);
-	}
-	xCDQ();
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
+	recShiftV(xSHL);
 }
 
 EERECOMPILE_CODE0(SLLV, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
@@ -433,27 +439,12 @@ void recSRLV_consts(int info)
 
 void recSRLV_constt(int info)
 {
-	xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-
-	xMOV(eax, g_cpuConstRegs[_Rt_].UL[0]);
-	xAND(ecx, 0x1f);
-	xSHR(eax, cl);
-
-	eeSignExtendTo(_Rd_);
+	recShiftV_constt(xSHR);
 }
 
 void recSRLV_(int info)
 {
-	xMOV(eax, ptr[&cpuRegs.GPR.r[_Rt_].UL[0]]);
-	if (_Rs_ != 0)
-	{
-		xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-		xAND(ecx, 0x1f);
-		xSHR(eax, cl);
-	}
-	xCDQ();
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
+	recShiftV(xSHR);
 }
 
 EERECOMPILE_CODE0(SRLV, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);
@@ -471,27 +462,12 @@ void recSRAV_consts(int info)
 
 void recSRAV_constt(int info)
 {
-	xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-
-	xMOV(eax, g_cpuConstRegs[_Rt_].UL[0]);
-	xAND(ecx, 0x1f);
-	xSAR(eax, cl);
-
-	eeSignExtendTo(_Rd_);
+	recShiftV_constt(xSAR);
 }
 
 void recSRAV_(int info)
 {
-	xMOV(eax, ptr[&cpuRegs.GPR.r[_Rt_].UL[0]]);
-	if (_Rs_ != 0)
-	{
-		xMOV(ecx, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
-		xAND(ecx, 0x1f);
-		xSAR(eax, cl);
-	}
-	xCDQ();
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
-	xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[1]], edx);
+	recShiftV(xSAR);
 }
 
 EERECOMPILE_CODE0(SRAV, XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED);