diff options
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index ae407585e..460001b1a 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2390,15 +2390,41 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) | |||
| 2390 | return inst_base; | 2390 | return inst_base; |
| 2391 | } | 2391 | } |
| 2392 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } | 2392 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } |
| 2393 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD16"); } | ||
| 2394 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD8"); } | 2393 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD8"); } |
| 2395 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADDSUBX"); } | 2394 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) |
| 2395 | { | ||
| 2396 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 2397 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 2398 | |||
| 2399 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2400 | inst_base->idx = index; | ||
| 2401 | inst_base->br = NON_BRANCH; | ||
| 2402 | inst_base->load_r15 = 0; | ||
| 2403 | |||
| 2404 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2405 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2406 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2407 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2408 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2409 | |||
| 2410 | return inst_base; | ||
| 2411 | } | ||
| 2412 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) | ||
| 2413 | { | ||
| 2414 | return INTERPRETER_TRANSLATE(qadd16)(inst, index); | ||
| 2415 | } | ||
| 2396 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } | 2416 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } |
| 2397 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } | 2417 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } |
| 2398 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } | 2418 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } |
| 2399 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB16"); } | ||
| 2400 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB8"); } | 2419 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB8"); } |
| 2401 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUBADDX"); } | 2420 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) |
| 2421 | { | ||
| 2422 | return INTERPRETER_TRANSLATE(qadd16)(inst, index); | ||
| 2423 | } | ||
| 2424 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) | ||
| 2425 | { | ||
| 2426 | return INTERPRETER_TRANSLATE(qadd16)(inst, index); | ||
| 2427 | } | ||
| 2402 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) | 2428 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) |
| 2403 | { | 2429 | { |
| 2404 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); | 2430 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); |
| @@ -5561,15 +5587,69 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 5561 | GOTO_NEXT_INST; | 5587 | GOTO_NEXT_INST; |
| 5562 | } | 5588 | } |
| 5563 | QADD_INST: | 5589 | QADD_INST: |
| 5564 | QADD16_INST: | ||
| 5565 | QADD8_INST: | 5590 | QADD8_INST: |
| 5591 | |||
| 5592 | QADD16_INST: | ||
| 5566 | QADDSUBX_INST: | 5593 | QADDSUBX_INST: |
| 5594 | QSUB16_INST: | ||
| 5595 | QSUBADDX_INST: | ||
| 5596 | { | ||
| 5597 | INC_ICOUNTER; | ||
| 5598 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5599 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5600 | const s16 rm_lo = (RM & 0xFFFF); | ||
| 5601 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5602 | const s16 rn_lo = (RN & 0xFFFF); | ||
| 5603 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); | ||
| 5604 | const u8 op2 = inst_cream->op2; | ||
| 5605 | |||
| 5606 | s32 lo_result = 0; | ||
| 5607 | s32 hi_result = 0; | ||
| 5608 | |||
| 5609 | // QADD16 | ||
| 5610 | if (op2 == 0x00) { | ||
| 5611 | lo_result = (rn_lo + rm_lo); | ||
| 5612 | hi_result = (rn_hi + rm_hi); | ||
| 5613 | } | ||
| 5614 | // QASX | ||
| 5615 | else if (op2 == 0x01) { | ||
| 5616 | lo_result = (rn_lo - rm_hi); | ||
| 5617 | hi_result = (rn_hi + rm_lo); | ||
| 5618 | } | ||
| 5619 | // QSAX | ||
| 5620 | else if (op2 == 0x02) { | ||
| 5621 | lo_result = (rn_lo + rm_hi); | ||
| 5622 | hi_result = (rn_hi - rm_lo); | ||
| 5623 | } | ||
| 5624 | // QSUB16 | ||
| 5625 | else if (op2 == 0x03) { | ||
| 5626 | lo_result = (rn_lo - rm_lo); | ||
| 5627 | hi_result = (rn_hi - rm_hi); | ||
| 5628 | } | ||
| 5629 | |||
| 5630 | if (lo_result > 0x7FFF) | ||
| 5631 | lo_result = 0x7FFF; | ||
| 5632 | else if (lo_result < -0x8000) | ||
| 5633 | lo_result = -0x8000; | ||
| 5634 | |||
| 5635 | if (hi_result > 0x7FFF) | ||
| 5636 | hi_result = 0x7FFF; | ||
| 5637 | else if (hi_result < -0x8000) | ||
| 5638 | hi_result = -0x8000; | ||
| 5639 | |||
| 5640 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | ||
| 5641 | } | ||
| 5642 | |||
| 5643 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5644 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5645 | FETCH_INST; | ||
| 5646 | GOTO_NEXT_INST; | ||
| 5647 | } | ||
| 5648 | |||
| 5567 | QDADD_INST: | 5649 | QDADD_INST: |
| 5568 | QDSUB_INST: | 5650 | QDSUB_INST: |
| 5569 | QSUB_INST: | 5651 | QSUB_INST: |
| 5570 | QSUB16_INST: | ||
| 5571 | QSUB8_INST: | 5652 | QSUB8_INST: |
| 5572 | QSUBADDX_INST: | ||
| 5573 | REV_INST: | 5653 | REV_INST: |
| 5574 | { | 5654 | { |
| 5575 | INC_ICOUNTER; | 5655 | INC_ICOUNTER; |