From 78330e634f3e4ab4c7fbfa94331c2ccbd5449889 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sun, 28 Feb 2021 21:42:06 +0000
Subject: [PATCH] thumb32: Implement SBC (immediate)

---
 src/frontend/A32/decoder/thumb32.inc           |  2 +-
 ...mb32_data_processing_modified_immediate.cpp | 18 ++++++++++++++++++
 .../A32/translate/impl/translate_thumb.h       |  1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc
index a4cbc0ea..5b7f52c8 100644
--- a/src/frontend/A32/decoder/thumb32.inc
+++ b/src/frontend/A32/decoder/thumb32.inc
@@ -65,7 +65,7 @@ INST(thumb32_EOR_imm,        "EOR (imm)",                "11110v00100Snnnn0vvvdd
 INST(thumb32_CMN_imm,        "CMN (imm)",                "11110v010001nnnn0vvv1111vvvvvvvv")
 INST(thumb32_ADD_imm_1,      "ADD (imm)",                "11110v01000Snnnn0vvvddddvvvvvvvv")
 INST(thumb32_ADC_imm,        "ADC (imm)",                "11110v01010Snnnn0vvvddddvvvvvvvv")
-//INST(thumb32_SBC_imm,        "SBC (imm)",                "11110-01011-----0---------------")
+INST(thumb32_SBC_imm,        "SBC (imm)",                "11110v01011Snnnn0vvvddddvvvvvvvv")
 //INST(thumb32_CMP_imm,        "CMP (imm)",                "11110-011011----0---1111--------")
 //INST(thumb32_SUB_imm_1,      "SUB (imm)",                "11110-01101-----0---------------")
 //INST(thumb32_RSB_imm,        "RSB (imm)",                "11110-01110-----0---------------")
diff --git a/src/frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp b/src/frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
index a6c598d0..93ced0ae 100644
--- a/src/frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
+++ b/src/frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
@@ -210,4 +210,22 @@ bool ThumbTranslatorVisitor::thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
     return true;
 }
 
+bool ThumbTranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
+    if (d == Reg::PC || n == Reg::PC) {
+        return UnpredictableInstruction();
+    }
+
+    const auto imm32 = ThumbExpandImm(i, imm3, imm8);
+    const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
+
+    ir.SetRegister(d, result.result);
+    if (S) {
+        ir.SetNFlag(ir.MostSignificantBit(result.result));
+        ir.SetZFlag(ir.IsZero(result.result));
+        ir.SetCFlag(result.carry);
+        ir.SetVFlag(result.overflow);
+    }
+    return true;
+}
+
 } // namespace Dynarmic::A32
diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h
index db707499..1268fd9a 100644
--- a/src/frontend/A32/translate/impl/translate_thumb.h
+++ b/src/frontend/A32/translate/impl/translate_thumb.h
@@ -161,6 +161,7 @@ struct ThumbTranslatorVisitor final {
     bool thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
     bool thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
     bool thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
+    bool thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
 
     // thumb32 data processing (plain binary immediate) instructions.
     bool thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);