summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/interpreter/armemu.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index b9ac8b9ad..399ee0886 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6326,7 +6326,30 @@ L_stm_s_takeabort:
6326 printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); 6326 printf ("Unhandled v6 insn: smmla/smmls/smmul\n");
6327 break; 6327 break;
6328 case 0x78: 6328 case 0x78:
6329 printf ("Unhandled v6 insn: usad/usada8\n"); 6329 if (BITS(20, 24) == 0x18)
6330 {
6331 const u8 rm_idx = BITS(8, 11);
6332 const u8 rn_idx = BITS(0, 3);
6333 const u8 rd_idx = BITS(16, 19);
6334
6335 const u32 rm_val = state->Reg[rm_idx];
6336 const u32 rn_val = state->Reg[rn_idx];
6337
6338 const u8 diff1 = (u8)::abs((rn_val & 0xFF) - (rm_val & 0xFF));
6339 const u8 diff2 = (u8)::abs(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF));
6340 const u8 diff3 = (u8)::abs(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF));
6341 const u8 diff4 = (u8)::abs(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
6342
6343 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
6344
6345 // Op is USADA8 if true.
6346 const u8 ra_idx = BITS(12, 15);
6347 if (ra_idx != 15)
6348 finalDif += state->Reg[ra_idx];
6349
6350 state->Reg[rd_idx] = finalDif;
6351 return 1;
6352 }
6330 break; 6353 break;
6331 case 0x7a: 6354 case 0x7a:
6332 printf ("Unhandled v6 insn: usbfx\n"); 6355 printf ("Unhandled v6 insn: usbfx\n");