summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2014-12-17 21:14:42 -0500
committerGravatar Lioncash2014-12-17 21:17:54 -0500
commit85c318078db2e950696d86f9f49dad17f88bedcb (patch)
tree6c747ac226b9dd87ca5d1a02afa301d19ecbfcd5
parentMerge pull request #292 from lioncash/backports (diff)
downloadyuzu-85c318078db2e950696d86f9f49dad17f88bedcb.tar.gz
yuzu-85c318078db2e950696d86f9f49dad17f88bedcb.tar.xz
yuzu-85c318078db2e950696d86f9f49dad17f88bedcb.zip
armemu: Combine SSUB16, SADD16, SASX, and SSAX.
-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 14330156b..c032c7168 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5805,8 +5805,10 @@ L_stm_s_takeabort:
5805 case 0x3f: 5805 case 0x3f:
5806 printf ("Unhandled v6 insn: rbit\n"); 5806 printf ("Unhandled v6 insn: rbit\n");
5807 break; 5807 break;
5808 case 0x61: 5808 case 0x61: // SSUB16, SADD16, SSAX, and SASX
5809 if ((instr & 0xFF0) == 0xf70) { //ssub16 5809 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10 ||
5810 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf30)
5811 {
5810 const u8 rd_idx = BITS(12, 15); 5812 const u8 rd_idx = BITS(12, 15);
5811 const u8 rm_idx = BITS(0, 3); 5813 const u8 rm_idx = BITS(0, 3);
5812 const u8 rn_idx = BITS(16, 19); 5814 const u8 rn_idx = BITS(16, 19);
@@ -5814,40 +5816,27 @@ L_stm_s_takeabort:
5814 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); 5816 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5815 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); 5817 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5816 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); 5818 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5817 state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16);
5818 return 1;
5819 } else if ((instr & 0xFF0) == 0xf10) { //sadd16
5820 const u8 rd_idx = BITS(12, 15);
5821 const u8 rm_idx = BITS(0, 3);
5822 const u8 rn_idx = BITS(16, 19);
5823 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5824 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5825 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5826 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5827 5819
5828 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16); 5820 // SSUB16
5829 return 1; 5821 if ((instr & 0xFF0) == 0xf70) {
5830 } else if ((instr & 0xFF0) == 0xf50) { //ssax 5822 state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16);
5831 u8 tar = BITS(12, 15); 5823 }
5832 u8 src1 = BITS(16, 19); 5824 // SADD16
5833 u8 src2 = BITS(0, 3); 5825 else if ((instr & 0xFF0) == 0xf10) {
5834 s16 a1 = (state->Reg[src1] & 0xFFFF); 5826 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16);
5835 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5827 }
5836 s16 b1 = (state->Reg[src2] & 0xFFFF); 5828 // SSAX
5837 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5829 else if ((instr & 0xFF0) == 0xf50) {
5838 state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); 5830 state->Reg[rd_idx] = ((rn_lo + rm_hi) & 0xFFFF) | (((rn_hi - rm_lo) & 0xFFFF) << 16);
5839 return 1; 5831 }
5840 } else if ((instr & 0xFF0) == 0xf30) { //sasx 5832 // SASX
5841 u8 tar = BITS(12, 15); 5833 else {
5842 u8 src1 = BITS(16, 19); 5834 state->Reg[rd_idx] = ((rn_lo - rm_hi) & 0xFFFF) | (((rn_hi + rm_lo) & 0xFFFF) << 16);
5843 u8 src2 = BITS(0, 3); 5835 }
5844 s16 a1 = (state->Reg[src1] & 0xFFFF);
5845 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5846 s16 b1 = (state->Reg[src2] & 0xFFFF);
5847 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5848 state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10);
5849 return 1; 5836 return 1;
5850 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5837 } else {
5838 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5839 }
5851 break; 5840 break;
5852 case 0x62: // QSUB16 and QADD16 5841 case 0x62: // QSUB16 and QADD16
5853 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { 5842 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {