From 9c2c89b7e1a93b52b53c567116b0d24bc4cb6ce7 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Mon, 12 Jan 2015 00:01:46 -0500
Subject: [PATCH 1/3] dyncom: Add a helper function for addition with a carry

---
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 21 ++++++++-----------
 src/core/arm/interpreter/armsupp.cpp          | 16 ++++++++++++++
 src/core/arm/skyeye_common/armdefs.h          |  1 +
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index bf864c7a7a..4c0a8f5cb9 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -4003,16 +4003,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     ADC_INST:
     {
-        adc_inst *inst_cream = (adc_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            u32 left = RN;
-            u32 right = SHIFTER_OPERAND;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            adc_inst* const inst_cream = (adc_inst*)inst_base->component;
 
-            u64 unsigned_sum = (left + right + cpu->CFlag);
-            s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)cpu->CFlag;
-            u32 result = (unsigned_sum & 0xFFFFFFFF);
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
 
-            RD = result;
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4020,10 +4017,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(result);
-                UPDATE_ZFLAG(result);
-                UPDATE_CFLAG_CARRY_FROM_ADD(left, right, cpu->CFlag);
-                cpu->VFlag = ((s64)(s32)result != signed_sum);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(adc_inst));
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 68ac2a0ce8..e2626eefb4 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -418,6 +418,22 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
     }
 }
 
