dyncom: Use ARMul_State as an object
Gets rid of C-like parameter passing.
This commit is contained in:
parent
392c7feba0
commit
0ecc6e2f04
12 changed files with 1023 additions and 1105 deletions
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue