summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp74
1 files changed, 42 insertions, 32 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 45e7b441f..808e2085a 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -2419,8 +2419,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2419 return inst_base; 2419 return inst_base;
2420} 2420}
2421ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } 2421ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); }
2422ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD8"); } 2422ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
2423ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
2424{ 2423{
2425 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); 2424 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2426 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; 2425 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
@@ -2438,21 +2437,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
2438 2437
2439 return inst_base; 2438 return inst_base;
2440} 2439}
2440ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
2441{
2442 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2443}
2441ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) 2444ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
2442{ 2445{
2443 return INTERPRETER_TRANSLATE(qadd16)(inst, index); 2446 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2444} 2447}
2445ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } 2448ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
2446ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } 2449ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
2447ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } 2450ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
2448ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB8"); } 2451ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
2452{
2453 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2454}
2449ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) 2455ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
2450{ 2456{
2451 return INTERPRETER_TRANSLATE(qadd16)(inst, index); 2457 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2452} 2458}
2453ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) 2459ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
2454{ 2460{
2455 return INTERPRETER_TRANSLATE(qadd16)(inst, index); 2461 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2456} 2462}
2457ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) 2463ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2458{ 2464{
@@ -5777,55 +5783,60 @@ unsigned InterpreterMainLoop(ARMul_State* state)
5777 GOTO_NEXT_INST; 5783 GOTO_NEXT_INST;
5778 } 5784 }
5779 QADD_INST: 5785 QADD_INST:
5780 QADD8_INST:
5781 5786
5787 QADD8_INST:
5782 QADD16_INST: 5788 QADD16_INST:
5783 QADDSUBX_INST: 5789 QADDSUBX_INST:
5790 QSUB8_INST:
5784 QSUB16_INST: 5791 QSUB16_INST:
5785 QSUBADDX_INST: 5792 QSUBADDX_INST:
5786 { 5793 {
5787 INC_ICOUNTER; 5794 INC_ICOUNTER;
5788 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5795 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5789 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; 5796 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5790 const s16 rm_lo = (RM & 0xFFFF); 5797 const u16 rm_lo = (RM & 0xFFFF);
5791 const s16 rm_hi = ((RM >> 16) & 0xFFFF); 5798 const u16 rm_hi = ((RM >> 16) & 0xFFFF);
5792 const s16 rn_lo = (RN & 0xFFFF); 5799 const u16 rn_lo = (RN & 0xFFFF);
5793 const s16 rn_hi = ((RN >> 16) & 0xFFFF); 5800 const u16 rn_hi = ((RN >> 16) & 0xFFFF);
5794 const u8 op2 = inst_cream->op2; 5801 const u8 op2 = inst_cream->op2;
5795 5802
5796 s32 lo_result = 0; 5803 u16 lo_result = 0;
5797 s32 hi_result = 0; 5804 u16 hi_result = 0;
5798 5805
5799 // QADD16 5806 // QADD16
5800 if (op2 == 0x00) { 5807 if (op2 == 0x00) {
5801 lo_result = (rn_lo + rm_lo); 5808 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
5802 hi_result = (rn_hi + rm_hi); 5809 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
5803 } 5810 }
5804 // QASX 5811 // QASX
5805 else if (op2 == 0x01) { 5812 else if (op2 == 0x01) {
5806 lo_result = (rn_lo - rm_hi); 5813 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5807 hi_result = (rn_hi + rm_lo); 5814 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5808 } 5815 }
5809 // QSAX 5816 // QSAX
5810 else if (op2 == 0x02) { 5817 else if (op2 == 0x02) {
5811 lo_result = (rn_lo + rm_hi); 5818 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5812 hi_result = (rn_hi - rm_lo); 5819 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5813 } 5820 }
5814 // QSUB16 5821 // QSUB16
5815 else if (op2 == 0x03) { 5822 else if (op2 == 0x03) {
5816 lo_result = (rn_lo - rm_lo); 5823 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5817 hi_result = (rn_hi - rm_hi); 5824 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5825 }
5826 // QADD8
5827 else if (op2 == 0x04) {
5828 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5829 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5830 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5831 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5832 }
5833 // QSUB8
5834 else if (op2 == 0x07) {
5835 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5836 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5837 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5838 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5818 } 5839 }
5819
5820 if (lo_result > 0x7FFF)
5821 lo_result = 0x7FFF;
5822 else if (lo_result < -0x8000)
5823 lo_result = -0x8000;
5824
5825 if (hi_result > 0x7FFF)
5826 hi_result = 0x7FFF;
5827 else if (hi_result < -0x8000)
5828 hi_result = -0x8000;
5829 5840
5830 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); 5841 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5831 } 5842 }
@@ -5839,7 +5850,6 @@ unsigned InterpreterMainLoop(ARMul_State* state)
5839 QDADD_INST: 5850 QDADD_INST:
5840 QDSUB_INST: 5851 QDSUB_INST:
5841 QSUB_INST: 5852 QSUB_INST:
5842 QSUB8_INST:
5843 REV_INST: 5853 REV_INST:
5844 { 5854 {
5845 INC_ICOUNTER; 5855 INC_ICOUNTER;