+// Add with carry, indicates if a carry-out or signed overflow occurred.
+u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred)
+{
+    u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in;
+    s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in;
+    u64 result = (unsigned_sum & 0xFFFFFFFF);
+
+    if (carry_out_occurred)
+        *carry_out_occurred = (result != unsigned_sum);
+
+    if (overflow_occurred)
+        *overflow_occurred = ((s64)(s32)result != signed_sum);
+
+    return (u32)result;
+}
+
 // Compute whether an addition of A and B, giving RESULT, overflowed.
 bool AddOverflow(ARMword a, ARMword b, ARMword result)
 {
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 1b2cef4513..560b51a9f4 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -795,6 +795,7 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
 extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
 extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
 
+extern u32 AddWithCarry(u32, u32, u32, bool*, bool*);
 extern bool ARMul_AddOverflowQ(ARMword, ARMword);
 
 extern u8 ARMul_SignedSaturatedAdd8(u8, u8);

From 3ace75a49f54d73a1d3ba876ef8dc0b03adc677f Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Mon, 12 Jan 2015 00:43:12 -0500
Subject: [PATCH 2/3] dyncom: Fix overflow flag setting for ADD/RSB/RSC/SUB/SBC

Also cleans up CMN, and CMP.
---
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 79 ++++++++++---------
 1 file changed, 41 insertions(+), 38 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 4c0a8f5cb9..88982d5fb7 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -4034,14 +4034,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     ADD_INST:
     {
-        add_inst *inst_cream = (add_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            if (inst_cream->Rn == 15) {
-                lop += 2 * GET_INST_SIZE(cpu);
-            }
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop + rop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            add_inst* const inst_cream = (add_inst*)inst_base->component;
+
+            u32 rn_val = RN;
+            if (inst_cream->Rn == 15)
+                rn_val += 2 * GET_INST_SIZE(cpu);
+
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4049,10 +4052,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
-                UPDATE_CFLAG(dst, lop, rop);
-                UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(add_inst));
@@ -5459,11 +5462,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 
     SBC_INST:
     {
-        sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = SHIFTER_OPERAND + !cpu->CFlag;
-            rop = RN;
-            RD = dst = rop - lop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
+
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -5471,15 +5476,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
-
-                if(rop >= !cpu->CFlag)
-                    UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
-                else
-                    UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
-
-                UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(sbc_inst));
@@ -6257,14 +6257,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     SUB_INST:
     {
-        sub_inst *inst_cream = (sub_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            if (inst_cream->Rn == 15) {
-                lop += 8;
-            }
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop - rop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            sub_inst* const inst_cream = (sub_inst*)inst_base->component;
+
+            u32 rn_val = RN;
+            if (inst_cream->Rn == 15)
+                rn_val += 8;
+
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -6272,10 +6275,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
-                UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
-                UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(sub_inst));

From 2843d1b98b74b7642f086833da09fd0b50f8ad57 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Mon, 12 Jan 2015 01:11:46 -0500
Subject: [PATCH 3/3] dyncom: Get rid of unnecessary outer-scope variables in
 InterpreterMainLoop

---
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 205 +++++++++---------
 1 file changed, 108 insertions(+), 97 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 88982d5fb7..bae280b1c3 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -3967,16 +3967,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
         &&INIT_INST_LENGTH,&&END
         };
 #endif
-    arm_inst * inst_base;
-    unsigned int lop, rop, dst;
+    arm_inst* inst_base;
     unsigned int addr;
     unsigned int phys_addr;
-    unsigned int last_pc = 0;
     unsigned int num_instrs = 0;
 
-    static unsigned int last_physical_base = 0, last_logical_base = 0;
     int ptr;
-    bool single_step = (cpu->NumInstrsToExecute == 1);
 
     LOAD_NZCVT;
     DISPATCH:
@@ -4071,9 +4067,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     {
         and_inst *inst_cream = (and_inst *)inst_base->component;
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop & rop;
+            u32 lop = RN;
+            u32 rop = SHIFTER_OPERAND;
+            RD = lop & rop;
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4081,8 +4077,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -4114,12 +4110,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     {
         bic_inst *inst_cream = (bic_inst *)inst_base->component;
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
+            u32 lop = RN;
             if (inst_cream->Rn == 15) {
                 lop += 2 * GET_INST_SIZE(cpu);
             }
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop & (~rop);
+            u32 rop = SHIFTER_OPERAND;
+            RD = lop & (~rop);
             if ((inst_cream->S) && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4127,8 +4123,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -4234,15 +4230,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     CMN_INST:
     {
-        cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            rop = SHIFTER_OPERAND;
-            dst = lop + rop;
-            UPDATE_NFLAG(dst);
-            UPDATE_ZFLAG(dst);
-            UPDATE_CFLAG(dst, lop, rop);
-            UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
+
+            bool carry;
+            bool overflow;
+            u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow);
+
+            UPDATE_NFLAG(result);
+            UPDATE_ZFLAG(result);
+            cpu->CFlag = carry;
+            cpu->VFlag = overflow;
         }
         cpu->Reg[15] += GET_INST_SIZE(cpu);
         INC_PC(sizeof(cmn_inst));
@@ -4251,19 +4249,21 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     CMP_INST:
     {
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
-            lop = RN;
-            if (inst_cream->Rn == 15) {
-                lop += 2 * GET_INST_SIZE(cpu);
-            }
-            rop = SHIFTER_OPERAND;
-            dst = lop - rop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
 
-            UPDATE_NFLAG(dst);
-            UPDATE_ZFLAG(dst);
-            UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
-            UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+            u32 rn_val = RN;
+            if (inst_cream->Rn == 15)
+                rn_val += 2 * GET_INST_SIZE(cpu);
+
+            bool carry;
+            bool overflow;
+            u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
+
+            UPDATE_NFLAG(result);
+            UPDATE_ZFLAG(result);
+            cpu->CFlag = carry;
+            cpu->VFlag = overflow;
         }
         cpu->Reg[15] += GET_INST_SIZE(cpu);
         INC_PC(sizeof(cmp_inst));
@@ -4321,12 +4321,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     {
         eor_inst *inst_cream = (eor_inst *)inst_base->component;
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
+            u32 lop = RN;
             if (inst_cream->Rn == 15) {
                 lop += 2 * GET_INST_SIZE(cpu);
             }
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop ^ rop;
+            u32 rop = SHIFTER_OPERAND;
+            RD = lop ^ rop;
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4334,8 +4334,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -4852,10 +4852,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                 LOG_ERROR(Core_ARM11, "invalid operands for MLA");
                 CITRA_IGNORE_EXIT(-1);
             }
-            RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
+            RD = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
             if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(mla_inst));
@@ -4871,7 +4871,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     {
         mov_inst *inst_cream = (mov_inst *)inst_base->component;
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            RD = dst = SHIFTER_OPERAND;
+            RD = SHIFTER_OPERAND;
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -4879,8 +4879,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -5016,10 +5016,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
             uint64_t rm = RM;
             uint64_t rs = RS;
-            RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
+            RD = static_cast<uint32_t>((rm * rs) & 0xffffffff);
             if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(mul_inst));
@@ -5033,9 +5033,11 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     MVN_INST:
     {
-        mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            RD = dst = ~SHIFTER_OPERAND;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
+
+            RD = ~SHIFTER_OPERAND;
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -5043,8 +5045,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -5059,11 +5061,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     ORR_INST:
     {
-        orr_inst *inst_cream = (orr_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            rop = SHIFTER_OPERAND;
-            RD = dst = lop | rop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            orr_inst* const inst_cream = (orr_inst*)inst_base->component;
+
+            u32 lop = RN;
+            u32 rop = SHIFTER_OPERAND;
+            RD = lop | rop;
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -5071,8 +5075,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
                 UPDATE_CFLAG_WITH_SC;
             }
             if (inst_cream->Rd == 15) {
@@ -5292,14 +5296,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     RFE_INST:
     RSB_INST:
     {
-        rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            rop = RN;
-            lop = SHIFTER_OPERAND;
-            if (inst_cream->Rn == 15) {
-                rop += 2 * GET_INST_SIZE(cpu);;
-            }
-            RD = dst = lop - rop;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
+
+            u32 rn_val = RN;
+            if (inst_cream->Rn == 15)
+                rn_val += 2 * GET_INST_SIZE(cpu);
+
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -5307,10 +5314,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
-                UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
-                UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(rsb_inst));
@@ -5324,11 +5331,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     RSC_INST:
     {
-        rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            lop = RN;
-            rop = SHIFTER_OPERAND;
-            RD = dst = rop - lop - !cpu->CFlag;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
+
+            bool carry;
+            bool overflow;
+            RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
@@ -5336,10 +5345,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
-                UPDATE_NFLAG(dst);
-                UPDATE_ZFLAG(dst);
-                UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
-                UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
+                UPDATE_NFLAG(RD);
+                UPDATE_ZFLAG(RD);
+                cpu->CFlag = carry;
+                cpu->VFlag = overflow;
             }
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(rsc_inst));
@@ -6406,18 +6415,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 
     TEQ_INST:
     {
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            teq_inst *inst_cream = (teq_inst *)inst_base->component;
-            lop = RN;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            teq_inst* const inst_cream = (teq_inst*)inst_base->component;
+
+            u32 lop = RN;
+            u32 rop = SHIFTER_OPERAND;
 
             if (inst_cream->Rn == 15)
                 lop += GET_INST_SIZE(cpu) * 2;
 
-            rop = SHIFTER_OPERAND;
-            dst = lop ^ rop;
+            u32 result = lop ^ rop;
 
-            UPDATE_NFLAG(dst);
-            UPDATE_ZFLAG(dst);
+            UPDATE_NFLAG(result);
+            UPDATE_ZFLAG(result);
             UPDATE_CFLAG_WITH_SC;
         }
         cpu->Reg[15] += GET_INST_SIZE(cpu);
@@ -6427,18 +6437,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
     }
     TST_INST:
     {
-        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
-            tst_inst *inst_cream = (tst_inst *)inst_base->component;
-            lop = RN;
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            tst_inst* const inst_cream = (tst_inst*)inst_base->component;
+
+            u32 lop = RN;
+            u32 rop = SHIFTER_OPERAND;
 
             if (inst_cream->Rn == 15)
                 lop += GET_INST_SIZE(cpu) * 2;
 
-            rop = SHIFTER_OPERAND;
-            dst = lop & rop;
+            u32 result = lop & rop;
 
-            UPDATE_NFLAG(dst);
-            UPDATE_ZFLAG(dst);
+            UPDATE_NFLAG(result);
+            UPDATE_ZFLAG(result);
             UPDATE_CFLAG_WITH_SC;
         }
         cpu->Reg[15] += GET_INST_SIZE(cpu);