diff options
| author | 2014-12-27 17:24:34 -0500 | |
|---|---|---|
| committer | 2014-12-27 17:24:34 -0500 | |
| commit | af69b0840b67328f23a8123e4a6dec9c11eada96 (patch) | |
| tree | 16621bd2dabe32e4a17f0014392c6c8f597e9a56 /src/core/arm/dyncom | |
| parent | armemu: Implement UQADD8, UQADD16, UQSUB16, UQASX, and UQSAX (diff) | |
| download | yuzu-af69b0840b67328f23a8123e4a6dec9c11eada96.tar.gz yuzu-af69b0840b67328f23a8123e4a6dec9c11eada96.tar.xz yuzu-af69b0840b67328f23a8123e4a6dec9c11eada96.zip | |
dyncom: Implement UQADD8, UQADD16, UQSUB8, UQSUB16, UQASX, and UQSAX.
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 105 |
1 files changed, 97 insertions, 8 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 9b355fc6e..7306794fe 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -3249,12 +3249,44 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) | |||
| 3249 | return inst_base; | 3249 | return inst_base; |
| 3250 | } | 3250 | } |
| 3251 | 3251 | ||
| 3252 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD16"); } | 3252 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) |
| 3253 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD8"); } | 3253 | { |
| 3254 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADDSUBX"); } | 3254 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3255 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB16"); } | 3255 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3256 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB8"); } | 3256 | |
| 3257 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUBADDX"); } | 3257 | inst_base->cond = BITS(inst, 28, 31); |
| 3258 | inst_base->idx = index; | ||
| 3259 | inst_base->br = NON_BRANCH; | ||
| 3260 | inst_base->load_r15 = 0; | ||
| 3261 | |||
| 3262 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 3263 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 3264 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 3265 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 3266 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 3267 | |||
| 3268 | return inst_base; | ||
| 3269 | } | ||
| 3270 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) | ||
| 3271 | { | ||
| 3272 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3273 | } | ||
| 3274 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) | ||
| 3275 | { | ||
| 3276 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3277 | } | ||
| 3278 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) | ||
| 3279 | { | ||
| 3280 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3281 | } | ||
| 3282 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) | ||
| 3283 | { | ||
| 3284 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3285 | } | ||
| 3286 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) | ||
| 3287 | { | ||
| 3288 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3289 | } | ||
| 3258 | ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAD8"); } | 3290 | ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAD8"); } |
| 3259 | ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USADA8"); } | 3291 | ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USADA8"); } |
| 3260 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } | 3292 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } |
| @@ -6876,12 +6908,69 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 6876 | goto DISPATCH; | 6908 | goto DISPATCH; |
| 6877 | } | 6909 | } |
| 6878 | 6910 | ||
| 6879 | UQADD16_INST: | ||
| 6880 | UQADD8_INST: | 6911 | UQADD8_INST: |
| 6912 | UQADD16_INST: | ||
| 6881 | UQADDSUBX_INST: | 6913 | UQADDSUBX_INST: |
| 6882 | UQSUB16_INST: | ||
| 6883 | UQSUB8_INST: | 6914 | UQSUB8_INST: |
| 6915 | UQSUB16_INST: | ||
| 6884 | UQSUBADDX_INST: | 6916 | UQSUBADDX_INST: |
| 6917 | { | ||
| 6918 | INC_ICOUNTER; | ||
| 6919 | |||
| 6920 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6921 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 6922 | |||
| 6923 | const u8 op2 = inst_cream->op2; | ||
| 6924 | const u32 rm_val = RM; | ||
| 6925 | const u32 rn_val = RN; | ||
| 6926 | |||
| 6927 | u16 lo_val = 0; | ||
| 6928 | u16 hi_val = 0; | ||
| 6929 | |||
| 6930 | // UQADD16 | ||
| 6931 | if (op2 == 0x00) { | ||
| 6932 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); | ||
| 6933 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6934 | } | ||
| 6935 | // UQASX | ||
| 6936 | else if (op2 == 0x01) { | ||
| 6937 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6938 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | ||
| 6939 | } | ||
| 6940 | // UQSAX | ||
| 6941 | else if (op2 == 0x02) { | ||
| 6942 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6943 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | ||
| 6944 | } | ||
| 6945 | // UQSUB16 | ||
| 6946 | else if (op2 == 0x03) { | ||
| 6947 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); | ||
| 6948 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6949 | } | ||
| 6950 | // UQADD8 | ||
| 6951 | else if (op2 == 0x04) { | ||
| 6952 | lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | | ||
| 6953 | ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; | ||
| 6954 | hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | | ||
| 6955 | ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; | ||
| 6956 | } | ||
| 6957 | // UQSUB8 | ||
| 6958 | else { | ||
| 6959 | lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | | ||
| 6960 | ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; | ||
| 6961 | hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | | ||
| 6962 | ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; | ||
| 6963 | } | ||
| 6964 | |||
| 6965 | RD = ((lo_val & 0xFFFF) | hi_val << 16); | ||
| 6966 | } | ||
| 6967 | |||
| 6968 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6969 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6970 | FETCH_INST; | ||
| 6971 | GOTO_NEXT_INST; | ||
| 6972 | } | ||
| 6973 | |||
| 6885 | USAD8_INST: | 6974 | USAD8_INST: |
| 6886 | USADA8_INST: | 6975 | USADA8_INST: |
| 6887 | USAT_INST: | 6976 | USAT_INST: |