diff options
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.cpp | 24 |
1 files 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 83b532aac..3e79c44c0 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) { | |||
| 327 | 327 | ||
| 328 | case 24: // STMIA | 328 | case 24: // STMIA |
| 329 | case 25: // LDMIA | 329 | case 25: // LDMIA |
| 330 | *ainstr = ((tinstr & (1 << 11)) // base | 330 | if (tinstr & (1 << 11)) |
| 331 | ? 0xE8B00000 // LDMIA | 331 | { |
| 332 | : 0xE8A00000) // STMIA | 332 | unsigned int base = 0xE8900000; |
| 333 | |((tinstr & 0x0700) << (16 - 8)) // Rb | 333 | unsigned int rn = BITS(tinstr, 8, 10); |
| 334 | |(tinstr & 0x00FF); // mask8 | 334 | |
| 335 | // Writeback | ||
| 336 | if ((tinstr & (1 << rn)) == 0) | ||
| 337 | base |= (1 << 21); | ||
| 338 | |||
| 339 | *ainstr = base // base (LDMIA) | ||
| 340 | | (rn << 16) // Rn | ||
| 341 | | (tinstr & 0x00FF); // Register list | ||
| 342 | } | ||
| 343 | else | ||
| 344 | { | ||
| 345 | *ainstr = 0xE8A00000 // base (STMIA) | ||
| 346 | | (BITS(tinstr, 8, 10) << 16) // Rn | ||
| 347 | | (tinstr & 0x00FF); // Register list | ||
| 348 | } | ||
| 335 | break; | 349 | break; |
| 336 | 350 | ||
| 337 | case 26: // Bcc | 351 | case 26: // Bcc |