Просмотр исходного кода

dyncom: Use ARMul_State as an object

Gets rid of C-like parameter passing.
Lioncash 11 лет назад
Родитель
Сommit
0ecc6e2f04

+ 1 - 3
src/core/CMakeLists.txt

@@ -4,9 +4,8 @@ set(SRCS
             arm/dyncom/arm_dyncom.cpp
             arm/dyncom/arm_dyncom_dec.cpp
             arm/dyncom/arm_dyncom_interpreter.cpp
-            arm/dyncom/arm_dyncom_run.cpp
             arm/dyncom/arm_dyncom_thumb.cpp
-            arm/skyeye_common/arminit.cpp
+            arm/skyeye_common/armstate.cpp
             arm/skyeye_common/armsupp.cpp
             arm/skyeye_common/vfp/vfp.cpp
             arm/skyeye_common/vfp/vfpdouble.cpp
@@ -133,7 +132,6 @@ set(HEADERS
             arm/dyncom/arm_dyncom_thumb.h
             arm/skyeye_common/arm_regformat.h
             arm/skyeye_common/armstate.h
-            arm/skyeye_common/armmmu.h
             arm/skyeye_common/armsupp.h
             arm/skyeye_common/vfp/asm_vfp.h
             arm/skyeye_common/vfp/vfp.h

+ 1 - 10
src/core/arm/dyncom/arm_dyncom.cpp

@@ -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() {

Разница между файлами не показана из-за своего большого размера
+ 120 - 121
src/core/arm/dyncom/arm_dyncom_interpreter.cpp


+ 0 - 93
src/core/arm/dyncom/arm_dyncom_run.cpp

@@ -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;
-    }
-}

+ 6 - 15
src/core/arm/dyncom/arm_dyncom_run.h

@@ -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];
 }

+ 0 - 100
src/core/arm/skyeye_common/arminit.cpp

