diff options
| author | 2015-05-14 15:41:40 -0400 | |
|---|---|---|
| committer | 2015-05-14 16:25:02 -0400 | |
| commit | 8cd72428c9c7314cc7add4b5619b62eab035977f (patch) | |
| tree | a9c1fc77edda58dba2ad49138c7dbb539aa86906 /src | |
| parent | dyncom: Handle some MSR variants individually (diff) | |
| download | yuzu-8cd72428c9c7314cc7add4b5619b62eab035977f.tar.gz yuzu-8cd72428c9c7314cc7add4b5619b62eab035977f.tar.xz yuzu-8cd72428c9c7314cc7add4b5619b62eab035977f.zip | |
dyncom: Add ARMv6K NOP and hint instructions to the decoding table
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.cpp | 10 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 154 |
2 files changed, 152 insertions, 12 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index d0d37bea0..3887189f1 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.cpp +++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp | |||
| @@ -198,6 +198,11 @@ const ISEITEM arm_instruction[] = { | |||
| 198 | { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 }, | 198 | { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 }, |
| 199 | { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 }, | 199 | { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 }, |
| 200 | { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 }, | 200 | { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 }, |
| 201 | { "nop", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000000 }, | ||
| 202 | { "yield", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000001 }, | ||
| 203 | { "wfe", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000002 }, | ||
| 204 | { "wfi", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000003 }, | ||
| 205 | { "sev", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000004 }, | ||
| 201 | { "swi", 1, 0, 24, 27, 0x0000000f }, | 206 | { "swi", 1, 0, 24, 27, 0x0000000f }, |
| 202 | { "bbl", 1, 0, 25, 27, 0x00000005 }, | 207 | { "bbl", 1, 0, 25, 27, 0x00000005 }, |
| 203 | }; | 208 | }; |
| @@ -395,6 +400,11 @@ const ISEITEM arm_exclusion_code[] = { | |||
| 395 | { "strexd", 0, ARMV6K, 0 }, | 400 | { "strexd", 0, ARMV6K, 0 }, |
| 396 | { "ldrexh", 0, ARMV6K, 0 }, | 401 | { "ldrexh", 0, ARMV6K, 0 }, |
| 397 | { "strexh", 0, ARMV6K, 0 }, | 402 | { "strexh", 0, ARMV6K, 0 }, |
| 403 | { "nop", 0, ARMV6K, 0 }, | ||
| 404 | { "yield", 0, ARMV6K, 0 }, | ||
| 405 | { "wfe", 0, ARMV6K, 0 }, | ||
| 406 | { "wfi", 0, ARMV6K, 0 }, | ||
| 407 | { "sev", 0, ARMV6K, 0 }, | ||
| 398 | { "swi", 0, 0, 0 }, | 408 | { "swi", 0, 0, 0 }, |
| 399 | { "bbl", 0, 0, 0 }, | 409 | { "bbl", 0, 0, 0 }, |
| 400 | 410 | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 7e8032b30..cb45cfb38 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2052,6 +2052,19 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) | |||
| 2052 | return inst_base; | 2052 | return inst_base; |
| 2053 | } | 2053 | } |
| 2054 | 2054 | ||
| 2055 | // NOP introduced in ARMv6K. | ||
| 2056 | static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index) | ||
| 2057 | { | ||
| 2058 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); | ||
| 2059 | |||
| 2060 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2061 | inst_base->idx = index; | ||
| 2062 | inst_base->br = NON_BRANCH; | ||
| 2063 | inst_base->load_r15 = 0; | ||
| 2064 | |||
| 2065 | return inst_base; | ||
| 2066 | } | ||
| 2067 | |||
| 2055 | static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) | 2068 | static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) |
| 2056 | { | 2069 | { |
| 2057 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); | 2070 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); |
| @@ -2343,6 +2356,18 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) | |||
| 2343 | return inst_base; | 2356 | return inst_base; |
| 2344 | } | 2357 | } |
| 2345 | 2358 | ||
| 2359 | static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index) | ||
| 2360 | { | ||
| 2361 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); | ||
| 2362 | |||
| 2363 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2364 | inst_base->idx = index; | ||
| 2365 | inst_base->br = NON_BRANCH; | ||
| 2366 | inst_base->load_r15 = 0; | ||
| 2367 | |||
| 2368 | return inst_base; | ||
| 2369 | } | ||
| 2370 | |||
| 2346 | static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) | 2371 | static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) |
| 2347 | { | 2372 | { |
| 2348 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2373 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| @@ -3347,6 +3372,40 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) | |||
| 3347 | return INTERPRETER_TRANSLATE(uxtab16)(inst, index); | 3372 | return INTERPRETER_TRANSLATE(uxtab16)(inst, index); |
| 3348 | } | 3373 | } |
| 3349 | 3374 | ||
| 3375 | static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index) | ||
| 3376 | { | ||
| 3377 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); | ||
| 3378 | |||
| 3379 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3380 | inst_base->idx = index; | ||
| 3381 | inst_base->br = NON_BRANCH; | ||
| 3382 | inst_base->load_r15 = 0; | ||
| 3383 | |||
| 3384 | return inst_base; | ||
| 3385 | } | ||
| 3386 | static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index) | ||
| 3387 | { | ||
| 3388 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); | ||
| 3389 | |||
| 3390 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3391 | inst_base->idx = index; | ||
| 3392 | inst_base->br = NON_BRANCH; | ||
| 3393 | inst_base->load_r15 = 0; | ||
| 3394 | |||
| 3395 | return inst_base; | ||
| 3396 | } | ||
| 3397 | static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) | ||
| 3398 | { | ||
| 3399 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); | ||
| 3400 | |||
| 3401 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3402 | inst_base->idx = index; | ||
| 3403 | inst_base->br = NON_BRANCH; | ||
| 3404 | inst_base->load_r15 = 0; | ||
| 3405 | |||
| 3406 | return inst_base; | ||
| 3407 | } | ||
| 3408 | |||
| 3350 | // Floating point VFPv3 structures and instructions | 3409 | // Floating point VFPv3 structures and instructions |
| 3351 | 3410 | ||
| 3352 | #define VFP_INTERPRETER_STRUCT | 3411 | #define VFP_INTERPRETER_STRUCT |
| @@ -3552,6 +3611,11 @@ const transop_fp_t arm_instruction_trans[] = { | |||
| 3552 | INTERPRETER_TRANSLATE(strexd), | 3611 | INTERPRETER_TRANSLATE(strexd), |
| 3553 | INTERPRETER_TRANSLATE(ldrexh), | 3612 | INTERPRETER_TRANSLATE(ldrexh), |
| 3554 | INTERPRETER_TRANSLATE(strexh), | 3613 | INTERPRETER_TRANSLATE(strexh), |
| 3614 | INTERPRETER_TRANSLATE(nop), | ||
| 3615 | INTERPRETER_TRANSLATE(yield), | ||
| 3616 | INTERPRETER_TRANSLATE(wfe), | ||
| 3617 | INTERPRETER_TRANSLATE(wfi), | ||
| 3618 | INTERPRETER_TRANSLATE(sev), | ||
| 3555 | INTERPRETER_TRANSLATE(swi), | 3619 | INTERPRETER_TRANSLATE(swi), |
| 3556 | INTERPRETER_TRANSLATE(bbl), | 3620 | INTERPRETER_TRANSLATE(bbl), |
| 3557 | 3621 | ||
| @@ -3727,7 +3791,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3727 | #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \ | 3791 | #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \ |
| 3728 | inst_base = (arm_inst *)&inst_buf[ptr] | 3792 | inst_base = (arm_inst *)&inst_buf[ptr] |
| 3729 | 3793 | ||
| 3730 | #define INC_PC(l) ptr += sizeof(arm_inst) + l | 3794 | #define INC_PC(l) ptr += sizeof(arm_inst) + l |
| 3795 | #define INC_PC_STUB ptr += sizeof(arm_inst) | ||
| 3731 | 3796 | ||
| 3732 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a | 3797 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a |
| 3733 | // clunky switch statement. | 3798 | // clunky switch statement. |
| @@ -3932,16 +3997,21 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3932 | case 188: goto STREXD_INST; \ | 3997 | case 188: goto STREXD_INST; \ |
| 3933 | case 189: goto LDREXH_INST; \ | 3998 | case 189: goto LDREXH_INST; \ |
| 3934 | case 190: goto STREXH_INST; \ | 3999 | case 190: goto STREXH_INST; \ |
| 3935 | case 191: goto SWI_INST; \ | 4000 | case 191: goto NOP_INST; \ |
| 3936 | case 192: goto BBL_INST; \ | 4001 | case 192: goto YIELD_INST; \ |
| 3937 | case 193: goto B_2_THUMB ; \ | 4002 | case 193: goto WFE_INST; \ |
| 3938 | case 194: goto B_COND_THUMB ; \ | 4003 | case 194: goto WFI_INST; \ |
| 3939 | case 195: goto BL_1_THUMB ; \ | 4004 | case 195: goto SEV_INST; \ |
| 3940 | case 196: goto BL_2_THUMB ; \ | 4005 | case 196: goto SWI_INST; \ |
| 3941 | case 197: goto BLX_1_THUMB ; \ | 4006 | case 197: goto BBL_INST; \ |
| 3942 | case 198: goto DISPATCH; \ | 4007 | case 198: goto B_2_THUMB ; \ |
| 3943 | case 199: goto INIT_INST_LENGTH; \ | 4008 | case 199: goto B_COND_THUMB ; \ |
| 3944 | case 200: goto END; \ | 4009 | case 200: goto BL_1_THUMB ; \ |
| 4010 | case 201: goto BL_2_THUMB ; \ | ||
| 4011 | case 202: goto BLX_1_THUMB ; \ | ||
| 4012 | case 203: goto DISPATCH; \ | ||
| 4013 | case 204: goto INIT_INST_LENGTH; \ | ||
| 4014 | case 205: goto END; \ | ||
| 3945 | } | 4015 | } |
| 3946 | #endif | 4016 | #endif |
| 3947 | 4017 | ||
| @@ -3990,7 +4060,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3990 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST, | 4060 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST, |
| 3991 | &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, | 4061 | &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, |
| 3992 | &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST, | 4062 | &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST, |
| 3993 | &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&SWI_INST,&&BBL_INST, | 4063 | &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST, |
| 3994 | &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH, | 4064 | &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH, |
| 3995 | &&INIT_INST_LENGTH,&&END | 4065 | &&INIT_INST_LENGTH,&&END |
| 3996 | }; | 4066 | }; |
| @@ -5044,6 +5114,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5044 | GOTO_NEXT_INST; | 5114 | GOTO_NEXT_INST; |
| 5045 | } | 5115 | } |
| 5046 | 5116 | ||
| 5117 | NOP_INST: | ||
| 5118 | { | ||
| 5119 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5120 | INC_PC_STUB; | ||
| 5121 | FETCH_INST; | ||
| 5122 | GOTO_NEXT_INST; | ||
| 5123 | } | ||
| 5124 | |||
| 5047 | PKHBT_INST: | 5125 | PKHBT_INST: |
| 5048 | { | 5126 | { |
| 5049 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5127 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| @@ -5527,6 +5605,19 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5527 | GOTO_NEXT_INST; | 5605 | GOTO_NEXT_INST; |
| 5528 | } | 5606 | } |
| 5529 | 5607 | ||
| 5608 | SEV_INST: | ||
| 5609 | { | ||
| 5610 | // Stubbed, as SEV is a hint instruction. | ||
| 5611 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5612 | LOG_TRACE(Core_ARM11, "SEV executed."); | ||
| 5613 | } | ||
| 5614 | |||
| 5615 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5616 | INC_PC_STUB; | ||
| 5617 | FETCH_INST; | ||
| 5618 | GOTO_NEXT_INST; | ||
| 5619 | } | ||
| 5620 | |||
| 5530 | SHADD8_INST: | 5621 | SHADD8_INST: |
| 5531 | SHADD16_INST: | 5622 | SHADD16_INST: |
| 5532 | SHADDSUBX_INST: | 5623 | SHADDSUBX_INST: |
| @@ -6990,6 +7081,45 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6990 | GOTO_NEXT_INST; | 7081 | GOTO_NEXT_INST; |
| 6991 | } | 7082 | } |
| 6992 | 7083 | ||
| 7084 | WFE_INST: | ||
| 7085 | { | ||
| 7086 | // Stubbed, as WFE is a hint instruction. | ||
| 7087 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 7088 | LOG_TRACE(Core_ARM11, "WFE executed."); | ||
| 7089 | } | ||
| 7090 | |||
| 7091 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 7092 | INC_PC_STUB; | ||
| 7093 | FETCH_INST; | ||
| 7094 | GOTO_NEXT_INST; | ||
| 7095 | } | ||
| 7096 | |||
| 7097 | WFI_INST: | ||
| 7098 | { | ||
| 7099 | // Stubbed, as WFI is a hint instruction. | ||
| 7100 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 7101 | LOG_TRACE(Core_ARM11, "WFI executed."); | ||
| 7102 | } | ||
| 7103 | |||
| 7104 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 7105 | INC_PC_STUB; | ||
| 7106 | FETCH_INST; | ||
| 7107 | GOTO_NEXT_INST; | ||
| 7108 | } | ||
| 7109 | |||
| 7110 | YIELD_INST: | ||
| 7111 | { | ||
| 7112 | // Stubbed, as YIELD is a hint instruction. | ||
| 7113 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 7114 | LOG_TRACE(Core_ARM11, "YIELD executed."); | ||
| 7115 | } | ||
| 7116 | |||
| 7117 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 7118 | INC_PC_STUB; | ||
| 7119 | FETCH_INST; | ||
| 7120 | GOTO_NEXT_INST; | ||
| 7121 | } | ||
| 7122 | |||
| 6993 | #define VFP_INTERPRETER_IMPL | 7123 | #define VFP_INTERPRETER_IMPL |
| 6994 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 7124 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| 6995 | #undef VFP_INTERPRETER_IMPL | 7125 | #undef VFP_INTERPRETER_IMPL |