diff options
| author | 2014-12-29 00:54:48 -0500 | |
|---|---|---|
| committer | 2014-12-29 00:54:48 -0500 | |
| commit | e412c0fc46ee151412f9d83d9bd3549a0a90e955 (patch) | |
| tree | 99a52b87face8a0acf470238e241e4ef4e4964b0 | |
| parent | armemu: Implement QADD8/QSUB8 (diff) | |
| download | yuzu-e412c0fc46ee151412f9d83d9bd3549a0a90e955.tar.gz yuzu-e412c0fc46ee151412f9d83d9bd3549a0a90e955.tar.xz yuzu-e412c0fc46ee151412f9d83d9bd3549a0a90e955.zip | |
dyncom: Implement QADD8/QSUB8
Diffstat (limited to '')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 74 |
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 | } |
| 2421 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } | 2421 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } |
| 2422 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD8"); } | 2422 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) |
| 2423 | ARM_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 | } |
| 2440 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) | ||
| 2441 | { | ||
| 2442 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2443 | } | ||
| 2441 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) | 2444 | ARM_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 | } |
| 2445 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } | 2448 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } |
| 2446 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } | 2449 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } |
| 2447 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } | 2450 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } |
| 2448 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB8"); } | 2451 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) |
| 2452 | { | ||
| 2453 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2454 | } | ||
| 2449 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) | 2455 | ARM_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 | } |
| 2453 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) | 2459 | ARM_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 | } |
| 2457 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) | 2463 | ARM_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; |