summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp68
1 files changed, 35 insertions, 33 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index f0d349de7..b9c2aa6c2 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5948,56 +5948,58 @@ L_stm_s_takeabort:
5948 printf("Unhandled v6 insn: %08x", instr); 5948 printf("Unhandled v6 insn: %08x", instr);
5949 } 5949 }
5950 break; 5950 break;
5951 case 0x62: // QADD16, QASX, QSAX, and QSUB16 5951 case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8
5952 if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
5953 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
5954 { 5952 {
5953 const u8 op2 = BITS(5, 7);
5954
5955 const u8 rd_idx = BITS(12, 15); 5955 const u8 rd_idx = BITS(12, 15);
5956 const u8 rn_idx = BITS(16, 19); 5956 const u8 rn_idx = BITS(16, 19);
5957 const u8 rm_idx = BITS(0, 3); 5957 const u8 rm_idx = BITS(0, 3);
5958 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); 5958 const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5959 const s16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF); 5959 const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
5960 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); 5960 const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5961 const s16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF); 5961 const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
5962 5962
5963 s32 lo_result; 5963 u16 lo_result = 0;
5964 s32 hi_result; 5964 u16 hi_result = 0;
5965 5965
5966 // QADD16 5966 // QADD16
5967 if ((instr & 0xFF0) == 0xf10) { 5967 if (op2 == 0x00) {
5968 lo_result = (rn_lo + rm_lo); 5968 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
5969 hi_result = (rn_hi + rm_hi); 5969 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
5970 } 5970 }
5971 // QASX 5971 // QASX
5972 else if ((instr & 0xFF0) == 0xf30) { 5972 else if (op2 == 0x01) {
5973 lo_result = (rn_lo - rm_hi); 5973 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5974 hi_result = (rn_hi + rm_lo); 5974 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5975 } 5975 }
5976 // QSAX 5976 // QSAX
5977 else if ((instr & 0xFF0) == 0xf50) { 5977 else if (op2 == 0x02) {
5978 lo_result = (rn_lo + rm_hi); 5978 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5979 hi_result = (rn_hi - rm_lo); 5979 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5980 } 5980 }
5981 // QSUB16 5981 // QSUB16
5982 else { 5982 else if (op2 == 0x03) {
5983 lo_result = (rn_lo - rm_lo); 5983 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5984 hi_result = (rn_hi - rm_hi); 5984 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5985 }
5986 // QADD8
5987 else if (op2 == 0x04) {
5988 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5989 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5990 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5991 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5992 }
5993 // QSUB8
5994 else if (op2 == 0x07) {
5995 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5996 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5997 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5998 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5985 } 5999 }
5986
5987 if (lo_result > 0x7FFF)
5988 lo_result = 0x7FFF;
5989 else if (lo_result < -0x8000)
5990 lo_result = -0x8000;
5991
5992 if (hi_result > 0x7FFF)
5993 hi_result = 0x7FFF;
5994 else if (hi_result < -0x8000)
5995 hi_result = -0x8000;
5996 6000
5997 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); 6001 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5998 return 1; 6002 return 1;
5999 } else {
6000 printf("Unhandled v6 insn: %08x", BITS(20, 27));
6001 } 6003 }
6002 break; 6004 break;
6003 case 0x63: 6005 case 0x63: