diff options
| author | 2014-12-27 00:57:32 -0500 | |
|---|---|---|
| committer | 2014-12-27 00:57:32 -0500 | |
| commit | 52d889d85d3212622b4e911cb40ef7cd3437adf7 (patch) | |
| tree | d9a70c953966e275b60b0471ca568b011e6f8a3c /src | |
| parent | Merge pull request #348 from lioncash/uhops (diff) | |
| download | yuzu-52d889d85d3212622b4e911cb40ef7cd3437adf7.tar.gz yuzu-52d889d85d3212622b4e911cb40ef7cd3437adf7.tar.xz yuzu-52d889d85d3212622b4e911cb40ef7cd3437adf7.zip | |
dyncom: Implement UHADD8, UHADD16, UHSUB8, UHSUB16, UHASX, and UHSAX
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 134 |
1 files changed, 123 insertions, 11 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 460001b1a..9b355fc6e 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -3086,15 +3086,47 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) | |||
| 3086 | inst_base->load_r15 = 1; | 3086 | inst_base->load_r15 = 1; |
| 3087 | return inst_base; | 3087 | return inst_base; |
| 3088 | } | 3088 | } |
| 3089 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } | ||
| 3090 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } | 3089 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } |
| 3090 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } | ||
| 3091 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } | 3091 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } |
| 3092 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD16"); } | 3092 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) |
| 3093 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD8"); } | 3093 | { |
| 3094 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADDSUBX"); } | 3094 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3095 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB16"); } | 3095 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3096 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB8"); } | 3096 | |
| 3097 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUBADDX"); } | 3097 | inst_base->cond = BITS(inst, 28, 31); |
| 3098 | inst_base->idx = index; | ||
| 3099 | inst_base->br = NON_BRANCH; | ||
| 3100 | inst_base->load_r15 = 0; | ||
| 3101 | |||
| 3102 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 3103 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 3104 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 3105 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 3106 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 3107 | |||
| 3108 | return inst_base; | ||
| 3109 | } | ||
| 3110 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) | ||
| 3111 | { | ||
| 3112 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 3113 | } | ||
| 3114 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) | ||
| 3115 | { | ||
| 3116 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 3117 | } | ||
| 3118 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) | ||
| 3119 | { | ||
| 3120 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 3121 | } | ||
| 3122 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) | ||
| 3123 | { | ||
| 3124 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 3125 | } | ||
| 3126 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) | ||
| 3127 | { | ||
| 3128 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 3129 | } | ||
| 3098 | ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) | 3130 | ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) |
| 3099 | { | 3131 | { |
| 3100 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); | 3132 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); |
| @@ -6622,15 +6654,95 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 6622 | FETCH_INST; | 6654 | FETCH_INST; |
| 6623 | GOTO_NEXT_INST; | 6655 | GOTO_NEXT_INST; |
| 6624 | } | 6656 | } |
| 6625 | UADD16_INST: | ||
| 6626 | UADD8_INST: | 6657 | UADD8_INST: |
| 6658 | UADD16_INST: | ||
| 6627 | UADDSUBX_INST: | 6659 | UADDSUBX_INST: |
| 6628 | UHADD16_INST: | 6660 | |
| 6629 | UHADD8_INST: | 6661 | UHADD8_INST: |
| 6662 | UHADD16_INST: | ||
| 6630 | UHADDSUBX_INST: | 6663 | UHADDSUBX_INST: |
| 6631 | UHSUB16_INST: | ||
| 6632 | UHSUB8_INST: | ||
| 6633 | UHSUBADDX_INST: | 6664 | UHSUBADDX_INST: |
| 6665 | UHSUB8_INST: | ||
| 6666 | UHSUB16_INST: | ||
| 6667 | { | ||
| 6668 | INC_ICOUNTER; | ||
| 6669 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6670 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 6671 | |||
| 6672 | const u32 rm_val = RM; | ||
| 6673 | const u32 rn_val = RN; | ||
| 6674 | const u8 op2 = inst_cream->op2; | ||
| 6675 | |||
| 6676 | |||
| 6677 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) | ||
| 6678 | { | ||
| 6679 | u32 lo_val = 0; | ||
| 6680 | u32 hi_val = 0; | ||
| 6681 | |||
| 6682 | // UHADD16 | ||
| 6683 | if (op2 == 0x00) { | ||
| 6684 | lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6685 | hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6686 | } | ||
| 6687 | // UHASX | ||
| 6688 | else if (op2 == 0x01) { | ||
| 6689 | lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6690 | hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6691 | } | ||
| 6692 | // UHSAX | ||
| 6693 | else if (op2 == 0x02) { | ||
| 6694 | lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6695 | hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6696 | } | ||
| 6697 | // UHSUB16 | ||
| 6698 | else if (op2 == 0x03) { | ||
| 6699 | lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6700 | hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6701 | } | ||
| 6702 | |||
| 6703 | lo_val >>= 1; | ||
| 6704 | hi_val >>= 1; | ||
| 6705 | |||
| 6706 | RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); | ||
| 6707 | } | ||
| 6708 | else if (op2 == 0x04 || op2 == 0x07) { | ||
| 6709 | u32 sum1; | ||
| 6710 | u32 sum2; | ||
| 6711 | u32 sum3; | ||
| 6712 | u32 sum4; | ||
| 6713 | |||
| 6714 | // UHADD8 | ||
| 6715 | if (op2 == 0x04) { | ||
| 6716 | sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); | ||
| 6717 | sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); | ||
| 6718 | sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); | ||
| 6719 | sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | ||
| 6720 | } | ||
| 6721 | // UHSUB8 | ||
| 6722 | else { | ||
| 6723 | sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); | ||
| 6724 | sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); | ||
| 6725 | sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | ||
| 6726 | sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); | ||
| 6727 | } | ||
| 6728 | |||
| 6729 | sum1 >>= 1; | ||
| 6730 | sum2 >>= 1; | ||
| 6731 | sum3 >>= 1; | ||
| 6732 | sum4 >>= 1; | ||
| 6733 | |||
| 6734 | RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); | ||
| 6735 | } | ||
| 6736 | |||
| 6737 | } | ||
| 6738 | |||
| 6739 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6740 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6741 | FETCH_INST; | ||
| 6742 | GOTO_NEXT_INST; | ||
| 6743 | } | ||
| 6744 | |||
| 6745 | |||
| 6634 | UMAAL_INST: | 6746 | UMAAL_INST: |
| 6635 | { | 6747 | { |
| 6636 | INC_ICOUNTER; | 6748 | INC_ICOUNTER; |