summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-18 10:04:31 -0500
committerGravatar bunnei2014-12-18 10:04:31 -0500
commit8ac22e7efc4c8fc25766892534c3e844c92e5d28 (patch)
tree73b3e8b0b4eb5873963c8e9db0f77c710f2081bb /src/core/arm/interpreter/armemu.cpp
parentMerge pull request #298 from lioncash/flags (diff)
parentarmemu: Combine SSUB16, SADD16, SASX, and SSAX. (diff)
downloadyuzu-8ac22e7efc4c8fc25766892534c3e844c92e5d28.tar.gz
yuzu-8ac22e7efc4c8fc25766892534c3e844c92e5d28.tar.xz
yuzu-8ac22e7efc4c8fc25766892534c3e844c92e5d28.zip
Merge pull request #299 from lioncash/join
Combine SSUB16, SADD16, SASX, and SSAX.
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp57
1 files changed, 23 insertions, 34 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 3b1a36bdd..b9ac8b9ad 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5827,8 +5827,10 @@ L_stm_s_takeabort:
5827 case 0x3f: 5827 case 0x3f:
5828 printf ("Unhandled v6 insn: rbit\n"); 5828 printf ("Unhandled v6 insn: rbit\n");
5829 break; 5829 break;
5830 case 0x61: 5830 case 0x61: // SSUB16, SADD16, SSAX, and SASX
5831 if ((instr & 0xFF0) == 0xf70) { //ssub16 5831 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10 ||
5832 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf30)
5833 {
5832 const u8 rd_idx = BITS(12, 15); 5834 const u8 rd_idx = BITS(12, 15);
5833 const u8 rm_idx = BITS(0, 3); 5835 const u8 rm_idx = BITS(0, 3);
5834 const u8 rn_idx = BITS(16, 19); 5836 const u8 rn_idx = BITS(16, 19);
@@ -5836,40 +5838,27 @@ L_stm_s_takeabort:
5836 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); 5838 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5837 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); 5839 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5838 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); 5840 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5839 state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16);
5840 return 1;
5841 } else if ((instr & 0xFF0) == 0xf10) { //sadd16
5842 const u8 rd_idx = BITS(12, 15);
5843 const u8 rm_idx = BITS(0, 3);
5844 const u8 rn_idx = BITS(16, 19);
5845 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5846 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5847 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5848 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5849 5841
5850 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16); 5842 // SSUB16
5851 return 1; 5843 if ((instr & 0xFF0) == 0xf70) {
5852 } else if ((instr & 0xFF0) == 0xf50) { //ssax 5844 state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16);
5853 u8 tar = BITS(12, 15); 5845 }
5854 u8 src1 = BITS(16, 19); 5846 // SADD16
5855 u8 src2 = BITS(0, 3); 5847 else if ((instr & 0xFF0) == 0xf10) {
5856 s16 a1 = (state->Reg[src1] & 0xFFFF); 5848 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16);
5857 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5849 }
5858 s16 b1 = (state->Reg[src2] & 0xFFFF); 5850 // SSAX
5859 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5851 else if ((instr & 0xFF0) == 0xf50) {
5860 state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); 5852 state->Reg[rd_idx] = ((rn_lo + rm_hi) & 0xFFFF) | (((rn_hi - rm_lo) & 0xFFFF) << 16);
5861 return 1; 5853 }
5862 } else if ((instr & 0xFF0) == 0xf30) { //sasx 5854 // SASX
5863 u8 tar = BITS(12, 15); 5855 else {
5864 u8 src1 = BITS(16, 19); 5856 state->Reg[rd_idx] = ((rn_lo - rm_hi) & 0xFFFF) | (((rn_hi + rm_lo) & 0xFFFF) << 16);
5865 u8 src2 = BITS(0, 3); 5857 }
5866 s16 a1 = (state->Reg[src1] & 0xFFFF);
5867 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5868 s16 b1 = (state->Reg[src2] & 0xFFFF);
5869 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5870 state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10);
5871 return 1; 5858 return 1;
5872 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5859 } else {
5860 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5861 }
5873 break; 5862 break;
5874 case 0x62: // QSUB16 and QADD16 5863 case 0x62: // QSUB16 and QADD16
5875 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { 5864 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {