From cf5058bccb0c28ef70e9a2e137a9ffc8efff7a95 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Sat, 6 Feb 2021 18:52:57 -0500
Subject: [PATCH] thumb32: Implement MLA

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

diff --git a/src/frontend/A32/decoder/thumb32.inc b/src/frontend/A32/decoder/thumb32.inc
index eb80cb53..ea6f92e8 100644
--- a/src/frontend/A32/decoder/thumb32.inc
+++ b/src/frontend/A32/decoder/thumb32.inc
@@ -262,7 +262,7 @@ INST(thumb32_CLZ,            "CLZ",                      "111110101011nnnn1111dd
 
 // Multiply, Multiply Accumulate, and Absolute Difference
 INST(thumb32_MUL,            "MUL",                      "111110110000nnnn1111dddd0000mmmm")
-//INST(thumb32_MLA,            "MLA",                      "111110110000------------0000----")
+INST(thumb32_MLA,            "MLA",                      "111110110000nnnnaaaadddd0000mmmm")
 //INST(thumb32_MLS,            "MLS",                      "111110110000------------0001----")
 //INST(thumb32_SMULXY,         "SMULXY",                   "111110110001----1111----00------")
 //INST(thumb32_SMLAXY,         "SMLAXY",                   "111110110001------------00------")
diff --git a/src/frontend/A32/translate/impl/thumb32_multiply.cpp b/src/frontend/A32/translate/impl/thumb32_multiply.cpp
index 53371d9d..f8f32883 100644
--- a/src/frontend/A32/translate/impl/thumb32_multiply.cpp
+++ b/src/frontend/A32/translate/impl/thumb32_multiply.cpp
@@ -7,6 +7,20 @@
 
 namespace Dynarmic::A32 {
 
+bool ThumbTranslatorVisitor::thumb32_MLA(Reg n, Reg a, Reg d, Reg m) {
+    if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
+        return UnpredictableInstruction();
+    }
+
+    const auto reg_a = ir.GetRegister(a);
+    const auto reg_m = ir.GetRegister(m);
+    const auto reg_n = ir.GetRegister(n);
+    const auto result = ir.Add(ir.Mul(reg_n, reg_m), reg_a);
+
+    ir.SetRegister(d, result);
+    return true;
+}
+
 bool ThumbTranslatorVisitor::thumb32_MUL(Reg n, Reg d, Reg m) {
     if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
         return UnpredictableInstruction();
diff --git a/src/frontend/A32/translate/impl/translate_thumb.h b/src/frontend/A32/translate/impl/translate_thumb.h
index 43f87722..2f39924c 100644
--- a/src/frontend/A32/translate/impl/translate_thumb.h
+++ b/src/frontend/A32/translate/impl/translate_thumb.h
@@ -129,6 +129,7 @@ struct ThumbTranslatorVisitor final {
     bool thumb32_SEL(Reg n, Reg d, Reg m);
 
     // thumb32 multiply instructions
+    bool thumb32_MLA(Reg n, Reg a, Reg d, Reg m);
     bool thumb32_MUL(Reg n, Reg d, Reg m);
 
     // thumb32 parallel add/sub instructions