summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2015-01-05 14:29:10 -0500
committerGravatar Lioncash2015-01-05 15:55:09 -0500
commitf75def619c28ed3f1293f2cb2740ae83d6972e4c (patch)
tree9846739f49d361ef421ab58d3b5db6226cf2b318 /src
parentMerge pull request #420 from lioncash/qflag (diff)
downloadyuzu-f75def619c28ed3f1293f2cb2740ae83d6972e4c.tar.gz
yuzu-f75def619c28ed3f1293f2cb2740ae83d6972e4c.tar.xz
yuzu-f75def619c28ed3f1293f2cb2740ae83d6972e4c.zip
dyncom: Partially emulate BXJ
Just in case some game studio let the intern write inline assembly or something.
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index ed2de115a..593e0eabd 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1419,15 +1419,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
1419 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); 1419 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
1420 bx_inst *inst_cream = (bx_inst *)inst_base->component; 1420 bx_inst *inst_cream = (bx_inst *)inst_base->component;
1421 1421
1422 inst_base->cond = BITS(inst, 28, 31); 1422 inst_base->cond = BITS(inst, 28, 31);
1423 inst_base->idx = index; 1423 inst_base->idx = index;
1424 inst_base->br = INDIRECT_BRANCH; 1424 inst_base->br = INDIRECT_BRANCH;
1425 1425
1426 inst_cream->Rm = BITS(inst, 0, 3); 1426 inst_cream->Rm = BITS(inst, 0, 3);
1427 1427
1428 return inst_base; 1428 return inst_base;
1429} 1429}
1430ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } 1430ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
1431{
1432 return INTERPRETER_TRANSLATE(bx)(inst, index);
1433}
1434
1431ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ 1435ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
1432 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); 1436 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
1433 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 1437 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -4129,22 +4133,35 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4129 INC_PC(sizeof(blx_inst)); 4133 INC_PC(sizeof(blx_inst));
4130 goto DISPATCH; 4134 goto DISPATCH;
4131 } 4135 }
4136
4132 BX_INST: 4137 BX_INST:
4138 BXJ_INST:
4133 { 4139 {
4134 bx_inst *inst_cream = (bx_inst *)inst_base->component; 4140 // Note that only the 'fail' case of BXJ is emulated. This is because
4135 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4141 // the facilities for Jazelle emulation are not implemented.
4142 //
4143 // According to the ARM documentation on BXJ, if setting the J bit in the APSR
4144 // fails, then BXJ functions identically like a regular BX instruction.
4145 //
4146 // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
4147
4148 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4149 bx_inst* const inst_cream = (bx_inst*)inst_base->component;
4150
4136 if (inst_cream->Rm == 15) 4151 if (inst_cream->Rm == 15)
4137 LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); 4152 LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
4153
4138 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; 4154 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4139 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; 4155 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
4140 INC_PC(sizeof(bx_inst)); 4156 INC_PC(sizeof(bx_inst));
4141 goto DISPATCH; 4157 goto DISPATCH;
4142 } 4158 }
4159
4143 cpu->Reg[15] += GET_INST_SIZE(cpu); 4160 cpu->Reg[15] += GET_INST_SIZE(cpu);
4144 INC_PC(sizeof(bx_inst)); 4161 INC_PC(sizeof(bx_inst));
4145 goto DISPATCH; 4162 goto DISPATCH;
4146 } 4163 }
4147 BXJ_INST: 4164
4148 CDP_INST: 4165 CDP_INST:
4149 { 4166 {
4150 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 4167 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;