diff options
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 217 |
1 files changed, 208 insertions, 9 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 926761cff..c61ae0053 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2785,9 +2785,46 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) | |||
| 2785 | inst_base->load_r15 = 1; | 2785 | inst_base->load_r15 = 1; |
| 2786 | return inst_base; | 2786 | return inst_base; |
| 2787 | } | 2787 | } |
| 2788 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } | 2788 | |
| 2789 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } | 2789 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) |
| 2790 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } | 2790 | { |
| 2791 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 2792 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 2793 | |||
| 2794 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2795 | inst_base->idx = index; | ||
| 2796 | inst_base->br = NON_BRANCH; | ||
| 2797 | inst_base->load_r15 = 0; | ||
| 2798 | |||
| 2799 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2800 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2801 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2802 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2803 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2804 | |||
| 2805 | return inst_base; | ||
| 2806 | } | ||
| 2807 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) | ||
| 2808 | { | ||
| 2809 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2810 | } | ||
| 2811 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) | ||
| 2812 | { | ||
| 2813 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2814 | } | ||
| 2815 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) | ||
| 2816 | { | ||
| 2817 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2818 | } | ||
| 2819 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) | ||
| 2820 | { | ||
| 2821 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2822 | } | ||
| 2823 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) | ||
| 2824 | { | ||
| 2825 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2826 | } | ||
| 2827 | |||
| 2791 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) | 2828 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) |
| 2792 | { | 2829 | { |
| 2793 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2830 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| @@ -3017,9 +3054,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) | |||
| 3017 | { | 3054 | { |
| 3018 | return INTERPRETER_TRANSLATE(ssat16)(inst, index); | 3055 | return INTERPRETER_TRANSLATE(ssat16)(inst, index); |
| 3019 | } | 3056 | } |
| 3020 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } | ||
| 3021 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } | ||
| 3022 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } | ||
| 3023 | 3057 | ||
| 3024 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) | 3058 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) |
| 3025 | { | 3059 | { |
| @@ -5769,9 +5803,177 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5769 | FETCH_INST; | 5803 | FETCH_INST; |
| 5770 | GOTO_NEXT_INST; | 5804 | GOTO_NEXT_INST; |
| 5771 | } | 5805 | } |
| 5806 | |||
| 5772 | UADD8_INST: | 5807 | UADD8_INST: |
| 5773 | UADD16_INST: | 5808 | UADD16_INST: |
| 5774 | UADDSUBX_INST: | 5809 | UADDSUBX_INST: |
| 5810 | USUB8_INST: | ||
| 5811 | USUB16_INST: | ||
| 5812 | USUBADDX_INST: | ||
| 5813 | { | ||
| 5814 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5815 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5816 | |||
| 5817 | const u8 op2 = inst_cream->op2; | ||
| 5818 | const u32 rm_val = RM; | ||
| 5819 | const u32 rn_val = RN; | ||
| 5820 | |||
| 5821 | s32 lo_result = 0; | ||
| 5822 | s32 hi_result = 0; | ||
| 5823 | |||
| 5824 | // UADD16 | ||
| 5825 | if (op2 == 0x00) { | ||
| 5826 | lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 5827 | hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 5828 | |||
| 5829 | if (lo_result & 0xFFFF0000) { | ||
| 5830 | cpu->Cpsr |= (1 << 16); | ||
| 5831 | cpu->Cpsr |= (1 << 17); | ||
| 5832 | } else { | ||
| 5833 | cpu->Cpsr &= ~(1 << 16); | ||
| 5834 | cpu->Cpsr &= ~(1 << 17); | ||
| 5835 | } | ||
| 5836 | |||
| 5837 | if (hi_result & 0xFFFF0000) { | ||
| 5838 | cpu->Cpsr |= (1 << 18); | ||
| 5839 | cpu->Cpsr |= (1 << 19); | ||
| 5840 | } else { | ||
| 5841 | cpu->Cpsr &= ~(1 << 18); | ||
| 5842 | cpu->Cpsr &= ~(1 << 19); | ||
| 5843 | } | ||
| 5844 | } | ||
| 5845 | // UASX | ||
| 5846 | else if (op2 == 0x01) { | ||
| 5847 | lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 5848 | hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 5849 | |||
| 5850 | if (lo_result >= 0) { | ||
| 5851 | cpu->Cpsr |= (1 << 16); | ||
| 5852 | cpu->Cpsr |= (1 << 17); | ||
| 5853 | } else { | ||
| 5854 | cpu->Cpsr &= ~(1 << 16); | ||
| 5855 | cpu->Cpsr &= ~(1 << 17); | ||
| 5856 | } | ||
| 5857 | |||
| 5858 | if (hi_result >= 0x10000) { | ||
| 5859 | cpu->Cpsr |= (1 << 18); | ||
| 5860 | cpu->Cpsr |= (1 << 19); | ||
| 5861 | } else { | ||
| 5862 | cpu->Cpsr &= ~(1 << 18); | ||
| 5863 | cpu->Cpsr &= ~(1 << 19); | ||
| 5864 | } | ||
| 5865 | } | ||
| 5866 | // USAX | ||
| 5867 | else if (op2 == 0x02) { | ||
| 5868 | lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 5869 | hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 5870 | |||
| 5871 | if (lo_result >= 0x10000) { | ||
| 5872 | cpu->Cpsr |= (1 << 16); | ||
| 5873 | cpu->Cpsr |= (1 << 17); | ||
| 5874 | } else { | ||
| 5875 | cpu->Cpsr &= ~(1 << 16); | ||
| 5876 | cpu->Cpsr &= ~(1 << 17); | ||
| 5877 | } | ||
| 5878 | |||
| 5879 | if (hi_result >= 0) { | ||
| 5880 | cpu->Cpsr |= (1 << 18); | ||
| 5881 | cpu->Cpsr |= (1 << 19); | ||
| 5882 | } else { | ||
| 5883 | cpu->Cpsr &= ~(1 << 18); | ||
| 5884 | cpu->Cpsr &= ~(1 << 19); | ||
| 5885 | } | ||
| 5886 | } | ||
| 5887 | // USUB16 | ||
| 5888 | else if (op2 == 0x03) { | ||
| 5889 | lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 5890 | hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 5891 | |||
| 5892 | if ((lo_result & 0xFFFF0000) == 0) { | ||
| 5893 | cpu->Cpsr |= (1 << 16); | ||
| 5894 | cpu->Cpsr |= (1 << 17); | ||
| 5895 | } else { | ||
| 5896 | cpu->Cpsr &= ~(1 << 16); | ||
| 5897 | cpu->Cpsr &= ~(1 << 17); | ||
| 5898 | } | ||
| 5899 | |||
| 5900 | if ((hi_result & 0xFFFF0000) == 0) { | ||
| 5901 | cpu->Cpsr |= (1 << 18); | ||
| 5902 | cpu->Cpsr |= (1 << 19); | ||
| 5903 | } else { | ||
| 5904 | cpu->Cpsr &= ~(1 << 18); | ||
| 5905 | cpu->Cpsr &= ~(1 << 19); | ||
| 5906 | } | ||
| 5907 | } | ||
| 5908 | // UADD8 | ||
| 5909 | else if (op2 == 0x04) { | ||
| 5910 | s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); | ||
| 5911 | s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); | ||
| 5912 | s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); | ||
| 5913 | s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | ||
| 5914 | |||
| 5915 | if (sum1 >= 0x100) | ||
| 5916 | state->Cpsr |= (1 << 16); | ||
| 5917 | else | ||
| 5918 | state->Cpsr &= ~(1 << 16); | ||
| 5919 | |||
| 5920 | if (sum2 >= 0x100) | ||
| 5921 | state->Cpsr |= (1 << 17); | ||
| 5922 | else | ||
| 5923 | state->Cpsr &= ~(1 << 17); | ||
| 5924 | |||
| 5925 | if (sum3 >= 0x100) | ||
| 5926 | state->Cpsr |= (1 << 18); | ||
| 5927 | else | ||
| 5928 | state->Cpsr &= ~(1 << 18); | ||
| 5929 | |||
| 5930 | if (sum4 >= 0x100) | ||
| 5931 | state->Cpsr |= (1 << 19); | ||
| 5932 | else | ||
| 5933 | state->Cpsr &= ~(1 << 19); | ||
| 5934 | |||
| 5935 | lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8); | ||
| 5936 | hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8); | ||
| 5937 | } | ||
| 5938 | // USUB8 | ||
| 5939 | else if (op2 == 0x07) { | ||
| 5940 | s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF); | ||
| 5941 | s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); | ||
| 5942 | s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | ||
| 5943 | s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); | ||
| 5944 | |||
| 5945 | if (diff1 >= 0) | ||
| 5946 | state->Cpsr |= (1 << 16); | ||
| 5947 | else | ||
| 5948 | state->Cpsr &= ~(1 << 16); | ||
| 5949 | |||
| 5950 | if (diff2 >= 0) | ||
| 5951 | state->Cpsr |= (1 << 17); | ||
| 5952 | else | ||
| 5953 | state->Cpsr &= ~(1 << 17); | ||
| 5954 | |||
| 5955 | if (diff3 >= 0) | ||
| 5956 | state->Cpsr |= (1 << 18); | ||
| 5957 | else | ||
| 5958 | state->Cpsr &= ~(1 << 18); | ||
| 5959 | |||
| 5960 | if (diff4 >= 0) | ||
| 5961 | state->Cpsr |= (1 << 19); | ||
| 5962 | else | ||
| 5963 | state->Cpsr &= ~(1 << 19); | ||
| 5964 | |||
| 5965 | lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8); | ||
| 5966 | hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8); | ||
| 5967 | } | ||
| 5968 | |||
| 5969 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5970 | } | ||
| 5971 | |||
| 5972 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5973 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5974 | FETCH_INST; | ||
| 5975 | GOTO_NEXT_INST; | ||
| 5976 | } | ||
| 5775 | 5977 | ||
| 5776 | UHADD8_INST: | 5978 | UHADD8_INST: |
| 5777 | UHADD16_INST: | 5979 | UHADD16_INST: |
| @@ -6109,9 +6311,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6109 | GOTO_NEXT_INST; | 6311 | GOTO_NEXT_INST; |
| 6110 | } | 6312 | } |
| 6111 | 6313 | ||
| 6112 | USUB16_INST: | ||
| 6113 | USUB8_INST: | ||
| 6114 | USUBADDX_INST: | ||
| 6115 | UXTAB16_INST: | 6314 | UXTAB16_INST: |
| 6116 | UXTB16_INST: | 6315 | UXTB16_INST: |
| 6117 | { | 6316 | { |