summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 64335b9c2..e3a8b1f6e 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -2369,7 +2369,25 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2369} 2369}
2370 2370
2371ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } 2371ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
2372ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); } 2372
2373ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
2374{
2375 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2376 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
2377
2378 inst_base->cond = BITS(inst, 28, 31);
2379 inst_base->idx = index;
2380 inst_base->br = NON_BRANCH;
2381 inst_base->load_r15 = 0;
2382
2383 inst_cream->Ra = BITS(inst, 12, 15);
2384 inst_cream->Rm = BITS(inst, 8, 11);
2385 inst_cream->Rn = BITS(inst, 0, 3);
2386 inst_cream->Rd = BITS(inst, 16, 19);
2387 inst_cream->m = BIT(inst, 6);
2388
2389 return inst_base;
2390}
2373 2391
2374ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) 2392ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
2375{ 2393{
@@ -5552,7 +5570,31 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5552 } 5570 }
5553 5571
5554 SMLALXY_INST: 5572 SMLALXY_INST:
5573
5555 SMLAW_INST: 5574 SMLAW_INST:
5575 {
5576 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5577 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
5578
5579 const u32 rm_val = RM;
5580 const u32 rn_val = RN;
5581 const u32 ra_val = cpu->Reg[inst_cream->Ra];
5582 const bool high = (inst_cream->m == 1);
5583
5584 const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
5585 const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
5586
5587 RD = (result & (0xFFFFFFFFFFFFFFFFLL >> 15)) >> 16;
5588
5589 if ((result >> 16) != (s32)RD)
5590 cpu->Cpsr |= (1 << 27);
5591 }
5592
5593 cpu->Reg[15] += GET_INST_SIZE(cpu);
5594 INC_PC(sizeof(smlad_inst));
5595 FETCH_INST;
5596 GOTO_NEXT_INST;
5597 }
5556 5598
5557 SMLALD_INST: 5599 SMLALD_INST:
5558 SMLSLD_INST: 5600 SMLSLD_INST: