summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-28 16:20:04 -0500
committerGravatar bunnei2014-12-28 16:50:08 -0500
commitbf9b33aa9f195bdbca2b9f3de8681e930819ae5c (patch)
tree2899322174893d32cb41b510d1d6453a7e8d80e4 /src/core
parentarmemu: Fix PKHTB to do an arithmetic shift and correctly decode immediate fi... (diff)
downloadyuzu-bf9b33aa9f195bdbca2b9f3de8681e930819ae5c.tar.gz
yuzu-bf9b33aa9f195bdbca2b9f3de8681e930819ae5c.tar.xz
yuzu-bf9b33aa9f195bdbca2b9f3de8681e930819ae5c.zip
dyncom: Implement PKHBT and PKHTB.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp59
1 files changed, 57 insertions, 2 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 98d825272..4cd8fe6ac 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1427,6 +1427,13 @@ typedef struct _blx_1_thumb {
1427 unsigned int instr; 1427 unsigned int instr;
1428}blx_1_thumb; 1428}blx_1_thumb;
1429 1429
1430typedef struct _pkh_inst {
1431 u32 Rm;
1432 u32 Rn;
1433 u32 Rd;
1434 u8 imm;
1435} pkh_inst;
1436
1430typedef arm_inst * ARM_INST_PTR; 1437typedef arm_inst * ARM_INST_PTR;
1431 1438
1432#define CACHE_BUFFER_SIZE (64 * 1024 * 2000) 1439#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
@@ -2376,8 +2383,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
2376 } 2383 }
2377 return inst_base; 2384 return inst_base;
2378} 2385}
2379ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHBT"); } 2386
2380ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHTB"); } 2387ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
2388{
2389 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
2390 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
2391
2392 inst_base->cond = BITS(inst, 28, 31);
2393 inst_base->idx = index;
2394 inst_base->br = NON_BRANCH;
2395 inst_base->load_r15 = 0;
2396
2397 inst_cream->Rd = BITS(inst, 12, 15);
2398 inst_cream->Rn = BITS(inst, 16, 19);
2399 inst_cream->Rm = BITS(inst, 0, 3);
2400 inst_cream->imm = BITS(inst, 7, 11);
2401
2402 return inst_base;
2403}
2404
2405ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
2406{
2407 return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
2408}
2409
2381ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) 2410ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2382{ 2411{
2383 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); 2412 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
@@ -5659,8 +5688,34 @@ unsigned InterpreterMainLoop(ARMul_State* state)
5659 FETCH_INST; 5688 FETCH_INST;
5660 GOTO_NEXT_INST; 5689 GOTO_NEXT_INST;
5661 } 5690 }
5691
5662 PKHBT_INST: 5692 PKHBT_INST:
5693 {
5694 INC_ICOUNTER;
5695 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5696 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5697 RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
5698 }
5699 cpu->Reg[15] += GET_INST_SIZE(cpu);
5700 INC_PC(sizeof(pkh_inst));
5701 FETCH_INST;
5702 GOTO_NEXT_INST;
5703 }
5704
5663 PKHTB_INST: 5705 PKHTB_INST:
5706 {
5707 INC_ICOUNTER;
5708 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5709 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
5710 int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
5711 RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
5712 }
5713 cpu->Reg[15] += GET_INST_SIZE(cpu);
5714 INC_PC(sizeof(pkh_inst));
5715 FETCH_INST;
5716 GOTO_NEXT_INST;
5717 }
5718
5664 PLD_INST: 5719 PLD_INST:
5665 { 5720 {
5666 INC_ICOUNTER; 5721 INC_ICOUNTER;