diff options
Diffstat (limited to 'src')
| -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 cecb81237..3afc26f56 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2944,9 +2944,46 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) | |||
| 2944 | inst_base->load_r15 = 1; | 2944 | inst_base->load_r15 = 1; |
| 2945 | return inst_base; | 2945 | return inst_base; |
| 2946 | } | 2946 | } |
| 2947 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } | 2947 | |
| 2948 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } | 2948 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) |
| 2949 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } | 2949 | { |
| 2950 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 2951 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 2952 | |||
| 2953 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2954 | inst_base->idx = index; | ||
| 2955 | inst_base->br = NON_BRANCH; | ||
| 2956 | inst_base->load_r15 = 0; | ||
| 2957 | |||
| 2958 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2959 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2960 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2961 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2962 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2963 | |||
| 2964 | return inst_base; | ||
| 2965 | } | ||
| 2966 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) | ||
| 2967 | { | ||
| 2968 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2969 | } | ||
| 2970 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) | ||
| 2971 | { | ||
| 2972 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2973 | } | ||
| 2974 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) | ||
| 2975 | { | ||
| 2976 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2977 | } | ||
| 2978 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) | ||
| 2979 | { | ||
| 2980 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2981 | } | ||
| 2982 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) | ||
| 2983 | { | ||
| 2984 | return INTERPRETER_TRANSLATE(uadd8)(inst, index); | ||
| 2985 | } | ||
| 2986 | |||
| 2950 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) | 2987 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) |
| 2951 | { | 2988 | { |
| 2952 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2989 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| @@ -3176,9 +3213,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) | |||
| 3176 | { | 3213 | { |
| 3177 | return INTERPRETER_TRANSLATE(ssat16)(inst, index); | 3214 | return INTERPRETER_TRANSLATE(ssat16)(inst, index); |
| 3178 | } | 3215 | } |
| 3179 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } | ||
| 3180 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } | ||
| 3181 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } | ||
| 3182 | 3216 | ||
| 3183 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) | 3217 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) |
| 3184 | { | 3218 | { |
| @@ -6074,9 +6108,177 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6074 | FETCH_INST; | 6108 | FETCH_INST; |
| 6075 | GOTO_NEXT_INST; | 6109 | GOTO_NEXT_INST; |
| 6076 | } | 6110 | } |
| 6111 | |||
| 6077 | UADD8_INST: | 6112 | UADD8_INST: |
| 6078 | UADD16_INST: | 6113 | UADD16_INST: |
| 6079 | UADDSUBX_INST: | 6114 | UADDSUBX_INST: |
| 6115 | USUB8_INST: | ||
| 6116 | USUB16_INST: | ||
| 6117 | USUBADDX_INST: | ||
| 6118 | { | ||
| 6119 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6120 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 6121 | |||
| 6122 | const u8 op2 = inst_cream->op2; | ||
| 6123 | const u32 rm_val = RM; | ||
| 6124 | const u32 rn_val = RN; | ||
| 6125 | |||
| 6126 | s32 lo_result = 0; | ||
| 6127 | s32 hi_result = 0; | ||
| 6128 | |||
| 6129 | // UADD16 | ||
| 6130 | if (op2 == 0x00) { | ||
| 6131 | lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6132 | hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6133 | |||
| 6134 | if (lo_result & 0xFFFF0000) { | ||
| 6135 | cpu->Cpsr |= (1 << 16); | ||
| 6136 | cpu->Cpsr |= (1 << 17); | ||
| 6137 | } else { | ||
| 6138 | cpu->Cpsr &= ~(1 << 16); | ||
| 6139 | cpu->Cpsr &= ~(1 << 17); | ||
| 6140 | } | ||
| 6141 | |||
| 6142 | if (hi_result & 0xFFFF0000) { | ||
| 6143 | cpu->Cpsr |= (1 << 18); | ||
| 6144 | cpu->Cpsr |= (1 << 19); | ||
| 6145 | } else { | ||
| 6146 | cpu->Cpsr &= ~(1 << 18); | ||
| 6147 | cpu->Cpsr &= ~(1 << 19); | ||
| 6148 | } | ||
| 6149 | } | ||
| 6150 | // UASX | ||
| 6151 | else if (op2 == 0x01) { | ||
| 6152 | lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6153 | hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6154 | |||
| 6155 | if (lo_result >= 0) { | ||
| 6156 | cpu->Cpsr |= (1 << 16); | ||
| 6157 | cpu->Cpsr |= (1 << 17); | ||
| 6158 | } else { | ||
| 6159 | cpu->Cpsr &= ~(1 << 16); | ||
| 6160 | cpu->Cpsr &= ~(1 << 17); | ||
| 6161 | } | ||
| 6162 | |||
| 6163 | if (hi_result >= 0x10000) { | ||
| 6164 | cpu->Cpsr |= (1 << 18); | ||
| 6165 | cpu->Cpsr |= (1 << 19); | ||
| 6166 | } else { | ||
| 6167 | cpu->Cpsr &= ~(1 << 18); | ||
| 6168 | cpu->Cpsr &= ~(1 << 19); | ||
| 6169 | } | ||
| 6170 | } | ||
| 6171 | // USAX | ||
| 6172 | else if (op2 == 0x02) { | ||
| 6173 | lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6174 | hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6175 | |||
| 6176 | if (lo_result >= 0x10000) { | ||
| 6177 | cpu->Cpsr |= (1 << 16); | ||
| 6178 | cpu->Cpsr |= (1 << 17); | ||
| 6179 | } else { | ||
| 6180 | cpu->Cpsr &= ~(1 << 16); | ||
| 6181 | cpu->Cpsr &= ~(1 << 17); | ||
| 6182 | } | ||
| 6183 | |||
| 6184 | if (hi_result >= 0) { | ||
| 6185 | cpu->Cpsr |= (1 << 18); | ||
| 6186 | cpu->Cpsr |= (1 << 19); | ||
| 6187 | } else { | ||
| 6188 | cpu->Cpsr &= ~(1 << 18); | ||
| 6189 | cpu->Cpsr &= ~(1 << 19); | ||
| 6190 | } | ||
| 6191 | } | ||
| 6192 | // USUB16 | ||
| 6193 | else if (op2 == 0x03) { | ||
| 6194 | lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6195 | hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6196 | |||
| 6197 | if ((lo_result & 0xFFFF0000) == 0) { | ||
| 6198 | cpu->Cpsr |= (1 << 16); | ||
| 6199 | cpu->Cpsr |= (1 << 17); | ||
| 6200 | } else { | ||
| 6201 | cpu->Cpsr &= ~(1 << 16); | ||
| 6202 | cpu->Cpsr &= ~(1 << 17); | ||
| 6203 | } | ||
| 6204 | |||
| 6205 | if ((hi_result & 0xFFFF0000) == 0) { | ||
| 6206 | cpu->Cpsr |= (1 << 18); | ||
| 6207 | cpu->Cpsr |= (1 << 19); | ||
| 6208 | } else { | ||
| 6209 | cpu->Cpsr &= ~(1 << 18); | ||
| 6210 | cpu->Cpsr &= ~(1 << 19); | ||
| 6211 | } | ||
| 6212 | } | ||
| 6213 | // UADD8 | ||
| 6214 | else if (op2 == 0x04) { | ||
| 6215 | s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); | ||
| 6216 | s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); | ||
| 6217 | s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); | ||
| 6218 | s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | ||
| 6219 | |||
| 6220 | if (sum1 >= 0x100) | ||
| 6221 | state->Cpsr |= (1 << 16); | ||
| 6222 | else | ||
| 6223 | state->Cpsr &= ~(1 << 16); | ||
| 6224 | |||
| 6225 | if (sum2 >= 0x100) | ||
| 6226 | state->Cpsr |= (1 << 17); | ||
| 6227 | else | ||
| 6228 | state->Cpsr &= ~(1 << 17); | ||
| 6229 | |||
| 6230 | if (sum3 >= 0x100) | ||
| 6231 | state->Cpsr |= (1 << 18); | ||
| 6232 | else | ||
| 6233 | state->Cpsr &= ~(1 << 18); | ||
| 6234 | |||
| 6235 | if (sum4 >= 0x100) | ||
| 6236 | state->Cpsr |= (1 << 19); | ||
| 6237 | else | ||
| 6238 | state->Cpsr &= ~(1 << 19); | ||
| 6239 | |||
| 6240 | lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8); | ||
| 6241 | hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8); | ||
| 6242 | } | ||
| 6243 | // USUB8 | ||
| 6244 | else if (op2 == 0x07) { | ||
| 6245 | s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF); | ||
| 6246 | s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); | ||
| 6247 | s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | ||
| 6248 | s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); | ||
| 6249 | |||
| 6250 | if (diff1 >= 0) | ||
| 6251 | state->Cpsr |= (1 << 16); | ||
| 6252 | else | ||
| 6253 | state->Cpsr &= ~(1 << 16); | ||
| 6254 | |||
| 6255 | if (diff2 >= 0) | ||
| 6256 | state->Cpsr |= (1 << 17); | ||
| 6257 | else | ||
| 6258 | state->Cpsr &= ~(1 << 17); | ||
| 6259 | |||
| 6260 | if (diff3 >= 0) | ||
| 6261 | state->Cpsr |= (1 << 18); | ||
| 6262 | else | ||
| 6263 | state->Cpsr &= ~(1 << 18); | ||
| 6264 | |||
| 6265 | if (diff4 >= 0) | ||
| 6266 | state->Cpsr |= (1 << 19); | ||
| 6267 | else | ||
| 6268 | state->Cpsr &= ~(1 << 19); | ||
| 6269 | |||
| 6270 | lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8); | ||
| 6271 | hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8); | ||
| 6272 | } | ||
| 6273 | |||
| 6274 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 6275 | } | ||
| 6276 | |||
| 6277 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6278 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6279 | FETCH_INST; | ||
| 6280 | GOTO_NEXT_INST; | ||
| 6281 | } | ||
| 6080 | 6282 | ||
| 6081 | UHADD8_INST: | 6283 | UHADD8_INST: |
| 6082 | UHADD16_INST: | 6284 | UHADD16_INST: |
| @@ -6414,9 +6616,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6414 | GOTO_NEXT_INST; | 6616 | GOTO_NEXT_INST; |
| 6415 | } | 6617 | } |
| 6416 | 6618 | ||
| 6417 | USUB16_INST: | ||
| 6418 | USUB8_INST: | ||
| 6419 | USUBADDX_INST: | ||
| 6420 | UXTAB16_INST: | 6619 | UXTAB16_INST: |
| 6421 | UXTB16_INST: | 6620 | UXTB16_INST: |
| 6422 | { | 6621 | { |