From 04f204ed006e0e3df46e62f14f6c9c627e06622e Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Thu, 4 Jun 2015 08:42:14 -0400
Subject: [PATCH] arm_dyncom_thumb: Fix handling of writeback for thumb LDMIA

---
 src/core/arm/dyncom/arm_dyncom_thumb.cpp | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index 83b532aace..3e79c44c0b 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -327,11 +327,25 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
 
     case 24: //  STMIA
     case 25: //  LDMIA
-        *ainstr = ((tinstr & (1 << 11))         // base
-               ? 0xE8B00000                     // LDMIA
-               : 0xE8A00000)                    // STMIA
-            |((tinstr & 0x0700) << (16 - 8))    // Rb
-            |(tinstr & 0x00FF);                 // mask8
+        if (tinstr & (1 << 11))
+        {
+            unsigned int base = 0xE8900000;
+            unsigned int rn = BITS(tinstr, 8, 10);
+
+            // Writeback
+            if ((tinstr & (1 << rn)) == 0)
+                base |= (1 << 21);
+
+            *ainstr = base           // base (LDMIA)
+                | (rn << 16)         // Rn
+                | (tinstr & 0x00FF); // Register list
+        }
+        else
+        {
+            *ainstr = 0xE8A00000              // base (STMIA)
+                | (BITS(tinstr, 8, 10) << 16) // Rn
+                | (tinstr & 0x00FF);          // Register list
+        }
         break;
 
     case 26: // Bcc