diff options
| author | 2015-01-01 10:34:20 -0500 | |
|---|---|---|
| committer | 2015-01-01 10:34:20 -0500 | |
| commit | 524da47698ce919f79788f1ea6a44c9a9f929ced (patch) | |
| tree | 828628cc374dfb34f3579235b4bb524b99831cbf /src | |
| parent | Merge pull request #265 from Subv/socu (diff) | |
| download | yuzu-524da47698ce919f79788f1ea6a44c9a9f929ced.tar.gz yuzu-524da47698ce919f79788f1ea6a44c9a9f929ced.tar.xz yuzu-524da47698ce919f79788f1ea6a44c9a9f929ced.zip | |
dyncom: Implement SHADD8/SHADD16/SHSUB8/SHSUB16/SHASX/SHSAX
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 118 |
1 files changed, 110 insertions, 8 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index c61ae0053..5642e341b 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2236,13 +2236,48 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) | |||
| 2236 | 2236 | ||
| 2237 | return inst_base; | 2237 | return inst_base; |
| 2238 | } | 2238 | } |
| 2239 | |||
| 2239 | ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } | 2240 | ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } |
| 2240 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); } | 2241 | |
| 2241 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); } | 2242 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) |
| 2242 | ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); } | 2243 | { |
| 2243 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); } | 2244 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2244 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); } | 2245 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2245 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } | 2246 | |
| 2247 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2248 | inst_base->idx = index; | ||
| 2249 | inst_base->br = NON_BRANCH; | ||
| 2250 | inst_base->load_r15 = 0; | ||
| 2251 | |||
| 2252 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2253 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2254 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2255 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2256 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2257 | |||
| 2258 | return inst_base; | ||
| 2259 | } | ||
| 2260 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) | ||
| 2261 | { | ||
| 2262 | return INTERPRETER_TRANSLATE(shadd8)(inst, index); | ||
| 2263 | } | ||
| 2264 | ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) | ||
| 2265 | { | ||
| 2266 | return INTERPRETER_TRANSLATE(shadd8)(inst, index); | ||
| 2267 | } | ||
| 2268 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) | ||
| 2269 | { | ||
| 2270 | return INTERPRETER_TRANSLATE(shadd8)(inst, index); | ||
| 2271 | } | ||
| 2272 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) | ||
| 2273 | { | ||
| 2274 | return INTERPRETER_TRANSLATE(shadd8)(inst, index); | ||
| 2275 | } | ||
| 2276 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) | ||
| 2277 | { | ||
| 2278 | return INTERPRETER_TRANSLATE(shadd8)(inst, index); | ||
| 2279 | } | ||
| 2280 | |||
| 2246 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) | 2281 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) |
| 2247 | { | 2282 | { |
| 2248 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); | 2283 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); |
| @@ -5176,12 +5211,79 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5176 | } | 5211 | } |
| 5177 | 5212 | ||
| 5178 | SETEND_INST: | 5213 | SETEND_INST: |
| 5179 | SHADD16_INST: | 5214 | |
| 5180 | SHADD8_INST: | 5215 | SHADD8_INST: |
| 5216 | SHADD16_INST: | ||
| 5181 | SHADDSUBX_INST: | 5217 | SHADDSUBX_INST: |
| 5182 | SHSUB16_INST: | ||
| 5183 | SHSUB8_INST: | 5218 | SHSUB8_INST: |
| 5219 | SHSUB16_INST: | ||
| 5184 | SHSUBADDX_INST: | 5220 | SHSUBADDX_INST: |
| 5221 | { | ||
| 5222 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5223 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5224 | |||
| 5225 | const u8 op2 = inst_cream->op2; | ||
| 5226 | const u32 rm_val = RM; | ||
| 5227 | const u32 rn_val = RN; | ||
| 5228 | |||
| 5229 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { | ||
| 5230 | s32 lo_result = 0; | ||
| 5231 | s32 hi_result = 0; | ||
| 5232 | |||
| 5233 | // SHADD16 | ||
| 5234 | if (op2 == 0x00) { | ||
| 5235 | lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; | ||
| 5236 | hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; | ||
| 5237 | } | ||
| 5238 | // SHASX | ||
| 5239 | else if (op2 == 0x01) { | ||
| 5240 | lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; | ||
| 5241 | hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; | ||
| 5242 | } | ||
| 5243 | // SHSAX | ||
| 5244 | else if (op2 == 0x02) { | ||
| 5245 | lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; | ||
| 5246 | hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; | ||
| 5247 | } | ||
| 5248 | // SHSUB16 | ||
| 5249 | else if (op2 == 0x03) { | ||
| 5250 | lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; | ||
| 5251 | hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; | ||
| 5252 | } | ||
| 5253 | |||
| 5254 | RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16)); | ||
| 5255 | } | ||
| 5256 | else if (op2 == 0x04 || op2 == 0x07) { | ||
| 5257 | s16 lo_val1, lo_val2; | ||
| 5258 | s16 hi_val1, hi_val2; | ||
| 5259 | |||
| 5260 | // SHADD8 | ||
| 5261 | if (op2 == 0x04) { | ||
| 5262 | lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1; | ||
| 5263 | lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1; | ||
| 5264 | |||
| 5265 | hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1; | ||
| 5266 | hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1; | ||
| 5267 | } | ||
| 5268 | // SHSUB8 | ||
| 5269 | else { | ||
| 5270 | lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1; | ||
| 5271 | lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1; | ||
| 5272 | |||
| 5273 | hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1; | ||
| 5274 | hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1; | ||
| 5275 | } | ||
| 5276 | |||
| 5277 | RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24); | ||
| 5278 | } | ||
| 5279 | } | ||
| 5280 | |||
| 5281 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5282 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5283 | FETCH_INST; | ||
| 5284 | GOTO_NEXT_INST; | ||
| 5285 | } | ||
| 5286 | |||
| 5185 | SMLA_INST: | 5287 | SMLA_INST: |
| 5186 | { | 5288 | { |
| 5187 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5289 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |