From 0ecc6e2f0421aef95f0dd30466e4c69e15020e83 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Sun, 26 Jul 2015 05:39:54 -0400
Subject: [PATCH 1/2] dyncom: Use ARMul_State as an object

Gets rid of C-like parameter passing.
---
 src/core/CMakeLists.txt                       |   4 +-
 src/core/arm/dyncom/arm_dyncom.cpp            |  11 +-
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 365 +++++-----
 src/core/arm/dyncom/arm_dyncom_run.cpp        |  93 ---
 src/core/arm/dyncom/arm_dyncom_run.h          |  21 +-
 src/core/arm/skyeye_common/arminit.cpp        | 100 ---
 src/core/arm/skyeye_common/armmmu.h           | 104 ---
 src/core/arm/skyeye_common/armstate.cpp       | 657 ++++++++++++++++++
 src/core/arm/skyeye_common/armstate.h         | 209 +++---
 src/core/arm/skyeye_common/armsupp.cpp        | 430 ------------
 src/core/arm/skyeye_common/armsupp.h          |   8 -
 src/core/arm/skyeye_common/vfp/vfpinstr.cpp   | 126 ++--
 12 files changed, 1023 insertions(+), 1105 deletions(-)
 delete mode 100644 src/core/arm/dyncom/arm_dyncom_run.cpp
 delete mode 100644 src/core/arm/skyeye_common/arminit.cpp
 delete mode 100644 src/core/arm/skyeye_common/armmmu.h
 create mode 100644 src/core/arm/skyeye_common/armstate.cpp

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ba9af2a1f5..6cc60fd582 100644
--- a/src/core/CMakeLists.txt
+++ b/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
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index a51a3acf80..9228a49abe 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/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() {
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index fd5e132952..cf09acb4e7 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -17,7 +17,6 @@
 #include "core/arm/dyncom/arm_dyncom_interpreter.h"
 #include "core/arm/dyncom/arm_dyncom_thumb.h"
 #include "core/arm/dyncom/arm_dyncom_run.h"
-#include "core/arm/skyeye_common/armmmu.h"
 #include "core/arm/skyeye_common/armstate.h"
 #include "core/arm/skyeye_common/armsupp.h"
 #include "core/arm/skyeye_common/vfp/vfp.h"
@@ -3964,7 +3963,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -3978,7 +3977,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(adc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -3990,7 +3989,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             u32 rn_val = RN;
             if (inst_cream->Rn == 15)
-                rn_val += 2 * GET_INST_SIZE(cpu);
+                rn_val += 2 * cpu->GetInstructionSize();
 
             bool carry;
             bool overflow;
@@ -3999,7 +3998,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Cpsr & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4013,7 +4012,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(add_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4028,7 +4027,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Cpsr & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4041,7 +4040,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(and_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4057,7 +4056,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             INC_PC(sizeof(bbl_inst));
             goto DISPATCH;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(bbl_inst));
         goto DISPATCH;
     }
@@ -4067,14 +4066,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
             u32 lop = RN;
             if (inst_cream->Rn == 15) {
-                lop += 2 * GET_INST_SIZE(cpu);
+                lop += 2 * cpu->GetInstructionSize();
             }
             u32 rop = SHIFTER_OPERAND;
             RD = lop & (~rop);
             if ((inst_cream->S) && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4087,7 +4086,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(bic_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4098,7 +4097,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
             LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(bkpt_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4109,13 +4108,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
             unsigned int inst = inst_cream->inst;
             if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
-                cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+                cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
                 if(cpu->TFlag)
                     cpu->Reg[14] |= 0x1;
                 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
                 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
             } else {
-                cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+                cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
                 cpu->TFlag = 0x1;
                 int signed_int = inst_cream->val.signed_immed_24;
                 signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
@@ -4125,7 +4124,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             INC_PC(sizeof(blx_inst));
             goto DISPATCH;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(blx_inst));
         goto DISPATCH;
     }
@@ -4147,7 +4146,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             u32 address = RM;
 
             if (inst_cream->Rm == 15)
-                address += 2 * GET_INST_SIZE(cpu);
+                address += 2 * cpu->GetInstructionSize();
 
             cpu->TFlag   = address & 1;
             cpu->Reg[15] = address & 0xfffffffe;
@@ -4155,7 +4154,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             goto DISPATCH;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(bx_inst));
         goto DISPATCH;
     }
@@ -4167,7 +4166,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             cpu->NumInstrsToExecute = 0;
             return num_instrs;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(cdp_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4178,7 +4177,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         remove_exclusive(cpu, 0);
         cpu->exclusive_state = 0;
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(clrex_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4189,7 +4188,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             clz_inst* inst_cream = (clz_inst*)inst_base->component;
             RD = clz(RM);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(clz_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4208,7 +4207,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             cpu->CFlag = carry;
             cpu->VFlag = overflow;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(cmn_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4220,7 +4219,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             u32 rn_val = RN;
             if (inst_cream->Rn == 15)
-                rn_val += 2 * GET_INST_SIZE(cpu);
+                rn_val += 2 * cpu->GetInstructionSize();
 
             bool carry;
             bool overflow;
@@ -4231,7 +4230,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             cpu->CFlag = carry;
             cpu->VFlag = overflow;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(cmp_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4241,7 +4240,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         cps_inst *inst_cream = (cps_inst *)inst_base->component;
         uint32_t aif_val = 0;
         uint32_t aif_mask = 0;
-        if (InAPrivilegedMode(cpu)) {
+        if (cpu->InAPrivilegedMode()) {
             if (inst_cream->imod1) {
                 if (inst_cream->A) {
                     aif_val |= (inst_cream->imod0 << 8);
@@ -4260,10 +4259,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
             if (inst_cream->mmod) {
                 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
-                switch_mode(cpu, inst_cream->mode);
+                cpu->ChangePrivilegeMode(inst_cream->mode);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(cps_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4279,7 +4278,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mov_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4291,14 +4290,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             u32 lop = RN;
             if (inst_cream->Rn == 15) {
-                lop += 2 * GET_INST_SIZE(cpu);
+                lop += 2 * cpu->GetInstructionSize();
             }
             u32 rop = SHIFTER_OPERAND;
             RD = lop ^ rop;
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4311,7 +4310,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(eor_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4320,7 +4319,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     {
         // Instruction not implemented
         //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4335,30 +4334,30 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (BIT(inst, 22) && !BIT(inst, 15)) {
                 for (int i = 0; i < 13; i++) {
                     if(BIT(inst, i)) {
-                        cpu->Reg[i] = ReadMemory32(cpu, addr);
+                        cpu->Reg[i] = cpu->ReadMemory32(addr);
                         addr += 4;
                     }
                 }
                 if (BIT(inst, 13)) {
                     if (cpu->Mode == USER32MODE)
-                        cpu->Reg[13] = ReadMemory32(cpu, addr);
+                        cpu->Reg[13] = cpu->ReadMemory32(addr);
                     else
-                        cpu->Reg_usr[0] = ReadMemory32(cpu, addr);
+                        cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
 
                     addr += 4;
                 }
                 if (BIT(inst, 14)) {
                     if (cpu->Mode == USER32MODE)
-                        cpu->Reg[14] = ReadMemory32(cpu, addr);
+                        cpu->Reg[14] = cpu->ReadMemory32(addr);
                     else
-                        cpu->Reg_usr[1] = ReadMemory32(cpu, addr);
+                        cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
 
                     addr += 4;
                 }
             } else if (!BIT(inst, 22)) {
                 for(int i = 0; i < 16; i++ ){
                     if(BIT(inst, i)){
-                        unsigned int ret = ReadMemory32(cpu, addr);
+                        unsigned int ret = cpu->ReadMemory32(addr);
 
                         // For armv5t, should enter thumb when bits[0] is non-zero.
                         if(i == 15){
@@ -4373,18 +4372,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             } else if (BIT(inst, 22) && BIT(inst, 15)) {
                 for(int i = 0; i < 15; i++ ){
                     if(BIT(inst, i)){
-                        cpu->Reg[i] = ReadMemory32(cpu, addr);
+                        cpu->Reg[i] = cpu->ReadMemory32(addr);
                         addr += 4;
                      }
                  }
 
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Cpsr & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
                     LOAD_NZCVT;
                 }
 
-                cpu->Reg[15] = ReadMemory32(cpu, addr);
+                cpu->Reg[15] = cpu->ReadMemory32(addr);
             }
 
             if (BIT(inst, 15)) {
@@ -4392,7 +4391,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4410,7 +4409,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
             RD = operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sxth_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4420,7 +4419,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
         inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
-        unsigned int value = ReadMemory32(cpu, addr);
+        unsigned int value = cpu->ReadMemory32(addr);
         cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
 
         if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4431,7 +4430,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             goto DISPATCH;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4442,7 +4441,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
-            unsigned int value = ReadMemory32(cpu, addr);
+            unsigned int value = cpu->ReadMemory32(addr);
             cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
 
             if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4453,7 +4452,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4464,7 +4463,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
             RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxth_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4477,7 +4476,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             RD = RN + operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxtah_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4495,7 +4494,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4513,7 +4512,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4527,8 +4526,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
             // wouldn't do this as a single read.
-            cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr);
-            cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4);
+            cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
+            cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
 
             // No dispatch since this operation should not modify R15
         }
@@ -4547,13 +4546,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             add_exclusive_addr(cpu, read_addr);
             cpu->exclusive_state = 1;
 
-            RD = ReadMemory32(cpu, read_addr);
+            RD = cpu->ReadMemory32(read_addr);
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(generic_arm_inst));
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4573,7 +4572,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4587,13 +4586,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             add_exclusive_addr(cpu, read_addr);
             cpu->exclusive_state = 1;
 
-            RD = ReadMemory16(cpu, read_addr);
+            RD = cpu->ReadMemory16(read_addr);
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(generic_arm_inst));
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4607,15 +4606,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             add_exclusive_addr(cpu, read_addr);
             cpu->exclusive_state = 1;
 
-            RD  = ReadMemory32(cpu, read_addr);
-            RD2 = ReadMemory32(cpu, read_addr + 4);
+            RD  = cpu->ReadMemory32(read_addr);
+            RD2 = cpu->ReadMemory32(read_addr + 4);
 
             if (inst_cream->Rd == 15) {
                 INC_PC(sizeof(generic_arm_inst));
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4626,13 +4625,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
-            cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr);
+            cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
             if (BITS(inst_cream->inst, 12, 15) == 15) {
                 INC_PC(sizeof(ldst_inst));
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4652,7 +4651,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4663,7 +4662,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
-            unsigned int value = ReadMemory16(cpu, addr);
+            unsigned int value = cpu->ReadMemory16(addr);
             if (BIT(value, 15)) {
                 value |= 0xffff0000;
             }
@@ -4673,7 +4672,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4684,7 +4683,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
-            unsigned int value = ReadMemory32(cpu, addr);
+            unsigned int value = cpu->ReadMemory32(addr);
             cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
 
             if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4692,7 +4691,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4707,10 +4706,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 DEBUG_MSG;
             } else {
                 if (inst_cream->cp_num == 15)
-                    WriteCP15Register(cpu, RD, CRn, OPCODE_1, CRm, OPCODE_2);
+                    cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mcr_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4727,7 +4726,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                       inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mcrr_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4752,7 +4751,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mla_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4766,7 +4765,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4779,7 +4778,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mov_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4800,10 +4799,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto END;
             } else {
                 if (inst_cream->cp_num == 15)
-                     RD = ReadCP15Register(cpu, CRn, OPCODE_1, CRm, OPCODE_2);
+                     RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mrc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4820,7 +4819,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                       inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mcrr_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4838,7 +4837,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 RD = cpu->Cpsr;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mrs_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4861,7 +4860,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                         | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
             uint32_t mask = 0;
             if (!inst_cream->R) {
-                if (InAPrivilegedMode(cpu)) {
+                if (cpu->InAPrivilegedMode()) {
                     if ((operand & StateMask) != 0) {
                         /// UNPREDICTABLE
                         DEBUG_MSG;
@@ -4873,7 +4872,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 SAVE_NZCVT;
 
                 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
-                switch_mode(cpu, cpu->Cpsr & 0x1f);
+                cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
                 LOAD_NZCVT;
             } else {
                 if (CurrentModeHasSPSR) {
@@ -4882,7 +4881,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 }
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(msr_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4904,7 +4903,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mul_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4919,7 +4918,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4932,7 +4931,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(mvn_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4949,7 +4948,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -4962,7 +4961,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(orr_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4970,7 +4969,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
     NOP_INST:
     {
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC_STUB;
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4982,7 +4981,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
             RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(pkh_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -4995,7 +4994,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
             RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(pkh_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5005,7 +5004,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     {
         // Not implemented. PLD is a hint instruction, so it's optional.
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(pld_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5078,7 +5077,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = result;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5140,7 +5139,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5173,7 +5172,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(rev_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5187,8 +5186,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         u32 address = 0;
         inst_cream->get_addr(cpu, inst_cream->inst, address);
 
-        cpu->Cpsr    = ReadMemory32(cpu, address);
-        cpu->Reg[15] = ReadMemory32(cpu, address + 4);
+        cpu->Cpsr    = cpu->ReadMemory32(address);
+        cpu->Reg[15] = cpu->ReadMemory32(address + 4);
 
         INC_PC(sizeof(ldst_inst));
         goto DISPATCH;
@@ -5201,7 +5200,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             u32 rn_val = RN;
             if (inst_cream->Rn == 15)
-                rn_val += 2 * GET_INST_SIZE(cpu);
+                rn_val += 2 * cpu->GetInstructionSize();
 
             bool carry;
             bool overflow;
@@ -5210,7 +5209,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -5224,7 +5223,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(rsb_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5241,7 +5240,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -5255,7 +5254,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(rsc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5363,7 +5362,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5381,7 +5380,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -5395,7 +5394,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sbc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5434,7 +5433,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = result;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5453,7 +5452,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
         LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(setend_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5466,7 +5465,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             LOG_TRACE(Core_ARM11, "SEV executed.");
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC_STUB;
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5538,7 +5537,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5563,7 +5562,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (AddOverflow(operand1 * operand2, RN, RD))
                 cpu->Cpsr |= (1 << 27);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smla_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5619,7 +5618,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlad_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5648,7 +5647,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(umlal_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5678,7 +5677,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RDHI = ((dest >> 32) & 0xFFFFFFFF);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlalxy_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5703,7 +5702,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->Cpsr |= (1 << 27);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlad_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5741,7 +5740,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RDHI = ((result >> 32) & 0xFFFFFFFF);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlald_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5777,7 +5776,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = ((result >> 32) & 0xFFFFFFFF);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlad_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5799,7 +5798,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
             RD = operand1 * operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smul_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5825,7 +5824,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(umull_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5841,7 +5840,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             s64 result = (s64)rm * (s64)(s32)RN;
             RD = BITS(result, 16, 47);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(smlad_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5855,10 +5854,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         u32 address = 0;
         inst_cream->get_addr(cpu, inst_cream->inst, address);
 
-        WriteMemory32(cpu, address + 0, cpu->Reg[14]);
-        WriteMemory32(cpu, address + 4, cpu->Spsr_copy);
+        cpu->WriteMemory32(address + 0, cpu->Reg[14]);
+        cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5891,7 +5890,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = rn_val;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ssat_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5913,7 +5912,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->Cpsr |= (1 << 27);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ssat_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5923,7 +5922,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     {
         // Instruction not implemented
         //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(stc_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5941,36 +5940,36 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (BIT(inst_cream->inst, 22) == 1) {
                 for (int i = 0; i < 13; i++) {
                     if (BIT(inst_cream->inst, i)) {
-                        WriteMemory32(cpu, addr, cpu->Reg[i]);
+                        cpu->WriteMemory32(addr, cpu->Reg[i]);
                         addr += 4;
                     }
                 }
                 if (BIT(inst_cream->inst, 13)) {
                     if (cpu->Mode == USER32MODE)
-                        WriteMemory32(cpu, addr, cpu->Reg[13]);
+                        cpu->WriteMemory32(addr, cpu->Reg[13]);
                     else
-                        WriteMemory32(cpu, addr, cpu->Reg_usr[0]);
+                        cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
 
                     addr += 4;
                 }
                 if (BIT(inst_cream->inst, 14)) {
                     if (cpu->Mode == USER32MODE)
-                        WriteMemory32(cpu, addr, cpu->Reg[14]);
+                        cpu->WriteMemory32(addr, cpu->Reg[14]);
                     else
-                        WriteMemory32(cpu, addr, cpu->Reg_usr[1]);
+                        cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
 
                     addr += 4;
                 }
                 if (BIT(inst_cream->inst, 15)) {
-                    WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
+                    cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
                 }
             } else {
                 for (int i = 0; i < 15; i++) {
                     if (BIT(inst_cream->inst, i)) {
                         if (i == Rn)
-                            WriteMemory32(cpu, addr, old_RN);
+                            cpu->WriteMemory32(addr, old_RN);
                         else
-                            WriteMemory32(cpu, addr, cpu->Reg[i]);
+                            cpu->WriteMemory32(addr, cpu->Reg[i]);
 
                         addr += 4;
                     }
@@ -5978,10 +5977,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
                 // Check PC reg
                 if (BIT(inst_cream->inst, 15))
-                    WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
+                    cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -5999,7 +5998,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
             RD = operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sxtb_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6011,9 +6010,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
             unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
-            WriteMemory32(cpu, addr, value);
+            cpu->WriteMemory32(addr, value);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6024,7 +6023,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
             RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxtb_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6037,7 +6036,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
             RD = RN + operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxtab_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6050,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
             Memory::Write8(addr, value);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6063,7 +6062,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
             Memory::Write8(addr, value);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6076,10 +6075,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 
             // The 3DS doesn't have the Large Physical Access Extension (LPAE)
             // so STRD wouldn't store these as a single write.
-            WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
-            WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
+            cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
+            cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6094,14 +6093,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 remove_exclusive(cpu, write_addr);
                 cpu->exclusive_state = 0;
 
-                WriteMemory32(cpu, write_addr, RM);
+                cpu->WriteMemory32(write_addr, RM);
                 RD = 0;
             } else {
                 // Failed to write due to mutex access
                 RD = 1;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6123,7 +6122,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 RD = 1;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6142,12 +6141,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
                 u64 value;
 
-                if (InBigEndianMode(cpu))
+                if (cpu->InBigEndianMode())
                     value = (((u64)rt << 32) | rt2);
                 else
                     value = (((u64)rt2 << 32) | rt);
 
-                WriteMemory64(cpu, write_addr, value);
+                cpu->WriteMemory64(write_addr, value);
                 RD = 0;
             }
             else {
@@ -6155,7 +6154,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 RD = 1;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6170,14 +6169,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 remove_exclusive(cpu, write_addr);
                 cpu->exclusive_state = 0;
 
-                WriteMemory16(cpu, write_addr, RM);
+                cpu->WriteMemory16(write_addr, RM);
                 RD = 0;
             } else {
                 // Failed to write due to mutex access
                 RD = 1;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6189,9 +6188,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
             unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
-            WriteMemory16(cpu, addr, value);
+            cpu->WriteMemory16(addr, value);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6203,9 +6202,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             inst_cream->get_addr(cpu, inst_cream->inst, addr);
 
             unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
-            WriteMemory32(cpu, addr, value);
+            cpu->WriteMemory32(addr, value);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ldst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6226,7 +6225,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             if (inst_cream->S && (inst_cream->Rd == 15)) {
                 if (CurrentModeHasSPSR) {
                     cpu->Cpsr = cpu->Spsr_copy;
-                    switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+                    cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
                     LOAD_NZCVT;
                 }
             } else if (inst_cream->S) {
@@ -6240,7 +6239,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 goto DISPATCH;
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sub_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6252,7 +6251,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             SVC::CallSVC(inst_cream->num & 0xFFFF);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(swi_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6263,12 +6262,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             swp_inst* inst_cream = (swp_inst*)inst_base->component;
 
             addr = RN;
-            unsigned int value = ReadMemory32(cpu, addr);
-            WriteMemory32(cpu, addr, RM);
+            unsigned int value = cpu->ReadMemory32(addr);
+            cpu->WriteMemory32(addr, RM);
 
             RD = value;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(swp_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6282,7 +6281,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             Memory::Write8(addr, (RM & 0xFF));
             RD = value;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(swp_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6298,7 +6297,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
             RD = RN + operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxtab_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6331,7 +6330,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sxtab_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6347,7 +6346,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
             RD = RN + operand2;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(sxtah_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6362,7 +6361,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             u32 rop = SHIFTER_OPERAND;
 
             if (inst_cream->Rn == 15)
-                lop += GET_INST_SIZE(cpu) * 2;
+                lop += cpu->GetInstructionSize() * 2;
 
             u32 result = lop ^ rop;
 
@@ -6370,7 +6369,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             UPDATE_ZFLAG(result);
             UPDATE_CFLAG_WITH_SC;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(teq_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6384,7 +6383,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             u32 rop = SHIFTER_OPERAND;
 
             if (inst_cream->Rn == 15)
-                lop += GET_INST_SIZE(cpu) * 2;
+                lop += cpu->GetInstructionSize() * 2;
 
             u32 result = lop & rop;
 
@@ -6392,7 +6391,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             UPDATE_ZFLAG(result);
             UPDATE_CFLAG_WITH_SC;
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(tst_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6563,7 +6562,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6643,7 +6642,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6662,7 +6661,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RDLO = (result & 0xFFFFFFFF);
             RDHI = ((result >> 32) & 0xFFFFFFFF);
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(umaal_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6685,7 +6684,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(umlal_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6705,7 +6704,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
             }
         }
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(umull_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6733,7 +6732,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     {
         bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
         cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(bl_1_thumb));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6814,7 +6813,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = ((lo_val & 0xFFFF) | hi_val << 16);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6844,7 +6843,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = finalDif;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(generic_arm_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6877,7 +6876,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             RD = rn_val;
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ssat_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6899,7 +6898,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
                 cpu->Cpsr |= (1 << 27);
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(ssat_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6930,7 +6929,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             }
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC(sizeof(uxtab_inst));
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6943,7 +6942,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             LOG_TRACE(Core_ARM11, "WFE executed.");
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC_STUB;
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6956,7 +6955,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             LOG_TRACE(Core_ARM11, "WFI executed.");
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC_STUB;
         FETCH_INST;
         GOTO_NEXT_INST;
@@ -6969,7 +6968,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
             LOG_TRACE(Core_ARM11, "YIELD executed.");
         }
 
-        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        cpu->Reg[15] += cpu->GetInstructionSize();
         INC_PC_STUB;
         FETCH_INST;
         GOTO_NEXT_INST;
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp
deleted file mode 100644
index 4c6acba987..0000000000
--- a/src/core/arm/dyncom/arm_dyncom_run.cpp
+++ /dev/null
@@ -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;
-    }
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index ef18455bc6..13bef17fc3 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/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];
 }
diff --git a/src/core/arm/skyeye_common/arminit.cpp b/src/core/arm/skyeye_common/arminit.cpp
deleted file mode 100644
index b7c508d75c..0000000000
--- a/src/core/arm/skyeye_common/arminit.cpp
+++ /dev/null
@@ -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;
-}
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
deleted file mode 100644
index 5423588c01..0000000000
--- a/src/core/arm/skyeye_common/armmmu.h
+++ /dev/null
@@ -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);
-}
diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp
new file mode 100644
index 0000000000..ccb2eb0ebe
--- /dev/null
+++ b/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;
+    }
+}
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h
index 3ba0ba5cdd..041e65ccc3 100644
--- a/src/core/arm/skyeye_common/armstate.h
+++ b/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();
+};
diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp
index affbf193a1..d31fb94490 100644
--- a/src/core/arm/skyeye_common/armsupp.cpp
+++ b/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;
-    }
-}
diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h
index 5cf1cd1d31..391309fa81 100644
--- a/src/core/arm/skyeye_common/armsupp.h
+++ b/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);
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 8efcbab1cf..9b99fc5bc0 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/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;

From 816b1ca776fe9d8ac0e618f82afd8e4b5549d582 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Sun, 26 Jul 2015 11:39:57 -0400
Subject: [PATCH 2/2] dyncom: Use std::array for register arrays

---
 src/core/arm/dyncom/arm_dyncom.cpp    |  8 ++---
 src/core/arm/skyeye_common/armstate.h | 49 ++++++++++++++-------------
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 9228a49abe..c665f706f3 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -82,8 +82,8 @@ void ARM_DynCom::ResetContext(Core::ThreadContext& context, u32 stack_top, u32 e
 }
 
 void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
-    memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
-    memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
+    memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers));
+    memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers));
 
     ctx.sp = state->Reg[13];
     ctx.lr = state->Reg[14];
@@ -95,8 +95,8 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
 }
 
 void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
-    memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
-    memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+    memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
+    memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
 
     state->Reg[13] = ctx.sp;
     state->Reg[14] = ctx.lr;
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h
index 041e65ccc3..88c1dab9dc 100644
--- a/src/core/arm/skyeye_common/armstate.h
+++ b/src/core/arm/skyeye_common/armstate.h
@@ -17,6 +17,7 @@
 
 #pragma once
 
+#include <array>
 #include <unordered_map>
 
 #include "common/common_types.h"
@@ -141,7 +142,7 @@ enum {
     RUN        = 3  // Continuous execution
 };
 
-#define VFP_REG_NUM 64
+
 struct ARMul_State final
 {
 public:
@@ -177,34 +178,34 @@ public:
         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];
+    std::array<u32, 16> Reg;      // The current register file
+    std::array<u32, 2> Reg_usr;
+    std::array<u32, 2> Reg_svc;   // R13_SVC R14_SVC
+    std::array<u32, 2> Reg_abort; // R13_ABORT R14_ABORT
+    std::array<u32, 2> Reg_undef; // R13 UNDEF R14 UNDEF
+    std::array<u32, 2> Reg_irq;   // R13_IRQ R14_IRQ
+    std::array<u32, 7> Reg_firq;  // R8---R14 FIRQ
+    std::array<u32, 7> Spsr;      // The exception psr's
+    std::array<u32, CP15_REGISTER_COUNT> CP15;
 
     // FPSID, FPSCR, and FPEXC
-    u32 VFP[VFP_SYSTEM_REGISTER_COUNT];
+    std::array<u32, VFP_SYSTEM_REGISTER_COUNT> VFP;
+
     // 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 ---- */
+    std::array<u32, 64> ExtReg;
+
+    u32 Emulate; // To start and stop emulation
+    u32 Cpsr;    // The current PSR
+    u32 Spsr_copy;
+    u32 phys_pc;
+
+    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 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
     unsigned int shifter_carry_out;