From 8efb2a5b059327fa3f24ce1ba4e079d3dd7cf920 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sun, 28 Feb 2021 21:43:45 +0000
Subject: [PATCH] thumb32: Implement CMP (immediate)

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

diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc
index 5b7f52c8..d8ce6862 100644
--- a/src/frontend/A32/decoder/thumb32.inc
+++ b/src/frontend/A32/decoder/thumb32.inc
@@ -66,7 +66,7 @@ INST(thumb32_CMN_imm,        "CMN (imm)",                "11110v010001nnnn0vvv11
 INST(thumb32_ADD_imm_1,      "ADD (imm)",                "11110v01000Snnnn0vvvddddvvvvvvvv")
 INST(thumb32_ADC_imm,        "ADC (imm)",                "11110v01010Snnnn0vvvddddvvvvvvvv")
 INST(thumb32_SBC_imm,        "SBC (imm)",                "11110v01011Snnnn0vvvddddvvvvvvvv")
-//INST(thumb32_CMP_imm,        "CMP (imm)",                "11110-011011----0---1111--------")
+INST(thumb32_CMP_imm,        "CMP (imm)",                "11110v011011nnnn0vvv1111vvvvvvvv")
 //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 93ced0ae..0d07f7a6 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
@@ -228,4 +228,19 @@ bool ThumbTranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
     return true;
 }
 
+bool ThumbTranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) {
+    if (n == Reg::PC) {
+        return UnpredictableInstruction();
+    }
+
+    const auto imm32 = ThumbExpandImm(i, imm3, imm8);
+    const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
+
+    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 1268fd9a..ad9466ef 100644
--- a/src/frontend/A32/translate/impl/translate_thumb.h
+++ b/src/frontend/A32/translate/impl/translate_thumb.h
@@ -162,6 +162,7 @@ struct ThumbTranslatorVisitor final {
     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);
+    bool thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, 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);