diff options
| author | 2014-12-25 21:57:31 -0500 | |
|---|---|---|
| committer | 2014-12-25 21:57:31 -0500 | |
| commit | 9c8ec675d91729b26dd1d7b3bd190008c711a146 (patch) | |
| tree | 2388492532bf4d5757207467e3e74fe4e268e4d4 /src/core/arm/interpreter/armemu.cpp | |
| parent | Merge pull request #341 from lioncash/moresmops (diff) | |
| parent | armemu: Implement SMMUL, SMMLA, and SMMLS. (diff) | |
| download | yuzu-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.cpp | 32 |
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) |