diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 5752d116f..5074542a4 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -1356,7 +1356,13 @@ mainswitch: | |||
| 1356 | } | 1356 | } |
| 1357 | break; | 1357 | break; |
| 1358 | 1358 | ||
| 1359 | case 0x04: /* SUB reg */ | 1359 | case 0x04: /* SUB reg */ |
| 1360 | // Signifies UMAAL | ||
| 1361 | if (state->is_v6 && BITS(4, 7) == 0x09) { | ||
| 1362 | if (handle_v6_insn(state, instr)) | ||
| 1363 | break; | ||
| 1364 | } | ||
| 1365 | |||
| 1360 | #ifdef MODET | 1366 | #ifdef MODET |
| 1361 | if (BITS (4, 7) == 0xB) { | 1367 | if (BITS (4, 7) == 0xB) { |
| 1362 | /* STRH immediate offset, no write-back, down, post indexed. */ | 1368 | /* STRH immediate offset, no write-back, down, post indexed. */ |
| @@ -5677,8 +5683,24 @@ L_stm_s_takeabort: | |||
| 5677 | case 0x03: | 5683 | case 0x03: |
| 5678 | printf ("Unhandled v6 insn: ldr\n"); | 5684 | printf ("Unhandled v6 insn: ldr\n"); |
| 5679 | break; | 5685 | break; |
| 5680 | case 0x04: | 5686 | case 0x04: // UMAAL |
| 5681 | printf ("Unhandled v6 insn: umaal\n"); | 5687 | { |
| 5688 | const u8 rm_idx = BITS(8, 11); | ||
| 5689 | const u8 rn_idx = BITS(0, 3); | ||
| 5690 | const u8 rd_lo_idx = BITS(12, 15); | ||
| 5691 | const u8 rd_hi_idx = BITS(16, 19); | ||
| 5692 | |||
| 5693 | const u32 rm_val = state->Reg[rm_idx]; | ||
| 5694 | const u32 rn_val = state->Reg[rn_idx]; | ||
| 5695 | const u32 rd_lo_val = state->Reg[rd_lo_idx]; | ||
| 5696 | const u32 rd_hi_val = state->Reg[rd_hi_idx]; | ||
| 5697 | |||
| 5698 | const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val; | ||
| 5699 | |||
| 5700 | state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF); | ||
| 5701 | state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF); | ||
| 5702 | return 1; | ||
| 5703 | } | ||
| 5682 | break; | 5704 | break; |
| 5683 | case 0x06: | 5705 | case 0x06: |
| 5684 | printf ("Unhandled v6 insn: mls/str\n"); | 5706 | printf ("Unhandled v6 insn: mls/str\n"); |