dyncom: Use ARMul_State as an object

Gets rid of C-like parameter passing.
This commit is contained in:
Lioncash 2015-07-26 05:39:54 -04:00
parent 392c7feba0
commit 0ecc6e2f04
12 changed files with 1023 additions and 1105 deletions

View file

@ -18,16 +18,7 @@
#include "core/core_timing.h"
ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
state = Common::make_unique<ARMul_State>();
// Reset the core to initial state
ARMul_Reset(state.get());
// Switch to the desired privilege mode.
switch_mode(state.get(), initial_mode);
state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
state->Reg[15] = 0x00000000;
state = Common::make_unique<ARMul_State>(initial_mode);
}
ARM_DynCom::~ARM_DynCom() {

File diff suppressed because it is too large Load diff

View file

@ -1,93 +0,0 @@
// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/arm/dyncom/arm_dyncom_run.h"
#include "core/arm/skyeye_common/armstate.h"
void switch_mode(ARMul_State* core, uint32_t mode) {
if (core->Mode == mode)
return;
if (mode != USERBANK) {
switch (core->Mode) {
case SYSTEM32MODE: // Shares registers with user mode
case USER32MODE:
core->Reg_usr[0] = core->Reg[13];
core->Reg_usr[1] = core->Reg[14];
break;
case IRQ32MODE:
core->Reg_irq[0] = core->Reg[13];
core->Reg_irq[1] = core->Reg[14];
core->Spsr[IRQBANK] = core->Spsr_copy;
break;
case SVC32MODE:
core->Reg_svc[0] = core->Reg[13];
core->Reg_svc[1] = core->Reg[14];
core->Spsr[SVCBANK] = core->Spsr_copy;
break;
case ABORT32MODE:
core->Reg_abort[0] = core->Reg[13];
core->Reg_abort[1] = core->Reg[14];
core->Spsr[ABORTBANK] = core->Spsr_copy;
break;
case UNDEF32MODE:
core->Reg_undef[0] = core->Reg[13];
core->Reg_undef[1] = core->Reg[14];
core->Spsr[UNDEFBANK] = core->Spsr_copy;
break;
case FIQ32MODE:
core->Reg_firq[0] = core->Reg[13];
core->Reg_firq[1] = core->Reg[14];
core->Spsr[FIQBANK] = core->Spsr_copy;
break;
}
switch (mode) {
case USER32MODE:
core->Reg[13] = core->Reg_usr[0];
core->Reg[14] = core->Reg_usr[1];
core->Bank = USERBANK;
break;
case IRQ32MODE:
core->Reg[13] = core->Reg_irq[0];
core->Reg[14] = core->Reg_irq[1];
core->Spsr_copy = core->Spsr[IRQBANK];
core->Bank = IRQBANK;
break;
case SVC32MODE:
core->Reg[13] = core->Reg_svc[0];
core->Reg[14] = core->Reg_svc[1];
core->Spsr_copy = core->Spsr[SVCBANK];
core->Bank = SVCBANK;
break;
case ABORT32MODE:
core->Reg[13] = core->Reg_abort[0];
core->Reg[14] = core->Reg_abort[1];
core->Spsr_copy = core->Spsr[ABORTBANK];
core->Bank = ABORTBANK;
break;
case UNDEF32MODE:
core->Reg[13] = core->Reg_undef[0];
core->Reg[14] = core->Reg_undef[1];
core->Spsr_copy = core->Spsr[UNDEFBANK];
core->Bank = UNDEFBANK;
break;
case FIQ32MODE:
core->Reg[13] = core->Reg_firq[0];
core->Reg[14] = core->Reg_firq[1];
core->Spsr_copy = core->Spsr[FIQBANK];
core->Bank = FIQBANK;
break;
case SYSTEM32MODE: // Shares registers with user mode.
core->Reg[13] = core->Reg_usr[0];
core->Reg[14] = core->Reg_usr[1];
core->Bank = SYSTEMBANK;
break;
}
// Set the mode bits in the APSR
core->Cpsr = (core->Cpsr & ~core->Mode) | mode;
core->Mode = mode;
}
}

View file

@ -20,38 +20,29 @@
#include "core/arm/skyeye_common/armstate.h"
void switch_mode(ARMul_State* core, uint32_t mode);
// Note that for the 3DS, a Thumb instruction will only ever be
// two bytes in size. Thus we don't need to worry about ThumbEE
// or Thumb-2 where instructions can be 4 bytes in length.
static inline u32 GET_INST_SIZE(ARMul_State* core) {
return core->TFlag? 2 : 4;
}
/**
* Checks if the PC is being read, and if so, word-aligns it.
* Used with address calculations.
*
* @param core The ARM CPU state instance.
* @param cpu The ARM CPU state instance.
* @param Rn The register being read.
*
* @return If the PC is being read, then the word-aligned PC value is returned.
* If the PC is not being read, then the value stored in the register is returned.
*/
static inline u32 CHECK_READ_REG15_WA(ARMul_State* core, int Rn) {
return (Rn == 15) ? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) {
return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
}
/**
* Reads the PC. Used for data processing operations that use the PC.
*
* @param core The ARM CPU state instance.
* @param cpu The ARM CPU state instance.
* @param Rn The register being read.
*
* @return If the PC is being read, then the incremented PC value is returned.
* If the PC is not being read, then the values stored in the register is returned.
*/
static inline u32 CHECK_READ_REG15(ARMul_State* core, int Rn) {
return (Rn == 15) ? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
static inline u32 CHECK_READ_REG15(ARMul_State* cpu, int Rn) {
return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
}