summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2014-12-27 00:57:32 -0500
committerGravatar Lioncash2014-12-27 00:57:32 -0500
commit52d889d85d3212622b4e911cb40ef7cd3437adf7 (patch)
treed9a70c953966e275b60b0471ca568b011e6f8a3c /src
parentMerge pull request #348 from lioncash/uhops (diff)
downloadyuzu-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.cpp134
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}
3089ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
3090ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } 3089ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); }
3090ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
3091ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } 3091ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); }
3092ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD16"); } 3092ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
3093ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD8"); } 3093{
3094ARM_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));
3095ARM_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;
3096ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB8"); } 3096
3097ARM_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}
3110ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
3111{
3112 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3113}
3114ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
3115{
3116 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3117}
3118ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
3119{
3120 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3121}
3122ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
3123{
3124 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3125}
3126ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
3127{
3128 return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
3129}
3098ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) 3130ARM_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;