@@ -1,100 +0,0 @@
-/*  arminit.c -- ARMulator initialization:  ARM6 Instruction Emulator.
-    Copyright (C) 1994 Advanced RISC Machines Ltd.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include <cstring>
-#include "core/arm/skyeye_common/armstate.h"
-#include "core/arm/skyeye_common/vfp/vfp.h"
-
-// Resets certain MPCore CP15 values to their ARM-defined reset values.
-static void ResetMPCoreCP15Registers(ARMul_State* cpu)
-{
-    // c0
-    cpu->CP15[CP15_MAIN_ID]  = 0x410FB024;
-    cpu->CP15[CP15_TLB_TYPE] = 0x00000800;
-    cpu->CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
-    cpu->CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
-    cpu->CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
-    cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
-    cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
-    cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
-    cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
-    cpu->CP15[CP15_ISA_FEATURE_0] = 0x00100011;
-    cpu->CP15[CP15_ISA_FEATURE_1] = 0x12002111;
-    cpu->CP15[CP15_ISA_FEATURE_2] = 0x11221011;
-    cpu->CP15[CP15_ISA_FEATURE_3] = 0x01102131;
-    cpu->CP15[CP15_ISA_FEATURE_4] = 0x00000141;
-
-    // c1
-    cpu->CP15[CP15_CONTROL] = 0x00054078;
-    cpu->CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
-    cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
-
-    // c2
-    cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
-    cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
-    cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
-
-    // c3
-    cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
-
-    // c7
-    cpu->CP15[CP15_PHYS_ADDRESS] = 0x00000000;
-
-    // c9
-    cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
-
-    // c10
-    cpu->CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
-    cpu->CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
-    cpu->CP15[CP15_NORMAL_REGION_REMAP]  = 0x44E048E0;
-
-    // c13
-    cpu->CP15[CP15_PID] = 0x00000000;
-    cpu->CP15[CP15_CONTEXT_ID]  = 0x00000000;
-    cpu->CP15[CP15_THREAD_UPRW] = 0x00000000;
-    cpu->CP15[CP15_THREAD_URO]  = 0x00000000;
-    cpu->CP15[CP15_THREAD_PRW]  = 0x00000000;
-
-    // c15
-    cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL]    = 0x00000000;
-    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
-    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
-    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE]    = 0x00000000;
-    cpu->CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
-}
-
-// Performs a reset
-void ARMul_Reset(ARMul_State* state)
-{
-    VFPInit(state);
-
-    state->Reg[15] = 0;
-    state->Cpsr = INTBITS | SVC32MODE;
-    state->Mode = SVC32MODE;
-    state->Bank = SVCBANK;
-
-    ResetMPCoreCP15Registers(state);
-
-    state->NresetSig = HIGH;
-    state->NfiqSig = HIGH;
-    state->NirqSig = HIGH;
-    state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
-    state->abortSig = LOW;
-
-    state->NumInstrs = 0;
-    state->Emulate = RUN;
-}

+ 0 - 104
src/core/arm/skyeye_common/armmmu.h

@@ -1,104 +0,0 @@
-/*
-    armmmu.c - Memory Management Unit emulation.
-    ARMulator extensions for the ARM7100 family.
-    Copyright (C) 1999  Ben Williamson
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#pragma once
-
-#include "common/swap.h"
-
-#include "core/memory.h"
-#include "core/arm/skyeye_common/armstate.h"
-#include "core/arm/skyeye_common/armsupp.h"
-
-// Register numbers in the MMU
-enum
-{
-    MMU_ID = 0,
-    MMU_CONTROL = 1,
-    MMU_TRANSLATION_TABLE_BASE = 2,
-    MMU_DOMAIN_ACCESS_CONTROL = 3,
-    MMU_FAULT_STATUS = 5,
-    MMU_FAULT_ADDRESS = 6,
-    MMU_CACHE_OPS = 7,
-    MMU_TLB_OPS = 8,
-    MMU_CACHE_LOCKDOWN = 9,
-    MMU_TLB_LOCKDOWN = 10,
-    MMU_PID = 13,
-
-    // MMU_V4
-    MMU_V4_CACHE_OPS = 7,
-    MMU_V4_TLB_OPS = 8,
-
-    // MMU_V3
-    MMU_V3_FLUSH_TLB = 5,
-    MMU_V3_FLUSH_TLB_ENTRY = 6,
-    MMU_V3_FLUSH_CACHE = 7,
-};
-
-// Reads data in big/little endian format based on the
-// state of the E (endian) bit in the emulated CPU's APSR.
-inline u16 ReadMemory16(ARMul_State* cpu, u32 address) {
-    u16 data = Memory::Read16(address);
-
-    if (InBigEndianMode(cpu))
-        data = Common::swap16(data);
-
-    return data;
-}
-
-inline u32 ReadMemory32(ARMul_State* cpu, u32 address) {
-    u32 data = Memory::Read32(address);
-
-    if (InBigEndianMode(cpu))
-        data = Common::swap32(data);
-
-    return data;
-}
-
-inline u64 ReadMemory64(ARMul_State* cpu, u32 address) {
-    u64 data = Memory::Read64(address);
-
-    if (InBigEndianMode(cpu))
-        data = Common::swap64(data);
-
-    return data;
-}
-
-// Writes data in big/little endian format based on the
-// state of the E (endian) bit in the emulated CPU's APSR.
-inline void WriteMemory16(ARMul_State* cpu, u32 address, u16 data) {
-    if (InBigEndianMode(cpu))
-        data = Common::swap16(data);
-
-    Memory::Write16(address, data);
-}
-
-inline void WriteMemory32(ARMul_State* cpu, u32 address, u32 data) {
-    if (InBigEndianMode(cpu))
-        data = Common::swap32(data);
-
-    Memory::Write32(address, data);
-}
-
-inline void WriteMemory64(ARMul_State* cpu, u32 address, u64 data) {
-    if (InBigEndianMode(cpu))
-        data = Common::swap64(data);
-
-    Memory::Write64(address, data);
-}

+ 657 - 0
src/core/arm/skyeye_common/armstate.cpp

@@ -0,0 +1,657 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/swap.h"
+#include "common/logging/log.h"
+#include "core/mem_map.h"
+#include "core/memory.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/vfp/vfp.h"
+
+ARMul_State::ARMul_State(PrivilegeMode initial_mode)
+{
+    Reset();
+    ChangePrivilegeMode(initial_mode);
+}
+
+void ARMul_State::ChangePrivilegeMode(u32 new_mode)
+{
+    if (Mode == new_mode)
+        return;
+
+    if (new_mode != USERBANK) {
+        switch (Mode) {
+        case SYSTEM32MODE: // Shares registers with user mode
+        case USER32MODE:
+            Reg_usr[0] = Reg[13];
+            Reg_usr[1] = Reg[14];
+            break;
+        case IRQ32MODE:
+            Reg_irq[0] = Reg[13];
+            Reg_irq[1] = Reg[14];
+            Spsr[IRQBANK] = Spsr_copy;
+            break;
+        case SVC32MODE:
+            Reg_svc[0] = Reg[13];
+            Reg_svc[1] = Reg[14];
+            Spsr[SVCBANK] = Spsr_copy;
+            break;
+        case ABORT32MODE:
+            Reg_abort[0] = Reg[13];
+            Reg_abort[1] = Reg[14];
+            Spsr[ABORTBANK] = Spsr_copy;
+            break;
+        case UNDEF32MODE:
+            Reg_undef[0] = Reg[13];
+            Reg_undef[1] = Reg[14];
+            Spsr[UNDEFBANK] = Spsr_copy;
+            break;
+        case FIQ32MODE:
+            Reg_firq[0] = Reg[13];
+            Reg_firq[1] = Reg[14];
+            Spsr[FIQBANK] = Spsr_copy;
+            break;
+        }
+
+        switch (new_mode) {
+        case USER32MODE:
+            Reg[13] = Reg_usr[0];
+            Reg[14] = Reg_usr[1];
+            Bank = USERBANK;
+            break;
+        case IRQ32MODE:
+            Reg[13] = Reg_irq[0];
+            Reg[14] = Reg_irq[1];
+            Spsr_copy = Spsr[IRQBANK];
+            Bank = IRQBANK;
+            break;
+        case SVC32MODE:
+            Reg[13] = Reg_svc[0];
+            Reg[14] = Reg_svc[1];
+            Spsr_copy = Spsr[SVCBANK];
+            Bank = SVCBANK;
+            break;
+        case ABORT32MODE:
+            Reg[13] = Reg_abort[0];
+            Reg[14] = Reg_abort[1];
+            Spsr_copy = Spsr[ABORTBANK];
+            Bank = ABORTBANK;
+            break;
+        case UNDEF32MODE:
+            Reg[13] = Reg_undef[0];
+            Reg[14] = Reg_undef[1];
+            Spsr_copy = Spsr[UNDEFBANK];
+            Bank = UNDEFBANK;
+            break;
+        case FIQ32MODE:
+            Reg[13] = Reg_firq[0];
+            Reg[14] = Reg_firq[1];
+            Spsr_copy = Spsr[FIQBANK];
+            Bank = FIQBANK;
+            break;
+        case SYSTEM32MODE: // Shares registers with user mode.
+            Reg[13] = Reg_usr[0];
+            Reg[14] = Reg_usr[1];
+            Bank = SYSTEMBANK;
+            break;
+        }
+
+        // Set the mode bits in the APSR
+        Cpsr = (Cpsr & ~Mode) | new_mode;
+        Mode = new_mode;
+    }
+}
+
+// Performs a reset
+void ARMul_State::Reset()
+{
+    VFPInit(this);
+
+    // Set stack pointer to the top of the stack
+    Reg[13] = 0x10000000;
+    Reg[15] = 0;
+
+    Cpsr = INTBITS | SVC32MODE;
+    Mode = SVC32MODE;
+    Bank = SVCBANK;
+
+    ResetMPCoreCP15Registers();
+
+    NresetSig = HIGH;
+    NfiqSig = HIGH;
+    NirqSig = HIGH;
+    NtransSig = (Mode & 3) ? HIGH : LOW;
+    abortSig = LOW;
+
+    NumInstrs = 0;
+    Emulate = RUN;
+}
+
+// Resets certain MPCore CP15 values to their ARM-defined reset values.
+void ARMul_State::ResetMPCoreCP15Registers()
+{
+    // c0
+    CP15[CP15_MAIN_ID] = 0x410FB024;
+    CP15[CP15_TLB_TYPE] = 0x00000800;
+    CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
+    CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
+    CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
+    CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
+    CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
+    CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
+    CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
+    CP15[CP15_ISA_FEATURE_0] = 0x00100011;
+    CP15[CP15_ISA_FEATURE_1] = 0x12002111;
+    CP15[CP15_ISA_FEATURE_2] = 0x11221011;
+    CP15[CP15_ISA_FEATURE_3] = 0x01102131;
+    CP15[CP15_ISA_FEATURE_4] = 0x00000141;
+
+    // c1
+    CP15[CP15_CONTROL] = 0x00054078;
+    CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
+    CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
+
+    // c2
+    CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
+    CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
+    CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
+
+    // c3
+    CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
+
+    // c7
+    CP15[CP15_PHYS_ADDRESS] = 0x00000000;
+
+    // c9
+    CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
+
+    // c10
+    CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
+    CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
+    CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
+
+    // c13
+    CP15[CP15_PID] = 0x00000000;
+    CP15[CP15_CONTEXT_ID] = 0x00000000;
+    CP15[CP15_THREAD_UPRW] = 0x00000000;
+    CP15[CP15_THREAD_URO] = 0x00000000;
+    CP15[CP15_THREAD_PRW] = 0x00000000;
+
+    // c15
+    CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
+    CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
+    CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
+    CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
+    CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
+}
+
+u16 ARMul_State::ReadMemory16(u32 address) const
+{
+    u16 data = Memory::Read16(address);
+
+    if (InBigEndianMode())
+        data = Common::swap16(data);
+
+    return data;
+}
+
+u32 ARMul_State::ReadMemory32(u32 address) const
+{
+    u32 data = Memory::Read32(address);
+
+    if (InBigEndianMode())
+        data = Common::swap32(data);
+
+    return data;
+}
+
+u64 ARMul_State::ReadMemory64(u32 address) const
+{
+    u64 data = Memory::Read64(address);
+
+    if (InBigEndianMode())
+        data = Common::swap64(data);
+
+    return data;
+}
+
+void ARMul_State::WriteMemory16(u32 address, u16 data)
+{
+    if (InBigEndianMode())
+        data = Common::swap16(data);
+
+    Memory::Write16(address, data);
+}
+
+void ARMul_State::WriteMemory32(u32 address, u32 data)
+{
+    if (InBigEndianMode())
+        data = Common::swap32(data);
+
+    Memory::Write32(address, data);
+}
+
+void ARMul_State::WriteMemory64(u32 address, u64 data)
+{
+    if (InBigEndianMode())
+        data = Common::swap64(data);
+
+    Memory::Write64(address, data);
+}
+
+
+// Reads from the CP15 registers. Used with implementation of the MRC instruction.
+// Note that since the 3DS does not have the hypervisor extensions, these registers
+// are not implemented.
+u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const
+{
+    // Unprivileged registers
+    if (crn == 13 && opcode_1 == 0 && crm == 0)
+    {
+        if (opcode_2 == 2)
+            return CP15[CP15_THREAD_UPRW];
+
+        if (opcode_2 == 3)
+            return CP15[CP15_THREAD_URO];
+    }
+
+    if (InAPrivilegedMode())
+    {
+        if (crn == 0 && opcode_1 == 0)
+        {
+            if (crm == 0)
+            {
+                if (opcode_2 == 0)
+                    return CP15[CP15_MAIN_ID];
+
+                if (opcode_2 == 1)
+                    return CP15[CP15_CACHE_TYPE];
+
+                if (opcode_2 == 3)
+                    return CP15[CP15_TLB_TYPE];
+
+                if (opcode_2 == 5)
+                    return CP15[CP15_CPU_ID];
+            }
+            else if (crm == 1)
+            {
+                if (opcode_2 == 0)
+                    return CP15[CP15_PROCESSOR_FEATURE_0];
+
+                if (opcode_2 == 1)
+                    return CP15[CP15_PROCESSOR_FEATURE_1];
+
+                if (opcode_2 == 2)
+                    return CP15[CP15_DEBUG_FEATURE_0];
+
+                if (opcode_2 == 4)
+                    return CP15[CP15_MEMORY_MODEL_FEATURE_0];
+
+                if (opcode_2 == 5)
+                    return CP15[CP15_MEMORY_MODEL_FEATURE_1];
+
+                if (opcode_2 == 6)
+                    return CP15[CP15_MEMORY_MODEL_FEATURE_2];
+
+                if (opcode_2 == 7)
+                    return CP15[CP15_MEMORY_MODEL_FEATURE_3];
+            }
+            else if (crm == 2)
+            {
+                if (opcode_2 == 0)
+                    return CP15[CP15_ISA_FEATURE_0];
+
+                if (opcode_2 == 1)
+                    return CP15[CP15_ISA_FEATURE_1];
+
+                if (opcode_2 == 2)
+                    return CP15[CP15_ISA_FEATURE_2];
+
+                if (opcode_2 == 3)
+                    return CP15[CP15_ISA_FEATURE_3];
+
+                if (opcode_2 == 4)
+                    return CP15[CP15_ISA_FEATURE_4];
+            }
+        }
+
+        if (crn == 1 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                return CP15[CP15_CONTROL];
+
+            if (opcode_2 == 1)
+                return CP15[CP15_AUXILIARY_CONTROL];
+
+            if (opcode_2 == 2)
+                return CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
+        }
+
+        if (crn == 2 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                return CP15[CP15_TRANSLATION_BASE_TABLE_0];
+
+            if (opcode_2 == 1)
+                return CP15[CP15_TRANSLATION_BASE_TABLE_1];
+
+            if (opcode_2 == 2)
+                return CP15[CP15_TRANSLATION_BASE_CONTROL];
+        }
+
+        if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+            return CP15[CP15_DOMAIN_ACCESS_CONTROL];
+
+        if (crn == 5 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                return CP15[CP15_FAULT_STATUS];
+
+            if (opcode_2 == 1)
+                return CP15[CP15_INSTR_FAULT_STATUS];
+        }
+
+        if (crn == 6 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                return CP15[CP15_FAULT_ADDRESS];
+
+            if (opcode_2 == 1)
+                return CP15[CP15_WFAR];
+        }
+
+        if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
+            return CP15[CP15_PHYS_ADDRESS];
+
+        if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+            return CP15[CP15_DATA_CACHE_LOCKDOWN];
+
+        if (crn == 10 && opcode_1 == 0)
+        {
+            if (crm == 0 && opcode_2 == 0)
+                return CP15[CP15_TLB_LOCKDOWN];
+
+            if (crm == 2)
+            {
+                if (opcode_2 == 0)
+                    return CP15[CP15_PRIMARY_REGION_REMAP];
+
+                if (opcode_2 == 1)
+                    return CP15[CP15_NORMAL_REGION_REMAP];
+            }
+        }
+
+        if (crn == 13 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                return CP15[CP15_PID];
+
+            if (opcode_2 == 1)
+                return CP15[CP15_CONTEXT_ID];
+
+            if (opcode_2 == 4)
+                return CP15[CP15_THREAD_PRW];
+        }
+
+        if (crn == 15)
+        {
+            if (opcode_1 == 0 && crm == 12)
+            {
+                if (opcode_2 == 0)
+                    return CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
+
+                if (opcode_2 == 1)
+                    return CP15[CP15_CYCLE_COUNTER];
+
+                if (opcode_2 == 2)
+                    return CP15[CP15_COUNT_0];
+
+                if (opcode_2 == 3)
+                    return CP15[CP15_COUNT_1];
+            }
+
+            if (opcode_1 == 5 && opcode_2 == 2)
+            {
+                if (crm == 5)
+                    return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
+
+                if (crm == 6)
+                    return CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
+
+                if (crm == 7)
+                    return CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
+            }
+
+            if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
+                return CP15[CP15_TLB_DEBUG_CONTROL];
+        }
+    }
+
+    LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
+    return 0;
+}
+
+// Write to the CP15 registers. Used with implementation of the MCR instruction.
+// Note that since the 3DS does not have the hypervisor extensions, these registers
+// are not implemented.
+void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
+{
+    if (InAPrivilegedMode())
+    {
+        if (crn == 1 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                CP15[CP15_CONTROL] = value;
+            else if (opcode_2 == 1)
+                CP15[CP15_AUXILIARY_CONTROL] = value;
+            else if (opcode_2 == 2)
+                CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
+        }
+        else if (crn == 2 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
+            else if (opcode_2 == 1)
+                CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
+            else if (opcode_2 == 2)
+                CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
+        }
+        else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+        {
+            CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
+        }
+        else if (crn == 5 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                CP15[CP15_FAULT_STATUS] = value;
+            else if (opcode_2 == 1)
+                CP15[CP15_INSTR_FAULT_STATUS] = value;
+        }
+        else if (crn == 6 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                CP15[CP15_FAULT_ADDRESS] = value;
+            else if (opcode_2 == 1)
+                CP15[CP15_WFAR] = value;
+        }
+        else if (crn == 7 && opcode_1 == 0)
+        {
+            if (crm == 0 && opcode_2 == 4)
+            {
+                CP15[CP15_WAIT_FOR_INTERRUPT] = value;
+            }
+            else if (crm == 4 && opcode_2 == 0)
+            {
+                // NOTE: Not entirely accurate. This should do permission checks.
+                CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
+            }
+            else if (crm == 5)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
+                else if (opcode_2 == 6)
+                    CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
+                else if (opcode_2 == 7)
+                    CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
+            }
+            else if (crm == 6)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_INVALIDATE_DATA_CACHE] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
+            }
+            else if (crm == 7 && opcode_2 == 0)
+            {
+                CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
+            }
+            else if (crm == 10)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_CLEAN_DATA_CACHE] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
+            }
+            else if (crm == 14)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
+            }
+        }
+        else if (crn == 8 && opcode_1 == 0)
+        {
+            if (crm == 5)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_INVALIDATE_ITLB] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
+                else if (opcode_2 == 3)
+                    CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
+            }
+            else if (crm == 6)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_INVALIDATE_DTLB] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
+                else if (opcode_2 == 3)
+                    CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
+            }
+            else if (crm == 7)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_INVALIDATE_UTLB] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
+                else if (opcode_2 == 3)
+                    CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
+            }
+        }
+        else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+        {
+            CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
+        }
+        else if (crn == 10 && opcode_1 == 0)
+        {
+            if (crm == 0 && opcode_2 == 0)
+            {
+                CP15[CP15_TLB_LOCKDOWN] = value;
+            }
+            else if (crm == 2)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_PRIMARY_REGION_REMAP] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_NORMAL_REGION_REMAP] = value;
+            }
+        }
+        else if (crn == 13 && opcode_1 == 0 && crm == 0)
+        {
+            if (opcode_2 == 0)
+                CP15[CP15_PID] = value;
+            else if (opcode_2 == 1)
+                CP15[CP15_CONTEXT_ID] = value;
+            else if (opcode_2 == 3)
+                CP15[CP15_THREAD_URO] = value;
+            else if (opcode_2 == 4)
+                CP15[CP15_THREAD_PRW] = value;
+        }
+        else if (crn == 15)
+        {
+            if (opcode_1 == 0 && crm == 12)
+            {
+                if (opcode_2 == 0)
+                    CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
+                else if (opcode_2 == 1)
+                    CP15[CP15_CYCLE_COUNTER] = value;
+                else if (opcode_2 == 2)
+                    CP15[CP15_COUNT_0] = value;
+                else if (opcode_2 == 3)
+                    CP15[CP15_COUNT_1] = value;
+            }
+            else if (opcode_1 == 5)
+            {
+                if (crm == 4)
+                {
+                    if (opcode_2 == 2)
+                        CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
+                    else if (opcode_2 == 4)
+                        CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
+                }
+                else if (crm == 5 && opcode_2 == 2)
+                {
+                    CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
+                }
+                else if (crm == 6 && opcode_2 == 2)
+                {
+                    CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
+                }
+                else if (crm == 7 && opcode_2 == 2)
+                {
+                    CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
+                }
+            }
+            else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
+            {
+                CP15[CP15_TLB_DEBUG_CONTROL] = value;
+            }
+        }
+    }
+
+    // Unprivileged registers
+    if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
+    {
+        CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
+    }
+    else if (crn == 7 && opcode_1 == 0 && crm == 10)
+    {
+        if (opcode_2 == 4)
+            CP15[CP15_DATA_SYNC_BARRIER] = value;
+        else if (opcode_2 == 5)
+            CP15[CP15_DATA_MEMORY_BARRIER] = value;
+    }
+    else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
+    {
+        CP15[CP15_THREAD_UPRW] = value;
+    }
+}

+ 113 - 96
src/core/arm/skyeye_common/armstate.h

@@ -37,67 +37,30 @@ enum {
     INSTCACHE = 2,
 };
 
-#define VFP_REG_NUM 64
-struct ARMul_State
-{
-    u32 Emulate;       // To start and stop emulation
-
-    // Order of the following register should not be modified
-    u32 Reg[16];            // The current register file
-    u32 Cpsr;               // The current PSR
-    u32 Spsr_copy;
-    u32 phys_pc;
-    u32 Reg_usr[2];
-    u32 Reg_svc[2];         // R13_SVC R14_SVC
-    u32 Reg_abort[2];       // R13_ABORT R14_ABORT
-    u32 Reg_undef[2];       // R13 UNDEF R14 UNDEF
-    u32 Reg_irq[2];         // R13_IRQ R14_IRQ
-    u32 Reg_firq[7];        // R8---R14 FIRQ
-    u32 Spsr[7];            // The exception psr's
-    u32 Mode;               // The current mode
-    u32 Bank;               // The current register bank
-    u32 exclusive_tag;      // The address for which the local monitor is in exclusive access mode
-    u32 exclusive_state;
-    u32 exclusive_result;
-    u32 CP15[CP15_REGISTER_COUNT];
-
-    // FPSID, FPSCR, and FPEXC
-    u32 VFP[VFP_SYSTEM_REGISTER_COUNT];
-    // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
-    // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
-    // and only 32 singleword registers are accessible (S0-S31).
-    u32 ExtReg[VFP_REG_NUM];
-    /* ---- End of the ordered registers ---- */
-
-    u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
-    unsigned int shifter_carry_out;
-
-    // Add armv6 flags dyf:2010-08-09
-    u32 GEFlag, EFlag, AFlag, QFlag;
-
-    u32 TFlag; // Thumb state
-
-    unsigned long long NumInstrs; // The number of instructions executed
-    unsigned NumInstrsToExecute;
-
-    unsigned NresetSig; // Reset the processor
-    unsigned NfiqSig;
-    unsigned NirqSig;
-
-    unsigned abortSig;
-    unsigned NtransSig;
-    unsigned bigendSig;
-    unsigned syscallSig;
-
-    // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
-    // process for our purposes), not per ARMul_State (which tracks CPU core state).
-    std::unordered_map<u32, int> instruction_cache;
+// ARM privilege modes
+enum PrivilegeMode {
+    USER32MODE   = 16,
+    FIQ32MODE    = 17,
+    IRQ32MODE    = 18,
+    SVC32MODE    = 19,
+    ABORT32MODE  = 23,
+    UNDEF32MODE  = 27,
+    SYSTEM32MODE = 31
 };
 
-/***************************************************************************\
-*                      The hardware vector addresses                        *
-\***************************************************************************/
+// ARM privilege mode register banks
+enum {
+    USERBANK   = 0,
+    FIQBANK    = 1,
+    IRQBANK    = 2,
+    SVCBANK    = 3,
+    ABORTBANK  = 4,
+    UNDEFBANK  = 5,
+    DUMMYBANK  = 6,
+    SYSTEMBANK = 7
+};
 
+// Hardware vector addresses
 enum {
     ARMResetV          = 0,
     ARMUndefinedInstrV = 4,
@@ -119,40 +82,7 @@ enum {
     ARMul_FIQV            = ARMFIQV
 };
 
-/***************************************************************************\
-*                          Mode and Bank Constants                          *
-\***************************************************************************/
-
-enum PrivilegeMode {
-    USER32MODE   = 16,
-    FIQ32MODE    = 17,
-    IRQ32MODE    = 18,
-    SVC32MODE    = 19,
-    ABORT32MODE  = 23,
-    UNDEF32MODE  = 27,
-    SYSTEM32MODE = 31
-};
-
-enum {
-    USERBANK   = 0,
-    FIQBANK    = 1,
-    IRQBANK    = 2,
-    SVCBANK    = 3,
-    ABORTBANK  = 4,
-    UNDEFBANK  = 5,
-    DUMMYBANK  = 6,
-    SYSTEMBANK = 7
-};
-
-/***************************************************************************\
-*                  Definitions of things in the emulator                     *
-\***************************************************************************/
-void ARMul_Reset(ARMul_State* state);
-
-/***************************************************************************\
-*            Definitions of things in the co-processor interface             *
-\***************************************************************************/
-
+// Coprocessor status values
 enum {
     ARMul_FIRST     = 0,
     ARMul_TRANSFER  = 1,
@@ -164,10 +94,7 @@ enum {
     ARMul_INC       = 3
 };
 
-/***************************************************************************\
-*               Definitions of things in the host environment                *
-\***************************************************************************/
-
+// Instruction condition codes
 enum ConditionCode {
     EQ = 0,
     NE = 1,
@@ -213,3 +140,93 @@ enum {
     ONCE       = 2, // Execute just one iteration
     RUN        = 3  // Continuous execution
 };
+
+#define VFP_REG_NUM 64
+struct ARMul_State final
+{
+public:
+    explicit ARMul_State(PrivilegeMode initial_mode);
+
+    void ChangePrivilegeMode(u32 new_mode);
+    void Reset();
+
+    // Reads/writes data in big/little endian format based on the
+    // state of the E (endian) bit in the APSR.
+    u16 ReadMemory16(u32 address) const;
+    u32 ReadMemory32(u32 address) const;
+    u64 ReadMemory64(u32 address) const;
+    void WriteMemory16(u32 address, u16 data);
+    void WriteMemory32(u32 address, u32 data);
+    void WriteMemory64(u32 address, u64 data);
+
+    u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const;
+    void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
+
+    // Whether or not the given CPU is in big endian mode (E bit is set)
+    bool InBigEndianMode() const {
+        return (Cpsr & (1 << 9)) != 0;
+    }
+    // Whether or not the given CPU is in a mode other than user mode.
+    bool InAPrivilegedMode() const {
+        return (Mode != USER32MODE);
+    }
+    // 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.
+    u32 GetInstructionSize() const {
+        return TFlag ? 2 : 4;
+    }
+
+    u32 Emulate;       // To start and stop emulation
+
+    // Order of the following register should not be modified
+    u32 Reg[16];            // The current register file
+    u32 Cpsr;               // The current PSR
+    u32 Spsr_copy;
+    u32 phys_pc;
+    u32 Reg_usr[2];
+    u32 Reg_svc[2];         // R13_SVC R14_SVC
+    u32 Reg_abort[2];       // R13_ABORT R14_ABORT
+    u32 Reg_undef[2];       // R13 UNDEF R14 UNDEF
+    u32 Reg_irq[2];         // R13_IRQ R14_IRQ
+    u32 Reg_firq[7];        // R8---R14 FIRQ
+    u32 Spsr[7];            // The exception psr's
+    u32 Mode;               // The current mode
+    u32 Bank;               // The current register bank
+    u32 exclusive_tag;      // The address for which the local monitor is in exclusive access mode
+    u32 exclusive_state;
+    u32 exclusive_result;
+    u32 CP15[CP15_REGISTER_COUNT];
+
+    // FPSID, FPSCR, and FPEXC
+    u32 VFP[VFP_SYSTEM_REGISTER_COUNT];
+    // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
+    // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
+    // and only 32 singleword registers are accessible (S0-S31).
+    u32 ExtReg[VFP_REG_NUM];
+    /* ---- End of the ordered registers ---- */
+
+    u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
+    unsigned int shifter_carry_out;
+
+    u32 TFlag; // Thumb state
+
+    unsigned long long NumInstrs; // The number of instructions executed
+    unsigned NumInstrsToExecute;
+
+    unsigned NresetSig; // Reset the processor
+    unsigned NfiqSig;
+    unsigned NirqSig;
+
+    unsigned abortSig;
+    unsigned NtransSig;
+    unsigned bigendSig;
+    unsigned syscallSig;
+
+    // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
+    // process for our purposes), not per ARMul_State (which tracks CPU core state).
+    std::unordered_map<u32, int> instruction_cache;
+
+private:
+    void ResetMPCoreCP15Registers();
+};

+ 0 - 430
src/core/arm/skyeye_common/armsupp.cpp

@@ -206,433 +206,3 @@ u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
     *saturation_occurred = false;
     return (u32)value;
 }
-
-// Whether or not the given CPU is in big endian mode (E bit is set)
-bool InBigEndianMode(ARMul_State* cpu)
-{
-    return (cpu->Cpsr & (1 << 9)) != 0;
-}
-
-// Whether or not the given CPU is in a mode other than user mode.
-bool InAPrivilegedMode(ARMul_State* cpu)
-{
-    return (cpu->Mode != USER32MODE);
-}
-
-// Reads from the CP15 registers. Used with implementation of the MRC instruction.
-// Note that since the 3DS does not have the hypervisor extensions, these registers
-// are not implemented.
-u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
-{
-    // Unprivileged registers
-    if (crn == 13 && opcode_1 == 0 && crm == 0)
-    {
-        if (opcode_2 == 2)
-            return cpu->CP15[CP15_THREAD_UPRW];
-
-        if (opcode_2 == 3)
-            return cpu->CP15[CP15_THREAD_URO];
-    }
-
-    if (InAPrivilegedMode(cpu))
-    {
-        if (crn == 0 && opcode_1 == 0)
-        {
-            if (crm == 0)
-            {
-                if (opcode_2 == 0)
-                    return cpu->CP15[CP15_MAIN_ID];
-
-                if (opcode_2 == 1)
-                    return cpu->CP15[CP15_CACHE_TYPE];
-
-                if (opcode_2 == 3)
-                    return cpu->CP15[CP15_TLB_TYPE];
-
-                if (opcode_2 == 5)
-                    return cpu->CP15[CP15_CPU_ID];
-            }
-            else if (crm == 1)
-            {
-                if (opcode_2 == 0)
-                    return cpu->CP15[CP15_PROCESSOR_FEATURE_0];
-
-                if (opcode_2 == 1)
-                    return cpu->CP15[CP15_PROCESSOR_FEATURE_1];
-
-                if (opcode_2 == 2)
-                    return cpu->CP15[CP15_DEBUG_FEATURE_0];
-
-                if (opcode_2 == 4)
-                    return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0];
-
-                if (opcode_2 == 5)
-                    return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1];
-
-                if (opcode_2 == 6)
-                    return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2];
-
-                if (opcode_2 == 7)
-                    return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3];
-            }
-            else if (crm == 2)
-            {
-                if (opcode_2 == 0)
-                    return cpu->CP15[CP15_ISA_FEATURE_0];
-
-                if (opcode_2 == 1)
-                    return cpu->CP15[CP15_ISA_FEATURE_1];
-
-                if (opcode_2 == 2)
-                    return cpu->CP15[CP15_ISA_FEATURE_2];
-
-                if (opcode_2 == 3)
-                    return cpu->CP15[CP15_ISA_FEATURE_3];
-
-                if (opcode_2 == 4)
-                    return cpu->CP15[CP15_ISA_FEATURE_4];
-            }
-        }
-
-        if (crn == 1 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                return cpu->CP15[CP15_CONTROL];
-
-            if (opcode_2 == 1)
-                return cpu->CP15[CP15_AUXILIARY_CONTROL];
-
-            if (opcode_2 == 2)
-                return cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
-        }
-
-        if (crn == 2 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0];
-
-            if (opcode_2 == 1)
-                return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1];
-
-            if (opcode_2 == 2)
-                return cpu->CP15[CP15_TRANSLATION_BASE_CONTROL];
-        }
-
-        if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
-            return cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL];
-
-        if (crn == 5 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                return cpu->CP15[CP15_FAULT_STATUS];
-
-            if (opcode_2 == 1)
-                return cpu->CP15[CP15_INSTR_FAULT_STATUS];
-        }
-
-        if (crn == 6 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                return cpu->CP15[CP15_FAULT_ADDRESS];
-
-            if (opcode_2 == 1)
-                return cpu->CP15[CP15_WFAR];
-        }
-
-        if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
-            return cpu->CP15[CP15_PHYS_ADDRESS];
-
-        if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
-            return cpu->CP15[CP15_DATA_CACHE_LOCKDOWN];
-
-        if (crn == 10 && opcode_1 == 0)
-        {
-            if (crm == 0 && opcode_2 == 0)
-                return cpu->CP15[CP15_TLB_LOCKDOWN];
-
-            if (crm == 2)
-            {
-                if (opcode_2 == 0)
-                    return cpu->CP15[CP15_PRIMARY_REGION_REMAP];
-
-                if (opcode_2 == 1)
-                    return cpu->CP15[CP15_NORMAL_REGION_REMAP];
-            }
-        }
-
-        if (crn == 13 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                return cpu->CP15[CP15_PID];
-
-            if (opcode_2 == 1)
-                return cpu->CP15[CP15_CONTEXT_ID];
-
-            if (opcode_2 == 4)
-                return cpu->CP15[CP15_THREAD_PRW];
-        }
-
-        if (crn == 15)
-        {
-            if (opcode_1 == 0 && crm == 12)
-            {
-                if (opcode_2 == 0)
-                    return cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
-
-                if (opcode_2 == 1)
-                    return cpu->CP15[CP15_CYCLE_COUNTER];
-
-                if (opcode_2 == 2)
-                    return cpu->CP15[CP15_COUNT_0];
-
-                if (opcode_2 == 3)
-                    return cpu->CP15[CP15_COUNT_1];
-            }
-
-            if (opcode_1 == 5 && opcode_2 == 2)
-            {
-                if (crm == 5)
-                    return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
-
-                if (crm == 6)
-                    return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
-
-                if (crm == 7)
-                    return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
-            }
-
-            if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
-                return cpu->CP15[CP15_TLB_DEBUG_CONTROL];
-        }
-    }
-
-    LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
-    return 0;
-}
-
-// Write to the CP15 registers. Used with implementation of the MCR instruction.
-// Note that since the 3DS does not have the hypervisor extensions, these registers
-// are not implemented.
-void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
-{
-    if (InAPrivilegedMode(cpu))
-    {
-        if (crn == 1 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                cpu->CP15[CP15_CONTROL] = value;
-            else if (opcode_2 == 1)
-                cpu->CP15[CP15_AUXILIARY_CONTROL] = value;
-            else if (opcode_2 == 2)
-                cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
-        }
-        else if (crn == 2 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
-            else if (opcode_2 == 1)
-                cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
-            else if (opcode_2 == 2)
-                cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
-        }
-        else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
-        {
-            cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
-        }
-        else if (crn == 5 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                cpu->CP15[CP15_FAULT_STATUS] = value;
-            else if (opcode_2 == 1)
-                cpu->CP15[CP15_INSTR_FAULT_STATUS] = value;
-        }
-        else if (crn == 6 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                cpu->CP15[CP15_FAULT_ADDRESS] = value;
-            else if (opcode_2 == 1)
-                cpu->CP15[CP15_WFAR] = value;
-        }
-        else if (crn == 7 && opcode_1 == 0)
-        {
-            if (crm == 0 && opcode_2 == 4)
-            {
-                cpu->CP15[CP15_WAIT_FOR_INTERRUPT] = value;
-            }
-            else if (crm == 4 && opcode_2 == 0)
-            {
-                // NOTE: Not entirely accurate. This should do permission checks.
-                cpu->CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
-            }
-            else if (crm == 5)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
-                else if (opcode_2 == 6)
-                    cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
-                else if (opcode_2 == 7)
-                    cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
-            }
-            else if (crm == 6)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_INVALIDATE_DATA_CACHE] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
-            }
-            else if (crm == 7 && opcode_2 == 0)
-            {
-                cpu->CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
-            }
-            else if (crm == 10)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_CLEAN_DATA_CACHE] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
-            }
-            else if (crm == 14)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
-            }
-        }
-        else if (crn == 8 && opcode_1 == 0)
-        {
-            LOG_WARNING(Core_ARM11, "TLB operations not fully implemented.");
-
-            if (crm == 5)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_INVALIDATE_ITLB] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
-                else if (opcode_2 == 3)
-                    cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
-            }
-            else if (crm == 6)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_INVALIDATE_DTLB] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
-                else if (opcode_2 == 3)
-                    cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
-            }
-            else if (crm == 7)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_INVALIDATE_UTLB] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
-                else if (opcode_2 == 3)
-                    cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
-            }
-        }
-        else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
-        {
-            cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
-        }
-        else if (crn == 10 && opcode_1 == 0)
-        {
-            if (crm == 0 && opcode_2 == 0)
-            {
-                cpu->CP15[CP15_TLB_LOCKDOWN] = value;
-            }
-            else if (crm == 2)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_PRIMARY_REGION_REMAP] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_NORMAL_REGION_REMAP] = value;
-            }
-        }
-        else if (crn == 13 && opcode_1 == 0 && crm == 0)
-        {
-            if (opcode_2 == 0)
-                cpu->CP15[CP15_PID] = value;
-            else if (opcode_2 == 1)
-                cpu->CP15[CP15_CONTEXT_ID] = value;
-            else if (opcode_2 == 3)
-                cpu->CP15[CP15_THREAD_URO] = value;
-            else if (opcode_2 == 4)
-                cpu->CP15[CP15_THREAD_PRW] = value;
-        }
-        else if (crn == 15)
-        {
-            if (opcode_1 == 0 && crm == 12)
-            {
-                if (opcode_2 == 0)
-                    cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
-                else if (opcode_2 == 1)
-                    cpu->CP15[CP15_CYCLE_COUNTER] = value;
-                else if (opcode_2 == 2)
-                    cpu->CP15[CP15_COUNT_0] = value;
-                else if (opcode_2 == 3)
-                    cpu->CP15[CP15_COUNT_1] = value;
-            }
-            else if (opcode_1 == 5)
-            {
-                if (crm == 4)
-                {
-                    if (opcode_2 == 2)
-                        cpu->CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
-                    else if (opcode_2 == 4)
-                        cpu->CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
-                }
-                else if (crm == 5 && opcode_2 == 2)
-                {
-                    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
-                }
-                else if (crm == 6 && opcode_2 == 2)
-                {
-                    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
-                }
-                else if (crm == 7 && opcode_2 == 2)
-                {
-                    cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
-                }
-            }
-            else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
-            {
-                cpu->CP15[CP15_TLB_DEBUG_CONTROL] = value;
-            }
-        }
-    }
-
-    // Unprivileged registers
-    if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
-    {
-        cpu->CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
-    }
-    else if (crn == 7 && opcode_1 == 0 && crm == 10)
-    {
-       if (opcode_2 == 4)
-           cpu->CP15[CP15_DATA_SYNC_BARRIER] = value;
-       else if (opcode_2 == 5)
-           cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value;
-
-    }
-    else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
-    {
-        cpu->CP15[CP15_THREAD_UPRW] = value;
-    }
-}

