summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/interpreter/armemu.cpp54
1 files changed, 47 insertions, 7 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index c032c7168..b9ac8b9ad 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. */
@@ -5683,8 +5689,24 @@ L_stm_s_takeabort:
5683 case 0x03: 5689 case 0x03:
5684 printf ("Unhandled v6 insn: ldr\n"); 5690 printf ("Unhandled v6 insn: ldr\n");
5685 break; 5691 break;
5686 case 0x04: 5692 case 0x04: // UMAAL
5687 printf ("Unhandled v6 insn: umaal\n"); 5693 {
5694 const u8 rm_idx = BITS(8, 11);
5695 const u8 rn_idx = BITS(0, 3);
5696 const u8 rd_lo_idx = BITS(12, 15);
5697 const u8 rd_hi_idx = BITS(16, 19);
5698
5699 const u32 rm_val = state->Reg[rm_idx];
5700 const u32 rn_val = state->Reg[rn_idx];
5701 const u32 rd_lo_val = state->Reg[rd_lo_idx];
5702 const u32 rd_hi_val = state->Reg[rd_hi_idx];
5703
5704 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
5705
5706 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
5707 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
5708 return 1;
5709 }
5688 break; 5710 break;
5689 case 0x06: 5711 case 0x06:
5690 printf ("Unhandled v6 insn: mls/str\n"); 5712 printf ("Unhandled v6 insn: mls/str\n");
@@ -5925,11 +5947,29 @@ L_stm_s_takeabort:
5925 b2 = ((u8)(from >> 8) + (u8)(to >> 8)); 5947 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
5926 b3 = ((u8)(from >> 16) + (u8)(to >> 16)); 5948 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
5927 b4 = ((u8)(from >> 24) + (u8)(to >> 24)); 5949 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5928 if (b1 & 0xffffff00) state->Cpsr |= (1 << 16); 5950
5929 if (b2 & 0xffffff00) state->Cpsr |= (1 << 17); 5951 if (b1 & 0xffffff00)
5930 if (b3 & 0xffffff00) state->Cpsr |= (1 << 18); 5952 state->Cpsr |= (1 << 16);
5931 if (b4 & 0xffffff00) state->Cpsr |= (1 << 19); 5953 else
5954 state->Cpsr &= ~(1 << 16);
5955
5956 if (b2 & 0xffffff00)
5957 state->Cpsr |= (1 << 17);
5958 else
5959 state->Cpsr &= ~(1 << 17);
5960
5961 if (b3 & 0xffffff00)
5962 state->Cpsr |= (1 << 18);
5963 else
5964 state->Cpsr &= ~(1 << 18);
5965
5966
5967 if (b4 & 0xffffff00)
5968 state->Cpsr |= (1 << 19);
5969 else
5970 state->Cpsr &= ~(1 << 19);
5932 } 5971 }
5972
5933 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); 5973 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5934 return 1; 5974 return 1;
5935 } 5975 }