summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2015-05-14 15:41:40 -0400
committerGravatar Lioncash2015-05-14 16:25:02 -0400
commit8cd72428c9c7314cc7add4b5619b62eab035977f (patch)
treea9c1fc77edda58dba2ad49138c7dbb539aa86906 /src
parentdyncom: Handle some MSR variants individually (diff)
downloadyuzu-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.cpp10
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp154
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.
2056static 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
2055static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) 2068static 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
2359static 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
2346static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) 2371static 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
3375static 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}
3386static 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}
3397static 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