+ 0 - 8
src/core/arm/skyeye_common/armsupp.h

@@ -6,8 +6,6 @@
 
 #include "common/common_types.h"
 
-struct ARMul_State;
-
 #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
 #define BIT(s, n) ((s >> (n)) & 1)
 
@@ -32,9 +30,3 @@ u16 ARMul_UnsignedSaturatedSub16(u16, u16);
 u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
 u32 ARMul_SignedSatQ(s32, u8, bool*);
 u32 ARMul_UnsignedSatQ(s32, u8, bool*);
-
-bool InBigEndianMode(ARMul_State*);
-bool InAPrivilegedMode(ARMul_State*);
-
-u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
-void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);

+ 63 - 63
src/core/arm/skyeye_common/vfp/vfpinstr.cpp

@@ -51,7 +51,7 @@ VMLA_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmla_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -100,7 +100,7 @@ VMLS_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmls_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -149,7 +149,7 @@ VNMLA_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vnmla_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -199,7 +199,7 @@ VNMLS_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vnmls_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -248,7 +248,7 @@ VNMUL_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vnmul_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -297,7 +297,7 @@ VMUL_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmul_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -346,7 +346,7 @@ VADD_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vadd_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -395,7 +395,7 @@ VSUB_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vsub_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -444,7 +444,7 @@ VDIV_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vdiv_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -492,7 +492,7 @@ VMOVI_INST:
 
         VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovi_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -536,7 +536,7 @@ VMOVR_INST:
 
         VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovr_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -585,7 +585,7 @@ VABS_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vabs_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -635,7 +635,7 @@ VNEG_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vneg_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -684,7 +684,7 @@ VSQRT_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vsqrt_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -733,7 +733,7 @@ VCMP_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vcmp_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -782,7 +782,7 @@ VCMP2_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vcmp2_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -831,7 +831,7 @@ VCVTBDS_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vcvtbds_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -882,7 +882,7 @@ VCVTBFF_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vcvtbff_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -931,7 +931,7 @@ VCVTBFI_INST:
 
         CHECK_VFP_CDP_RET;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vcvtbfi_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -981,7 +981,7 @@ VMOVBRS_INST:
 
         VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovbrs_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1032,7 +1032,7 @@ VMSR_INST:
         {
             cpu->VFP[VFP_FPSCR] = cpu->Reg[rt];
         }
