summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 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}
2947ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } 2947
2948ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } 2948ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index)
2949ARM_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}
2966ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index)
2967{
2968 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2969}
2970ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index)
2971{
2972 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2973}
2974ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index)
2975{
2976 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2977}
2978ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index)
2979{
2980 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2981}
2982ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index)
2983{
2984 return INTERPRETER_TRANSLATE(uadd8)(inst, index);
2985}
2986
2950ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) 2987ARM_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}
3179ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
3180ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); }
3181ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); }
3182 3216
3183ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) 3217ARM_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 {