summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp217
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}
2788ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } 2788
2789ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } 2789ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index)
2790ARM_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}
2807ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index)
2808{
2809 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2810}
2811ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index)
2812{
2813 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2814}
2815ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index)
2816{
2817 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2818}
2819ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index)
2820{
2821 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2822}
2823ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index)
2824{
2825 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2826}
2827
2791ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) 2828ARM_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}
3020ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
3021ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); }
3022ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); }
3023 3057
3024ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) 3058ARM_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 {