-        else if (InAPrivilegedMode(cpu))
+        else if (cpu->InAPrivilegedMode())
         {
             if (reg == 8)
                 cpu->VFP[VFP_FPEXC] = cpu->Reg[rt];
@@ -1042,7 +1042,7 @@ VMSR_INST:
                 cpu->VFP[VFP_FPINST2] = cpu->Reg[rt];
         }
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmsr_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1090,7 +1090,7 @@ VMOVBRC_INST:
 
         cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t];
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovbrc_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1163,7 +1163,7 @@ VMRS_INST:
         {
             cpu->Reg[rt] = cpu->VFP[VFP_MVFR0];
         }
-        else if (InAPrivilegedMode(cpu))
+        else if (cpu->InAPrivilegedMode())
         {
             if (reg == 8)
                 cpu->Reg[rt] = cpu->VFP[VFP_FPEXC];
@@ -1173,7 +1173,7 @@ VMRS_INST:
                 cpu->Reg[rt] = cpu->VFP[VFP_FPINST2];
         }
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmrs_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1221,7 +1221,7 @@ VMOVBCR_INST:
 
         cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index];
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovbcr_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1274,7 +1274,7 @@ VMOVBRRSS_INST:
         VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
             &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]);
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovbrrss_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1322,7 +1322,7 @@ VMOVBRRD_INST:
         VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
             &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vmovbrrd_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1378,23 +1378,23 @@ VSTR_INST:
 
         if (inst_cream->single)
         {
-            WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d]);
+            cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]);
         }
         else
         {
             const u32 word1 = cpu->ExtReg[inst_cream->d*2+0];
             const u32 word2 = cpu->ExtReg[inst_cream->d*2+1];
 
-            if (InBigEndianMode(cpu)) {
-                WriteMemory32(cpu, addr + 0, word2);
-                WriteMemory32(cpu, addr + 4, word1);
+            if (cpu->InBigEndianMode()) {
+                cpu->WriteMemory32(addr + 0, word2);
+                cpu->WriteMemory32(addr + 4, word1);
             } else {
-                WriteMemory32(cpu, addr + 0, word1);
-                WriteMemory32(cpu, addr + 4, word2);
+                cpu->WriteMemory32(addr + 0, word1);
+                cpu->WriteMemory32(addr + 4, word2);
             }
         }
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vstr_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1444,7 +1444,7 @@ VPUSH_INST:
         {
             if (inst_cream->single)
             {
-                WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
+                cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
                 addr += 4;
             }
             else
@@ -1452,12 +1452,12 @@ VPUSH_INST:
                 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
                 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
 
-                if (InBigEndianMode(cpu)) {
-                    WriteMemory32(cpu, addr + 0, word2);
-                    WriteMemory32(cpu, addr + 4, word1);
+                if (cpu->InBigEndianMode()) {
+                    cpu->WriteMemory32(addr + 0, word2);
+                    cpu->WriteMemory32(addr + 4, word1);
                 } else {
-                    WriteMemory32(cpu, addr + 0, word1);
-                    WriteMemory32(cpu, addr + 4, word2);
+                    cpu->WriteMemory32(addr + 0, word1);
+                    cpu->WriteMemory32(addr + 4, word2);
                 }
 
                 addr += 8;
@@ -1466,7 +1466,7 @@ VPUSH_INST:
 
         cpu->Reg[R13] -= inst_cream->imm32;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vpush_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1522,7 +1522,7 @@ VSTM_INST: /* encoding 1 */
         {
             if (inst_cream->single)
             {
-                WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
+                cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
                 addr += 4;
             }
             else
@@ -1530,12 +1530,12 @@ VSTM_INST: /* encoding 1 */
                 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
                 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
 
-                if (InBigEndianMode(cpu)) {
-                    WriteMemory32(cpu, addr + 0, word2);
-                    WriteMemory32(cpu, addr + 4, word1);
+                if (cpu->InBigEndianMode()) {
+                    cpu->WriteMemory32(addr + 0, word2);
+                    cpu->WriteMemory32(addr + 4, word1);
                 } else {
-                    WriteMemory32(cpu, addr + 0, word1);
-                    WriteMemory32(cpu, addr + 4, word2);
+                    cpu->WriteMemory32(addr + 0, word1);
+                    cpu->WriteMemory32(addr + 4, word2);
                 }
 
                 addr += 8;
@@ -1597,15 +1597,15 @@ VPOP_INST:
         {
             if (inst_cream->single)
             {
-                cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
+                cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
                 addr += 4;
             }
             else
             {
-                const u32 word1 = ReadMemory32(cpu, addr + 0);
-                const u32 word2 = ReadMemory32(cpu, addr + 4);
+                const u32 word1 = cpu->ReadMemory32(addr + 0);
+                const u32 word2 = cpu->ReadMemory32(addr + 4);
 
-                if (InBigEndianMode(cpu)) {
+                if (cpu->InBigEndianMode()) {
                     cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
                     cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
                 } else {
@@ -1618,7 +1618,7 @@ VPOP_INST:
         }
         cpu->Reg[R13] += inst_cream->imm32;
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vpop_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1670,14 +1670,14 @@ VLDR_INST:
 
         if (inst_cream->single)
         {
-            cpu->ExtReg[inst_cream->d] = ReadMemory32(cpu, addr);
+            cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr);
         }
         else
         {
-            const u32 word1 = ReadMemory32(cpu, addr + 0);
-            const u32 word2 = ReadMemory32(cpu, addr + 4);
+            const u32 word1 = cpu->ReadMemory32(addr + 0);
+            const u32 word2 = cpu->ReadMemory32(addr + 4);
 
-            if (InBigEndianMode(cpu)) {
+            if (cpu->InBigEndianMode()) {
                 cpu->ExtReg[inst_cream->d*2+0] = word2;
                 cpu->ExtReg[inst_cream->d*2+1] = word1;
             } else {
@@ -1686,7 +1686,7 @@ VLDR_INST:
             }
         }
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vldr_inst));
     FETCH_INST;
     GOTO_NEXT_INST;
@@ -1742,15 +1742,15 @@ VLDM_INST:
         {
             if (inst_cream->single)
             {
-                cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
+                cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
                 addr += 4;
             }
             else
             {
-                const u32 word1 = ReadMemory32(cpu, addr + 0);
-                const u32 word2 = ReadMemory32(cpu, addr + 4);
+                const u32 word1 = cpu->ReadMemory32(addr + 0);
+                const u32 word2 = cpu->ReadMemory32(addr + 4);
 
-                if (InBigEndianMode(cpu)) {
+                if (cpu->InBigEndianMode()) {
                     cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
                     cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
                 } else {
@@ -1766,7 +1766,7 @@ VLDM_INST:
                 cpu->Reg[inst_cream->n] - inst_cream->imm32);
         }
     }
-    cpu->Reg[15] += GET_INST_SIZE(cpu);
+    cpu->Reg[15] += cpu->GetInstructionSize();
     INC_PC(sizeof(vldm_inst));
     FETCH_INST;
     GOTO_NEXT_INST;

Некоторые файлы не были показаны из-за большого количества измененных файлов