|
|
@ -2052,6 +2052,19 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
|
|
|
|
return inst_base;
|
|
|
|
return inst_base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOP introduced in ARMv6K.
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst_base->cond = BITS(inst, 28, 31);
|
|
|
|
|
|
|
|
inst_base->idx = index;
|
|
|
|
|
|
|
|
inst_base->br = NON_BRANCH;
|
|
|
|
|
|
|
|
inst_base->load_r15 = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inst_base;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
|
|
|
|
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)
|
|
|
|
return inst_base;
|
|
|
|
return inst_base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst_base->cond = BITS(inst, 28, 31);
|
|
|
|
|
|
|
|
inst_base->idx = index;
|
|
|
|
|
|
|
|
inst_base->br = NON_BRANCH;
|
|
|
|
|
|
|
|
inst_base->load_r15 = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inst_base;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
|
|
|
|
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)
|
|
|
|
return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
|
|
|
|
return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst_base->cond = BITS(inst, 28, 31);
|
|
|
|
|
|
|
|
inst_base->idx = index;
|
|
|
|
|
|
|
|
inst_base->br = NON_BRANCH;
|
|
|
|
|
|
|
|
inst_base->load_r15 = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inst_base;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst_base->cond = BITS(inst, 28, 31);
|
|
|
|
|
|
|
|
inst_base->idx = index;
|
|
|
|
|
|
|
|
inst_base->br = NON_BRANCH;
|
|
|
|
|
|
|
|
inst_base->load_r15 = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inst_base;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst_base->cond = BITS(inst, 28, 31);
|
|
|
|
|
|
|
|
inst_base->idx = index;
|
|
|
|
|
|
|
|
inst_base->br = NON_BRANCH;
|
|
|
|
|
|
|
|
inst_base->load_r15 = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inst_base;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Floating point VFPv3 structures and instructions
|
|
|
|
// Floating point VFPv3 structures and instructions
|
|
|
|
|
|
|
|
|
|
|
|
#define VFP_INTERPRETER_STRUCT
|
|
|
|
#define VFP_INTERPRETER_STRUCT
|
|
|
@ -3552,6 +3611,11 @@ const transop_fp_t arm_instruction_trans[] = {
|
|
|
|
INTERPRETER_TRANSLATE(strexd),
|
|
|
|
INTERPRETER_TRANSLATE(strexd),
|
|
|
|
INTERPRETER_TRANSLATE(ldrexh),
|
|
|
|
INTERPRETER_TRANSLATE(ldrexh),
|
|
|
|
INTERPRETER_TRANSLATE(strexh),
|
|
|
|
INTERPRETER_TRANSLATE(strexh),
|
|
|
|
|
|
|
|
INTERPRETER_TRANSLATE(nop),
|
|
|
|
|
|
|
|
INTERPRETER_TRANSLATE(yield),
|
|
|
|
|
|
|
|
INTERPRETER_TRANSLATE(wfe),
|
|
|
|
|
|
|
|
INTERPRETER_TRANSLATE(wfi),
|
|
|
|
|
|
|
|
INTERPRETER_TRANSLATE(sev),
|
|
|
|
INTERPRETER_TRANSLATE(swi),
|
|
|
|
INTERPRETER_TRANSLATE(swi),
|
|
|
|
INTERPRETER_TRANSLATE(bbl),
|
|
|
|
INTERPRETER_TRANSLATE(bbl),
|
|
|
|
|
|
|
|
|
|
|
@ -3728,6 +3792,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
inst_base = (arm_inst *)&inst_buf[ptr]
|
|
|
|
inst_base = (arm_inst *)&inst_buf[ptr]
|
|
|
|
|
|
|
|
|
|
|
|
#define INC_PC(l) ptr += sizeof(arm_inst) + l
|
|
|
|
#define INC_PC(l) ptr += sizeof(arm_inst) + l
|
|
|
|
|
|
|
|
#define INC_PC_STUB ptr += sizeof(arm_inst)
|
|
|
|
|
|
|
|
|
|
|
|
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
|
|
|
|
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
|
|
|
|
// clunky switch statement.
|
|
|
|
// clunky switch statement.
|
|
|
@ -3932,16 +3997,21 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
case 188: goto STREXD_INST; \
|
|
|
|
case 188: goto STREXD_INST; \
|
|
|
|
case 189: goto LDREXH_INST; \
|
|
|
|
case 189: goto LDREXH_INST; \
|
|
|
|
case 190: goto STREXH_INST; \
|
|
|
|
case 190: goto STREXH_INST; \
|
|
|
|
case 191: goto SWI_INST; \
|
|
|
|
case 191: goto NOP_INST; \
|
|
|
|
case 192: goto BBL_INST; \
|
|
|
|
case 192: goto YIELD_INST; \
|
|
|
|
case 193: goto B_2_THUMB ; \
|
|
|
|
case 193: goto WFE_INST; \
|
|
|
|
case 194: goto B_COND_THUMB ; \
|
|
|
|
case 194: goto WFI_INST; \
|
|
|
|
case 195: goto BL_1_THUMB ; \
|
|
|
|
case 195: goto SEV_INST; \
|
|
|
|
case 196: goto BL_2_THUMB ; \
|
|
|
|
case 196: goto SWI_INST; \
|
|
|
|
case 197: goto BLX_1_THUMB ; \
|
|
|
|
case 197: goto BBL_INST; \
|
|
|
|
case 198: goto DISPATCH; \
|
|
|
|
case 198: goto B_2_THUMB ; \
|
|
|
|
case 199: goto INIT_INST_LENGTH; \
|
|
|
|
case 199: goto B_COND_THUMB ; \
|
|
|
|
case 200: goto END; \
|
|
|
|
case 200: goto BL_1_THUMB ; \
|
|
|
|
|
|
|
|
case 201: goto BL_2_THUMB ; \
|
|
|
|
|
|
|
|
case 202: goto BLX_1_THUMB ; \
|
|
|
|
|
|
|
|
case 203: goto DISPATCH; \
|
|
|
|
|
|
|
|
case 204: goto INIT_INST_LENGTH; \
|
|
|
|
|
|
|
|
case 205: goto END; \
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -3990,7 +4060,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
&&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,
|
|
|
|
&&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,
|
|
|
|
&&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST,
|
|
|
|
&&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST,
|
|
|
|
&&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST,
|
|
|
|
&&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST,
|
|
|
|
&&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&SWI_INST,&&BBL_INST,
|
|
|
|
&&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST,
|
|
|
|
&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
|
|
|
|
&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
|
|
|
|
&&INIT_INST_LENGTH,&&END
|
|
|
|
&&INIT_INST_LENGTH,&&END
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -5044,6 +5114,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NOP_INST:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu);
|
|
|
|
|
|
|
|
INC_PC_STUB;
|
|
|
|
|
|
|
|
FETCH_INST;
|
|
|
|
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PKHBT_INST:
|
|
|
|
PKHBT_INST:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
@ -5527,6 +5605,19 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SEV_INST:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Stubbed, as SEV is a hint instruction.
|
|
|
|
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "SEV executed.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu);
|
|
|
|
|
|
|
|
INC_PC_STUB;
|
|
|
|
|
|
|
|
FETCH_INST;
|
|
|
|
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SHADD8_INST:
|
|
|
|
SHADD8_INST:
|
|
|
|
SHADD16_INST:
|
|
|
|
SHADD16_INST:
|
|
|
|
SHADDSUBX_INST:
|
|
|
|
SHADDSUBX_INST:
|
|
|
@ -6990,6 +7081,45 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WFE_INST:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Stubbed, as WFE is a hint instruction.
|
|
|
|
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "WFE executed.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu);
|
|
|
|
|
|
|
|
INC_PC_STUB;
|
|
|
|
|
|
|
|
FETCH_INST;
|
|
|
|
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WFI_INST:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Stubbed, as WFI is a hint instruction.
|
|
|
|
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "WFI executed.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu);
|
|
|
|
|
|
|
|
INC_PC_STUB;
|
|
|
|
|
|
|
|
FETCH_INST;
|
|
|
|
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
YIELD_INST:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Stubbed, as YIELD is a hint instruction.
|
|
|
|
|
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "YIELD executed.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu);
|
|
|
|
|
|
|
|
INC_PC_STUB;
|
|
|
|
|
|
|
|
FETCH_INST;
|
|
|
|
|
|
|
|
GOTO_NEXT_INST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define VFP_INTERPRETER_IMPL
|
|
|
|
#define VFP_INTERPRETER_IMPL
|
|
|
|
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
|
|
|
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
|
|
|
#undef VFP_INTERPRETER_IMPL
|
|
|
|
#undef VFP_INTERPRETER_IMPL
|
|
|
|