summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-25 21:57:31 -0500
committerGravatar bunnei2014-12-25 21:57:31 -0500
commit9c8ec675d91729b26dd1d7b3bd190008c711a146 (patch)
tree2388492532bf4d5757207467e3e74fe4e268e4d4 /src/core/arm/interpreter/armemu.cpp
parentMerge pull request #341 from lioncash/moresmops (diff)
parentarmemu: Implement SMMUL, SMMLA, and SMMLS. (diff)
downloadyuzu-9c8ec675d91729b26dd1d7b3bd190008c711a146.tar.gz
yuzu-9c8ec675d91729b26dd1d7b3bd190008c711a146.tar.xz
yuzu-9c8ec675d91729b26dd1d7b3bd190008c711a146.zip
Merge pull request #343 from lioncash/smmla
armemu: Implement SMMUL, SMMLA, and SMMLS.
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 449fd3640..d54dbeac5 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6531,8 +6531,36 @@ L_stm_s_takeabort:
6531 return 1; 6531 return 1;
6532 } 6532 }
6533 break; 6533 break;
6534 case 0x75: 6534 case 0x75: // SMMLA, SMMUL, and SMMLS
6535 printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); 6535 {
6536 const u8 rm_idx = BITS(8, 11);
6537 const u8 rn_idx = BITS(0, 3);
6538 const u8 ra_idx = BITS(12, 15);
6539 const u8 rd_idx = BITS(16, 19);
6540 const bool do_round = (BIT(5) == 1);
6541
6542 const u32 rm_val = state->Reg[rm_idx];
6543 const u32 rn_val = state->Reg[rn_idx];
6544
6545 // Assume SMMUL by default.
6546 s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
6547
6548 if (ra_idx != 15) {
6549 const u32 ra_val = state->Reg[ra_idx];
6550
6551 // SMMLA, otherwise SMMLS
6552 if (BIT(6) == 0)
6553 result += ((s64)ra_val << 32);
6554 else
6555 result = ((s64)ra_val << 32) - result;
6556 }
6557
6558 if (do_round)
6559 result += 0x80000000;
6560
6561 state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
6562 return 1;
6563 }
6536 break; 6564 break;
6537 case 0x78: 6565 case 0x78:
6538 if (BITS(20, 24) == 0x18) 6566 if (BITS(20, 24) == 0x18)