summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2014-12-15 23:46:58 -0500
committerGravatar Lioncash2014-12-16 00:11:19 -0500
commit49817e89d9b496be0d38cbf92890d01f94f855b8 (patch)
tree1d466f549b8f407b3564468c666ad40cfc1b6c7e /src
parentMerge pull request #281 from lioncash/uxtb16 (diff)
downloadyuzu-49817e89d9b496be0d38cbf92890d01f94f855b8.tar.gz
yuzu-49817e89d9b496be0d38cbf92890d01f94f855b8.tar.xz
yuzu-49817e89d9b496be0d38cbf92890d01f94f855b8.zip
armemu: Join QADD16 and QSUB16 together.
The only difference between these ops is one adds and one subtracts. Everything is literally the same.
Diffstat (limited to '')
-rw-r--r--src/core/arm/interpreter/armemu.cpp70
1 files changed, 37 insertions, 33 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 33ebc7986..8ee8badd5 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5842,40 +5842,44 @@ L_stm_s_takeabort:
5842 return 1; 5842 return 1;
5843 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5843 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n");
5844 break; 5844 break;
5845 case 0x62: 5845 case 0x62: // QSUB16 and QADD16
5846 if ((instr & 0xFF0) == 0xf70) { //QSUB16 5846 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {
5847 u8 tar = BITS(12, 15); 5847 const u8 rd_idx = BITS(12, 15);
5848 u8 src1 = BITS(16, 19); 5848 const u8 rn_idx = BITS(16, 19);
5849 u8 src2 = BITS(0, 3); 5849 const u8 rm_idx = BITS(0, 3);
5850 s16 a1 = (state->Reg[src1] & 0xFFFF); 5850 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5851 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5851 const s16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
5852 s16 b1 = (state->Reg[src2] & 0xFFFF); 5852 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5853 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5853 const s16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
5854 s32 res1 = (a1 - b1); 5854
5855 s32 res2 = (a2 - b2); 5855 s32 lo_result;
5856 if (res1 > 0x7FFF) res1 = 0x7FFF; 5856 s32 hi_result;
5857 if (res2 > 0x7FFF) res2 = 0x7FFF; 5857
5858 if (res1 < 0x7FFF) res1 = -0x8000; 5858 // QSUB16
5859 if (res2 < 0x7FFF) res2 = -0x8000; 5859 if ((instr & 0xFF0) == 0xf70) {
5860 state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); 5860 lo_result = (rn_lo - rm_lo);
5861 return 1; 5861 hi_result = (rn_hi - rm_hi);
5862 } else if ((instr & 0xFF0) == 0xf10) { //QADD16 5862 }
5863 u8 tar = BITS(12, 15); 5863 else { // QADD16
5864 u8 src1 = BITS(16, 19); 5864 lo_result = (rn_lo + rm_lo);
5865 u8 src2 = BITS(0, 3); 5865 hi_result = (rn_hi + rm_hi);
5866 s16 a1 = (state->Reg[src1] & 0xFFFF); 5866 }
5867 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5867
5868 s16 b1 = (state->Reg[src2] & 0xFFFF); 5868 if (lo_result > 0x7FFF)
5869 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5869 lo_result = 0x7FFF;
5870 s32 res1 = (a1 + b1); 5870 else if (lo_result < 0x7FFF)
5871 s32 res2 = (a2 + b2); 5871 lo_result = -0x8000;
5872 if (res1 > 0x7FFF) res1 = 0x7FFF; 5872
5873 if (res2 > 0x7FFF) res2 = 0x7FFF; 5873 if (hi_result > 0x7FFF)
5874 if (res1 < 0x7FFF) res1 = -0x8000; 5874 hi_result = 0x7FFF;
5875 if (res2 < 0x7FFF) res2 = -0x8000; 5875 else if (hi_result < 0x7FFF)
5876 state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); 5876 hi_result = -0x8000;
5877
5878 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5877 return 1; 5879 return 1;
5878 } else printf ("Unhandled v6 insn: qadd16/qsub16\n"); 5880 } else {
5881 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5882 }
5879 break; 5883 break;
5880 case 0x63: 5884 case 0x63:
5881 printf ("Unhandled v6 insn: shadd/shsub\n"); 5885 printf ("Unhandled v6 insn: shadd/shsub\n");