summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/default_ini.h4
-rw-r--r--src/citra_qt/debugger/disassembler.cpp3
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp34
-rw-r--r--src/core/CMakeLists.txt9
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp32
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp4
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h4
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp377
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.cpp93
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h23
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp23
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h2
-rw-r--r--src/core/arm/interpreter/arminit.cpp128
-rw-r--r--src/core/arm/interpreter/armsupp.cpp637
-rw-r--r--src/core/arm/skyeye_common/armdefs.h318
-rw-r--r--src/core/arm/skyeye_common/armmmu.h103
-rw-r--r--src/core/arm/skyeye_common/armstate.cpp657
-rw-r--r--src/core/arm/skyeye_common/armstate.h233
-rw-r--r--src/core/arm/skyeye_common/armsupp.cpp208
-rw-r--r--src/core/arm/skyeye_common/armsupp.h32
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp12
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h10
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h4
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpdouble.cpp12
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp126
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/command_processor.cpp10
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp12
-rw-r--r--src/video_core/debug_utils/debug_utils.h5
-rw-r--r--src/video_core/pica.cpp72
-rw-r--r--src/video_core/pica.h65
-rw-r--r--src/video_core/rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp111
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h110
-rw-r--r--src/video_core/vertex_shader.cpp59
38 files changed, 1658 insertions, 1883 deletions
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index fd5a90d56..1925bece8 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -33,10 +33,6 @@ pad_cleft =
33pad_cright = 33pad_cright =
34 34
35[Core] 35[Core]
36# The refresh rate for the GPU
37# Defaults to 30
38gpu_refresh_rate =
39
40# The applied frameskip amount. Must be a power of two. 36# The applied frameskip amount. Must be a power of two.
41# 0 (default): No frameskip, 1: x2 frameskip, 2: x4 frameskip, 3: x8 frameskip, etc. 37# 0 (default): No frameskip, 1: x2 frameskip, 2: x4 frameskip, 3: x8 frameskip, etc.
42frame_skip = 38frame_skip =
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index b41c40a0e..1e5ef5299 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -15,7 +15,6 @@
15#include "common/break_points.h" 15#include "common/break_points.h"
16#include "common/symbols.h" 16#include "common/symbols.h"
17#include "core/arm/arm_interface.h" 17#include "core/arm/arm_interface.h"
18#include "core/arm/skyeye_common/armdefs.h"
19#include "core/arm/disassembler/arm_disasm.h" 18#include "core/arm/disassembler/arm_disasm.h"
20 19
21 20
@@ -219,7 +218,7 @@ void DisassemblerWidget::OnToggleStartStop() {
219} 218}
220 219
221void DisassemblerWidget::OnDebugModeEntered() { 220void DisassemblerWidget::OnDebugModeEntered() {
222 ARMword next_instr = Core::g_app_core->GetPC(); 221 u32 next_instr = Core::g_app_core->GetPC();
223 222
224 if (model->GetBreakPoints().IsAddressBreakPoint(next_instr)) 223 if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
225 emu_thread->SetRunning(false); 224 emu_thread->SetRunning(false);
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index de10bce1f..7ac3ea542 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -10,6 +10,7 @@
10#include <QPushButton> 10#include <QPushButton>
11#include <QVBoxLayout> 11#include <QVBoxLayout>
12#include <QTreeView> 12#include <QTreeView>
13#include <QHeaderView>
13#include <QSpinBox> 14#include <QSpinBox>
14#include <QComboBox> 15#include <QComboBox>
15 16
@@ -174,7 +175,7 @@ int GPUCommandListModel::rowCount(const QModelIndex& parent) const {
174} 175}
175 176
176int GPUCommandListModel::columnCount(const QModelIndex& parent) const { 177int GPUCommandListModel::columnCount(const QModelIndex& parent) const {
177 return 2; 178 return 3;
178} 179}
179 180
180QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const { 181QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const {
@@ -187,14 +188,13 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const {
187 188
188 if (role == Qt::DisplayRole) { 189 if (role == Qt::DisplayRole) {
189 QString content; 190 QString content;
190 if (index.column() == 0) { 191 switch ( index.column() ) {
191 QString content = QString::fromLatin1(Pica::Regs::GetCommandName(cmd.cmd_id).c_str()); 192 case 0:
192 content.append(" "); 193 return QString::fromLatin1(Pica::Regs::GetCommandName(cmd.cmd_id).c_str());
193 return content; 194 case 1:
194 } else if (index.column() == 1) { 195 return QString("%1").arg(cmd.cmd_id, 3, 16, QLatin1Char('0'));
195 QString content = QString("%1 ").arg(cmd.hex, 8, 16, QLatin1Char('0')); 196 case 2:
196 content.append(QString("%1 ").arg(val, 8, 16, QLatin1Char('0'))); 197 return QString("%1").arg(val, 8, 16, QLatin1Char('0'));
197 return content;
198 } 198 }
199 } else if (role == CommandIdRole) { 199 } else if (role == CommandIdRole) {
200 return QVariant::fromValue<int>(cmd.cmd_id.Value()); 200 return QVariant::fromValue<int>(cmd.cmd_id.Value());
@@ -207,10 +207,13 @@ QVariant GPUCommandListModel::headerData(int section, Qt::Orientation orientatio
207 switch(role) { 207 switch(role) {
208 case Qt::DisplayRole: 208 case Qt::DisplayRole:
209 { 209 {
210 if (section == 0) { 210 switch (section) {
211 case 0:
211 return tr("Command Name"); 212 return tr("Command Name");
212 } else if (section == 1) { 213 case 1:
213 return tr("Data"); 214 return tr("Register");
215 case 2:
216 return tr("New Value");
214 } 217 }
215 218
216 break; 219 break;
@@ -299,6 +302,13 @@ GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pi
299 list_widget->setModel(model); 302 list_widget->setModel(model);
300 list_widget->setFont(QFont("monospace")); 303 list_widget->setFont(QFont("monospace"));
301 list_widget->setRootIsDecorated(false); 304 list_widget->setRootIsDecorated(false);
305 list_widget->setUniformRowHeights(true);
306
307#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
308 list_widget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
309#else
310 list_widget->header()->setResizeMode(QHeaderView::ResizeToContents);
311#endif
302 312
303 connect(list_widget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), 313 connect(list_widget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
304 this, SLOT(SetCommandInfo(const QModelIndex&))); 314 this, SLOT(SetCommandInfo(const QModelIndex&)));
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8267ee586..6cc60fd58 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -4,10 +4,9 @@ set(SRCS
4 arm/dyncom/arm_dyncom.cpp 4 arm/dyncom/arm_dyncom.cpp
5 arm/dyncom/arm_dyncom_dec.cpp 5 arm/dyncom/arm_dyncom_dec.cpp
6 arm/dyncom/arm_dyncom_interpreter.cpp 6 arm/dyncom/arm_dyncom_interpreter.cpp
7 arm/dyncom/arm_dyncom_run.cpp
8 arm/dyncom/arm_dyncom_thumb.cpp 7 arm/dyncom/arm_dyncom_thumb.cpp
9 arm/interpreter/arminit.cpp 8 arm/skyeye_common/armstate.cpp
10 arm/interpreter/armsupp.cpp 9 arm/skyeye_common/armsupp.cpp
11 arm/skyeye_common/vfp/vfp.cpp 10 arm/skyeye_common/vfp/vfp.cpp
12 arm/skyeye_common/vfp/vfpdouble.cpp 11 arm/skyeye_common/vfp/vfpdouble.cpp
13 arm/skyeye_common/vfp/vfpinstr.cpp 12 arm/skyeye_common/vfp/vfpinstr.cpp
@@ -132,8 +131,8 @@ set(HEADERS
132 arm/dyncom/arm_dyncom_run.h 131 arm/dyncom/arm_dyncom_run.h
133 arm/dyncom/arm_dyncom_thumb.h 132 arm/dyncom/arm_dyncom_thumb.h
134 arm/skyeye_common/arm_regformat.h 133 arm/skyeye_common/arm_regformat.h
135 arm/skyeye_common/armdefs.h 134 arm/skyeye_common/armstate.h
136 arm/skyeye_common/armmmu.h 135 arm/skyeye_common/armsupp.h
137 arm/skyeye_common/vfp/asm_vfp.h 136 arm/skyeye_common/vfp/asm_vfp.h
138 arm/skyeye_common/vfp/vfp.h 137 arm/skyeye_common/vfp/vfp.h
139 arm/skyeye_common/vfp/vfp_helper.h 138 arm/skyeye_common/vfp/vfp_helper.h
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 529c4ac70..c665f706f 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -6,7 +6,8 @@
6 6
7#include "common/make_unique.h" 7#include "common/make_unique.h"
8 8
9#include "core/arm/skyeye_common/armdefs.h" 9#include "core/arm/skyeye_common/armstate.h"
10#include "core/arm/skyeye_common/armsupp.h"
10#include "core/arm/skyeye_common/vfp/vfp.h" 11#include "core/arm/skyeye_common/vfp/vfp.h"
11 12
12#include "core/arm/dyncom/arm_dyncom.h" 13#include "core/arm/dyncom/arm_dyncom.h"
@@ -17,26 +18,7 @@
17#include "core/core_timing.h" 18#include "core/core_timing.h"
18 19
19ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { 20ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
20 state = Common::make_unique<ARMul_State>(); 21 state = Common::make_unique<ARMul_State>(initial_mode);
21
22 ARMul_NewState(state.get());
23 ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
24
25 state->abort_model = ABORT_BASE_RESTORED;
26
27 state->bigendSig = LOW;
28 state->lateabtSig = LOW;
29 state->NirqSig = HIGH;
30
31 // Reset the core to initial state
32 ARMul_Reset(state.get());
33 state->Emulate = RUN;
34
35 // Switch to the desired privilege mode.
36 switch_mode(state.get(), initial_mode);
37
38 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
39 state->Reg[15] = 0x00000000;
40} 22}
41 23
42ARM_DynCom::~ARM_DynCom() { 24ARM_DynCom::~ARM_DynCom() {
@@ -100,8 +82,8 @@ void ARM_DynCom::ResetContext(Core::ThreadContext& context, u32 stack_top, u32 e
100} 82}
101 83
102void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { 84void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
103 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); 85 memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers));
104 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); 86 memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers));
105 87
106 ctx.sp = state->Reg[13]; 88 ctx.sp = state->Reg[13];
107 ctx.lr = state->Reg[14]; 89 ctx.lr = state->Reg[14];
@@ -113,8 +95,8 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
113} 95}
114 96
115void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) { 97void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
116 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); 98 memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
117 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); 99 memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
118 100
119 state->Reg[13] = ctx.sp; 101 state->Reg[13] = ctx.sp;
120 state->Reg[14] = ctx.lr; 102 state->Reg[14] = ctx.lr;
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
index cc9355722..87ab6908a 100644
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -9,8 +9,8 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11#include "core/arm/arm_interface.h" 11#include "core/arm/arm_interface.h"
12#include "core/arm/skyeye_common/armdefs.h"
13#include "core/arm/skyeye_common/arm_regformat.h" 12#include "core/arm/skyeye_common/arm_regformat.h"
13#include "core/arm/skyeye_common/armstate.h"
14 14
15namespace Core { 15namespace Core {
16struct ThreadContext; 16struct ThreadContext;
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 697be9556..3ab9f2c17 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -2,8 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/arm/skyeye_common/armdefs.h"
6#include "core/arm/dyncom/arm_dyncom_dec.h" 5#include "core/arm/dyncom/arm_dyncom_dec.h"
6#include "core/arm/skyeye_common/armsupp.h"
7 7
8const ISEITEM arm_instruction[] = { 8const ISEITEM arm_instruction[] = {
9 { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, 9 { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }},
@@ -414,7 +414,7 @@ const ISEITEM arm_exclusion_code[] = {
414 { "invalid", 0, INVALID, { 0 }} 414 { "invalid", 0, INVALID, { 0 }}
415}; 415};
416 416
417int decode_arm_instr(uint32_t instr, int32_t *idx) { 417int decode_arm_instr(u32 instr, s32* idx) {
418 int n = 0; 418 int n = 0;
419 int base = 0; 419 int base = 0;
420 int ret = DECODE_FAILURE; 420 int ret = DECODE_FAILURE;
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 4b5f5ad7e..5f6279627 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -4,7 +4,9 @@
4 4
5#pragma once 5#pragma once
6 6
7int decode_arm_instr(uint32_t instr, int32_t *idx); 7#include "common/common_types.h"
8
9int decode_arm_instr(u32 instr, s32* idx);
8 10
9enum DECODE_STATUS { 11enum DECODE_STATUS {
10 DECODE_SUCCESS, 12 DECODE_SUCCESS,
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 785f39566..cf09acb4e 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -17,8 +17,8 @@
17#include "core/arm/dyncom/arm_dyncom_interpreter.h" 17#include "core/arm/dyncom/arm_dyncom_interpreter.h"
18#include "core/arm/dyncom/arm_dyncom_thumb.h" 18#include "core/arm/dyncom/arm_dyncom_thumb.h"
19#include "core/arm/dyncom/arm_dyncom_run.h" 19#include "core/arm/dyncom/arm_dyncom_run.h"
20#include "core/arm/skyeye_common/armdefs.h" 20#include "core/arm/skyeye_common/armstate.h"
21#include "core/arm/skyeye_common/armmmu.h" 21#include "core/arm/skyeye_common/armsupp.h"
22#include "core/arm/skyeye_common/vfp/vfp.h" 22#include "core/arm/skyeye_common/vfp/vfp.h"
23 23
24Common::Profiling::TimingCategory profile_execute("DynCom::Execute"); 24Common::Profiling::TimingCategory profile_execute("DynCom::Execute");
@@ -50,22 +50,21 @@ typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
50// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. 50// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
51// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to 51// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
52// support LDR/STREXD. 52// support LDR/STREXD.
53static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8; 53static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
54 54
55// Exclusive memory access 55// Exclusive memory access
56static int exclusive_detect(ARMul_State* state, ARMword addr) { 56static int exclusive_detect(ARMul_State* state, u32 addr) {
57 if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) 57 if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK))
58 return 0; 58 return 0;
59 else 59 else
60 return -1; 60 return -1;
61} 61}
62 62
63static void add_exclusive_addr(ARMul_State* state, ARMword addr){ 63static void add_exclusive_addr(ARMul_State* state, u32 addr){
64 state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; 64 state->exclusive_tag = addr & RESERVATION_GRANULE_MASK;
65 return;
66} 65}
67 66
68static void remove_exclusive(ARMul_State* state, ARMword addr){ 67static void remove_exclusive(ARMul_State* state, u32 addr){
69 state->exclusive_tag = 0xFFFFFFFF; 68 state->exclusive_tag = 0xFFFFFFFF;
70} 69}
71 70
@@ -3964,7 +3963,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3964 if (inst_cream->S && (inst_cream->Rd == 15)) { 3963 if (inst_cream->S && (inst_cream->Rd == 15)) {
3965 if (CurrentModeHasSPSR) { 3964 if (CurrentModeHasSPSR) {
3966 cpu->Cpsr = cpu->Spsr_copy; 3965 cpu->Cpsr = cpu->Spsr_copy;
3967 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 3966 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
3968 LOAD_NZCVT; 3967 LOAD_NZCVT;
3969 } 3968 }
3970 } else if (inst_cream->S) { 3969 } else if (inst_cream->S) {
@@ -3978,7 +3977,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3978 goto DISPATCH; 3977 goto DISPATCH;
3979 } 3978 }
3980 } 3979 }
3981 cpu->Reg[15] += GET_INST_SIZE(cpu); 3980 cpu->Reg[15] += cpu->GetInstructionSize();
3982 INC_PC(sizeof(adc_inst)); 3981 INC_PC(sizeof(adc_inst));
3983 FETCH_INST; 3982 FETCH_INST;
3984 GOTO_NEXT_INST; 3983 GOTO_NEXT_INST;
@@ -3990,7 +3989,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3990 3989
3991 u32 rn_val = RN; 3990 u32 rn_val = RN;
3992 if (inst_cream->Rn == 15) 3991 if (inst_cream->Rn == 15)
3993 rn_val += 2 * GET_INST_SIZE(cpu); 3992 rn_val += 2 * cpu->GetInstructionSize();
3994 3993
3995 bool carry; 3994 bool carry;
3996 bool overflow; 3995 bool overflow;
@@ -3999,7 +3998,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3999 if (inst_cream->S && (inst_cream->Rd == 15)) { 3998 if (inst_cream->S && (inst_cream->Rd == 15)) {
4000 if (CurrentModeHasSPSR) { 3999 if (CurrentModeHasSPSR) {
4001 cpu->Cpsr = cpu->Spsr_copy; 4000 cpu->Cpsr = cpu->Spsr_copy;
4002 switch_mode(cpu, cpu->Cpsr & 0x1f); 4001 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
4003 LOAD_NZCVT; 4002 LOAD_NZCVT;
4004 } 4003 }
4005 } else if (inst_cream->S) { 4004 } else if (inst_cream->S) {
@@ -4013,7 +4012,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4013 goto DISPATCH; 4012 goto DISPATCH;
4014 } 4013 }
4015 } 4014 }
4016 cpu->Reg[15] += GET_INST_SIZE(cpu); 4015 cpu->Reg[15] += cpu->GetInstructionSize();
4017 INC_PC(sizeof(add_inst)); 4016 INC_PC(sizeof(add_inst));
4018 FETCH_INST; 4017 FETCH_INST;
4019 GOTO_NEXT_INST; 4018 GOTO_NEXT_INST;
@@ -4028,7 +4027,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4028 if (inst_cream->S && (inst_cream->Rd == 15)) { 4027 if (inst_cream->S && (inst_cream->Rd == 15)) {
4029 if (CurrentModeHasSPSR) { 4028 if (CurrentModeHasSPSR) {
4030 cpu->Cpsr = cpu->Spsr_copy; 4029 cpu->Cpsr = cpu->Spsr_copy;
4031 switch_mode(cpu, cpu->Cpsr & 0x1f); 4030 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
4032 LOAD_NZCVT; 4031 LOAD_NZCVT;
4033 } 4032 }
4034 } else if (inst_cream->S) { 4033 } else if (inst_cream->S) {
@@ -4041,7 +4040,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4041 goto DISPATCH; 4040 goto DISPATCH;
4042 } 4041 }
4043 } 4042 }
4044 cpu->Reg[15] += GET_INST_SIZE(cpu); 4043 cpu->Reg[15] += cpu->GetInstructionSize();
4045 INC_PC(sizeof(and_inst)); 4044 INC_PC(sizeof(and_inst));
4046 FETCH_INST; 4045 FETCH_INST;
4047 GOTO_NEXT_INST; 4046 GOTO_NEXT_INST;
@@ -4057,7 +4056,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4057 INC_PC(sizeof(bbl_inst)); 4056 INC_PC(sizeof(bbl_inst));
4058 goto DISPATCH; 4057 goto DISPATCH;
4059 } 4058 }
4060 cpu->Reg[15] += GET_INST_SIZE(cpu); 4059 cpu->Reg[15] += cpu->GetInstructionSize();
4061 INC_PC(sizeof(bbl_inst)); 4060 INC_PC(sizeof(bbl_inst));
4062 goto DISPATCH; 4061 goto DISPATCH;
4063 } 4062 }
@@ -4067,14 +4066,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4067 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4066 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4068 u32 lop = RN; 4067 u32 lop = RN;
4069 if (inst_cream->Rn == 15) { 4068 if (inst_cream->Rn == 15) {
4070 lop += 2 * GET_INST_SIZE(cpu); 4069 lop += 2 * cpu->GetInstructionSize();
4071 } 4070 }
4072 u32 rop = SHIFTER_OPERAND; 4071 u32 rop = SHIFTER_OPERAND;
4073 RD = lop & (~rop); 4072 RD = lop & (~rop);
4074 if ((inst_cream->S) && (inst_cream->Rd == 15)) { 4073 if ((inst_cream->S) && (inst_cream->Rd == 15)) {
4075 if (CurrentModeHasSPSR) { 4074 if (CurrentModeHasSPSR) {
4076 cpu->Cpsr = cpu->Spsr_copy; 4075 cpu->Cpsr = cpu->Spsr_copy;
4077 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4076 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
4078 LOAD_NZCVT; 4077 LOAD_NZCVT;
4079 } 4078 }
4080 } else if (inst_cream->S) { 4079 } else if (inst_cream->S) {
@@ -4087,7 +4086,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4087 goto DISPATCH; 4086 goto DISPATCH;
4088 } 4087 }
4089 } 4088 }
4090 cpu->Reg[15] += GET_INST_SIZE(cpu); 4089 cpu->Reg[15] += cpu->GetInstructionSize();
4091 INC_PC(sizeof(bic_inst)); 4090 INC_PC(sizeof(bic_inst));
4092 FETCH_INST; 4091 FETCH_INST;
4093 GOTO_NEXT_INST; 4092 GOTO_NEXT_INST;
@@ -4098,7 +4097,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4098 bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; 4097 bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
4099 LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm); 4098 LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
4100 } 4099 }
4101 cpu->Reg[15] += GET_INST_SIZE(cpu); 4100 cpu->Reg[15] += cpu->GetInstructionSize();
4102 INC_PC(sizeof(bkpt_inst)); 4101 INC_PC(sizeof(bkpt_inst));
4103 FETCH_INST; 4102 FETCH_INST;
4104 GOTO_NEXT_INST; 4103 GOTO_NEXT_INST;
@@ -4109,13 +4108,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4109 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4108 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4110 unsigned int inst = inst_cream->inst; 4109 unsigned int inst = inst_cream->inst;
4111 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { 4110 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
4112 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); 4111 cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
4113 if(cpu->TFlag) 4112 if(cpu->TFlag)
4114 cpu->Reg[14] |= 0x1; 4113 cpu->Reg[14] |= 0x1;
4115 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; 4114 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
4116 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; 4115 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
4117 } else { 4116 } else {
4118 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); 4117 cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
4119 cpu->TFlag = 0x1; 4118 cpu->TFlag = 0x1;
4120 int signed_int = inst_cream->val.signed_immed_24; 4119 int signed_int = inst_cream->val.signed_immed_24;
4121 signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; 4120 signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
@@ -4125,7 +4124,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4125 INC_PC(sizeof(blx_inst)); 4124 INC_PC(sizeof(blx_inst));
4126 goto DISPATCH; 4125 goto DISPATCH;
4127 } 4126 }
4128 cpu->Reg[15] += GET_INST_SIZE(cpu); 4127 cpu->Reg[15] += cpu->GetInstructionSize();
4129 INC_PC(sizeof(blx_inst)); 4128 INC_PC(sizeof(blx_inst));
4130 goto DISPATCH; 4129 goto DISPATCH;
4131 } 4130 }
@@ -4147,7 +4146,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4147 u32 address = RM; 4146 u32 address = RM;
4148 4147
4149 if (inst_cream->Rm == 15) 4148 if (inst_cream->Rm == 15)
4150 address += 2 * GET_INST_SIZE(cpu); 4149 address += 2 * cpu->GetInstructionSize();
4151 4150
4152 cpu->TFlag = address & 1; 4151 cpu->TFlag = address & 1;
4153 cpu->Reg[15] = address & 0xfffffffe; 4152 cpu->Reg[15] = address & 0xfffffffe;
@@ -4155,7 +4154,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4155 goto DISPATCH; 4154 goto DISPATCH;
4156 } 4155 }
4157 4156
4158 cpu->Reg[15] += GET_INST_SIZE(cpu); 4157 cpu->Reg[15] += cpu->GetInstructionSize();
4159 INC_PC(sizeof(bx_inst)); 4158 INC_PC(sizeof(bx_inst));
4160 goto DISPATCH; 4159 goto DISPATCH;
4161 } 4160 }
@@ -4167,7 +4166,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4167 cpu->NumInstrsToExecute = 0; 4166 cpu->NumInstrsToExecute = 0;
4168 return num_instrs; 4167 return num_instrs;
4169 } 4168 }
4170 cpu->Reg[15] += GET_INST_SIZE(cpu); 4169 cpu->Reg[15] += cpu->GetInstructionSize();
4171 INC_PC(sizeof(cdp_inst)); 4170 INC_PC(sizeof(cdp_inst));
4172 FETCH_INST; 4171 FETCH_INST;
4173 GOTO_NEXT_INST; 4172 GOTO_NEXT_INST;
@@ -4178,7 +4177,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4178 remove_exclusive(cpu, 0); 4177 remove_exclusive(cpu, 0);
4179 cpu->exclusive_state = 0; 4178 cpu->exclusive_state = 0;
4180 4179
4181 cpu->Reg[15] += GET_INST_SIZE(cpu); 4180 cpu->Reg[15] += cpu->GetInstructionSize();
4182 INC_PC(sizeof(clrex_inst)); 4181 INC_PC(sizeof(clrex_inst));
4183 FETCH_INST; 4182 FETCH_INST;
4184 GOTO_NEXT_INST; 4183 GOTO_NEXT_INST;
@@ -4189,7 +4188,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4189 clz_inst* inst_cream = (clz_inst*)inst_base->component; 4188 clz_inst* inst_cream = (clz_inst*)inst_base->component;
4190 RD = clz(RM); 4189 RD = clz(RM);
4191 } 4190 }
4192 cpu->Reg[15] += GET_INST_SIZE(cpu); 4191 cpu->Reg[15] += cpu->GetInstructionSize();
4193 INC_PC(sizeof(clz_inst)); 4192 INC_PC(sizeof(clz_inst));
4194 FETCH_INST; 4193 FETCH_INST;
4195 GOTO_NEXT_INST; 4194 GOTO_NEXT_INST;
@@ -4208,7 +4207,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4208 cpu->CFlag = carry; 4207 cpu->CFlag = carry;
4209 cpu->VFlag = overflow; 4208 cpu->VFlag = overflow;
4210 } 4209 }
4211 cpu->Reg[15] += GET_INST_SIZE(cpu); 4210 cpu->Reg[15] += cpu->GetInstructionSize();
4212 INC_PC(sizeof(cmn_inst)); 4211 INC_PC(sizeof(cmn_inst));
4213 FETCH_INST; 4212 FETCH_INST;
4214 GOTO_NEXT_INST; 4213 GOTO_NEXT_INST;
@@ -4220,7 +4219,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4220 4219
4221 u32 rn_val = RN; 4220 u32 rn_val = RN;
4222 if (inst_cream->Rn == 15) 4221 if (inst_cream->Rn == 15)
4223 rn_val += 2 * GET_INST_SIZE(cpu); 4222 rn_val += 2 * cpu->GetInstructionSize();
4224 4223
4225 bool carry; 4224 bool carry;
4226 bool overflow; 4225 bool overflow;
@@ -4231,7 +4230,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4231 cpu->CFlag = carry; 4230 cpu->CFlag = carry;
4232 cpu->VFlag = overflow; 4231 cpu->VFlag = overflow;
4233 } 4232 }
4234 cpu->Reg[15] += GET_INST_SIZE(cpu); 4233 cpu->Reg[15] += cpu->GetInstructionSize();
4235 INC_PC(sizeof(cmp_inst)); 4234 INC_PC(sizeof(cmp_inst));
4236 FETCH_INST; 4235 FETCH_INST;
4237 GOTO_NEXT_INST; 4236 GOTO_NEXT_INST;
@@ -4241,7 +4240,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4241 cps_inst *inst_cream = (cps_inst *)inst_base->component; 4240 cps_inst *inst_cream = (cps_inst *)inst_base->component;
4242 uint32_t aif_val = 0; 4241 uint32_t aif_val = 0;
4243 uint32_t aif_mask = 0; 4242 uint32_t aif_mask = 0;
4244 if (InAPrivilegedMode(cpu)) { 4243 if (cpu->InAPrivilegedMode()) {
4245 if (inst_cream->imod1) { 4244 if (inst_cream->imod1) {
4246 if (inst_cream->A) { 4245 if (inst_cream->A) {
4247 aif_val |= (inst_cream->imod0 << 8); 4246 aif_val |= (inst_cream->imod0 << 8);
@@ -4260,10 +4259,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4260 } 4259 }
4261 if (inst_cream->mmod) { 4260 if (inst_cream->mmod) {
4262 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; 4261 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
4263 switch_mode(cpu, inst_cream->mode); 4262 cpu->ChangePrivilegeMode(inst_cream->mode);
4264 } 4263 }
4265 } 4264 }
4266 cpu->Reg[15] += GET_INST_SIZE(cpu); 4265 cpu->Reg[15] += cpu->GetInstructionSize();
4267 INC_PC(sizeof(cps_inst)); 4266 INC_PC(sizeof(cps_inst));
4268 FETCH_INST; 4267 FETCH_INST;
4269 GOTO_NEXT_INST; 4268 GOTO_NEXT_INST;
@@ -4279,7 +4278,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4279 goto DISPATCH; 4278 goto DISPATCH;
4280 } 4279 }
4281 } 4280 }
4282 cpu->Reg[15] += GET_INST_SIZE(cpu); 4281 cpu->Reg[15] += cpu->GetInstructionSize();
4283 INC_PC(sizeof(mov_inst)); 4282 INC_PC(sizeof(mov_inst));
4284 FETCH_INST; 4283 FETCH_INST;
4285 GOTO_NEXT_INST; 4284 GOTO_NEXT_INST;
@@ -4291,14 +4290,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4291 4290
4292 u32 lop = RN; 4291 u32 lop = RN;
4293 if (inst_cream->Rn == 15) { 4292 if (inst_cream->Rn == 15) {
4294 lop += 2 * GET_INST_SIZE(cpu); 4293 lop += 2 * cpu->GetInstructionSize();
4295 } 4294 }
4296 u32 rop = SHIFTER_OPERAND; 4295 u32 rop = SHIFTER_OPERAND;
4297 RD = lop ^ rop; 4296 RD = lop ^ rop;
4298 if (inst_cream->S && (inst_cream->Rd == 15)) { 4297 if (inst_cream->S && (inst_cream->Rd == 15)) {
4299 if (CurrentModeHasSPSR) { 4298 if (CurrentModeHasSPSR) {
4300 cpu->Cpsr = cpu->Spsr_copy; 4299 cpu->Cpsr = cpu->Spsr_copy;
4301 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4300 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
4302 LOAD_NZCVT; 4301 LOAD_NZCVT;
4303 } 4302 }
4304 } else if (inst_cream->S) { 4303 } else if (inst_cream->S) {
@@ -4311,7 +4310,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4311 goto DISPATCH; 4310 goto DISPATCH;
4312 } 4311 }
4313 } 4312 }
4314 cpu->Reg[15] += GET_INST_SIZE(cpu); 4313 cpu->Reg[15] += cpu->GetInstructionSize();
4315 INC_PC(sizeof(eor_inst)); 4314 INC_PC(sizeof(eor_inst));
4316 FETCH_INST; 4315 FETCH_INST;
4317 GOTO_NEXT_INST; 4316 GOTO_NEXT_INST;
@@ -4320,7 +4319,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4320 { 4319 {
4321 // Instruction not implemented 4320 // Instruction not implemented
4322 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); 4321 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
4323 cpu->Reg[15] += GET_INST_SIZE(cpu); 4322 cpu->Reg[15] += cpu->GetInstructionSize();
4324 INC_PC(sizeof(ldc_inst)); 4323 INC_PC(sizeof(ldc_inst));
4325 FETCH_INST; 4324 FETCH_INST;
4326 GOTO_NEXT_INST; 4325 GOTO_NEXT_INST;
@@ -4335,30 +4334,30 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4335 if (BIT(inst, 22) && !BIT(inst, 15)) { 4334 if (BIT(inst, 22) && !BIT(inst, 15)) {
4336 for (int i = 0; i < 13; i++) { 4335 for (int i = 0; i < 13; i++) {
4337 if(BIT(inst, i)) { 4336 if(BIT(inst, i)) {
4338 cpu->Reg[i] = ReadMemory32(cpu, addr); 4337 cpu->Reg[i] = cpu->ReadMemory32(addr);
4339 addr += 4; 4338 addr += 4;
4340 } 4339 }
4341 } 4340 }
4342 if (BIT(inst, 13)) { 4341 if (BIT(inst, 13)) {
4343 if (cpu->Mode == USER32MODE) 4342 if (cpu->Mode == USER32MODE)
4344 cpu->Reg[13] = ReadMemory32(cpu, addr); 4343 cpu->Reg[13] = cpu->ReadMemory32(addr);
4345 else 4344 else
4346 cpu->Reg_usr[0] = ReadMemory32(cpu, addr); 4345 cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
4347 4346
4348 addr += 4; 4347 addr += 4;
4349 } 4348 }
4350 if (BIT(inst, 14)) { 4349 if (BIT(inst, 14)) {
4351 if (cpu->Mode == USER32MODE) 4350 if (cpu->Mode == USER32MODE)
4352 cpu->Reg[14] = ReadMemory32(cpu, addr); 4351 cpu->Reg[14] = cpu->ReadMemory32(addr);
4353 else 4352 else
4354 cpu->Reg_usr[1] = ReadMemory32(cpu, addr); 4353 cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
4355 4354
4356 addr += 4; 4355 addr += 4;
4357 } 4356 }
4358 } else if (!BIT(inst, 22)) { 4357 } else if (!BIT(inst, 22)) {
4359 for(int i = 0; i < 16; i++ ){ 4358 for(int i = 0; i < 16; i++ ){
4360 if(BIT(inst, i)){ 4359 if(BIT(inst, i)){
4361 unsigned int ret = ReadMemory32(cpu, addr); 4360 unsigned int ret = cpu->ReadMemory32(addr);
4362 4361
4363 // For armv5t, should enter thumb when bits[0] is non-zero. 4362 // For armv5t, should enter thumb when bits[0] is non-zero.
4364 if(i == 15){ 4363 if(i == 15){
@@ -4373,18 +4372,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4373 } else if (BIT(inst, 22) && BIT(inst, 15)) { 4372 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4374 for(int i = 0; i < 15; i++ ){ 4373 for(int i = 0; i < 15; i++ ){
4375 if(BIT(inst, i)){ 4374 if(BIT(inst, i)){
4376 cpu->Reg[i] = ReadMemory32(cpu, addr); 4375 cpu->Reg[i] = cpu->ReadMemory32(addr);
4377 addr += 4; 4376 addr += 4;
4378 } 4377 }
4379 } 4378 }
4380 4379
4381 if (CurrentModeHasSPSR) { 4380 if (CurrentModeHasSPSR) {
4382 cpu->Cpsr = cpu->Spsr_copy; 4381 cpu->Cpsr = cpu->Spsr_copy;
4383 switch_mode(cpu, cpu->Cpsr & 0x1f); 4382 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
4384 LOAD_NZCVT; 4383 LOAD_NZCVT;
4385 } 4384 }
4386 4385
4387 cpu->Reg[15] = ReadMemory32(cpu, addr); 4386 cpu->Reg[15] = cpu->ReadMemory32(addr);
4388 } 4387 }
4389 4388
4390 if (BIT(inst, 15)) { 4389 if (BIT(inst, 15)) {
@@ -4392,7 +4391,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4392 goto DISPATCH; 4391 goto DISPATCH;
4393 } 4392 }
4394 } 4393 }
4395 cpu->Reg[15] += GET_INST_SIZE(cpu); 4394 cpu->Reg[15] += cpu->GetInstructionSize();
4396 INC_PC(sizeof(ldst_inst)); 4395 INC_PC(sizeof(ldst_inst));
4397 FETCH_INST; 4396 FETCH_INST;
4398 GOTO_NEXT_INST; 4397 GOTO_NEXT_INST;
@@ -4410,7 +4409,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4410 } 4409 }
4411 RD = operand2; 4410 RD = operand2;
4412 } 4411 }
4413 cpu->Reg[15] += GET_INST_SIZE(cpu); 4412 cpu->Reg[15] += cpu->GetInstructionSize();
4414 INC_PC(sizeof(sxth_inst)); 4413 INC_PC(sizeof(sxth_inst));
4415 FETCH_INST; 4414 FETCH_INST;
4416 GOTO_NEXT_INST; 4415 GOTO_NEXT_INST;
@@ -4420,7 +4419,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4420 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4419 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4421 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4420 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4422 4421
4423 unsigned int value = ReadMemory32(cpu, addr); 4422 unsigned int value = cpu->ReadMemory32(addr);
4424 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4423 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4425 4424
4426 if (BITS(inst_cream->inst, 12, 15) == 15) { 4425 if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4431,7 +4430,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4431 goto DISPATCH; 4430 goto DISPATCH;
4432 } 4431 }
4433 4432
4434 cpu->Reg[15] += GET_INST_SIZE(cpu); 4433 cpu->Reg[15] += cpu->GetInstructionSize();
4435 INC_PC(sizeof(ldst_inst)); 4434 INC_PC(sizeof(ldst_inst));
4436 FETCH_INST; 4435 FETCH_INST;
4437 GOTO_NEXT_INST; 4436 GOTO_NEXT_INST;
@@ -4442,7 +4441,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4442 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4441 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4443 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4442 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4444 4443
4445 unsigned int value = ReadMemory32(cpu, addr); 4444 unsigned int value = cpu->ReadMemory32(addr);
4446 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4445 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4447 4446
4448 if (BITS(inst_cream->inst, 12, 15) == 15) { 4447 if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4453,7 +4452,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4453 goto DISPATCH; 4452 goto DISPATCH;
4454 } 4453 }
4455 } 4454 }
4456 cpu->Reg[15] += GET_INST_SIZE(cpu); 4455 cpu->Reg[15] += cpu->GetInstructionSize();
4457 INC_PC(sizeof(ldst_inst)); 4456 INC_PC(sizeof(ldst_inst));
4458 FETCH_INST; 4457 FETCH_INST;
4459 GOTO_NEXT_INST; 4458 GOTO_NEXT_INST;
@@ -4464,7 +4463,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4464 uxth_inst* inst_cream = (uxth_inst*)inst_base->component; 4463 uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
4465 RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; 4464 RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
4466 } 4465 }
4467 cpu->Reg[15] += GET_INST_SIZE(cpu); 4466 cpu->Reg[15] += cpu->GetInstructionSize();
4468 INC_PC(sizeof(uxth_inst)); 4467 INC_PC(sizeof(uxth_inst));
4469 FETCH_INST; 4468 FETCH_INST;
4470 GOTO_NEXT_INST; 4469 GOTO_NEXT_INST;
@@ -4477,7 +4476,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4477 4476
4478 RD = RN + operand2; 4477 RD = RN + operand2;
4479 } 4478 }
4480 cpu->Reg[15] += GET_INST_SIZE(cpu); 4479 cpu->Reg[15] += cpu->GetInstructionSize();
4481 INC_PC(sizeof(uxtah_inst)); 4480 INC_PC(sizeof(uxtah_inst));
4482 FETCH_INST; 4481 FETCH_INST;
4483 GOTO_NEXT_INST; 4482 GOTO_NEXT_INST;
@@ -4495,7 +4494,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4495 goto DISPATCH; 4494 goto DISPATCH;
4496 } 4495 }
4497 } 4496 }
4498 cpu->Reg[15] += GET_INST_SIZE(cpu); 4497 cpu->Reg[15] += cpu->GetInstructionSize();
4499 INC_PC(sizeof(ldst_inst)); 4498 INC_PC(sizeof(ldst_inst));
4500 FETCH_INST; 4499 FETCH_INST;
4501 GOTO_NEXT_INST; 4500 GOTO_NEXT_INST;
@@ -4513,7 +4512,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4513 goto DISPATCH; 4512 goto DISPATCH;
4514 } 4513 }
4515 } 4514 }
4516 cpu->Reg[15] += GET_INST_SIZE(cpu); 4515 cpu->Reg[15] += cpu->GetInstructionSize();
4517 INC_PC(sizeof(ldst_inst)); 4516 INC_PC(sizeof(ldst_inst));
4518 FETCH_INST; 4517 FETCH_INST;
4519 GOTO_NEXT_INST; 4518 GOTO_NEXT_INST;
@@ -4527,8 +4526,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4527 4526
4528 // The 3DS doesn't have LPAE (Large Physical Access Extension), so it 4527 // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
4529 // wouldn't do this as a single read. 4528 // wouldn't do this as a single read.
4530 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr); 4529 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
4531 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4); 4530 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
4532 4531
4533 // No dispatch since this operation should not modify R15 4532 // No dispatch since this operation should not modify R15
4534 } 4533 }
@@ -4547,13 +4546,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4547 add_exclusive_addr(cpu, read_addr); 4546 add_exclusive_addr(cpu, read_addr);
4548 cpu->exclusive_state = 1; 4547 cpu->exclusive_state = 1;
4549 4548
4550 RD = ReadMemory32(cpu, read_addr); 4549 RD = cpu->ReadMemory32(read_addr);
4551 if (inst_cream->Rd == 15) { 4550 if (inst_cream->Rd == 15) {
4552 INC_PC(sizeof(generic_arm_inst)); 4551 INC_PC(sizeof(generic_arm_inst));
4553 goto DISPATCH; 4552 goto DISPATCH;
4554 } 4553 }
4555 } 4554 }
4556 cpu->Reg[15] += GET_INST_SIZE(cpu); 4555 cpu->Reg[15] += cpu->GetInstructionSize();
4557 INC_PC(sizeof(generic_arm_inst)); 4556 INC_PC(sizeof(generic_arm_inst));
4558 FETCH_INST; 4557 FETCH_INST;
4559 GOTO_NEXT_INST; 4558 GOTO_NEXT_INST;
@@ -4573,7 +4572,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4573 goto DISPATCH; 4572 goto DISPATCH;
4574 } 4573 }
4575 } 4574 }
4576 cpu->Reg[15] += GET_INST_SIZE(cpu); 4575 cpu->Reg[15] += cpu->GetInstructionSize();
4577 INC_PC(sizeof(generic_arm_inst)); 4576 INC_PC(sizeof(generic_arm_inst));
4578 FETCH_INST; 4577 FETCH_INST;
4579 GOTO_NEXT_INST; 4578 GOTO_NEXT_INST;
@@ -4587,13 +4586,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4587 add_exclusive_addr(cpu, read_addr); 4586 add_exclusive_addr(cpu, read_addr);
4588 cpu->exclusive_state = 1; 4587 cpu->exclusive_state = 1;
4589 4588
4590 RD = ReadMemory16(cpu, read_addr); 4589 RD = cpu->ReadMemory16(read_addr);
4591 if (inst_cream->Rd == 15) { 4590 if (inst_cream->Rd == 15) {
4592 INC_PC(sizeof(generic_arm_inst)); 4591 INC_PC(sizeof(generic_arm_inst));
4593 goto DISPATCH; 4592 goto DISPATCH;
4594 } 4593 }
4595 } 4594 }
4596 cpu->Reg[15] += GET_INST_SIZE(cpu); 4595 cpu->Reg[15] += cpu->GetInstructionSize();
4597 INC_PC(sizeof(generic_arm_inst)); 4596 INC_PC(sizeof(generic_arm_inst));
4598 FETCH_INST; 4597 FETCH_INST;
4599 GOTO_NEXT_INST; 4598 GOTO_NEXT_INST;
@@ -4607,15 +4606,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4607 add_exclusive_addr(cpu, read_addr); 4606 add_exclusive_addr(cpu, read_addr);
4608 cpu->exclusive_state = 1; 4607 cpu->exclusive_state = 1;
4609 4608
4610 RD = ReadMemory32(cpu, read_addr); 4609 RD = cpu->ReadMemory32(read_addr);
4611 RD2 = ReadMemory32(cpu, read_addr + 4); 4610 RD2 = cpu->ReadMemory32(read_addr + 4);
4612 4611
4613 if (inst_cream->Rd == 15) { 4612 if (inst_cream->Rd == 15) {
4614 INC_PC(sizeof(generic_arm_inst)); 4613 INC_PC(sizeof(generic_arm_inst));
4615 goto DISPATCH; 4614 goto DISPATCH;
4616 } 4615 }
4617 } 4616 }
4618 cpu->Reg[15] += GET_INST_SIZE(cpu); 4617 cpu->Reg[15] += cpu->GetInstructionSize();
4619 INC_PC(sizeof(generic_arm_inst)); 4618 INC_PC(sizeof(generic_arm_inst));
4620 FETCH_INST; 4619 FETCH_INST;
4621 GOTO_NEXT_INST; 4620 GOTO_NEXT_INST;
@@ -4626,13 +4625,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4626 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4625 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4627 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4626 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4628 4627
4629 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr); 4628 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
4630 if (BITS(inst_cream->inst, 12, 15) == 15) { 4629 if (BITS(inst_cream->inst, 12, 15) == 15) {
4631 INC_PC(sizeof(ldst_inst)); 4630 INC_PC(sizeof(ldst_inst));
4632 goto DISPATCH; 4631 goto DISPATCH;
4633 } 4632 }
4634 } 4633 }
4635 cpu->Reg[15] += GET_INST_SIZE(cpu); 4634 cpu->Reg[15] += cpu->GetInstructionSize();
4636 INC_PC(sizeof(ldst_inst)); 4635 INC_PC(sizeof(ldst_inst));
4637 FETCH_INST; 4636 FETCH_INST;
4638 GOTO_NEXT_INST; 4637 GOTO_NEXT_INST;
@@ -4652,7 +4651,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4652 goto DISPATCH; 4651 goto DISPATCH;
4653 } 4652 }
4654 } 4653 }
4655 cpu->Reg[15] += GET_INST_SIZE(cpu); 4654 cpu->Reg[15] += cpu->GetInstructionSize();
4656 INC_PC(sizeof(ldst_inst)); 4655 INC_PC(sizeof(ldst_inst));
4657 FETCH_INST; 4656 FETCH_INST;
4658 GOTO_NEXT_INST; 4657 GOTO_NEXT_INST;
@@ -4663,7 +4662,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4663 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4662 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4664 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4663 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4665 4664
4666 unsigned int value = ReadMemory16(cpu, addr); 4665 unsigned int value = cpu->ReadMemory16(addr);
4667 if (BIT(value, 15)) { 4666 if (BIT(value, 15)) {
4668 value |= 0xffff0000; 4667 value |= 0xffff0000;
4669 } 4668 }
@@ -4673,7 +4672,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4673 goto DISPATCH; 4672 goto DISPATCH;
4674 } 4673 }
4675 } 4674 }
4676 cpu->Reg[15] += GET_INST_SIZE(cpu); 4675 cpu->Reg[15] += cpu->GetInstructionSize();
4677 INC_PC(sizeof(ldst_inst)); 4676 INC_PC(sizeof(ldst_inst));
4678 FETCH_INST; 4677 FETCH_INST;
4679 GOTO_NEXT_INST; 4678 GOTO_NEXT_INST;
@@ -4684,7 +4683,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4684 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4683 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4685 inst_cream->get_addr(cpu, inst_cream->inst, addr); 4684 inst_cream->get_addr(cpu, inst_cream->inst, addr);
4686 4685
4687 unsigned int value = ReadMemory32(cpu, addr); 4686 unsigned int value = cpu->ReadMemory32(addr);
4688 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4687 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4689 4688
4690 if (BITS(inst_cream->inst, 12, 15) == 15) { 4689 if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4692,7 +4691,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4692 goto DISPATCH; 4691 goto DISPATCH;
4693 } 4692 }
4694 } 4693 }
4695 cpu->Reg[15] += GET_INST_SIZE(cpu); 4694 cpu->Reg[15] += cpu->GetInstructionSize();
4696 INC_PC(sizeof(ldst_inst)); 4695 INC_PC(sizeof(ldst_inst));
4697 FETCH_INST; 4696 FETCH_INST;
4698 GOTO_NEXT_INST; 4697 GOTO_NEXT_INST;
@@ -4707,10 +4706,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4707 DEBUG_MSG; 4706 DEBUG_MSG;
4708 } else { 4707 } else {
4709 if (inst_cream->cp_num == 15) 4708 if (inst_cream->cp_num == 15)
4710 WriteCP15Register(cpu, RD, CRn, OPCODE_1, CRm, OPCODE_2); 4709 cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
4711 } 4710 }
4712 } 4711 }
4713 cpu->Reg[15] += GET_INST_SIZE(cpu); 4712 cpu->Reg[15] += cpu->GetInstructionSize();
4714 INC_PC(sizeof(mcr_inst)); 4713 INC_PC(sizeof(mcr_inst));
4715 FETCH_INST; 4714 FETCH_INST;
4716 GOTO_NEXT_INST; 4715 GOTO_NEXT_INST;
@@ -4727,7 +4726,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4727 inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); 4726 inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
4728 } 4727 }
4729 4728
4730 cpu->Reg[15] += GET_INST_SIZE(cpu); 4729 cpu->Reg[15] += cpu->GetInstructionSize();
4731 INC_PC(sizeof(mcrr_inst)); 4730 INC_PC(sizeof(mcrr_inst));
4732 FETCH_INST; 4731 FETCH_INST;
4733 GOTO_NEXT_INST; 4732 GOTO_NEXT_INST;
@@ -4752,7 +4751,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4752 goto DISPATCH; 4751 goto DISPATCH;
4753 } 4752 }
4754 } 4753 }
4755 cpu->Reg[15] += GET_INST_SIZE(cpu); 4754 cpu->Reg[15] += cpu->GetInstructionSize();
4756 INC_PC(sizeof(mla_inst)); 4755 INC_PC(sizeof(mla_inst));
4757 FETCH_INST; 4756 FETCH_INST;
4758 GOTO_NEXT_INST; 4757 GOTO_NEXT_INST;
@@ -4766,7 +4765,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4766 if (inst_cream->S && (inst_cream->Rd == 15)) { 4765 if (inst_cream->S && (inst_cream->Rd == 15)) {
4767 if (CurrentModeHasSPSR) { 4766 if (CurrentModeHasSPSR) {
4768 cpu->Cpsr = cpu->Spsr_copy; 4767 cpu->Cpsr = cpu->Spsr_copy;
4769 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4768 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
4770 LOAD_NZCVT; 4769 LOAD_NZCVT;
4771 } 4770 }
4772 } else if (inst_cream->S) { 4771 } else if (inst_cream->S) {
@@ -4779,7 +4778,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4779 goto DISPATCH; 4778 goto DISPATCH;
4780 } 4779 }
4781 } 4780 }
4782 cpu->Reg[15] += GET_INST_SIZE(cpu); 4781 cpu->Reg[15] += cpu->GetInstructionSize();
4783 INC_PC(sizeof(mov_inst)); 4782 INC_PC(sizeof(mov_inst));
4784 FETCH_INST; 4783 FETCH_INST;
4785 GOTO_NEXT_INST; 4784 GOTO_NEXT_INST;
@@ -4800,10 +4799,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4800 goto END; 4799 goto END;
4801 } else { 4800 } else {
4802 if (inst_cream->cp_num == 15) 4801 if (inst_cream->cp_num == 15)
4803 RD = ReadCP15Register(cpu, CRn, OPCODE_1, CRm, OPCODE_2); 4802 RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
4804 } 4803 }
4805 } 4804 }
4806 cpu->Reg[15] += GET_INST_SIZE(cpu); 4805 cpu->Reg[15] += cpu->GetInstructionSize();
4807 INC_PC(sizeof(mrc_inst)); 4806 INC_PC(sizeof(mrc_inst));
4808 FETCH_INST; 4807 FETCH_INST;
4809 GOTO_NEXT_INST; 4808 GOTO_NEXT_INST;
@@ -4820,7 +4819,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4820 inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); 4819 inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
4821 } 4820 }
4822 4821
4823 cpu->Reg[15] += GET_INST_SIZE(cpu); 4822 cpu->Reg[15] += cpu->GetInstructionSize();
4824 INC_PC(sizeof(mcrr_inst)); 4823 INC_PC(sizeof(mcrr_inst));
4825 FETCH_INST; 4824 FETCH_INST;
4826 GOTO_NEXT_INST; 4825 GOTO_NEXT_INST;
@@ -4838,7 +4837,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4838 RD = cpu->Cpsr; 4837 RD = cpu->Cpsr;
4839 } 4838 }
4840 } 4839 }
4841 cpu->Reg[15] += GET_INST_SIZE(cpu); 4840 cpu->Reg[15] += cpu->GetInstructionSize();
4842 INC_PC(sizeof(mrs_inst)); 4841 INC_PC(sizeof(mrs_inst));
4843 FETCH_INST; 4842 FETCH_INST;
4844 GOTO_NEXT_INST; 4843 GOTO_NEXT_INST;
@@ -4861,7 +4860,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4861 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); 4860 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
4862 uint32_t mask = 0; 4861 uint32_t mask = 0;
4863 if (!inst_cream->R) { 4862 if (!inst_cream->R) {
4864 if (InAPrivilegedMode(cpu)) { 4863 if (cpu->InAPrivilegedMode()) {
4865 if ((operand & StateMask) != 0) { 4864 if ((operand & StateMask) != 0) {
4866 /// UNPREDICTABLE 4865 /// UNPREDICTABLE
4867 DEBUG_MSG; 4866 DEBUG_MSG;
@@ -4873,7 +4872,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4873 SAVE_NZCVT; 4872 SAVE_NZCVT;
4874 4873
4875 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); 4874 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
4876 switch_mode(cpu, cpu->Cpsr & 0x1f); 4875 cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
4877 LOAD_NZCVT; 4876 LOAD_NZCVT;
4878 } else { 4877 } else {
4879 if (CurrentModeHasSPSR) { 4878 if (CurrentModeHasSPSR) {
@@ -4882,7 +4881,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4882 } 4881 }
4883 } 4882 }
4884 } 4883 }
4885 cpu->Reg[15] += GET_INST_SIZE(cpu); 4884 cpu->Reg[15] += cpu->GetInstructionSize();
4886 INC_PC(sizeof(msr_inst)); 4885 INC_PC(sizeof(msr_inst));
4887 FETCH_INST; 4886 FETCH_INST;
4888 GOTO_NEXT_INST; 4887 GOTO_NEXT_INST;
@@ -4904,7 +4903,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4904 goto DISPATCH; 4903 goto DISPATCH;
4905 } 4904 }
4906 } 4905 }
4907 cpu->Reg[15] += GET_INST_SIZE(cpu); 4906 cpu->Reg[15] += cpu->GetInstructionSize();
4908 INC_PC(sizeof(mul_inst)); 4907 INC_PC(sizeof(mul_inst));
4909 FETCH_INST; 4908 FETCH_INST;
4910 GOTO_NEXT_INST; 4909 GOTO_NEXT_INST;
@@ -4919,7 +4918,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4919 if (inst_cream->S && (inst_cream->Rd == 15)) { 4918 if (inst_cream->S && (inst_cream->Rd == 15)) {
4920 if (CurrentModeHasSPSR) { 4919 if (CurrentModeHasSPSR) {
4921 cpu->Cpsr = cpu->Spsr_copy; 4920 cpu->Cpsr = cpu->Spsr_copy;
4922 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4921 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
4923 LOAD_NZCVT; 4922 LOAD_NZCVT;
4924 } 4923 }
4925 } else if (inst_cream->S) { 4924 } else if (inst_cream->S) {
@@ -4932,7 +4931,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4932 goto DISPATCH; 4931 goto DISPATCH;
4933 } 4932 }
4934 } 4933 }
4935 cpu->Reg[15] += GET_INST_SIZE(cpu); 4934 cpu->Reg[15] += cpu->GetInstructionSize();
4936 INC_PC(sizeof(mvn_inst)); 4935 INC_PC(sizeof(mvn_inst));
4937 FETCH_INST; 4936 FETCH_INST;
4938 GOTO_NEXT_INST; 4937 GOTO_NEXT_INST;
@@ -4949,7 +4948,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4949 if (inst_cream->S && (inst_cream->Rd == 15)) { 4948 if (inst_cream->S && (inst_cream->Rd == 15)) {
4950 if (CurrentModeHasSPSR) { 4949 if (CurrentModeHasSPSR) {
4951 cpu->Cpsr = cpu->Spsr_copy; 4950 cpu->Cpsr = cpu->Spsr_copy;
4952 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 4951 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
4953 LOAD_NZCVT; 4952 LOAD_NZCVT;
4954 } 4953 }
4955 } else if (inst_cream->S) { 4954 } else if (inst_cream->S) {
@@ -4962,7 +4961,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4962 goto DISPATCH; 4961 goto DISPATCH;
4963 } 4962 }
4964 } 4963 }
4965 cpu->Reg[15] += GET_INST_SIZE(cpu); 4964 cpu->Reg[15] += cpu->GetInstructionSize();
4966 INC_PC(sizeof(orr_inst)); 4965 INC_PC(sizeof(orr_inst));
4967 FETCH_INST; 4966 FETCH_INST;
4968 GOTO_NEXT_INST; 4967 GOTO_NEXT_INST;
@@ -4970,7 +4969,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4970 4969
4971 NOP_INST: 4970 NOP_INST:
4972 { 4971 {
4973 cpu->Reg[15] += GET_INST_SIZE(cpu); 4972 cpu->Reg[15] += cpu->GetInstructionSize();
4974 INC_PC_STUB; 4973 INC_PC_STUB;
4975 FETCH_INST; 4974 FETCH_INST;
4976 GOTO_NEXT_INST; 4975 GOTO_NEXT_INST;
@@ -4982,7 +4981,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4982 pkh_inst *inst_cream = (pkh_inst *)inst_base->component; 4981 pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
4983 RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); 4982 RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
4984 } 4983 }
4985 cpu->Reg[15] += GET_INST_SIZE(cpu); 4984 cpu->Reg[15] += cpu->GetInstructionSize();
4986 INC_PC(sizeof(pkh_inst)); 4985 INC_PC(sizeof(pkh_inst));
4987 FETCH_INST; 4986 FETCH_INST;
4988 GOTO_NEXT_INST; 4987 GOTO_NEXT_INST;
@@ -4995,7 +4994,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4995 int shift_imm = inst_cream->imm ? inst_cream->imm : 31; 4994 int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
4996 RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); 4995 RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
4997 } 4996 }
4998 cpu->Reg[15] += GET_INST_SIZE(cpu); 4997 cpu->Reg[15] += cpu->GetInstructionSize();
4999 INC_PC(sizeof(pkh_inst)); 4998 INC_PC(sizeof(pkh_inst));
5000 FETCH_INST; 4999 FETCH_INST;
5001 GOTO_NEXT_INST; 5000 GOTO_NEXT_INST;
@@ -5005,7 +5004,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5005 { 5004 {
5006 // Not implemented. PLD is a hint instruction, so it's optional. 5005 // Not implemented. PLD is a hint instruction, so it's optional.
5007 5006
5008 cpu->Reg[15] += GET_INST_SIZE(cpu); 5007 cpu->Reg[15] += cpu->GetInstructionSize();
5009 INC_PC(sizeof(pld_inst)); 5008 INC_PC(sizeof(pld_inst));
5010 FETCH_INST; 5009 FETCH_INST;
5011 GOTO_NEXT_INST; 5010 GOTO_NEXT_INST;
@@ -5078,7 +5077,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5078 RD = result; 5077 RD = result;
5079 } 5078 }
5080 5079
5081 cpu->Reg[15] += GET_INST_SIZE(cpu); 5080 cpu->Reg[15] += cpu->GetInstructionSize();
5082 INC_PC(sizeof(generic_arm_inst)); 5081 INC_PC(sizeof(generic_arm_inst));
5083 FETCH_INST; 5082 FETCH_INST;
5084 GOTO_NEXT_INST; 5083 GOTO_NEXT_INST;
@@ -5140,7 +5139,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5140 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); 5139 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5141 } 5140 }
5142 5141
5143 cpu->Reg[15] += GET_INST_SIZE(cpu); 5142 cpu->Reg[15] += cpu->GetInstructionSize();
5144 INC_PC(sizeof(generic_arm_inst)); 5143 INC_PC(sizeof(generic_arm_inst));
5145 FETCH_INST; 5144 FETCH_INST;
5146 GOTO_NEXT_INST; 5145 GOTO_NEXT_INST;
@@ -5173,7 +5172,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5173 } 5172 }
5174 } 5173 }
5175 5174
5176 cpu->Reg[15] += GET_INST_SIZE(cpu); 5175 cpu->Reg[15] += cpu->GetInstructionSize();
5177 INC_PC(sizeof(rev_inst)); 5176 INC_PC(sizeof(rev_inst));
5178 FETCH_INST; 5177 FETCH_INST;
5179 GOTO_NEXT_INST; 5178 GOTO_NEXT_INST;
@@ -5187,8 +5186,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5187 u32 address = 0; 5186 u32 address = 0;
5188 inst_cream->get_addr(cpu, inst_cream->inst, address); 5187 inst_cream->get_addr(cpu, inst_cream->inst, address);
5189 5188
5190 cpu->Cpsr = ReadMemory32(cpu, address); 5189 cpu->Cpsr = cpu->ReadMemory32(address);
5191 cpu->Reg[15] = ReadMemory32(cpu, address + 4); 5190 cpu->Reg[15] = cpu->ReadMemory32(address + 4);
5192 5191
5193 INC_PC(sizeof(ldst_inst)); 5192 INC_PC(sizeof(ldst_inst));
5194 goto DISPATCH; 5193 goto DISPATCH;
@@ -5201,7 +5200,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5201 5200
5202 u32 rn_val = RN; 5201 u32 rn_val = RN;
5203 if (inst_cream->Rn == 15) 5202 if (inst_cream->Rn == 15)
5204 rn_val += 2 * GET_INST_SIZE(cpu); 5203 rn_val += 2 * cpu->GetInstructionSize();
5205 5204
5206 bool carry; 5205 bool carry;
5207 bool overflow; 5206 bool overflow;
@@ -5210,7 +5209,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5210 if (inst_cream->S && (inst_cream->Rd == 15)) { 5209 if (inst_cream->S && (inst_cream->Rd == 15)) {
5211 if (CurrentModeHasSPSR) { 5210 if (CurrentModeHasSPSR) {
5212 cpu->Cpsr = cpu->Spsr_copy; 5211 cpu->Cpsr = cpu->Spsr_copy;
5213 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5212 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
5214 LOAD_NZCVT; 5213 LOAD_NZCVT;
5215 } 5214 }
5216 } else if (inst_cream->S) { 5215 } else if (inst_cream->S) {
@@ -5224,7 +5223,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5224 goto DISPATCH; 5223 goto DISPATCH;
5225 } 5224 }
5226 } 5225 }
5227 cpu->Reg[15] += GET_INST_SIZE(cpu); 5226 cpu->Reg[15] += cpu->GetInstructionSize();
5228 INC_PC(sizeof(rsb_inst)); 5227 INC_PC(sizeof(rsb_inst));
5229 FETCH_INST; 5228 FETCH_INST;
5230 GOTO_NEXT_INST; 5229 GOTO_NEXT_INST;
@@ -5241,7 +5240,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5241 if (inst_cream->S && (inst_cream->Rd == 15)) { 5240 if (inst_cream->S && (inst_cream->Rd == 15)) {
5242 if (CurrentModeHasSPSR) { 5241 if (CurrentModeHasSPSR) {
5243 cpu->Cpsr = cpu->Spsr_copy; 5242 cpu->Cpsr = cpu->Spsr_copy;
5244 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5243 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
5245 LOAD_NZCVT; 5244 LOAD_NZCVT;
5246 } 5245 }
5247 } else if (inst_cream->S) { 5246 } else if (inst_cream->S) {
@@ -5255,7 +5254,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5255 goto DISPATCH; 5254 goto DISPATCH;
5256 } 5255 }
5257 } 5256 }
5258 cpu->Reg[15] += GET_INST_SIZE(cpu); 5257 cpu->Reg[15] += cpu->GetInstructionSize();
5259 INC_PC(sizeof(rsc_inst)); 5258 INC_PC(sizeof(rsc_inst));
5260 FETCH_INST; 5259 FETCH_INST;
5261 GOTO_NEXT_INST; 5260 GOTO_NEXT_INST;
@@ -5363,7 +5362,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5363 } 5362 }
5364 } 5363 }
5365 5364
5366 cpu->Reg[15] += GET_INST_SIZE(cpu); 5365 cpu->Reg[15] += cpu->GetInstructionSize();
5367 INC_PC(sizeof(generic_arm_inst)); 5366 INC_PC(sizeof(generic_arm_inst));
5368 FETCH_INST; 5367 FETCH_INST;
5369 GOTO_NEXT_INST; 5368 GOTO_NEXT_INST;
@@ -5381,7 +5380,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5381 if (inst_cream->S && (inst_cream->Rd == 15)) { 5380 if (inst_cream->S && (inst_cream->Rd == 15)) {
5382 if (CurrentModeHasSPSR) { 5381 if (CurrentModeHasSPSR) {
5383 cpu->Cpsr = cpu->Spsr_copy; 5382 cpu->Cpsr = cpu->Spsr_copy;
5384 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 5383 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
5385 LOAD_NZCVT; 5384 LOAD_NZCVT;
5386 } 5385 }
5387 } else if (inst_cream->S) { 5386 } else if (inst_cream->S) {
@@ -5395,7 +5394,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5395 goto DISPATCH; 5394 goto DISPATCH;
5396 } 5395 }
5397 } 5396 }
5398 cpu->Reg[15] += GET_INST_SIZE(cpu); 5397 cpu->Reg[15] += cpu->GetInstructionSize();
5399 INC_PC(sizeof(sbc_inst)); 5398 INC_PC(sizeof(sbc_inst));
5400 FETCH_INST; 5399 FETCH_INST;
5401 GOTO_NEXT_INST; 5400 GOTO_NEXT_INST;
@@ -5434,7 +5433,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5434 RD = result; 5433 RD = result;
5435 } 5434 }
5436 5435
5437 cpu->Reg[15] += GET_INST_SIZE(cpu); 5436 cpu->Reg[15] += cpu->GetInstructionSize();
5438 INC_PC(sizeof(generic_arm_inst)); 5437 INC_PC(sizeof(generic_arm_inst));
5439 FETCH_INST; 5438 FETCH_INST;
5440 GOTO_NEXT_INST; 5439 GOTO_NEXT_INST;
@@ -5453,7 +5452,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5453 5452
5454 LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); 5453 LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
5455 5454
5456 cpu->Reg[15] += GET_INST_SIZE(cpu); 5455 cpu->Reg[15] += cpu->GetInstructionSize();
5457 INC_PC(sizeof(setend_inst)); 5456 INC_PC(sizeof(setend_inst));
5458 FETCH_INST; 5457 FETCH_INST;
5459 GOTO_NEXT_INST; 5458 GOTO_NEXT_INST;
@@ -5466,7 +5465,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5466 LOG_TRACE(Core_ARM11, "SEV executed."); 5465 LOG_TRACE(Core_ARM11, "SEV executed.");
5467 } 5466 }
5468 5467
5469 cpu->Reg[15] += GET_INST_SIZE(cpu); 5468 cpu->Reg[15] += cpu->GetInstructionSize();
5470 INC_PC_STUB; 5469 INC_PC_STUB;
5471 FETCH_INST; 5470 FETCH_INST;
5472 GOTO_NEXT_INST; 5471 GOTO_NEXT_INST;
@@ -5538,7 +5537,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5538 } 5537 }
5539 } 5538 }
5540 5539
5541 cpu->Reg[15] += GET_INST_SIZE(cpu); 5540 cpu->Reg[15] += cpu->GetInstructionSize();
5542 INC_PC(sizeof(generic_arm_inst)); 5541 INC_PC(sizeof(generic_arm_inst));
5543 FETCH_INST; 5542 FETCH_INST;
5544 GOTO_NEXT_INST; 5543 GOTO_NEXT_INST;
@@ -5563,7 +5562,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5563 if (AddOverflow(operand1 * operand2, RN, RD)) 5562 if (AddOverflow(operand1 * operand2, RN, RD))
5564 cpu->Cpsr |= (1 << 27); 5563 cpu->Cpsr |= (1 << 27);
5565 } 5564 }
5566 cpu->Reg[15] += GET_INST_SIZE(cpu); 5565 cpu->Reg[15] += cpu->GetInstructionSize();
5567 INC_PC(sizeof(smla_inst)); 5566 INC_PC(sizeof(smla_inst));
5568 FETCH_INST; 5567 FETCH_INST;
5569 GOTO_NEXT_INST; 5568 GOTO_NEXT_INST;
@@ -5619,7 +5618,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5619 } 5618 }
5620 } 5619 }
5621 5620
5622 cpu->Reg[15] += GET_INST_SIZE(cpu); 5621 cpu->Reg[15] += cpu->GetInstructionSize();
5623 INC_PC(sizeof(smlad_inst)); 5622 INC_PC(sizeof(smlad_inst));
5624 FETCH_INST; 5623 FETCH_INST;
5625 GOTO_NEXT_INST; 5624 GOTO_NEXT_INST;
@@ -5648,7 +5647,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5648 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 5647 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5649 } 5648 }
5650 } 5649 }
5651 cpu->Reg[15] += GET_INST_SIZE(cpu); 5650 cpu->Reg[15] += cpu->GetInstructionSize();
5652 INC_PC(sizeof(umlal_inst)); 5651 INC_PC(sizeof(umlal_inst));
5653 FETCH_INST; 5652 FETCH_INST;
5654 GOTO_NEXT_INST; 5653 GOTO_NEXT_INST;
@@ -5678,7 +5677,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5678 RDHI = ((dest >> 32) & 0xFFFFFFFF); 5677 RDHI = ((dest >> 32) & 0xFFFFFFFF);
5679 } 5678 }
5680 5679
5681 cpu->Reg[15] += GET_INST_SIZE(cpu); 5680 cpu->Reg[15] += cpu->GetInstructionSize();
5682 INC_PC(sizeof(smlalxy_inst)); 5681 INC_PC(sizeof(smlalxy_inst));
5683 FETCH_INST; 5682 FETCH_INST;
5684 GOTO_NEXT_INST; 5683 GOTO_NEXT_INST;
@@ -5703,7 +5702,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5703 cpu->Cpsr |= (1 << 27); 5702 cpu->Cpsr |= (1 << 27);
5704 } 5703 }
5705 5704
5706 cpu->Reg[15] += GET_INST_SIZE(cpu); 5705 cpu->Reg[15] += cpu->GetInstructionSize();
5707 INC_PC(sizeof(smlad_inst)); 5706 INC_PC(sizeof(smlad_inst));
5708 FETCH_INST; 5707 FETCH_INST;
5709 GOTO_NEXT_INST; 5708 GOTO_NEXT_INST;
@@ -5741,7 +5740,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5741 RDHI = ((result >> 32) & 0xFFFFFFFF); 5740 RDHI = ((result >> 32) & 0xFFFFFFFF);
5742 } 5741 }
5743 5742
5744 cpu->Reg[15] += GET_INST_SIZE(cpu); 5743 cpu->Reg[15] += cpu->GetInstructionSize();
5745 INC_PC(sizeof(smlald_inst)); 5744 INC_PC(sizeof(smlald_inst));
5746 FETCH_INST; 5745 FETCH_INST;
5747 GOTO_NEXT_INST; 5746 GOTO_NEXT_INST;
@@ -5777,7 +5776,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5777 RD = ((result >> 32) & 0xFFFFFFFF); 5776 RD = ((result >> 32) & 0xFFFFFFFF);
5778 } 5777 }
5779 5778
5780 cpu->Reg[15] += GET_INST_SIZE(cpu); 5779 cpu->Reg[15] += cpu->GetInstructionSize();
5781 INC_PC(sizeof(smlad_inst)); 5780 INC_PC(sizeof(smlad_inst));
5782 FETCH_INST; 5781 FETCH_INST;
5783 GOTO_NEXT_INST; 5782 GOTO_NEXT_INST;
@@ -5799,7 +5798,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5799 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); 5798 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5800 RD = operand1 * operand2; 5799 RD = operand1 * operand2;
5801 } 5800 }
5802 cpu->Reg[15] += GET_INST_SIZE(cpu); 5801 cpu->Reg[15] += cpu->GetInstructionSize();
5803 INC_PC(sizeof(smul_inst)); 5802 INC_PC(sizeof(smul_inst));
5804 FETCH_INST; 5803 FETCH_INST;
5805 GOTO_NEXT_INST; 5804 GOTO_NEXT_INST;
@@ -5825,7 +5824,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5825 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 5824 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5826 } 5825 }
5827 } 5826 }
5828 cpu->Reg[15] += GET_INST_SIZE(cpu); 5827 cpu->Reg[15] += cpu->GetInstructionSize();
5829 INC_PC(sizeof(umull_inst)); 5828 INC_PC(sizeof(umull_inst));
5830 FETCH_INST; 5829 FETCH_INST;
5831 GOTO_NEXT_INST; 5830 GOTO_NEXT_INST;
@@ -5841,7 +5840,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5841 s64 result = (s64)rm * (s64)(s32)RN; 5840 s64 result = (s64)rm * (s64)(s32)RN;
5842 RD = BITS(result, 16, 47); 5841 RD = BITS(result, 16, 47);
5843 } 5842 }
5844 cpu->Reg[15] += GET_INST_SIZE(cpu); 5843 cpu->Reg[15] += cpu->GetInstructionSize();
5845 INC_PC(sizeof(smlad_inst)); 5844 INC_PC(sizeof(smlad_inst));
5846 FETCH_INST; 5845 FETCH_INST;
5847 GOTO_NEXT_INST; 5846 GOTO_NEXT_INST;
@@ -5855,10 +5854,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5855 u32 address = 0; 5854 u32 address = 0;
5856 inst_cream->get_addr(cpu, inst_cream->inst, address); 5855 inst_cream->get_addr(cpu, inst_cream->inst, address);
5857 5856
5858 WriteMemory32(cpu, address + 0, cpu->Reg[14]); 5857 cpu->WriteMemory32(address + 0, cpu->Reg[14]);
5859 WriteMemory32(cpu, address + 4, cpu->Spsr_copy); 5858 cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
5860 5859
5861 cpu->Reg[15] += GET_INST_SIZE(cpu); 5860 cpu->Reg[15] += cpu->GetInstructionSize();
5862 INC_PC(sizeof(ldst_inst)); 5861 INC_PC(sizeof(ldst_inst));
5863 FETCH_INST; 5862 FETCH_INST;
5864 GOTO_NEXT_INST; 5863 GOTO_NEXT_INST;
@@ -5891,7 +5890,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5891 RD = rn_val; 5890 RD = rn_val;
5892 } 5891 }
5893 5892
5894 cpu->Reg[15] += GET_INST_SIZE(cpu); 5893 cpu->Reg[15] += cpu->GetInstructionSize();
5895 INC_PC(sizeof(ssat_inst)); 5894 INC_PC(sizeof(ssat_inst));
5896 FETCH_INST; 5895 FETCH_INST;
5897 GOTO_NEXT_INST; 5896 GOTO_NEXT_INST;
@@ -5913,7 +5912,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5913 cpu->Cpsr |= (1 << 27); 5912 cpu->Cpsr |= (1 << 27);
5914 } 5913 }
5915 5914
5916 cpu->Reg[15] += GET_INST_SIZE(cpu); 5915 cpu->Reg[15] += cpu->GetInstructionSize();
5917 INC_PC(sizeof(ssat_inst)); 5916 INC_PC(sizeof(ssat_inst));
5918 FETCH_INST; 5917 FETCH_INST;
5919 GOTO_NEXT_INST; 5918 GOTO_NEXT_INST;
@@ -5923,7 +5922,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5923 { 5922 {
5924 // Instruction not implemented 5923 // Instruction not implemented
5925 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); 5924 //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
5926 cpu->Reg[15] += GET_INST_SIZE(cpu); 5925 cpu->Reg[15] += cpu->GetInstructionSize();
5927 INC_PC(sizeof(stc_inst)); 5926 INC_PC(sizeof(stc_inst));
5928 FETCH_INST; 5927 FETCH_INST;
5929 GOTO_NEXT_INST; 5928 GOTO_NEXT_INST;
@@ -5941,36 +5940,36 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5941 if (BIT(inst_cream->inst, 22) == 1) { 5940 if (BIT(inst_cream->inst, 22) == 1) {
5942 for (int i = 0; i < 13; i++) { 5941 for (int i = 0; i < 13; i++) {
5943 if (BIT(inst_cream->inst, i)) { 5942 if (BIT(inst_cream->inst, i)) {
5944 WriteMemory32(cpu, addr, cpu->Reg[i]); 5943 cpu->WriteMemory32(addr, cpu->Reg[i]);
5945 addr += 4; 5944 addr += 4;
5946 } 5945 }
5947 } 5946 }
5948 if (BIT(inst_cream->inst, 13)) { 5947 if (BIT(inst_cream->inst, 13)) {
5949 if (cpu->Mode == USER32MODE) 5948 if (cpu->Mode == USER32MODE)
5950 WriteMemory32(cpu, addr, cpu->Reg[13]); 5949 cpu->WriteMemory32(addr, cpu->Reg[13]);
5951 else 5950 else
5952 WriteMemory32(cpu, addr, cpu->Reg_usr[0]); 5951 cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
5953 5952
5954 addr += 4; 5953 addr += 4;
5955 } 5954 }
5956 if (BIT(inst_cream->inst, 14)) { 5955 if (BIT(inst_cream->inst, 14)) {
5957 if (cpu->Mode == USER32MODE) 5956 if (cpu->Mode == USER32MODE)
5958 WriteMemory32(cpu, addr, cpu->Reg[14]); 5957 cpu->WriteMemory32(addr, cpu->Reg[14]);
5959 else 5958 else
5960 WriteMemory32(cpu, addr, cpu->Reg_usr[1]); 5959 cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
5961 5960
5962 addr += 4; 5961 addr += 4;
5963 } 5962 }
5964 if (BIT(inst_cream->inst, 15)) { 5963 if (BIT(inst_cream->inst, 15)) {
5965 WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); 5964 cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
5966 } 5965 }
5967 } else { 5966 } else {
5968 for (int i = 0; i < 15; i++) { 5967 for (int i = 0; i < 15; i++) {
5969 if (BIT(inst_cream->inst, i)) { 5968 if (BIT(inst_cream->inst, i)) {
5970 if (i == Rn) 5969 if (i == Rn)
5971 WriteMemory32(cpu, addr, old_RN); 5970 cpu->WriteMemory32(addr, old_RN);
5972 else 5971 else
5973 WriteMemory32(cpu, addr, cpu->Reg[i]); 5972 cpu->WriteMemory32(addr, cpu->Reg[i]);
5974 5973
5975 addr += 4; 5974 addr += 4;
5976 } 5975 }
@@ -5978,10 +5977,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5978 5977
5979 // Check PC reg 5978 // Check PC reg
5980 if (BIT(inst_cream->inst, 15)) 5979 if (BIT(inst_cream->inst, 15))
5981 WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); 5980 cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
5982 } 5981 }
5983 } 5982 }
5984 cpu->Reg[15] += GET_INST_SIZE(cpu); 5983 cpu->Reg[15] += cpu->GetInstructionSize();
5985 INC_PC(sizeof(ldst_inst)); 5984 INC_PC(sizeof(ldst_inst));
5986 FETCH_INST; 5985 FETCH_INST;
5987 GOTO_NEXT_INST; 5986 GOTO_NEXT_INST;
@@ -5999,7 +5998,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5999 } 5998 }
6000 RD = operand2; 5999 RD = operand2;
6001 } 6000 }
6002 cpu->Reg[15] += GET_INST_SIZE(cpu); 6001 cpu->Reg[15] += cpu->GetInstructionSize();
6003 INC_PC(sizeof(sxtb_inst)); 6002 INC_PC(sizeof(sxtb_inst));
6004 FETCH_INST; 6003 FETCH_INST;
6005 GOTO_NEXT_INST; 6004 GOTO_NEXT_INST;
@@ -6011,9 +6010,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6011 inst_cream->get_addr(cpu, inst_cream->inst, addr); 6010 inst_cream->get_addr(cpu, inst_cream->inst, addr);
6012 6011
6013 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6012 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6014 WriteMemory32(cpu, addr, value); 6013 cpu->WriteMemory32(addr, value);
6015 } 6014 }
6016 cpu->Reg[15] += GET_INST_SIZE(cpu); 6015 cpu->Reg[15] += cpu->GetInstructionSize();
6017 INC_PC(sizeof(ldst_inst)); 6016 INC_PC(sizeof(ldst_inst));
6018 FETCH_INST; 6017 FETCH_INST;
6019 GOTO_NEXT_INST; 6018 GOTO_NEXT_INST;
@@ -6024,7 +6023,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6024 uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; 6023 uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
6025 RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; 6024 RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
6026 } 6025 }
6027 cpu->Reg[15] += GET_INST_SIZE(cpu); 6026 cpu->Reg[15] += cpu->GetInstructionSize();
6028 INC_PC(sizeof(uxtb_inst)); 6027 INC_PC(sizeof(uxtb_inst));
6029 FETCH_INST; 6028 FETCH_INST;
6030 GOTO_NEXT_INST; 6029 GOTO_NEXT_INST;
@@ -6037,7 +6036,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6037 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; 6036 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
6038 RD = RN + operand2; 6037 RD = RN + operand2;
6039 } 6038 }
6040 cpu->Reg[15] += GET_INST_SIZE(cpu); 6039 cpu->Reg[15] += cpu->GetInstructionSize();
6041 INC_PC(sizeof(uxtab_inst)); 6040 INC_PC(sizeof(uxtab_inst));
6042 FETCH_INST; 6041 FETCH_INST;
6043 GOTO_NEXT_INST; 6042 GOTO_NEXT_INST;
@@ -6050,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6050 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; 6049 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6051 Memory::Write8(addr, value); 6050 Memory::Write8(addr, value);
6052 } 6051 }
6053 cpu->Reg[15] += GET_INST_SIZE(cpu); 6052 cpu->Reg[15] += cpu->GetInstructionSize();
6054 INC_PC(sizeof(ldst_inst)); 6053 INC_PC(sizeof(ldst_inst));
6055 FETCH_INST; 6054 FETCH_INST;
6056 GOTO_NEXT_INST; 6055 GOTO_NEXT_INST;
@@ -6063,7 +6062,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6063 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; 6062 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6064 Memory::Write8(addr, value); 6063 Memory::Write8(addr, value);
6065 } 6064 }
6066 cpu->Reg[15] += GET_INST_SIZE(cpu); 6065 cpu->Reg[15] += cpu->GetInstructionSize();
6067 INC_PC(sizeof(ldst_inst)); 6066 INC_PC(sizeof(ldst_inst));
6068 FETCH_INST; 6067 FETCH_INST;
6069 GOTO_NEXT_INST; 6068 GOTO_NEXT_INST;
@@ -6076,10 +6075,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6076 6075
6077 // The 3DS doesn't have the Large Physical Access Extension (LPAE) 6076 // The 3DS doesn't have the Large Physical Access Extension (LPAE)
6078 // so STRD wouldn't store these as a single write. 6077 // so STRD wouldn't store these as a single write.
6079 WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); 6078 cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
6080 WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); 6079 cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
6081 } 6080 }
6082 cpu->Reg[15] += GET_INST_SIZE(cpu); 6081 cpu->Reg[15] += cpu->GetInstructionSize();
6083 INC_PC(sizeof(ldst_inst)); 6082 INC_PC(sizeof(ldst_inst));
6084 FETCH_INST; 6083 FETCH_INST;
6085 GOTO_NEXT_INST; 6084 GOTO_NEXT_INST;
@@ -6094,14 +6093,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6094 remove_exclusive(cpu, write_addr); 6093 remove_exclusive(cpu, write_addr);
6095 cpu->exclusive_state = 0; 6094 cpu->exclusive_state = 0;
6096 6095
6097 WriteMemory32(cpu, write_addr, RM); 6096 cpu->WriteMemory32(write_addr, RM);
6098 RD = 0; 6097 RD = 0;
6099 } else { 6098 } else {
6100 // Failed to write due to mutex access 6099 // Failed to write due to mutex access
6101 RD = 1; 6100 RD = 1;
6102 } 6101 }
6103 } 6102 }
6104 cpu->Reg[15] += GET_INST_SIZE(cpu); 6103 cpu->Reg[15] += cpu->GetInstructionSize();
6105 INC_PC(sizeof(generic_arm_inst)); 6104 INC_PC(sizeof(generic_arm_inst));
6106 FETCH_INST; 6105 FETCH_INST;
6107 GOTO_NEXT_INST; 6106 GOTO_NEXT_INST;
@@ -6123,7 +6122,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6123 RD = 1; 6122 RD = 1;
6124 } 6123 }
6125 } 6124 }
6126 cpu->Reg[15] += GET_INST_SIZE(cpu); 6125 cpu->Reg[15] += cpu->GetInstructionSize();
6127 INC_PC(sizeof(generic_arm_inst)); 6126 INC_PC(sizeof(generic_arm_inst));
6128 FETCH_INST; 6127 FETCH_INST;
6129 GOTO_NEXT_INST; 6128 GOTO_NEXT_INST;
@@ -6142,12 +6141,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6142 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; 6141 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
6143 u64 value; 6142 u64 value;
6144 6143
6145 if (InBigEndianMode(cpu)) 6144 if (cpu->InBigEndianMode())
6146 value = (((u64)rt << 32) | rt2); 6145 value = (((u64)rt << 32) | rt2);
6147 else 6146 else
6148 value = (((u64)rt2 << 32) | rt); 6147 value = (((u64)rt2 << 32) | rt);
6149 6148
6150 WriteMemory64(cpu, write_addr, value); 6149 cpu->WriteMemory64(write_addr, value);
6151 RD = 0; 6150 RD = 0;
6152 } 6151 }
6153 else { 6152 else {
@@ -6155,7 +6154,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6155 RD = 1; 6154 RD = 1;
6156 } 6155 }
6157 } 6156 }
6158 cpu->Reg[15] += GET_INST_SIZE(cpu); 6157 cpu->Reg[15] += cpu->GetInstructionSize();
6159 INC_PC(sizeof(generic_arm_inst)); 6158 INC_PC(sizeof(generic_arm_inst));
6160 FETCH_INST; 6159 FETCH_INST;
6161 GOTO_NEXT_INST; 6160 GOTO_NEXT_INST;
@@ -6170,14 +6169,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6170 remove_exclusive(cpu, write_addr); 6169 remove_exclusive(cpu, write_addr);
6171 cpu->exclusive_state = 0; 6170 cpu->exclusive_state = 0;
6172 6171
6173 WriteMemory16(cpu, write_addr, RM); 6172 cpu->WriteMemory16(write_addr, RM);
6174 RD = 0; 6173 RD = 0;
6175 } else { 6174 } else {
6176 // Failed to write due to mutex access 6175 // Failed to write due to mutex access
6177 RD = 1; 6176 RD = 1;
6178 } 6177 }
6179 } 6178 }
6180 cpu->Reg[15] += GET_INST_SIZE(cpu); 6179 cpu->Reg[15] += cpu->GetInstructionSize();
6181 INC_PC(sizeof(generic_arm_inst)); 6180 INC_PC(sizeof(generic_arm_inst));
6182 FETCH_INST; 6181 FETCH_INST;
6183 GOTO_NEXT_INST; 6182 GOTO_NEXT_INST;
@@ -6189,9 +6188,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6189 inst_cream->get_addr(cpu, inst_cream->inst, addr); 6188 inst_cream->get_addr(cpu, inst_cream->inst, addr);
6190 6189
6191 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; 6190 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6192 WriteMemory16(cpu, addr, value); 6191 cpu->WriteMemory16(addr, value);
6193 } 6192 }
6194 cpu->Reg[15] += GET_INST_SIZE(cpu); 6193 cpu->Reg[15] += cpu->GetInstructionSize();
6195 INC_PC(sizeof(ldst_inst)); 6194 INC_PC(sizeof(ldst_inst));
6196 FETCH_INST; 6195 FETCH_INST;
6197 GOTO_NEXT_INST; 6196 GOTO_NEXT_INST;
@@ -6203,9 +6202,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6203 inst_cream->get_addr(cpu, inst_cream->inst, addr); 6202 inst_cream->get_addr(cpu, inst_cream->inst, addr);
6204 6203
6205 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6204 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6206 WriteMemory32(cpu, addr, value); 6205 cpu->WriteMemory32(addr, value);
6207 } 6206 }
6208 cpu->Reg[15] += GET_INST_SIZE(cpu); 6207 cpu->Reg[15] += cpu->GetInstructionSize();
6209 INC_PC(sizeof(ldst_inst)); 6208 INC_PC(sizeof(ldst_inst));
6210 FETCH_INST; 6209 FETCH_INST;
6211 GOTO_NEXT_INST; 6210 GOTO_NEXT_INST;
@@ -6226,7 +6225,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6226 if (inst_cream->S && (inst_cream->Rd == 15)) { 6225 if (inst_cream->S && (inst_cream->Rd == 15)) {
6227 if (CurrentModeHasSPSR) { 6226 if (CurrentModeHasSPSR) {
6228 cpu->Cpsr = cpu->Spsr_copy; 6227 cpu->Cpsr = cpu->Spsr_copy;
6229 switch_mode(cpu, cpu->Spsr_copy & 0x1f); 6228 cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
6230 LOAD_NZCVT; 6229 LOAD_NZCVT;
6231 } 6230 }
6232 } else if (inst_cream->S) { 6231 } else if (inst_cream->S) {
@@ -6240,7 +6239,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6240 goto DISPATCH; 6239 goto DISPATCH;
6241 } 6240 }
6242 } 6241 }
6243 cpu->Reg[15] += GET_INST_SIZE(cpu); 6242 cpu->Reg[15] += cpu->GetInstructionSize();
6244 INC_PC(sizeof(sub_inst)); 6243 INC_PC(sizeof(sub_inst));
6245 FETCH_INST; 6244 FETCH_INST;
6246 GOTO_NEXT_INST; 6245 GOTO_NEXT_INST;
@@ -6252,7 +6251,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6252 SVC::CallSVC(inst_cream->num & 0xFFFF); 6251 SVC::CallSVC(inst_cream->num & 0xFFFF);
6253 } 6252 }
6254 6253
6255 cpu->Reg[15] += GET_INST_SIZE(cpu); 6254 cpu->Reg[15] += cpu->GetInstructionSize();
6256 INC_PC(sizeof(swi_inst)); 6255 INC_PC(sizeof(swi_inst));
6257 FETCH_INST; 6256 FETCH_INST;
6258 GOTO_NEXT_INST; 6257 GOTO_NEXT_INST;
@@ -6263,12 +6262,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6263 swp_inst* inst_cream = (swp_inst*)inst_base->component; 6262 swp_inst* inst_cream = (swp_inst*)inst_base->component;
6264 6263
6265 addr = RN; 6264 addr = RN;
6266 unsigned int value = ReadMemory32(cpu, addr); 6265 unsigned int value = cpu->ReadMemory32(addr);
6267 WriteMemory32(cpu, addr, RM); 6266 cpu->WriteMemory32(addr, RM);
6268 6267
6269 RD = value; 6268 RD = value;
6270 } 6269 }
6271 cpu->Reg[15] += GET_INST_SIZE(cpu); 6270 cpu->Reg[15] += cpu->GetInstructionSize();
6272 INC_PC(sizeof(swp_inst)); 6271 INC_PC(sizeof(swp_inst));
6273 FETCH_INST; 6272 FETCH_INST;
6274 GOTO_NEXT_INST; 6273 GOTO_NEXT_INST;
@@ -6282,7 +6281,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6282 Memory::Write8(addr, (RM & 0xFF)); 6281 Memory::Write8(addr, (RM & 0xFF));
6283 RD = value; 6282 RD = value;
6284 } 6283 }
6285 cpu->Reg[15] += GET_INST_SIZE(cpu); 6284 cpu->Reg[15] += cpu->GetInstructionSize();
6286 INC_PC(sizeof(swp_inst)); 6285 INC_PC(sizeof(swp_inst));
6287 FETCH_INST; 6286 FETCH_INST;
6288 GOTO_NEXT_INST; 6287 GOTO_NEXT_INST;
@@ -6298,7 +6297,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6298 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; 6297 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
6299 RD = RN + operand2; 6298 RD = RN + operand2;
6300 } 6299 }
6301 cpu->Reg[15] += GET_INST_SIZE(cpu); 6300 cpu->Reg[15] += cpu->GetInstructionSize();
6302 INC_PC(sizeof(uxtab_inst)); 6301 INC_PC(sizeof(uxtab_inst));
6303 FETCH_INST; 6302 FETCH_INST;
6304 GOTO_NEXT_INST; 6303 GOTO_NEXT_INST;
@@ -6331,7 +6330,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6331 } 6330 }
6332 } 6331 }
6333 6332
6334 cpu->Reg[15] += GET_INST_SIZE(cpu); 6333 cpu->Reg[15] += cpu->GetInstructionSize();
6335 INC_PC(sizeof(sxtab_inst)); 6334 INC_PC(sizeof(sxtab_inst));
6336 FETCH_INST; 6335 FETCH_INST;
6337 GOTO_NEXT_INST; 6336 GOTO_NEXT_INST;
@@ -6347,7 +6346,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6347 operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; 6346 operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
6348 RD = RN + operand2; 6347 RD = RN + operand2;
6349 } 6348 }
6350 cpu->Reg[15] += GET_INST_SIZE(cpu); 6349 cpu->Reg[15] += cpu->GetInstructionSize();
6351 INC_PC(sizeof(sxtah_inst)); 6350 INC_PC(sizeof(sxtah_inst));
6352 FETCH_INST; 6351 FETCH_INST;
6353 GOTO_NEXT_INST; 6352 GOTO_NEXT_INST;
@@ -6362,7 +6361,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6362 u32 rop = SHIFTER_OPERAND; 6361 u32 rop = SHIFTER_OPERAND;
6363 6362
6364 if (inst_cream->Rn == 15) 6363 if (inst_cream->Rn == 15)
6365 lop += GET_INST_SIZE(cpu) * 2; 6364 lop += cpu->GetInstructionSize() * 2;
6366 6365
6367 u32 result = lop ^ rop; 6366 u32 result = lop ^ rop;
6368 6367
@@ -6370,7 +6369,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6370 UPDATE_ZFLAG(result); 6369 UPDATE_ZFLAG(result);
6371 UPDATE_CFLAG_WITH_SC; 6370 UPDATE_CFLAG_WITH_SC;
6372 } 6371 }
6373 cpu->Reg[15] += GET_INST_SIZE(cpu); 6372 cpu->Reg[15] += cpu->GetInstructionSize();
6374 INC_PC(sizeof(teq_inst)); 6373 INC_PC(sizeof(teq_inst));
6375 FETCH_INST; 6374 FETCH_INST;
6376 GOTO_NEXT_INST; 6375 GOTO_NEXT_INST;
@@ -6384,7 +6383,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6384 u32 rop = SHIFTER_OPERAND; 6383 u32 rop = SHIFTER_OPERAND;
6385 6384
6386 if (inst_cream->Rn == 15) 6385 if (inst_cream->Rn == 15)
6387 lop += GET_INST_SIZE(cpu) * 2; 6386 lop += cpu->GetInstructionSize() * 2;
6388 6387
6389 u32 result = lop & rop; 6388 u32 result = lop & rop;
6390 6389
@@ -6392,7 +6391,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6392 UPDATE_ZFLAG(result); 6391 UPDATE_ZFLAG(result);
6393 UPDATE_CFLAG_WITH_SC; 6392 UPDATE_CFLAG_WITH_SC;
6394 } 6393 }
6395 cpu->Reg[15] += GET_INST_SIZE(cpu); 6394 cpu->Reg[15] += cpu->GetInstructionSize();
6396 INC_PC(sizeof(tst_inst)); 6395 INC_PC(sizeof(tst_inst));
6397 FETCH_INST; 6396 FETCH_INST;
6398 GOTO_NEXT_INST; 6397 GOTO_NEXT_INST;
@@ -6563,7 +6562,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6563 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); 6562 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
6564 } 6563 }
6565 6564
6566 cpu->Reg[15] += GET_INST_SIZE(cpu); 6565 cpu->Reg[15] += cpu->GetInstructionSize();
6567 INC_PC(sizeof(generic_arm_inst)); 6566 INC_PC(sizeof(generic_arm_inst));
6568 FETCH_INST; 6567 FETCH_INST;
6569 GOTO_NEXT_INST; 6568 GOTO_NEXT_INST;
@@ -6643,7 +6642,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6643 } 6642 }
6644 } 6643 }
6645 6644
6646 cpu->Reg[15] += GET_INST_SIZE(cpu); 6645 cpu->Reg[15] += cpu->GetInstructionSize();
6647 INC_PC(sizeof(generic_arm_inst)); 6646 INC_PC(sizeof(generic_arm_inst));
6648 FETCH_INST; 6647 FETCH_INST;
6649 GOTO_NEXT_INST; 6648 GOTO_NEXT_INST;
@@ -6662,7 +6661,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6662 RDLO = (result & 0xFFFFFFFF); 6661 RDLO = (result & 0xFFFFFFFF);
6663 RDHI = ((result >> 32) & 0xFFFFFFFF); 6662 RDHI = ((result >> 32) & 0xFFFFFFFF);
6664 } 6663 }
6665 cpu->Reg[15] += GET_INST_SIZE(cpu); 6664 cpu->Reg[15] += cpu->GetInstructionSize();
6666 INC_PC(sizeof(umaal_inst)); 6665 INC_PC(sizeof(umaal_inst));
6667 FETCH_INST; 6666 FETCH_INST;
6668 GOTO_NEXT_INST; 6667 GOTO_NEXT_INST;
@@ -6685,7 +6684,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6685 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 6684 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6686 } 6685 }
6687 } 6686 }
6688 cpu->Reg[15] += GET_INST_SIZE(cpu); 6687 cpu->Reg[15] += cpu->GetInstructionSize();
6689 INC_PC(sizeof(umlal_inst)); 6688 INC_PC(sizeof(umlal_inst));
6690 FETCH_INST; 6689 FETCH_INST;
6691 GOTO_NEXT_INST; 6690 GOTO_NEXT_INST;
@@ -6705,7 +6704,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6705 cpu->ZFlag = (RDHI == 0 && RDLO == 0); 6704 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6706 } 6705 }
6707 } 6706 }
6708 cpu->Reg[15] += GET_INST_SIZE(cpu); 6707 cpu->Reg[15] += cpu->GetInstructionSize();
6709 INC_PC(sizeof(umull_inst)); 6708 INC_PC(sizeof(umull_inst));
6710 FETCH_INST; 6709 FETCH_INST;
6711 GOTO_NEXT_INST; 6710 GOTO_NEXT_INST;
@@ -6733,7 +6732,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6733 { 6732 {
6734 bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; 6733 bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
6735 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; 6734 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
6736 cpu->Reg[15] += GET_INST_SIZE(cpu); 6735 cpu->Reg[15] += cpu->GetInstructionSize();
6737 INC_PC(sizeof(bl_1_thumb)); 6736 INC_PC(sizeof(bl_1_thumb));
6738 FETCH_INST; 6737 FETCH_INST;
6739 GOTO_NEXT_INST; 6738 GOTO_NEXT_INST;
@@ -6814,7 +6813,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6814 RD = ((lo_val & 0xFFFF) | hi_val << 16); 6813 RD = ((lo_val & 0xFFFF) | hi_val << 16);
6815 } 6814 }
6816 6815
6817 cpu->Reg[15] += GET_INST_SIZE(cpu); 6816 cpu->Reg[15] += cpu->GetInstructionSize();
6818 INC_PC(sizeof(generic_arm_inst)); 6817 INC_PC(sizeof(generic_arm_inst));
6819 FETCH_INST; 6818 FETCH_INST;
6820 GOTO_NEXT_INST; 6819 GOTO_NEXT_INST;
@@ -6844,7 +6843,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6844 RD = finalDif; 6843 RD = finalDif;
6845 } 6844 }
6846 6845
6847 cpu->Reg[15] += GET_INST_SIZE(cpu); 6846 cpu->Reg[15] += cpu->GetInstructionSize();
6848 INC_PC(sizeof(generic_arm_inst)); 6847 INC_PC(sizeof(generic_arm_inst));
6849 FETCH_INST; 6848 FETCH_INST;
6850 GOTO_NEXT_INST; 6849 GOTO_NEXT_INST;
@@ -6877,7 +6876,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6877 RD = rn_val; 6876 RD = rn_val;
6878 } 6877 }
6879 6878
6880 cpu->Reg[15] += GET_INST_SIZE(cpu); 6879 cpu->Reg[15] += cpu->GetInstructionSize();
6881 INC_PC(sizeof(ssat_inst)); 6880 INC_PC(sizeof(ssat_inst));
6882 FETCH_INST; 6881 FETCH_INST;
6883 GOTO_NEXT_INST; 6882 GOTO_NEXT_INST;
@@ -6899,7 +6898,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6899 cpu->Cpsr |= (1 << 27); 6898 cpu->Cpsr |= (1 << 27);
6900 } 6899 }
6901 6900
6902 cpu->Reg[15] += GET_INST_SIZE(cpu); 6901 cpu->Reg[15] += cpu->GetInstructionSize();
6903 INC_PC(sizeof(ssat_inst)); 6902 INC_PC(sizeof(ssat_inst));
6904 FETCH_INST; 6903 FETCH_INST;
6905 GOTO_NEXT_INST; 6904 GOTO_NEXT_INST;
@@ -6930,7 +6929,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6930 } 6929 }
6931 } 6930 }
6932 6931
6933 cpu->Reg[15] += GET_INST_SIZE(cpu); 6932 cpu->Reg[15] += cpu->GetInstructionSize();
6934 INC_PC(sizeof(uxtab_inst)); 6933 INC_PC(sizeof(uxtab_inst));
6935 FETCH_INST; 6934 FETCH_INST;
6936 GOTO_NEXT_INST; 6935 GOTO_NEXT_INST;
@@ -6943,7 +6942,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6943 LOG_TRACE(Core_ARM11, "WFE executed."); 6942 LOG_TRACE(Core_ARM11, "WFE executed.");
6944 } 6943 }
6945 6944
6946 cpu->Reg[15] += GET_INST_SIZE(cpu); 6945 cpu->Reg[15] += cpu->GetInstructionSize();
6947 INC_PC_STUB; 6946 INC_PC_STUB;
6948 FETCH_INST; 6947 FETCH_INST;
6949 GOTO_NEXT_INST; 6948 GOTO_NEXT_INST;
@@ -6956,7 +6955,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6956 LOG_TRACE(Core_ARM11, "WFI executed."); 6955 LOG_TRACE(Core_ARM11, "WFI executed.");
6957 } 6956 }
6958 6957
6959 cpu->Reg[15] += GET_INST_SIZE(cpu); 6958 cpu->Reg[15] += cpu->GetInstructionSize();
6960 INC_PC_STUB; 6959 INC_PC_STUB;
6961 FETCH_INST; 6960 FETCH_INST;
6962 GOTO_NEXT_INST; 6961 GOTO_NEXT_INST;
@@ -6969,7 +6968,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6969 LOG_TRACE(Core_ARM11, "YIELD executed."); 6968 LOG_TRACE(Core_ARM11, "YIELD executed.");
6970 } 6969 }
6971 6970
6972 cpu->Reg[15] += GET_INST_SIZE(cpu); 6971 cpu->Reg[15] += cpu->GetInstructionSize();
6973 INC_PC_STUB; 6972 INC_PC_STUB;
6974 FETCH_INST; 6973 FETCH_INST;
6975 GOTO_NEXT_INST; 6974 GOTO_NEXT_INST;
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
index 1c324d29c..7a46dcc94 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.h
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h
@@ -4,6 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/arm/skyeye_common/armdefs.h" 7struct ARMul_State;
8 8
9unsigned InterpreterMainLoop(ARMul_State* state); 9unsigned InterpreterMainLoop(ARMul_State* state);
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 5a9a6a788..000000000
--- a/src/core/arm/dyncom/arm_dyncom_run.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
1// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/arm/dyncom/arm_dyncom_run.h"
6#include "core/arm/skyeye_common/armdefs.h"
7
8void switch_mode(ARMul_State* core, uint32_t mode) {
9 if (core->Mode == mode)
10 return;
11
12 if (mode != USERBANK) {
13 switch (core->Mode) {
14 case SYSTEM32MODE: // Shares registers with user mode
15 case USER32MODE:
16 core->Reg_usr[0] = core->Reg[13];
17 core->Reg_usr[1] = core->Reg[14];
18 break;
19 case IRQ32MODE:
20 core->Reg_irq[0] = core->Reg[13];
21 core->Reg_irq[1] = core->Reg[14];
22 core->Spsr[IRQBANK] = core->Spsr_copy;
23 break;
24 case SVC32MODE:
25 core->Reg_svc[0] = core->Reg[13];
26 core->Reg_svc[1] = core->Reg[14];
27 core->Spsr[SVCBANK] = core->Spsr_copy;
28 break;
29 case ABORT32MODE:
30 core->Reg_abort[0] = core->Reg[13];
31 core->Reg_abort[1] = core->Reg[14];
32 core->Spsr[ABORTBANK] = core->Spsr_copy;
33 break;
34 case UNDEF32MODE:
35 core->Reg_undef[0] = core->Reg[13];
36 core->Reg_undef[1] = core->Reg[14];
37 core->Spsr[UNDEFBANK] = core->Spsr_copy;
38 break;
39 case FIQ32MODE:
40 core->Reg_firq[0] = core->Reg[13];
41 core->Reg_firq[1] = core->Reg[14];
42 core->Spsr[FIQBANK] = core->Spsr_copy;
43 break;
44 }
45
46 switch (mode) {
47 case USER32MODE:
48 core->Reg[13] = core->Reg_usr[0];
49 core->Reg[14] = core->Reg_usr[1];
50 core->Bank = USERBANK;
51 break;
52 case IRQ32MODE:
53 core->Reg[13] = core->Reg_irq[0];
54 core->Reg[14] = core->Reg_irq[1];
55 core->Spsr_copy = core->Spsr[IRQBANK];
56 core->Bank = IRQBANK;
57 break;
58 case SVC32MODE:
59 core->Reg[13] = core->Reg_svc[0];
60 core->Reg[14] = core->Reg_svc[1];
61 core->Spsr_copy = core->Spsr[SVCBANK];
62 core->Bank = SVCBANK;
63 break;
64 case ABORT32MODE:
65 core->Reg[13] = core->Reg_abort[0];
66 core->Reg[14] = core->Reg_abort[1];
67 core->Spsr_copy = core->Spsr[ABORTBANK];
68 core->Bank = ABORTBANK;
69 break;
70 case UNDEF32MODE:
71 core->Reg[13] = core->Reg_undef[0];
72 core->Reg[14] = core->Reg_undef[1];
73 core->Spsr_copy = core->Spsr[UNDEFBANK];
74 core->Bank = UNDEFBANK;
75 break;
76 case FIQ32MODE:
77 core->Reg[13] = core->Reg_firq[0];
78 core->Reg[14] = core->Reg_firq[1];
79 core->Spsr_copy = core->Spsr[FIQBANK];
80 core->Bank = FIQBANK;
81 break;
82 case SYSTEM32MODE: // Shares registers with user mode.
83 core->Reg[13] = core->Reg_usr[0];
84 core->Reg[14] = core->Reg_usr[1];
85 core->Bank = SYSTEMBANK;
86 break;
87 }
88
89 // Set the mode bits in the APSR
90 core->Cpsr = (core->Cpsr & ~core->Mode) | mode;
91 core->Mode = mode;
92 }
93}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index 85774c565..13bef17fc 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -18,40 +18,31 @@
18 18
19#pragma once 19#pragma once
20 20
21#include "core/arm/skyeye_common/armdefs.h" 21#include "core/arm/skyeye_common/armstate.h"
22
23void switch_mode(ARMul_State* core, uint32_t mode);
24
25// Note that for the 3DS, a Thumb instruction will only ever be
26// two bytes in size. Thus we don't need to worry about ThumbEE
27// or Thumb-2 where instructions can be 4 bytes in length.
28static inline u32 GET_INST_SIZE(ARMul_State* core) {
29 return core->TFlag? 2 : 4;
30}
31 22
32/** 23/**
33 * Checks if the PC is being read, and if so, word-aligns it. 24 * Checks if the PC is being read, and if so, word-aligns it.
34 * Used with address calculations. 25 * Used with address calculations.
35 * 26 *
36 * @param core The ARM CPU state instance. 27 * @param cpu The ARM CPU state instance.
37 * @param Rn The register being read. 28 * @param Rn The register being read.
38 * 29 *
39 * @return If the PC is being read, then the word-aligned PC value is returned. 30 * @return If the PC is being read, then the word-aligned PC value is returned.
40 * If the PC is not being read, then the value stored in the register is returned. 31 * If the PC is not being read, then the value stored in the register is returned.
41 */ 32 */
42static inline u32 CHECK_READ_REG15_WA(ARMul_State* core, int Rn) { 33static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) {
43 return (Rn == 15) ? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; 34 return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
44} 35}
45 36
46/** 37/**
47 * Reads the PC. Used for data processing operations that use the PC. 38 * Reads the PC. Used for data processing operations that use the PC.
48 * 39 *
49 * @param core The ARM CPU state instance. 40 * @param cpu The ARM CPU state instance.
50 * @param Rn The register being read. 41 * @param Rn The register being read.
51 * 42 *
52 * @return If the PC is being read, then the incremented PC value is returned. 43 * @return If the PC is being read, then the incremented PC value is returned.
53 * If the PC is not being read, then the values stored in the register is returned. 44 * If the PC is not being read, then the values stored in the register is returned.
54 */ 45 */
55static inline u32 CHECK_READ_REG15(ARMul_State* core, int Rn) { 46static inline u32 CHECK_READ_REG15(ARMul_State* cpu, int Rn) {
56 return (Rn == 15) ? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; 47 return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
57} 48}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index f10a5b70f..2860af376 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -6,6 +6,7 @@
6// ARM instruction, and using the existing ARM simulator. 6// ARM instruction, and using the existing ARM simulator.
7 7
8#include "core/arm/dyncom/arm_dyncom_thumb.h" 8#include "core/arm/dyncom/arm_dyncom_thumb.h"
9#include "core/arm/skyeye_common/armsupp.h"
9 10
10// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, 11// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field,
11// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions 12// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
@@ -13,7 +14,7 @@
13 14
14tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { 15tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
15 tdstate valid = t_uninitialized; 16 tdstate valid = t_uninitialized;
16 ARMword tinstr = instr; 17 u32 tinstr = instr;
17 18
18 // The endian should be judge here 19 // The endian should be judge here
19 if((addr & 0x3) != 0) 20 if((addr & 0x3) != 0)
@@ -36,7 +37,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
36 37
37 case 3: // ADD/SUB 38 case 3: // ADD/SUB
38 { 39 {
39 static const ARMword subset[4] = { 40 static const u32 subset[4] = {
40 0xE0900000, // ADDS Rd,Rs,Rn 41 0xE0900000, // ADDS Rd,Rs,Rn
41 0xE0500000, // SUBS Rd,Rs,Rn 42 0xE0500000, // SUBS Rd,Rs,Rn
42 0xE2900000, // ADDS Rd,Rs,#imm3 43 0xE2900000, // ADDS Rd,Rs,#imm3
@@ -55,7 +56,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
55 case 6: // ADD 56 case 6: // ADD
56 case 7: // SUB 57 case 7: // SUB
57 { 58 {
58 static const ARMword subset[4] = { 59 static const u32 subset[4] = {
59 0xE3B00000, // MOVS Rd,#imm8 60 0xE3B00000, // MOVS Rd,#imm8
60 0xE3500000, // CMP Rd,#imm8 61 0xE3500000, // CMP Rd,#imm8
61 0xE2900000, // ADDS Rd,Rd,#imm8 62 0xE2900000, // ADDS Rd,Rd,#imm8
@@ -84,7 +85,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
84 }; 85 };
85 86
86 static const struct { 87 static const struct {
87 ARMword opcode; 88 u32 opcode;
88 otype type; 89 otype type;
89 } subset[16] = { 90 } subset[16] = {
90 { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs 91 { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs
@@ -129,8 +130,8 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
129 break; 130 break;
130 } 131 }
131 } else { 132 } else {
132 ARMword Rd = ((tinstr & 0x0007) >> 0); 133 u32 Rd = ((tinstr & 0x0007) >> 0);
133 ARMword Rs = ((tinstr & 0x0078) >> 3); 134 u32 Rs = ((tinstr & 0x0078) >> 3);
134 135
135 if (tinstr & (1 << 7)) 136 if (tinstr & (1 << 7))
136 Rd += 8; 137 Rd += 8;
@@ -184,7 +185,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
184 case 10: 185 case 10:
185 case 11: 186 case 11:
186 { 187 {
187 static const ARMword subset[8] = { 188 static const u32 subset[8] = {
188 0xE7800000, // STR Rd,[Rb,Ro] 189 0xE7800000, // STR Rd,[Rb,Ro]
189 0xE18000B0, // STRH Rd,[Rb,Ro] 190 0xE18000B0, // STRH Rd,[Rb,Ro]
190 0xE7C00000, // STRB Rd,[Rb,Ro] 191 0xE7C00000, // STRB Rd,[Rb,Ro]
@@ -207,7 +208,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
207 case 14: // STRB Rd,[Rb,#imm5] 208 case 14: // STRB Rd,[Rb,#imm5]
208 case 15: // LDRB Rd,[Rb,#imm5] 209 case 15: // LDRB Rd,[Rb,#imm5]
209 { 210 {
210 static const ARMword subset[4] = { 211 static const u32 subset[4] = {
211 0xE5800000, // STR Rd,[Rb,#imm5] 212 0xE5800000, // STR Rd,[Rb,#imm5]
212 0xE5900000, // LDR Rd,[Rb,#imm5] 213 0xE5900000, // LDR Rd,[Rb,#imm5]
213 0xE5C00000, // STRB Rd,[Rb,#imm5] 214 0xE5C00000, // STRB Rd,[Rb,#imm5]
@@ -274,7 +275,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
274 | BITS(tinstr, 0, 3) // imm4 field; 275 | BITS(tinstr, 0, 3) // imm4 field;
275 | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 276 | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12
276 } else if ((tinstr & 0x0F00) == 0x0200) { 277 } else if ((tinstr & 0x0F00) == 0x0200) {
277 static const ARMword subset[4] = { 278 static const u32 subset[4] = {
278 0xE6BF0070, // SXTH 279 0xE6BF0070, // SXTH
279 0xE6AF0070, // SXTB 280 0xE6AF0070, // SXTB
280 0xE6FF0070, // UXTH 281 0xE6FF0070, // UXTH
@@ -298,7 +299,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
298 | (BIT(tinstr, 4) << 18); // enable bit 299 | (BIT(tinstr, 4) << 18); // enable bit
299 } 300 }
300 } else if ((tinstr & 0x0F00) == 0x0a00) { 301 } else if ((tinstr & 0x0F00) == 0x0a00) {
301 static const ARMword subset[3] = { 302 static const u32 subset[3] = {
302 0xE6BF0F30, // REV 303 0xE6BF0F30, // REV
303 0xE6BF0FB0, // REV16 304 0xE6BF0FB0, // REV16
304 0xE6FF0FB0, // REVSH 305 0xE6FF0FB0, // REVSH
@@ -308,7 +309,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
308 | (BITS(tinstr, 0, 2) << 12) // Rd 309 | (BITS(tinstr, 0, 2) << 12) // Rd
309 | BITS(tinstr, 3, 5); // Rm 310 | BITS(tinstr, 3, 5); // Rm
310 } else { 311 } else {
311 static const ARMword subset[4] = { 312 static const u32 subset[4] = {
312 0xE92D0000, // STMDB sp!,{rlist} 313 0xE92D0000, // STMDB sp!,{rlist}
313 0xE92D4000, // STMDB sp!,{rlist,lr} 314 0xE92D4000, // STMDB sp!,{rlist,lr}
314 0xE8BD0000, // LDMIA sp!,{rlist} 315 0xE8BD0000, // LDMIA sp!,{rlist}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 8394ff156..c06f09580 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -26,7 +26,7 @@
26 26
27#pragma once 27#pragma once
28 28
29#include "core/arm/skyeye_common/armdefs.h" 29#include "common/common_types.h"
30 30
31enum tdstate { 31enum tdstate {
32 t_undefined, // Undefined Thumb instruction 32 t_undefined, // Undefined Thumb instruction
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
deleted file mode 100644
index 4f7a48fab..000000000
--- a/src/core/arm/interpreter/arminit.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
1/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include <cstring>
19#include "core/arm/skyeye_common/armdefs.h"
20#include "core/arm/skyeye_common/vfp/vfp.h"
21
22/***************************************************************************\
23* Returns a new instantiation of the ARMulator's state *
24\***************************************************************************/
25ARMul_State* ARMul_NewState(ARMul_State* state)
26{
27 state->Emulate = RUN;
28 state->Mode = USER32MODE;
29
30 state->lateabtSig = HIGH;
31 state->bigendSig = LOW;
32
33 return state;
34}
35
36/***************************************************************************\
37* Call this routine to set ARMulator to model a certain processor *
38\***************************************************************************/
39
40void ARMul_SelectProcessor(ARMul_State* state, unsigned properties)
41{
42 state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0;
43 state->is_v5 = (properties & ARM_v5_Prop) != 0;
44 state->is_v5e = (properties & ARM_v5e_Prop) != 0;
45 state->is_v6 = (properties & ARM_v6_Prop) != 0;
46 state->is_v7 = (properties & ARM_v7_Prop) != 0;
47}
48
49// Resets certain MPCore CP15 values to their ARM-defined reset values.
50static void ResetMPCoreCP15Registers(ARMul_State* cpu)
51{
52 // c0
53 cpu->CP15[CP15_MAIN_ID] = 0x410FB024;
54 cpu->CP15[CP15_TLB_TYPE] = 0x00000800;
55 cpu->CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
56 cpu->CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
57 cpu->CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
58 cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
59 cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
60 cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
61 cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
62 cpu->CP15[CP15_ISA_FEATURE_0] = 0x00100011;
63 cpu->CP15[CP15_ISA_FEATURE_1] = 0x12002111;
64 cpu->CP15[CP15_ISA_FEATURE_2] = 0x11221011;
65 cpu->CP15[CP15_ISA_FEATURE_3] = 0x01102131;
66 cpu->CP15[CP15_ISA_FEATURE_4] = 0x00000141;
67
68 // c1
69 cpu->CP15[CP15_CONTROL] = 0x00054078;
70 cpu->CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
71 cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
72
73 // c2
74 cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
75 cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
76 cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
77
78 // c3
79 cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
80
81 // c7
82 cpu->CP15[CP15_PHYS_ADDRESS] = 0x00000000;
83
84 // c9
85 cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
86
87 // c10
88 cpu->CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
89 cpu->CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
90 cpu->CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
91
92 // c13
93 cpu->CP15[CP15_PID] = 0x00000000;
94 cpu->CP15[CP15_CONTEXT_ID] = 0x00000000;
95 cpu->CP15[CP15_THREAD_UPRW] = 0x00000000;
96 cpu->CP15[CP15_THREAD_URO] = 0x00000000;
97 cpu->CP15[CP15_THREAD_PRW] = 0x00000000;
98
99 // c15
100 cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
101 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
102 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
103 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
104 cpu->CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
105}
106
107/***************************************************************************\
108* Call this routine to set up the initial machine state (or perform a RESET *
109\***************************************************************************/
110void ARMul_Reset(ARMul_State* state)
111{
112 VFPInit(state);
113
114 state->Reg[15] = 0;
115 state->Cpsr = INTBITS | SVC32MODE;
116 state->Mode = SVC32MODE;
117 state->Bank = SVCBANK;
118
119 ResetMPCoreCP15Registers(state);
120
121 state->NresetSig = HIGH;
122 state->NfiqSig = HIGH;
123 state->NirqSig = HIGH;
124 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
125 state->abortSig = LOW;
126
127 state->NumInstrs = 0;
128}
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
deleted file mode 100644
index 83f7f3e2c..000000000
--- a/src/core/arm/interpreter/armsupp.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include "common/logging/log.h"
19
20#include "core/mem_map.h"
21#include "core/arm/skyeye_common/armdefs.h"
22#include "core/arm/skyeye_common/arm_regformat.h"
23
24// Unsigned sum of absolute difference
25u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
26{
27 if (left > right)
28 return left - right;
29
30 return right - left;
31}
32
33// Add with carry, indicates if a carry-out or signed overflow occurred.
34u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred)
35{
36 u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in;
37 s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in;
38 u64 result = (unsigned_sum & 0xFFFFFFFF);
39
40 if (carry_out_occurred)
41 *carry_out_occurred = (result != unsigned_sum);
42
43 if (overflow_occurred)
44 *overflow_occurred = ((s64)(s32)result != signed_sum);
45
46 return (u32)result;
47}
48
49// Compute whether an addition of A and B, giving RESULT, overflowed.
50bool AddOverflow(ARMword a, ARMword b, ARMword result)
51{
52 return ((NEG(a) && NEG(b) && POS(result)) ||
53 (POS(a) && POS(b) && NEG(result)));
54}
55
56// Compute whether a subtraction of A and B, giving RESULT, overflowed.
57bool SubOverflow(ARMword a, ARMword b, ARMword result)
58{
59 return ((NEG(a) && POS(b) && POS(result)) ||
60 (POS(a) && NEG(b) && NEG(result)));
61}
62
63// Returns true if the Q flag should be set as a result of overflow.
64bool ARMul_AddOverflowQ(ARMword a, ARMword b)
65{
66 u32 result = a + b;
67 if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
68 return true;
69
70 return false;
71}
72
73// 8-bit signed saturated addition
74u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
75{
76 u8 result = left + right;
77
78 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
79 if (left & 0x80)
80 result = 0x80;
81 else
82 result = 0x7F;
83 }
84
85 return result;
86}
87
88// 8-bit signed saturated subtraction
89u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
90{
91 u8 result = left - right;
92
93 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
94 if (left & 0x80)
95 result = 0x80;
96 else
97 result = 0x7F;
98 }
99
100 return result;
101}
102
103// 16-bit signed saturated addition
104u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
105{
106 u16 result = left + right;
107
108 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
109 if (left & 0x8000)
110 result = 0x8000;
111 else
112 result = 0x7FFF;
113 }
114
115 return result;
116}
117
118// 16-bit signed saturated subtraction
119u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
120{
121 u16 result = left - right;
122
123 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
124 if (left & 0x8000)
125 result = 0x8000;
126 else
127 result = 0x7FFF;
128 }
129
130 return result;
131}
132
133// 8-bit unsigned saturated addition
134u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
135{
136 u8 result = left + right;
137
138 if (result < left)
139 result = 0xFF;
140
141 return result;
142}
143
144// 16-bit unsigned saturated addition
145u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
146{
147 u16 result = left + right;
148
149 if (result < left)
150 result = 0xFFFF;
151
152 return result;
153}
154
155// 8-bit unsigned saturated subtraction
156u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
157{
158 if (left <= right)
159 return 0;
160
161 return left - right;
162}
163
164// 16-bit unsigned saturated subtraction
165u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
166{
167 if (left <= right)
168 return 0;
169
170 return left - right;
171}
172
173// Signed saturation.
174u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
175{
176 const u32 max = (1 << shift) - 1;
177 const s32 top = (value >> shift);
178
179 if (top > 0) {
180 *saturation_occurred = true;
181 return max;
182 }
183 else if (top < -1) {
184 *saturation_occurred = true;
185 return ~max;
186 }
187
188 *saturation_occurred = false;
189 return (u32)value;
190}
191
192// Unsigned saturation
193u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
194{
195 const u32 max = (1 << shift) - 1;
196
197 if (value < 0) {
198 *saturation_occurred = true;
199 return 0;
200 } else if ((u32)value > max) {
201 *saturation_occurred = true;
202 return max;
203 }
204
205 *saturation_occurred = false;
206 return (u32)value;
207}
208
209// Whether or not the given CPU is in big endian mode (E bit is set)
210bool InBigEndianMode(ARMul_State* cpu)
211{
212 return (cpu->Cpsr & (1 << 9)) != 0;
213}
214
215// Whether or not the given CPU is in a mode other than user mode.
216bool InAPrivilegedMode(ARMul_State* cpu)
217{
218 return (cpu->Mode != USER32MODE);
219}
220
221// Reads from the CP15 registers. Used with implementation of the MRC instruction.
222// Note that since the 3DS does not have the hypervisor extensions, these registers
223// are not implemented.
224u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
225{
226 // Unprivileged registers
227 if (crn == 13 && opcode_1 == 0 && crm == 0)
228 {
229 if (opcode_2 == 2)
230 return cpu->CP15[CP15_THREAD_UPRW];
231
232 if (opcode_2 == 3)
233 return cpu->CP15[CP15_THREAD_URO];
234 }
235
236 if (InAPrivilegedMode(cpu))
237 {
238 if (crn == 0 && opcode_1 == 0)
239 {
240 if (crm == 0)
241 {
242 if (opcode_2 == 0)
243 return cpu->CP15[CP15_MAIN_ID];
244
245 if (opcode_2 == 1)
246 return cpu->CP15[CP15_CACHE_TYPE];
247
248 if (opcode_2 == 3)
249 return cpu->CP15[CP15_TLB_TYPE];
250
251 if (opcode_2 == 5)
252 return cpu->CP15[CP15_CPU_ID];
253 }
254 else if (crm == 1)
255 {
256 if (opcode_2 == 0)
257 return cpu->CP15[CP15_PROCESSOR_FEATURE_0];
258
259 if (opcode_2 == 1)
260 return cpu->CP15[CP15_PROCESSOR_FEATURE_1];
261
262 if (opcode_2 == 2)
263 return cpu->CP15[CP15_DEBUG_FEATURE_0];
264
265 if (opcode_2 == 4)
266 return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0];
267
268 if (opcode_2 == 5)
269 return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1];
270
271 if (opcode_2 == 6)
272 return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2];
273
274 if (opcode_2 == 7)
275 return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3];
276 }
277 else if (crm == 2)
278 {
279 if (opcode_2 == 0)
280 return cpu->CP15[CP15_ISA_FEATURE_0];
281
282 if (opcode_2 == 1)
283 return cpu->CP15[CP15_ISA_FEATURE_1];
284
285 if (opcode_2 == 2)
286 return cpu->CP15[CP15_ISA_FEATURE_2];
287
288 if (opcode_2 == 3)
289 return cpu->CP15[CP15_ISA_FEATURE_3];
290
291 if (opcode_2 == 4)
292 return cpu->CP15[CP15_ISA_FEATURE_4];
293 }
294 }
295
296 if (crn == 1 && opcode_1 == 0 && crm == 0)
297 {
298 if (opcode_2 == 0)
299 return cpu->CP15[CP15_CONTROL];
300
301 if (opcode_2 == 1)
302 return cpu->CP15[CP15_AUXILIARY_CONTROL];
303
304 if (opcode_2 == 2)
305 return cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
306 }
307
308 if (crn == 2 && opcode_1 == 0 && crm == 0)
309 {
310 if (opcode_2 == 0)
311 return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0];
312
313 if (opcode_2 == 1)
314 return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1];
315
316 if (opcode_2 == 2)
317 return cpu->CP15[CP15_TRANSLATION_BASE_CONTROL];
318 }
319
320 if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
321 return cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL];
322
323 if (crn == 5 && opcode_1 == 0 && crm == 0)
324 {
325 if (opcode_2 == 0)
326 return cpu->CP15[CP15_FAULT_STATUS];
327
328 if (opcode_2 == 1)
329 return cpu->CP15[CP15_INSTR_FAULT_STATUS];
330 }
331
332 if (crn == 6 && opcode_1 == 0 && crm == 0)
333 {
334 if (opcode_2 == 0)
335 return cpu->CP15[CP15_FAULT_ADDRESS];
336
337 if (opcode_2 == 1)
338 return cpu->CP15[CP15_WFAR];
339 }
340
341 if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
342 return cpu->CP15[CP15_PHYS_ADDRESS];
343
344 if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
345 return cpu->CP15[CP15_DATA_CACHE_LOCKDOWN];
346
347 if (crn == 10 && opcode_1 == 0)
348 {
349 if (crm == 0 && opcode_2 == 0)
350 return cpu->CP15[CP15_TLB_LOCKDOWN];
351
352 if (crm == 2)
353 {
354 if (opcode_2 == 0)
355 return cpu->CP15[CP15_PRIMARY_REGION_REMAP];
356
357 if (opcode_2 == 1)
358 return cpu->CP15[CP15_NORMAL_REGION_REMAP];
359 }
360 }
361
362 if (crn == 13 && crm == 0)
363 {
364 if (opcode_2 == 0)
365 return cpu->CP15[CP15_PID];
366
367 if (opcode_2 == 1)
368 return cpu->CP15[CP15_CONTEXT_ID];
369
370 if (opcode_2 == 4)
371 return cpu->CP15[CP15_THREAD_PRW];
372 }
373
374 if (crn == 15)
375 {
376 if (opcode_1 == 0 && crm == 12)
377 {
378 if (opcode_2 == 0)
379 return cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
380
381 if (opcode_2 == 1)
382 return cpu->CP15[CP15_CYCLE_COUNTER];
383
384 if (opcode_2 == 2)
385 return cpu->CP15[CP15_COUNT_0];
386
387 if (opcode_2 == 3)
388 return cpu->CP15[CP15_COUNT_1];
389 }
390
391 if (opcode_1 == 5 && opcode_2 == 2)
392 {
393 if (crm == 5)
394 return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
395
396 if (crm == 6)
397 return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
398
399 if (crm == 7)
400 return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
401 }
402
403 if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
404 return cpu->CP15[CP15_TLB_DEBUG_CONTROL];
405 }
406 }
407
408 LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
409 return 0;
410}
411
412// Write to the CP15 registers. Used with implementation of the MCR instruction.
413// Note that since the 3DS does not have the hypervisor extensions, these registers
414// are not implemented.
415void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
416{
417 if (InAPrivilegedMode(cpu))
418 {
419 if (crn == 1 && opcode_1 == 0 && crm == 0)
420 {
421 if (opcode_2 == 0)
422 cpu->CP15[CP15_CONTROL] = value;
423 else if (opcode_2 == 1)
424 cpu->CP15[CP15_AUXILIARY_CONTROL] = value;
425 else if (opcode_2 == 2)
426 cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
427 }
428 else if (crn == 2 && opcode_1 == 0 && crm == 0)
429 {
430 if (opcode_2 == 0)
431 cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
432 else if (opcode_2 == 1)
433 cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
434 else if (opcode_2 == 2)
435 cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
436 }
437 else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
438 {
439 cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
440 }
441 else if (crn == 5 && opcode_1 == 0 && crm == 0)
442 {
443 if (opcode_2 == 0)
444 cpu->CP15[CP15_FAULT_STATUS] = value;
445 else if (opcode_2 == 1)
446 cpu->CP15[CP15_INSTR_FAULT_STATUS] = value;
447 }
448 else if (crn == 6 && opcode_1 == 0 && crm == 0)
449 {
450 if (opcode_2 == 0)
451 cpu->CP15[CP15_FAULT_ADDRESS] = value;
452 else if (opcode_2 == 1)
453 cpu->CP15[CP15_WFAR] = value;
454 }
455 else if (crn == 7 && opcode_1 == 0)
456 {
457 if (crm == 0 && opcode_2 == 4)
458 {
459 cpu->CP15[CP15_WAIT_FOR_INTERRUPT] = value;
460 }
461 else if (crm == 4 && opcode_2 == 0)
462 {
463 // NOTE: Not entirely accurate. This should do permission checks.
464 cpu->CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
465 }
466 else if (crm == 5)
467 {
468 if (opcode_2 == 0)
469 cpu->CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
470 else if (opcode_2 == 1)
471 cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
472 else if (opcode_2 == 2)
473 cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
474 else if (opcode_2 == 6)
475 cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
476 else if (opcode_2 == 7)
477 cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
478 }
479 else if (crm == 6)
480 {
481 if (opcode_2 == 0)
482 cpu->CP15[CP15_INVALIDATE_DATA_CACHE] = value;
483 else if (opcode_2 == 1)
484 cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
485 else if (opcode_2 == 2)
486 cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
487 }
488 else if (crm == 7 && opcode_2 == 0)
489 {
490 cpu->CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
491 }
492 else if (crm == 10)
493 {
494 if (opcode_2 == 0)
495 cpu->CP15[CP15_CLEAN_DATA_CACHE] = value;
496 else if (opcode_2 == 1)
497 cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
498 else if (opcode_2 == 2)
499 cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
500 }
501 else if (crm == 14)
502 {
503 if (opcode_2 == 0)
504 cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
505 else if (opcode_2 == 1)
506 cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
507 else if (opcode_2 == 2)
508 cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
509 }
510 }
511 else if (crn == 8 && opcode_1 == 0)
512 {
513 LOG_WARNING(Core_ARM11, "TLB operations not fully implemented.");
514
515 if (crm == 5)
516 {
517 if (opcode_2 == 0)
518 cpu->CP15[CP15_INVALIDATE_ITLB] = value;
519 else if (opcode_2 == 1)
520 cpu->CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
521 else if (opcode_2 == 2)
522 cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
523 else if (opcode_2 == 3)
524 cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
525 }
526 else if (crm == 6)
527 {
528 if (opcode_2 == 0)
529 cpu->CP15[CP15_INVALIDATE_DTLB] = value;
530 else if (opcode_2 == 1)
531 cpu->CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
532 else if (opcode_2 == 2)
533 cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
534 else if (opcode_2 == 3)
535 cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
536 }
537 else if (crm == 7)
538 {
539 if (opcode_2 == 0)
540 cpu->CP15[CP15_INVALIDATE_UTLB] = value;
541 else if (opcode_2 == 1)
542 cpu->CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
543 else if (opcode_2 == 2)
544 cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
545 else if (opcode_2 == 3)
546 cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
547 }
548 }
549 else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
550 {
551 cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
552 }
553 else if (crn == 10 && opcode_1 == 0)
554 {
555 if (crm == 0 && opcode_2 == 0)
556 {
557 cpu->CP15[CP15_TLB_LOCKDOWN] = value;
558 }
559 else if (crm == 2)
560 {
561 if (opcode_2 == 0)
562 cpu->CP15[CP15_PRIMARY_REGION_REMAP] = value;
563 else if (opcode_2 == 1)
564 cpu->CP15[CP15_NORMAL_REGION_REMAP] = value;
565 }
566 }
567 else if (crn == 13 && opcode_1 == 0 && crm == 0)
568 {
569 if (opcode_2 == 0)
570 cpu->CP15[CP15_PID] = value;
571 else if (opcode_2 == 1)
572 cpu->CP15[CP15_CONTEXT_ID] = value;
573 else if (opcode_2 == 3)
574 cpu->CP15[CP15_THREAD_URO] = value;
575 else if (opcode_2 == 4)
576 cpu->CP15[CP15_THREAD_PRW] = value;
577 }
578 else if (crn == 15)
579 {
580 if (opcode_1 == 0 && crm == 12)
581 {
582 if (opcode_2 == 0)
583 cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
584 else if (opcode_2 == 1)
585 cpu->CP15[CP15_CYCLE_COUNTER] = value;
586 else if (opcode_2 == 2)
587 cpu->CP15[CP15_COUNT_0] = value;
588 else if (opcode_2 == 3)
589 cpu->CP15[CP15_COUNT_1] = value;
590 }
591 else if (opcode_1 == 5)
592 {
593 if (crm == 4)
594 {
595 if (opcode_2 == 2)
596 cpu->CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
597 else if (opcode_2 == 4)
598 cpu->CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
599 }
600 else if (crm == 5 && opcode_2 == 2)
601 {
602 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
603 }
604 else if (crm == 6 && opcode_2 == 2)
605 {
606 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
607 }
608 else if (crm == 7 && opcode_2 == 2)
609 {
610 cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
611 }
612 }
613 else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
614 {
615 cpu->CP15[CP15_TLB_DEBUG_CONTROL] = value;
616 }
617 }
618 }
619
620 // Unprivileged registers
621 if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
622 {
623 cpu->CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
624 }
625 else if (crn == 7 && opcode_1 == 0 && crm == 10)
626 {
627 if (opcode_2 == 4)
628 cpu->CP15[CP15_DATA_SYNC_BARRIER] = value;
629 else if (opcode_2 == 5)
630 cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value;
631
632 }
633 else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
634 {
635 cpu->CP15[CP15_THREAD_UPRW] = value;
636 }
637}
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
deleted file mode 100644
index a0ec108c7..000000000
--- a/src/core/arm/skyeye_common/armdefs.h
+++ /dev/null
@@ -1,318 +0,0 @@
1/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#pragma once
19
20#include <unordered_map>
21
22#include "common/common_types.h"
23#include "core/arm/skyeye_common/arm_regformat.h"
24
25#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
26#define BIT(s, n) ((s >> (n)) & 1)
27
28// Signal levels
29enum {
30 LOW = 0,
31 HIGH = 1,
32 LOWHIGH = 1,
33 HIGHLOW = 2
34};
35
36// Cache types
37enum {
38 NONCACHE = 0,
39 DATACACHE = 1,
40 INSTCACHE = 2,
41};
42
43// Abort models
44enum {
45 ABORT_BASE_RESTORED = 0,
46 ABORT_EARLY = 1,
47 ABORT_BASE_UPDATED = 2
48};
49
50#define POS(i) ( (~(i)) >> 31 )
51#define NEG(i) ( (i) >> 31 )
52
53typedef u64 ARMdword; // must be 64 bits wide
54typedef u32 ARMword; // must be 32 bits wide
55typedef u16 ARMhword; // must be 16 bits wide
56typedef u8 ARMbyte; // must be 8 bits wide
57
58#define VFP_REG_NUM 64
59struct ARMul_State
60{
61 ARMword Emulate; // To start and stop emulation
62
63 // Order of the following register should not be modified
64 ARMword Reg[16]; // The current register file
65 ARMword Cpsr; // The current PSR
66 ARMword Spsr_copy;
67 ARMword phys_pc;
68 ARMword Reg_usr[2];
69 ARMword Reg_svc[2]; // R13_SVC R14_SVC
70 ARMword Reg_abort[2]; // R13_ABORT R14_ABORT
71 ARMword Reg_undef[2]; // R13 UNDEF R14 UNDEF
72 ARMword Reg_irq[2]; // R13_IRQ R14_IRQ
73 ARMword Reg_firq[7]; // R8---R14 FIRQ
74 ARMword Spsr[7]; // The exception psr's
75 ARMword Mode; // The current mode
76 ARMword Bank; // The current register bank
77 ARMword exclusive_tag; // The address for which the local monitor is in exclusive access mode
78 ARMword exclusive_state;
79 ARMword exclusive_result;
80 ARMword CP15[CP15_REGISTER_COUNT];
81
82 // FPSID, FPSCR, and FPEXC
83 ARMword VFP[VFP_SYSTEM_REGISTER_COUNT];
84 // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
85 // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
86 // and only 32 singleword registers are accessible (S0-S31).
87 ARMword ExtReg[VFP_REG_NUM];
88 /* ---- End of the ordered registers ---- */
89
90 ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
91 unsigned int shifter_carry_out;
92
93 // Add armv6 flags dyf:2010-08-09
94 ARMword GEFlag, EFlag, AFlag, QFlag;
95
96 ARMword TFlag; // Thumb state
97
98 unsigned long long NumInstrs; // The number of instructions executed
99 unsigned NumInstrsToExecute;
100
101 unsigned NresetSig; // Reset the processor
102 unsigned NfiqSig;
103 unsigned NirqSig;
104
105 unsigned abortSig;
106 unsigned NtransSig;
107 unsigned bigendSig;
108 unsigned syscallSig;
109
110/* 2004-05-09 chy
111----------------------------------------------------------
112read ARM Architecture Reference Manual
1132.6.5 Data Abort
114There are three Abort Model in ARM arch.
115
116Early Abort Model: used in some ARMv3 and earlier implementations. In this
117model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
118the base register was unchanged for all other instructions. (oldest)
119
120Base Restored Abort Model: If a Data Abort occurs in an instruction which
121specifies base register writeback, the value in the base register is
122unchanged. (strongarm, xscale)
123
124Base Updated Abort Model: If a Data Abort occurs in an instruction which
125specifies base register writeback, the base register writeback still occurs.
126(arm720T)
127
128read PART B
129chap2 The System Control Coprocessor CP15
1302.4 Register1:control register
131L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
132processor could be configured:
1330=early Abort Model Selected(now obsolete)
1341=Late Abort Model selceted(same as Base Updated Abort Model)
135
136on later processors, this bit reads as 1 and ignores writes.
137-------------------------------------------------------------
138So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
139 if lateabtSig=0, then it means Base Restored Abort Model
140*/
141 unsigned lateabtSig;
142
143 // For differentiating ARM core emulaiton.
144 bool is_v4; // Are we emulating a v4 architecture (or higher)?
145 bool is_v5; // Are we emulating a v5 architecture?
146 bool is_v5e; // Are we emulating a v5e architecture?
147 bool is_v6; // Are we emulating a v6 architecture?
148 bool is_v7; // Are we emulating a v7 architecture?
149
150 // ARM_ARM A2-18
151 // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model
152 int abort_model;
153
154 // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
155 // process for our purposes), not per ARMul_State (which tracks CPU core state).
156 std::unordered_map<u32, int> instruction_cache;
157};
158
159/***************************************************************************\
160* Types of ARM we know about *
161\***************************************************************************/
162
163enum {
164 ARM_v4_Prop = 0x01,
165 ARM_v5_Prop = 0x02,
166 ARM_v5e_Prop = 0x04,
167 ARM_v6_Prop = 0x08,
168 ARM_v7_Prop = 0x10,
169};
170
171/***************************************************************************\
172* The hardware vector addresses *
173\***************************************************************************/
174
175enum {
176 ARMResetV = 0,
177 ARMUndefinedInstrV = 4,
178 ARMSWIV = 8,
179 ARMPrefetchAbortV = 12,
180 ARMDataAbortV = 16,
181 ARMAddrExceptnV = 20,
182 ARMIRQV = 24,
183 ARMFIQV = 28,
184 ARMErrorV = 32, // This is an offset, not an address!
185
186 ARMul_ResetV = ARMResetV,
187 ARMul_UndefinedInstrV = ARMUndefinedInstrV,
188 ARMul_SWIV = ARMSWIV,
189 ARMul_PrefetchAbortV = ARMPrefetchAbortV,
190 ARMul_DataAbortV = ARMDataAbortV,
191 ARMul_AddrExceptnV = ARMAddrExceptnV,
192 ARMul_IRQV = ARMIRQV,
193 ARMul_FIQV = ARMFIQV
194};
195
196/***************************************************************************\
197* Mode and Bank Constants *
198\***************************************************************************/
199
200enum PrivilegeMode {
201 USER32MODE = 16,
202 FIQ32MODE = 17,
203 IRQ32MODE = 18,
204 SVC32MODE = 19,
205 ABORT32MODE = 23,
206 UNDEF32MODE = 27,
207 SYSTEM32MODE = 31
208};
209
210enum {
211 USERBANK = 0,
212 FIQBANK = 1,
213 IRQBANK = 2,
214 SVCBANK = 3,
215 ABORTBANK = 4,
216 UNDEFBANK = 5,
217 DUMMYBANK = 6,
218 SYSTEMBANK = 7
219};
220
221/***************************************************************************\
222* Definitions of things in the emulator *
223\***************************************************************************/
224void ARMul_Reset(ARMul_State* state);
225ARMul_State* ARMul_NewState(ARMul_State* state);
226
227/***************************************************************************\
228* Definitions of things in the co-processor interface *
229\***************************************************************************/
230
231enum {
232 ARMul_FIRST = 0,
233 ARMul_TRANSFER = 1,
234 ARMul_BUSY = 2,
235 ARMul_DATA = 3,
236 ARMul_INTERRUPT = 4,
237 ARMul_DONE = 0,
238 ARMul_CANT = 1,
239 ARMul_INC = 3
240};
241
242/***************************************************************************\
243* Definitions of things in the host environment *
244\***************************************************************************/
245
246enum ConditionCode {
247 EQ = 0,
248 NE = 1,
249 CS = 2,
250 CC = 3,
251 MI = 4,
252 PL = 5,
253 VS = 6,
254 VC = 7,
255 HI = 8,
256 LS = 9,
257 GE = 10,
258 LT = 11,
259 GT = 12,
260 LE = 13,
261 AL = 14,
262 NV = 15,
263};
264
265// Flags for use with the APSR.
266enum : u32 {
267 NBIT = (1U << 31U),
268 ZBIT = (1 << 30),
269 CBIT = (1 << 29),
270 VBIT = (1 << 28),
271 QBIT = (1 << 27),
272 JBIT = (1 << 24),
273 EBIT = (1 << 9),
274 ABIT = (1 << 8),
275 IBIT = (1 << 7),
276 FBIT = (1 << 6),
277 TBIT = (1 << 5),
278
279 // Masks for groups of bits in the APSR.
280 MODEBITS = 0x1F,
281 INTBITS = 0x1C0,
282};
283
284// Values for Emulate.
285enum {
286 STOP = 0, // Stop
287 CHANGEMODE = 1, // Change mode
288 ONCE = 2, // Execute just one iteration
289 RUN = 3 // Continuous execution
290};
291
292
293bool AddOverflow(ARMword, ARMword, ARMword);
294bool SubOverflow(ARMword, ARMword, ARMword);
295
296void ARMul_SelectProcessor(ARMul_State*, unsigned);
297
298u32 AddWithCarry(u32, u32, u32, bool*, bool*);
299bool ARMul_AddOverflowQ(ARMword, ARMword);
300
301u8 ARMul_SignedSaturatedAdd8(u8, u8);
302u8 ARMul_SignedSaturatedSub8(u8, u8);
303u16 ARMul_SignedSaturatedAdd16(u16, u16);
304u16 ARMul_SignedSaturatedSub16(u16, u16);
305
306u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
307u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
308u8 ARMul_UnsignedSaturatedSub8(u8, u8);
309u16 ARMul_UnsignedSaturatedSub16(u16, u16);
310u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
311u32 ARMul_SignedSatQ(s32, u8, bool*);
312u32 ARMul_UnsignedSatQ(s32, u8, bool*);
313
314bool InBigEndianMode(ARMul_State*);
315bool InAPrivilegedMode(ARMul_State*);
316
317u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
318void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
deleted file mode 100644
index c67d7209b..000000000
--- a/src/core/arm/skyeye_common/armmmu.h
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#pragma once
22
23#include "common/swap.h"
24
25#include "core/memory.h"
26#include "core/arm/skyeye_common/armdefs.h"
27
28// Register numbers in the MMU
29enum
30{
31 MMU_ID = 0,
32 MMU_CONTROL = 1,
33 MMU_TRANSLATION_TABLE_BASE = 2,
34 MMU_DOMAIN_ACCESS_CONTROL = 3,
35 MMU_FAULT_STATUS = 5,
36 MMU_FAULT_ADDRESS = 6,
37 MMU_CACHE_OPS = 7,
38 MMU_TLB_OPS = 8,
39 MMU_CACHE_LOCKDOWN = 9,
40 MMU_TLB_LOCKDOWN = 10,
41 MMU_PID = 13,
42
43 // MMU_V4
44 MMU_V4_CACHE_OPS = 7,
45 MMU_V4_TLB_OPS = 8,
46
47 // MMU_V3
48 MMU_V3_FLUSH_TLB = 5,
49 MMU_V3_FLUSH_TLB_ENTRY = 6,
50 MMU_V3_FLUSH_CACHE = 7,
51};
52
53// Reads data in big/little endian format based on the
54// state of the E (endian) bit in the emulated CPU's APSR.
55inline u16 ReadMemory16(ARMul_State* cpu, u32 address) {
56 u16 data = Memory::Read16(address);
57
58 if (InBigEndianMode(cpu))
59 data = Common::swap16(data);
60
61 return data;
62}
63
64inline u32 ReadMemory32(ARMul_State* cpu, u32 address) {
65 u32 data = Memory::Read32(address);
66
67 if (InBigEndianMode(cpu))
68 data = Common::swap32(data);
69
70 return data;
71}
72
73inline u64 ReadMemory64(ARMul_State* cpu, u32 address) {
74 u64 data = Memory::Read64(address);
75
76 if (InBigEndianMode(cpu))
77 data = Common::swap64(data);
78
79 return data;
80}
81
82// Writes data in big/little endian format based on the
83// state of the E (endian) bit in the emulated CPU's APSR.
84inline void WriteMemory16(ARMul_State* cpu, u32 address, u16 data) {
85 if (InBigEndianMode(cpu))
86 data = Common::swap16(data);
87
88 Memory::Write16(address, data);
89}
90
91inline void WriteMemory32(ARMul_State* cpu, u32 address, u32 data) {
92 if (InBigEndianMode(cpu))
93 data = Common::swap32(data);
94
95 Memory::Write32(address, data);
96}
97
98inline void WriteMemory64(ARMul_State* cpu, u32 address, u64 data) {
99 if (InBigEndianMode(cpu))
100 data = Common::swap64(data);
101
102 Memory::Write64(address, data);
103}
diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp
new file mode 100644
index 000000000..ccb2eb0eb
--- /dev/null
+++ b/src/core/arm/skyeye_common/armstate.cpp
@@ -0,0 +1,657 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/swap.h"
6#include "common/logging/log.h"
7#include "core/mem_map.h"
8#include "core/memory.h"
9#include "core/arm/skyeye_common/armstate.h"
10#include "core/arm/skyeye_common/vfp/vfp.h"
11
12ARMul_State::ARMul_State(PrivilegeMode initial_mode)
13{
14 Reset();
15 ChangePrivilegeMode(initial_mode);
16}
17
18void ARMul_State::ChangePrivilegeMode(u32 new_mode)
19{
20 if (Mode == new_mode)
21 return;
22
23 if (new_mode != USERBANK) {
24 switch (Mode) {
25 case SYSTEM32MODE: // Shares registers with user mode
26 case USER32MODE:
27 Reg_usr[0] = Reg[13];
28 Reg_usr[1] = Reg[14];
29 break;
30 case IRQ32MODE:
31 Reg_irq[0] = Reg[13];
32 Reg_irq[1] = Reg[14];
33 Spsr[IRQBANK] = Spsr_copy;
34 break;
35 case SVC32MODE:
36 Reg_svc[0] = Reg[13];
37 Reg_svc[1] = Reg[14];
38 Spsr[SVCBANK] = Spsr_copy;
39 break;
40 case ABORT32MODE:
41 Reg_abort[0] = Reg[13];
42 Reg_abort[1] = Reg[14];
43 Spsr[ABORTBANK] = Spsr_copy;
44 break;
45 case UNDEF32MODE:
46 Reg_undef[0] = Reg[13];
47 Reg_undef[1] = Reg[14];
48 Spsr[UNDEFBANK] = Spsr_copy;
49 break;
50 case FIQ32MODE:
51 Reg_firq[0] = Reg[13];
52 Reg_firq[1] = Reg[14];
53 Spsr[FIQBANK] = Spsr_copy;
54 break;
55 }
56
57 switch (new_mode) {
58 case USER32MODE:
59 Reg[13] = Reg_usr[0];
60 Reg[14] = Reg_usr[1];
61 Bank = USERBANK;
62 break;
63 case IRQ32MODE:
64 Reg[13] = Reg_irq[0];
65 Reg[14] = Reg_irq[1];
66 Spsr_copy = Spsr[IRQBANK];
67 Bank = IRQBANK;
68 break;
69 case SVC32MODE:
70 Reg[13] = Reg_svc[0];
71 Reg[14] = Reg_svc[1];
72 Spsr_copy = Spsr[SVCBANK];
73 Bank = SVCBANK;
74 break;
75 case ABORT32MODE:
76 Reg[13] = Reg_abort[0];
77 Reg[14] = Reg_abort[1];
78 Spsr_copy = Spsr[ABORTBANK];
79 Bank = ABORTBANK;
80 break;
81 case UNDEF32MODE:
82 Reg[13] = Reg_undef[0];
83 Reg[14] = Reg_undef[1];
84 Spsr_copy = Spsr[UNDEFBANK];
85 Bank = UNDEFBANK;
86 break;
87 case FIQ32MODE:
88 Reg[13] = Reg_firq[0];
89 Reg[14] = Reg_firq[1];
90 Spsr_copy = Spsr[FIQBANK];
91 Bank = FIQBANK;
92 break;
93 case SYSTEM32MODE: // Shares registers with user mode.
94 Reg[13] = Reg_usr[0];
95 Reg[14] = Reg_usr[1];
96 Bank = SYSTEMBANK;
97 break;
98 }
99
100 // Set the mode bits in the APSR
101 Cpsr = (Cpsr & ~Mode) | new_mode;
102 Mode = new_mode;
103 }
104}
105
106// Performs a reset
107void ARMul_State::Reset()
108{
109 VFPInit(this);
110
111 // Set stack pointer to the top of the stack
112 Reg[13] = 0x10000000;
113 Reg[15] = 0;
114
115 Cpsr = INTBITS | SVC32MODE;
116 Mode = SVC32MODE;
117 Bank = SVCBANK;
118
119 ResetMPCoreCP15Registers();
120
121 NresetSig = HIGH;
122 NfiqSig = HIGH;
123 NirqSig = HIGH;
124 NtransSig = (Mode & 3) ? HIGH : LOW;
125 abortSig = LOW;
126
127 NumInstrs = 0;
128 Emulate = RUN;
129}
130
131// Resets certain MPCore CP15 values to their ARM-defined reset values.
132void ARMul_State::ResetMPCoreCP15Registers()
133{
134 // c0
135 CP15[CP15_MAIN_ID] = 0x410FB024;
136 CP15[CP15_TLB_TYPE] = 0x00000800;
137 CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
138 CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
139 CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
140 CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
141 CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
142 CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
143 CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
144 CP15[CP15_ISA_FEATURE_0] = 0x00100011;
145 CP15[CP15_ISA_FEATURE_1] = 0x12002111;
146 CP15[CP15_ISA_FEATURE_2] = 0x11221011;
147 CP15[CP15_ISA_FEATURE_3] = 0x01102131;
148 CP15[CP15_ISA_FEATURE_4] = 0x00000141;
149
150 // c1
151 CP15[CP15_CONTROL] = 0x00054078;
152 CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
153 CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
154
155 // c2
156 CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
157 CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
158 CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
159
160 // c3
161 CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
162
163 // c7
164 CP15[CP15_PHYS_ADDRESS] = 0x00000000;
165
166 // c9
167 CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
168
169 // c10
170 CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
171 CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
172 CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
173
174 // c13
175 CP15[CP15_PID] = 0x00000000;
176 CP15[CP15_CONTEXT_ID] = 0x00000000;
177 CP15[CP15_THREAD_UPRW] = 0x00000000;
178 CP15[CP15_THREAD_URO] = 0x00000000;
179 CP15[CP15_THREAD_PRW] = 0x00000000;
180
181 // c15
182 CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
183 CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
184 CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
185 CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
186 CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
187}
188
189u16 ARMul_State::ReadMemory16(u32 address) const
190{
191 u16 data = Memory::Read16(address);
192
193 if (InBigEndianMode())
194 data = Common::swap16(data);
195
196 return data;
197}
198
199u32 ARMul_State::ReadMemory32(u32 address) const
200{
201 u32 data = Memory::Read32(address);
202
203 if (InBigEndianMode())
204 data = Common::swap32(data);
205
206 return data;
207}
208
209u64 ARMul_State::ReadMemory64(u32 address) const
210{
211 u64 data = Memory::Read64(address);
212
213 if (InBigEndianMode())
214 data = Common::swap64(data);
215
216 return data;
217}
218
219void ARMul_State::WriteMemory16(u32 address, u16 data)
220{
221 if (InBigEndianMode())
222 data = Common::swap16(data);
223
224 Memory::Write16(address, data);
225}
226
227void ARMul_State::WriteMemory32(u32 address, u32 data)
228{
229 if (InBigEndianMode())
230 data = Common::swap32(data);
231
232 Memory::Write32(address, data);
233}
234
235void ARMul_State::WriteMemory64(u32 address, u64 data)
236{
237 if (InBigEndianMode())
238 data = Common::swap64(data);
239
240 Memory::Write64(address, data);
241}
242
243
244// Reads from the CP15 registers. Used with implementation of the MRC instruction.
245// Note that since the 3DS does not have the hypervisor extensions, these registers
246// are not implemented.
247u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const
248{
249 // Unprivileged registers
250 if (crn == 13 && opcode_1 == 0 && crm == 0)
251 {
252 if (opcode_2 == 2)
253 return CP15[CP15_THREAD_UPRW];
254
255 if (opcode_2 == 3)
256 return CP15[CP15_THREAD_URO];
257 }
258
259 if (InAPrivilegedMode())
260 {
261 if (crn == 0 && opcode_1 == 0)
262 {
263 if (crm == 0)
264 {
265 if (opcode_2 == 0)
266 return CP15[CP15_MAIN_ID];
267
268 if (opcode_2 == 1)
269 return CP15[CP15_CACHE_TYPE];
270
271 if (opcode_2 == 3)
272 return CP15[CP15_TLB_TYPE];
273
274 if (opcode_2 == 5)
275 return CP15[CP15_CPU_ID];
276 }
277 else if (crm == 1)
278 {
279 if (opcode_2 == 0)
280 return CP15[CP15_PROCESSOR_FEATURE_0];
281
282 if (opcode_2 == 1)
283 return CP15[CP15_PROCESSOR_FEATURE_1];
284
285 if (opcode_2 == 2)
286 return CP15[CP15_DEBUG_FEATURE_0];
287
288 if (opcode_2 == 4)
289 return CP15[CP15_MEMORY_MODEL_FEATURE_0];
290
291 if (opcode_2 == 5)
292 return CP15[CP15_MEMORY_MODEL_FEATURE_1];
293
294 if (opcode_2 == 6)
295 return CP15[CP15_MEMORY_MODEL_FEATURE_2];
296
297 if (opcode_2 == 7)
298 return CP15[CP15_MEMORY_MODEL_FEATURE_3];
299 }
300 else if (crm == 2)
301 {
302 if (opcode_2 == 0)
303 return CP15[CP15_ISA_FEATURE_0];
304
305 if (opcode_2 == 1)
306 return CP15[CP15_ISA_FEATURE_1];
307
308 if (opcode_2 == 2)
309 return CP15[CP15_ISA_FEATURE_2];
310
311 if (opcode_2 == 3)
312 return CP15[CP15_ISA_FEATURE_3];
313
314 if (opcode_2 == 4)
315 return CP15[CP15_ISA_FEATURE_4];
316 }
317 }
318
319 if (crn == 1 && opcode_1 == 0 && crm == 0)
320 {
321 if (opcode_2 == 0)
322 return CP15[CP15_CONTROL];
323
324 if (opcode_2 == 1)
325 return CP15[CP15_AUXILIARY_CONTROL];
326
327 if (opcode_2 == 2)
328 return CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
329 }
330
331 if (crn == 2 && opcode_1 == 0 && crm == 0)
332 {
333 if (opcode_2 == 0)
334 return CP15[CP15_TRANSLATION_BASE_TABLE_0];
335
336 if (opcode_2 == 1)
337 return CP15[CP15_TRANSLATION_BASE_TABLE_1];
338
339 if (opcode_2 == 2)
340 return CP15[CP15_TRANSLATION_BASE_CONTROL];
341 }
342
343 if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
344 return CP15[CP15_DOMAIN_ACCESS_CONTROL];
345
346 if (crn == 5 && opcode_1 == 0 && crm == 0)
347 {
348 if (opcode_2 == 0)
349 return CP15[CP15_FAULT_STATUS];
350
351 if (opcode_2 == 1)
352 return CP15[CP15_INSTR_FAULT_STATUS];
353 }
354
355 if (crn == 6 && opcode_1 == 0 && crm == 0)
356 {
357 if (opcode_2 == 0)
358 return CP15[CP15_FAULT_ADDRESS];
359
360 if (opcode_2 == 1)
361 return CP15[CP15_WFAR];
362 }
363
364 if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
365 return CP15[CP15_PHYS_ADDRESS];
366
367 if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
368 return CP15[CP15_DATA_CACHE_LOCKDOWN];
369
370 if (crn == 10 && opcode_1 == 0)
371 {
372 if (crm == 0 && opcode_2 == 0)
373 return CP15[CP15_TLB_LOCKDOWN];
374
375 if (crm == 2)
376 {
377 if (opcode_2 == 0)
378 return CP15[CP15_PRIMARY_REGION_REMAP];
379
380 if (opcode_2 == 1)
381 return CP15[CP15_NORMAL_REGION_REMAP];
382 }
383 }
384
385 if (crn == 13 && crm == 0)
386 {
387 if (opcode_2 == 0)
388 return CP15[CP15_PID];
389
390 if (opcode_2 == 1)
391 return CP15[CP15_CONTEXT_ID];
392
393 if (opcode_2 == 4)
394 return CP15[CP15_THREAD_PRW];
395 }
396
397 if (crn == 15)
398 {
399 if (opcode_1 == 0 && crm == 12)
400 {
401 if (opcode_2 == 0)
402 return CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
403
404 if (opcode_2 == 1)
405 return CP15[CP15_CYCLE_COUNTER];
406
407 if (opcode_2 == 2)
408 return CP15[CP15_COUNT_0];
409
410 if (opcode_2 == 3)
411 return CP15[CP15_COUNT_1];
412 }
413
414 if (opcode_1 == 5 && opcode_2 == 2)
415 {
416 if (crm == 5)
417 return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
418
419 if (crm == 6)
420 return CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
421
422 if (crm == 7)
423 return CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
424 }
425
426 if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
427 return CP15[CP15_TLB_DEBUG_CONTROL];
428 }
429 }
430
431 LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
432 return 0;
433}
434
435// Write to the CP15 registers. Used with implementation of the MCR instruction.
436// Note that since the 3DS does not have the hypervisor extensions, these registers
437// are not implemented.
438void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
439{
440 if (InAPrivilegedMode())
441 {
442 if (crn == 1 && opcode_1 == 0 && crm == 0)
443 {
444 if (opcode_2 == 0)
445 CP15[CP15_CONTROL] = value;
446 else if (opcode_2 == 1)
447 CP15[CP15_AUXILIARY_CONTROL] = value;
448 else if (opcode_2 == 2)
449 CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
450 }
451 else if (crn == 2 && opcode_1 == 0 && crm == 0)
452 {
453 if (opcode_2 == 0)
454 CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
455 else if (opcode_2 == 1)
456 CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
457 else if (opcode_2 == 2)
458 CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
459 }
460 else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
461 {
462 CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
463 }
464 else if (crn == 5 && opcode_1 == 0 && crm == 0)
465 {
466 if (opcode_2 == 0)
467 CP15[CP15_FAULT_STATUS] = value;
468 else if (opcode_2 == 1)
469 CP15[CP15_INSTR_FAULT_STATUS] = value;
470 }
471 else if (crn == 6 && opcode_1 == 0 && crm == 0)
472 {
473 if (opcode_2 == 0)
474 CP15[CP15_FAULT_ADDRESS] = value;
475 else if (opcode_2 == 1)
476 CP15[CP15_WFAR] = value;
477 }
478 else if (crn == 7 && opcode_1 == 0)
479 {
480 if (crm == 0 && opcode_2 == 4)
481 {
482 CP15[CP15_WAIT_FOR_INTERRUPT] = value;
483 }
484 else if (crm == 4 && opcode_2 == 0)
485 {
486 // NOTE: Not entirely accurate. This should do permission checks.
487 CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
488 }
489 else if (crm == 5)
490 {
491 if (opcode_2 == 0)
492 CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
493 else if (opcode_2 == 1)
494 CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
495 else if (opcode_2 == 2)
496 CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
497 else if (opcode_2 == 6)
498 CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
499 else if (opcode_2 == 7)
500 CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
501 }
502 else if (crm == 6)
503 {
504 if (opcode_2 == 0)
505 CP15[CP15_INVALIDATE_DATA_CACHE] = value;
506 else if (opcode_2 == 1)
507 CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
508 else if (opcode_2 == 2)
509 CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
510 }
511 else if (crm == 7 && opcode_2 == 0)
512 {
513 CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
514 }
515 else if (crm == 10)
516 {
517 if (opcode_2 == 0)
518 CP15[CP15_CLEAN_DATA_CACHE] = value;
519 else if (opcode_2 == 1)
520 CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
521 else if (opcode_2 == 2)
522 CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
523 }
524 else if (crm == 14)
525 {
526 if (opcode_2 == 0)
527 CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
528 else if (opcode_2 == 1)
529 CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
530 else if (opcode_2 == 2)
531 CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
532 }
533 }
534 else if (crn == 8 && opcode_1 == 0)
535 {
536 if (crm == 5)
537 {
538 if (opcode_2 == 0)
539 CP15[CP15_INVALIDATE_ITLB] = value;
540 else if (opcode_2 == 1)
541 CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
542 else if (opcode_2 == 2)
543 CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
544 else if (opcode_2 == 3)
545 CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
546 }
547 else if (crm == 6)
548 {
549 if (opcode_2 == 0)
550 CP15[CP15_INVALIDATE_DTLB] = value;
551 else if (opcode_2 == 1)
552 CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
553 else if (opcode_2 == 2)
554 CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
555 else if (opcode_2 == 3)
556 CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
557 }
558 else if (crm == 7)
559 {
560 if (opcode_2 == 0)
561 CP15[CP15_INVALIDATE_UTLB] = value;
562 else if (opcode_2 == 1)
563 CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
564 else if (opcode_2 == 2)
565 CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
566 else if (opcode_2 == 3)
567 CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
568 }
569 }
570 else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
571 {
572 CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
573 }
574 else if (crn == 10 && opcode_1 == 0)
575 {
576 if (crm == 0 && opcode_2 == 0)
577 {
578 CP15[CP15_TLB_LOCKDOWN] = value;
579 }
580 else if (crm == 2)
581 {
582 if (opcode_2 == 0)
583 CP15[CP15_PRIMARY_REGION_REMAP] = value;
584 else if (opcode_2 == 1)
585 CP15[CP15_NORMAL_REGION_REMAP] = value;
586 }
587 }
588 else if (crn == 13 && opcode_1 == 0 && crm == 0)
589 {
590 if (opcode_2 == 0)
591 CP15[CP15_PID] = value;
592 else if (opcode_2 == 1)
593 CP15[CP15_CONTEXT_ID] = value;
594 else if (opcode_2 == 3)
595 CP15[CP15_THREAD_URO] = value;
596 else if (opcode_2 == 4)
597 CP15[CP15_THREAD_PRW] = value;
598 }
599 else if (crn == 15)
600 {
601 if (opcode_1 == 0 && crm == 12)
602 {
603 if (opcode_2 == 0)
604 CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
605 else if (opcode_2 == 1)
606 CP15[CP15_CYCLE_COUNTER] = value;
607 else if (opcode_2 == 2)
608 CP15[CP15_COUNT_0] = value;
609 else if (opcode_2 == 3)
610 CP15[CP15_COUNT_1] = value;
611 }
612 else if (opcode_1 == 5)
613 {
614 if (crm == 4)
615 {
616 if (opcode_2 == 2)
617 CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
618 else if (opcode_2 == 4)
619 CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
620 }
621 else if (crm == 5 && opcode_2 == 2)
622 {
623 CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
624 }
625 else if (crm == 6 && opcode_2 == 2)
626 {
627 CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
628 }
629 else if (crm == 7 && opcode_2 == 2)
630 {
631 CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
632 }
633 }
634 else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
635 {
636 CP15[CP15_TLB_DEBUG_CONTROL] = value;
637 }
638 }
639 }
640
641 // Unprivileged registers
642 if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
643 {
644 CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
645 }
646 else if (crn == 7 && opcode_1 == 0 && crm == 10)
647 {
648 if (opcode_2 == 4)
649 CP15[CP15_DATA_SYNC_BARRIER] = value;
650 else if (opcode_2 == 5)
651 CP15[CP15_DATA_MEMORY_BARRIER] = value;
652 }
653 else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
654 {
655 CP15[CP15_THREAD_UPRW] = value;
656 }
657}
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h
new file mode 100644
index 000000000..88c1dab9d
--- /dev/null
+++ b/src/core/arm/skyeye_common/armstate.h
@@ -0,0 +1,233 @@
1/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#pragma once
19
20#include <array>
21#include <unordered_map>
22
23#include "common/common_types.h"
24#include "core/arm/skyeye_common/arm_regformat.h"
25
26// Signal levels
27enum {
28 LOW = 0,
29 HIGH = 1,
30 LOWHIGH = 1,
31 HIGHLOW = 2
32};
33
34// Cache types
35enum {
36 NONCACHE = 0,
37 DATACACHE = 1,
38 INSTCACHE = 2,
39};
40
41// ARM privilege modes
42enum PrivilegeMode {
43 USER32MODE = 16,
44 FIQ32MODE = 17,
45 IRQ32MODE = 18,
46 SVC32MODE = 19,
47 ABORT32MODE = 23,
48 UNDEF32MODE = 27,
49 SYSTEM32MODE = 31
50};
51
52// ARM privilege mode register banks
53enum {
54 USERBANK = 0,
55 FIQBANK = 1,
56 IRQBANK = 2,
57 SVCBANK = 3,
58 ABORTBANK = 4,
59 UNDEFBANK = 5,
60 DUMMYBANK = 6,
61 SYSTEMBANK = 7
62};
63
64// Hardware vector addresses
65enum {
66 ARMResetV = 0,
67 ARMUndefinedInstrV = 4,
68 ARMSWIV = 8,
69 ARMPrefetchAbortV = 12,
70 ARMDataAbortV = 16,
71 ARMAddrExceptnV = 20,
72 ARMIRQV = 24,
73 ARMFIQV = 28,
74 ARMErrorV = 32, // This is an offset, not an address!
75
76 ARMul_ResetV = ARMResetV,
77 ARMul_UndefinedInstrV = ARMUndefinedInstrV,
78 ARMul_SWIV = ARMSWIV,
79 ARMul_PrefetchAbortV = ARMPrefetchAbortV,
80 ARMul_DataAbortV = ARMDataAbortV,
81 ARMul_AddrExceptnV = ARMAddrExceptnV,
82 ARMul_IRQV = ARMIRQV,
83 ARMul_FIQV = ARMFIQV
84};
85
86// Coprocessor status values
87enum {
88 ARMul_FIRST = 0,
89 ARMul_TRANSFER = 1,
90 ARMul_BUSY = 2,
91 ARMul_DATA = 3,
92 ARMul_INTERRUPT = 4,
93 ARMul_DONE = 0,
94 ARMul_CANT = 1,
95 ARMul_INC = 3
96};
97
98// Instruction condition codes
99enum ConditionCode {
100 EQ = 0,
101 NE = 1,
102 CS = 2,
103 CC = 3,
104 MI = 4,
105 PL = 5,
106 VS = 6,
107 VC = 7,
108 HI = 8,
109 LS = 9,
110 GE = 10,
111 LT = 11,
112 GT = 12,
113 LE = 13,
114 AL = 14,
115 NV = 15,
116};
117
118// Flags for use with the APSR.
119enum : u32 {
120 NBIT = (1U << 31U),
121 ZBIT = (1 << 30),
122 CBIT = (1 << 29),
123 VBIT = (1 << 28),
124 QBIT = (1 << 27),
125 JBIT = (1 << 24),
126 EBIT = (1 << 9),
127 ABIT = (1 << 8),
128 IBIT = (1 << 7),
129 FBIT = (1 << 6),
130 TBIT = (1 << 5),
131
132 // Masks for groups of bits in the APSR.
133 MODEBITS = 0x1F,
134 INTBITS = 0x1C0,
135};
136
137// Values for Emulate.
138enum {
139 STOP = 0, // Stop
140 CHANGEMODE = 1, // Change mode
141 ONCE = 2, // Execute just one iteration
142 RUN = 3 // Continuous execution
143};
144
145
146struct ARMul_State final
147{
148public:
149 explicit ARMul_State(PrivilegeMode initial_mode);
150
151 void ChangePrivilegeMode(u32 new_mode);
152 void Reset();
153
154 // Reads/writes data in big/little endian format based on the
155 // state of the E (endian) bit in the APSR.
156 u16 ReadMemory16(u32 address) const;
157 u32 ReadMemory32(u32 address) const;
158 u64 ReadMemory64(u32 address) const;
159 void WriteMemory16(u32 address, u16 data);
160 void WriteMemory32(u32 address, u32 data);
161 void WriteMemory64(u32 address, u64 data);
162
163 u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const;
164 void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
165
166 // Whether or not the given CPU is in big endian mode (E bit is set)
167 bool InBigEndianMode() const {
168 return (Cpsr & (1 << 9)) != 0;
169 }
170 // Whether or not the given CPU is in a mode other than user mode.
171 bool InAPrivilegedMode() const {
172 return (Mode != USER32MODE);
173 }
174 // Note that for the 3DS, a Thumb instruction will only ever be
175 // two bytes in size. Thus we don't need to worry about ThumbEE
176 // or Thumb-2 where instructions can be 4 bytes in length.
177 u32 GetInstructionSize() const {
178 return TFlag ? 2 : 4;
179 }
180
181 std::array<u32, 16> Reg; // The current register file
182 std::array<u32, 2> Reg_usr;
183 std::array<u32, 2> Reg_svc; // R13_SVC R14_SVC
184 std::array<u32, 2> Reg_abort; // R13_ABORT R14_ABORT
185 std::array<u32, 2> Reg_undef; // R13 UNDEF R14 UNDEF
186 std::array<u32, 2> Reg_irq; // R13_IRQ R14_IRQ
187 std::array<u32, 7> Reg_firq; // R8---R14 FIRQ
188 std::array<u32, 7> Spsr; // The exception psr's
189 std::array<u32, CP15_REGISTER_COUNT> CP15;
190
191 // FPSID, FPSCR, and FPEXC
192 std::array<u32, VFP_SYSTEM_REGISTER_COUNT> VFP;
193
194 // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
195 // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
196 // and only 32 singleword registers are accessible (S0-S31).
197 std::array<u32, 64> ExtReg;
198
199 u32 Emulate; // To start and stop emulation
200 u32 Cpsr; // The current PSR
201 u32 Spsr_copy;
202 u32 phys_pc;
203
204 u32 Mode; // The current mode
205 u32 Bank; // The current register bank
206 u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
207 u32 exclusive_state;
208 u32 exclusive_result;
209
210 u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
211 unsigned int shifter_carry_out;
212
213 u32 TFlag; // Thumb state
214
215 unsigned long long NumInstrs; // The number of instructions executed
216 unsigned NumInstrsToExecute;
217
218 unsigned NresetSig; // Reset the processor
219 unsigned NfiqSig;
220 unsigned NirqSig;
221
222 unsigned abortSig;
223 unsigned NtransSig;
224 unsigned bigendSig;
225 unsigned syscallSig;
226
227 // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
228 // process for our purposes), not per ARMul_State (which tracks CPU core state).
229 std::unordered_map<u32, int> instruction_cache;
230
231private:
232 void ResetMPCoreCP15Registers();
233};
diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp
new file mode 100644
index 000000000..d31fb9449
--- /dev/null
+++ b/src/core/arm/skyeye_common/armsupp.cpp
@@ -0,0 +1,208 @@
1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include "common/logging/log.h"
19
20#include "core/mem_map.h"
21#include "core/arm/skyeye_common/arm_regformat.h"
22#include "core/arm/skyeye_common/armstate.h"
23#include "core/arm/skyeye_common/armsupp.h"
24
25// Unsigned sum of absolute difference
26u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
27{
28 if (left > right)
29 return left - right;
30
31 return right - left;
32}
33
34// Add with carry, indicates if a carry-out or signed overflow occurred.
35u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred)
36{
37 u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in;
38 s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in;
39 u64 result = (unsigned_sum & 0xFFFFFFFF);
40
41 if (carry_out_occurred)
42 *carry_out_occurred = (result != unsigned_sum);
43
44 if (overflow_occurred)
45 *overflow_occurred = ((s64)(s32)result != signed_sum);
46
47 return (u32)result;
48}
49
50// Compute whether an addition of A and B, giving RESULT, overflowed.
51bool AddOverflow(u32 a, u32 b, u32 result)
52{
53 return ((NEG(a) && NEG(b) && POS(result)) ||
54 (POS(a) && POS(b) && NEG(result)));
55}
56
57// Compute whether a subtraction of A and B, giving RESULT, overflowed.
58bool SubOverflow(u32 a, u32 b, u32 result)
59{
60 return ((NEG(a) && POS(b) && POS(result)) ||
61 (POS(a) && NEG(b) && NEG(result)));
62}
63
64// Returns true if the Q flag should be set as a result of overflow.
65bool ARMul_AddOverflowQ(u32 a, u32 b)
66{
67 u32 result = a + b;
68 if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
69 return true;
70
71 return false;
72}
73
74// 8-bit signed saturated addition
75u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
76{
77 u8 result = left + right;
78
79 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
80 if (left & 0x80)
81 result = 0x80;
82 else
83 result = 0x7F;
84 }
85
86 return result;
87}
88
89// 8-bit signed saturated subtraction
90u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
91{
92 u8 result = left - right;
93
94 if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
95 if (left & 0x80)
96 result = 0x80;
97 else
98 result = 0x7F;
99 }
100
101 return result;
102}
103
104// 16-bit signed saturated addition
105u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
106{
107 u16 result = left + right;
108
109 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
110 if (left & 0x8000)
111 result = 0x8000;
112 else
113 result = 0x7FFF;
114 }
115
116 return result;
117}
118
119// 16-bit signed saturated subtraction
120u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
121{
122 u16 result = left - right;
123
124 if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
125 if (left & 0x8000)
126 result = 0x8000;
127 else
128 result = 0x7FFF;
129 }
130
131 return result;
132}
133
134// 8-bit unsigned saturated addition
135u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
136{
137 u8 result = left + right;
138
139 if (result < left)
140 result = 0xFF;
141
142 return result;
143}
144
145// 16-bit unsigned saturated addition
146u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
147{
148 u16 result = left + right;
149
150 if (result < left)
151 result = 0xFFFF;
152
153 return result;
154}
155
156// 8-bit unsigned saturated subtraction
157u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
158{
159 if (left <= right)
160 return 0;
161
162 return left - right;
163}
164
165// 16-bit unsigned saturated subtraction
166u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
167{
168 if (left <= right)
169 return 0;
170
171 return left - right;
172}
173
174// Signed saturation.
175u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
176{
177 const u32 max = (1 << shift) - 1;
178 const s32 top = (value >> shift);
179
180 if (top > 0) {
181 *saturation_occurred = true;
182 return max;
183 }
184 else if (top < -1) {
185 *saturation_occurred = true;
186 return ~max;
187 }
188
189 *saturation_occurred = false;
190 return (u32)value;
191}
192
193// Unsigned saturation
194u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
195{
196 const u32 max = (1 << shift) - 1;
197
198 if (value < 0) {
199 *saturation_occurred = true;
200 return 0;
201 } else if ((u32)value > max) {
202 *saturation_occurred = true;
203 return max;
204 }
205
206 *saturation_occurred = false;
207 return (u32)value;
208}
diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h
new file mode 100644
index 000000000..391309fa8
--- /dev/null
+++ b/src/core/arm/skyeye_common/armsupp.h
@@ -0,0 +1,32 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
10#define BIT(s, n) ((s >> (n)) & 1)
11
12#define POS(i) ( (~(i)) >> 31 )
13#define NEG(i) ( (i) >> 31 )
14
15bool AddOverflow(u32, u32, u32);
16bool SubOverflow(u32, u32, u32);
17
18u32 AddWithCarry(u32, u32, u32, bool*, bool*);
19bool ARMul_AddOverflowQ(u32, u32);
20
21u8 ARMul_SignedSaturatedAdd8(u8, u8);
22u8 ARMul_SignedSaturatedSub8(u8, u8);
23u16 ARMul_SignedSaturatedAdd16(u16, u16);
24u16 ARMul_SignedSaturatedSub16(u16, u16);
25
26u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
27u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
28u8 ARMul_UnsignedSaturatedSub8(u8, u8);
29u16 ARMul_UnsignedSaturatedSub16(u16, u16);
30u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
31u32 ARMul_SignedSatQ(s32, u8, bool*);
32u32 ARMul_UnsignedSatQ(s32, u8, bool*);
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index 1ffc1f9af..26f303de4 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -23,7 +23,7 @@
23#include "common/common_funcs.h" 23#include "common/common_funcs.h"
24#include "common/logging/log.h" 24#include "common/logging/log.h"
25 25
26#include "core/arm/skyeye_common/armdefs.h" 26#include "core/arm/skyeye_common/armstate.h"
27#include "core/arm/skyeye_common/vfp/asm_vfp.h" 27#include "core/arm/skyeye_common/vfp/asm_vfp.h"
28#include "core/arm/skyeye_common/vfp/vfp.h" 28#include "core/arm/skyeye_common/vfp/vfp.h"
29 29
@@ -43,7 +43,7 @@ void VFPInit(ARMul_State* state)
43 state->VFP[VFP_MVFR1] = 0; 43 state->VFP[VFP_MVFR1] = 0;
44} 44}
45 45
46void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value) 46void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value)
47{ 47{
48 if (to_arm) 48 if (to_arm)
49 { 49 {
@@ -55,7 +55,7 @@ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword*
55 } 55 }
56} 56}
57 57
58void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) 58void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2)
59{ 59{
60 if (to_arm) 60 if (to_arm)
61 { 61 {
@@ -68,7 +68,7 @@ void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword
68 state->ExtReg[n*2] = *value1; 68 state->ExtReg[n*2] = *value1;
69 } 69 }
70} 70}
71void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) 71void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2)
72{ 72{
73 if (to_arm) 73 if (to_arm)
74 { 74 {
@@ -82,7 +82,7 @@ void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMwor
82 } 82 }
83} 83}
84 84
85void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) 85void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm)
86{ 86{
87 if (single) 87 if (single)
88 { 88 {
@@ -95,7 +95,7 @@ void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
95 state->ExtReg[d*2] = 0; 95 state->ExtReg[d*2] = 0;
96 } 96 }
97} 97}
98void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) 98void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m)
99{ 99{
100 if (single) 100 if (single)
101 { 101 {
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index 80ca93ccd..88908da9f 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -36,8 +36,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc
36u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr); 36u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
37u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr); 37u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
38 38
39void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value); 39void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value);
40void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); 40void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2);
41void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); 41void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2);
42void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm); 42void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm);
43void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm); 43void VMOVR(ARMul_State* state, u32 single, u32 d, u32 imm);
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h
index 2007d6dc4..91a8d4d57 100644
--- a/src/core/arm/skyeye_common/vfp/vfp_helper.h
+++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h
@@ -34,7 +34,7 @@
34 34
35#include <cstdio> 35#include <cstdio>
36#include "common/common_types.h" 36#include "common/common_types.h"
37#include "core/arm/skyeye_common/armdefs.h" 37#include "core/arm/skyeye_common/armstate.h"
38#include "core/arm/skyeye_common/vfp/asm_vfp.h" 38#include "core/arm/skyeye_common/vfp/asm_vfp.h"
39 39
40#define do_div(n, base) {n/=base;} 40#define do_div(n, base) {n/=base;}
@@ -415,7 +415,7 @@ struct op {
415 u32 flags; 415 u32 flags;
416}; 416};
417 417
418static inline u32 fls(ARMword x) 418static inline u32 fls(u32 x)
419{ 419{
420 int r = 32; 420 int r = 32;
421 421
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
index f91049585..1d844a66e 100644
--- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
@@ -70,9 +70,9 @@ static void vfp_double_dump(const char *str, struct vfp_double *d)
70 70
71static void vfp_double_normalise_denormal(struct vfp_double *vd) 71static void vfp_double_normalise_denormal(struct vfp_double *vd)
72{ 72{
73 int bits = 31 - fls((ARMword)(vd->significand >> 32)); 73 int bits = 31 - fls((u32)(vd->significand >> 32));
74 if (bits == 31) 74 if (bits == 31)
75 bits = 63 - fls((ARMword)vd->significand); 75 bits = 63 - fls((u32)vd->significand);
76 76
77 vfp_double_dump("normalise_denormal: in", vd); 77 vfp_double_dump("normalise_denormal: in", vd);
78 78
@@ -109,9 +109,9 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd,
109 exponent = vd->exponent; 109 exponent = vd->exponent;
110 significand = vd->significand; 110 significand = vd->significand;
111 111
112 shift = 32 - fls((ARMword)(significand >> 32)); 112 shift = 32 - fls((u32)(significand >> 32));
113 if (shift == 32) 113 if (shift == 32)
114 shift = 64 - fls((ARMword)significand); 114 shift = 64 - fls((u32)significand);
115 if (shift) { 115 if (shift) {
116 exponent -= shift; 116 exponent -= shift;
117 significand <<= shift; 117 significand <<= shift;
@@ -566,7 +566,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32
566 /* 566 /*
567 * 2^0 <= m < 2^32-2^8 567 * 2^0 <= m < 2^32-2^8
568 */ 568 */
569 d = (ARMword)((vdm.significand << 1) >> shift); 569 d = (u32)((vdm.significand << 1) >> shift);
570 rem = vdm.significand << (65 - shift); 570 rem = vdm.significand << (65 - shift);
571 571
572 if (rmode == FPSCR_ROUND_NEAREST) { 572 if (rmode == FPSCR_ROUND_NEAREST) {
@@ -647,7 +647,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32
647 int shift = 1023 + 63 - vdm.exponent; /* 58 */ 647 int shift = 1023 + 63 - vdm.exponent; /* 58 */
648 u64 rem, incr = 0; 648 u64 rem, incr = 0;
649 649
650 d = (ARMword)((vdm.significand << 1) >> shift); 650 d = (u32)((vdm.significand << 1) >> shift);
651 rem = vdm.significand << (65 - shift); 651 rem = vdm.significand << (65 - shift);
652 652
653 if (rmode == FPSCR_ROUND_NEAREST) { 653 if (rmode == FPSCR_ROUND_NEAREST) {
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 8efcbab1c..9b99fc5bc 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:
51 51
52 CHECK_VFP_CDP_RET; 52 CHECK_VFP_CDP_RET;
53 } 53 }
54 cpu->Reg[15] += GET_INST_SIZE(cpu); 54 cpu->Reg[15] += cpu->GetInstructionSize();
55 INC_PC(sizeof(vmla_inst)); 55 INC_PC(sizeof(vmla_inst));
56 FETCH_INST; 56 FETCH_INST;
57 GOTO_NEXT_INST; 57 GOTO_NEXT_INST;
@@ -100,7 +100,7 @@ VMLS_INST:
100 100
101 CHECK_VFP_CDP_RET; 101 CHECK_VFP_CDP_RET;
102 } 102 }
103 cpu->Reg[15] += GET_INST_SIZE(cpu); 103 cpu->Reg[15] += cpu->GetInstructionSize();
104 INC_PC(sizeof(vmls_inst)); 104 INC_PC(sizeof(vmls_inst));
105 FETCH_INST; 105 FETCH_INST;
106 GOTO_NEXT_INST; 106 GOTO_NEXT_INST;
@@ -149,7 +149,7 @@ VNMLA_INST:
149 149
150 CHECK_VFP_CDP_RET; 150 CHECK_VFP_CDP_RET;
151 } 151 }
152 cpu->Reg[15] += GET_INST_SIZE(cpu); 152 cpu->Reg[15] += cpu->GetInstructionSize();
153 INC_PC(sizeof(vnmla_inst)); 153 INC_PC(sizeof(vnmla_inst));
154 FETCH_INST; 154 FETCH_INST;
155 GOTO_NEXT_INST; 155 GOTO_NEXT_INST;
@@ -199,7 +199,7 @@ VNMLS_INST:
199 199
200 CHECK_VFP_CDP_RET; 200 CHECK_VFP_CDP_RET;
201 } 201 }
202 cpu->Reg[15] += GET_INST_SIZE(cpu); 202 cpu->Reg[15] += cpu->GetInstructionSize();
203 INC_PC(sizeof(vnmls_inst)); 203 INC_PC(sizeof(vnmls_inst));
204 FETCH_INST; 204 FETCH_INST;
205 GOTO_NEXT_INST; 205 GOTO_NEXT_INST;
@@ -248,7 +248,7 @@ VNMUL_INST:
248 248
249 CHECK_VFP_CDP_RET; 249 CHECK_VFP_CDP_RET;
250 } 250 }
251 cpu->Reg[15] += GET_INST_SIZE(cpu); 251 cpu->Reg[15] += cpu->GetInstructionSize();
252 INC_PC(sizeof(vnmul_inst)); 252 INC_PC(sizeof(vnmul_inst));
253 FETCH_INST; 253 FETCH_INST;
254 GOTO_NEXT_INST; 254 GOTO_NEXT_INST;
@@ -297,7 +297,7 @@ VMUL_INST:
297 297
298 CHECK_VFP_CDP_RET; 298 CHECK_VFP_CDP_RET;
299 } 299 }
300 cpu->Reg[15] += GET_INST_SIZE(cpu); 300 cpu->Reg[15] += cpu->GetInstructionSize();
301 INC_PC(sizeof(vmul_inst)); 301 INC_PC(sizeof(vmul_inst));
302 FETCH_INST; 302 FETCH_INST;
303 GOTO_NEXT_INST; 303 GOTO_NEXT_INST;
@@ -346,7 +346,7 @@ VADD_INST:
346 346
347 CHECK_VFP_CDP_RET; 347 CHECK_VFP_CDP_RET;
348 } 348 }
349 cpu->Reg[15] += GET_INST_SIZE(cpu); 349 cpu->Reg[15] += cpu->GetInstructionSize();
350 INC_PC(sizeof(vadd_inst)); 350 INC_PC(sizeof(vadd_inst));
351 FETCH_INST; 351 FETCH_INST;
352 GOTO_NEXT_INST; 352 GOTO_NEXT_INST;
@@ -395,7 +395,7 @@ VSUB_INST:
395 395
396 CHECK_VFP_CDP_RET; 396 CHECK_VFP_CDP_RET;
397 } 397 }
398 cpu->Reg[15] += GET_INST_SIZE(cpu); 398 cpu->Reg[15] += cpu->GetInstructionSize();
399 INC_PC(sizeof(vsub_inst)); 399 INC_PC(sizeof(vsub_inst));
400 FETCH_INST; 400 FETCH_INST;
401 GOTO_NEXT_INST; 401 GOTO_NEXT_INST;
@@ -444,7 +444,7 @@ VDIV_INST:
444 444
445 CHECK_VFP_CDP_RET; 445 CHECK_VFP_CDP_RET;
446 } 446 }
447 cpu->Reg[15] += GET_INST_SIZE(cpu); 447 cpu->Reg[15] += cpu->GetInstructionSize();
448 INC_PC(sizeof(vdiv_inst)); 448 INC_PC(sizeof(vdiv_inst));
449 FETCH_INST; 449 FETCH_INST;
450 GOTO_NEXT_INST; 450 GOTO_NEXT_INST;
@@ -492,7 +492,7 @@ VMOVI_INST:
492 492
493 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); 493 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
494 } 494 }
495 cpu->Reg[15] += GET_INST_SIZE(cpu); 495 cpu->Reg[15] += cpu->GetInstructionSize();
496 INC_PC(sizeof(vmovi_inst)); 496 INC_PC(sizeof(vmovi_inst));
497 FETCH_INST; 497 FETCH_INST;
498 GOTO_NEXT_INST; 498 GOTO_NEXT_INST;
@@ -536,7 +536,7 @@ VMOVR_INST:
536 536
537 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); 537 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
538 } 538 }
539 cpu->Reg[15] += GET_INST_SIZE(cpu); 539 cpu->Reg[15] += cpu->GetInstructionSize();
540 INC_PC(sizeof(vmovr_inst)); 540 INC_PC(sizeof(vmovr_inst));
541 FETCH_INST; 541 FETCH_INST;
542 GOTO_NEXT_INST; 542 GOTO_NEXT_INST;
@@ -585,7 +585,7 @@ VABS_INST:
585 585
586 CHECK_VFP_CDP_RET; 586 CHECK_VFP_CDP_RET;
587 } 587 }
588 cpu->Reg[15] += GET_INST_SIZE(cpu); 588 cpu->Reg[15] += cpu->GetInstructionSize();
589 INC_PC(sizeof(vabs_inst)); 589 INC_PC(sizeof(vabs_inst));
590 FETCH_INST; 590 FETCH_INST;
591 GOTO_NEXT_INST; 591 GOTO_NEXT_INST;
@@ -635,7 +635,7 @@ VNEG_INST:
635 635
636 CHECK_VFP_CDP_RET; 636 CHECK_VFP_CDP_RET;
637 } 637 }
638 cpu->Reg[15] += GET_INST_SIZE(cpu); 638 cpu->Reg[15] += cpu->GetInstructionSize();
639 INC_PC(sizeof(vneg_inst)); 639 INC_PC(sizeof(vneg_inst));
640 FETCH_INST; 640 FETCH_INST;
641 GOTO_NEXT_INST; 641 GOTO_NEXT_INST;
@@ -684,7 +684,7 @@ VSQRT_INST:
684 684
685 CHECK_VFP_CDP_RET; 685 CHECK_VFP_CDP_RET;
686 } 686 }
687 cpu->Reg[15] += GET_INST_SIZE(cpu); 687 cpu->Reg[15] += cpu->GetInstructionSize();
688 INC_PC(sizeof(vsqrt_inst)); 688 INC_PC(sizeof(vsqrt_inst));
689 FETCH_INST; 689 FETCH_INST;
690 GOTO_NEXT_INST; 690 GOTO_NEXT_INST;
@@ -733,7 +733,7 @@ VCMP_INST:
733 733
734 CHECK_VFP_CDP_RET; 734 CHECK_VFP_CDP_RET;
735 } 735 }
736 cpu->Reg[15] += GET_INST_SIZE(cpu); 736 cpu->Reg[15] += cpu->GetInstructionSize();
737 INC_PC(sizeof(vcmp_inst)); 737 INC_PC(sizeof(vcmp_inst));
738 FETCH_INST; 738 FETCH_INST;
739 GOTO_NEXT_INST; 739 GOTO_NEXT_INST;
@@ -782,7 +782,7 @@ VCMP2_INST:
782 782
783 CHECK_VFP_CDP_RET; 783 CHECK_VFP_CDP_RET;
784 } 784 }
785 cpu->Reg[15] += GET_INST_SIZE(cpu); 785 cpu->Reg[15] += cpu->GetInstructionSize();
786 INC_PC(sizeof(vcmp2_inst)); 786 INC_PC(sizeof(vcmp2_inst));
787 FETCH_INST; 787 FETCH_INST;
788 GOTO_NEXT_INST; 788 GOTO_NEXT_INST;
@@ -831,7 +831,7 @@ VCVTBDS_INST:
831 831
832 CHECK_VFP_CDP_RET; 832 CHECK_VFP_CDP_RET;
833 } 833 }
834 cpu->Reg[15] += GET_INST_SIZE(cpu); 834 cpu->Reg[15] += cpu->GetInstructionSize();
835 INC_PC(sizeof(vcvtbds_inst)); 835 INC_PC(sizeof(vcvtbds_inst));
836 FETCH_INST; 836 FETCH_INST;
837 GOTO_NEXT_INST; 837 GOTO_NEXT_INST;
@@ -882,7 +882,7 @@ VCVTBFF_INST:
882 882
883 CHECK_VFP_CDP_RET; 883 CHECK_VFP_CDP_RET;
884 } 884 }
885 cpu->Reg[15] += GET_INST_SIZE(cpu); 885 cpu->Reg[15] += cpu->GetInstructionSize();
886 INC_PC(sizeof(vcvtbff_inst)); 886 INC_PC(sizeof(vcvtbff_inst));
887 FETCH_INST; 887 FETCH_INST;
888 GOTO_NEXT_INST; 888 GOTO_NEXT_INST;
@@ -931,7 +931,7 @@ VCVTBFI_INST:
931 931
932 CHECK_VFP_CDP_RET; 932 CHECK_VFP_CDP_RET;
933 } 933 }
934 cpu->Reg[15] += GET_INST_SIZE(cpu); 934 cpu->Reg[15] += cpu->GetInstructionSize();
935 INC_PC(sizeof(vcvtbfi_inst)); 935 INC_PC(sizeof(vcvtbfi_inst));
936 FETCH_INST; 936 FETCH_INST;
937 GOTO_NEXT_INST; 937 GOTO_NEXT_INST;
@@ -981,7 +981,7 @@ VMOVBRS_INST:
981 981
982 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); 982 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
983 } 983 }
984 cpu->Reg[15] += GET_INST_SIZE(cpu); 984 cpu->Reg[15] += cpu->GetInstructionSize();
985 INC_PC(sizeof(vmovbrs_inst)); 985 INC_PC(sizeof(vmovbrs_inst));
986 FETCH_INST; 986 FETCH_INST;
987 GOTO_NEXT_INST; 987 GOTO_NEXT_INST;
@@ -1032,7 +1032,7 @@ VMSR_INST:
1032 { 1032 {
1033 cpu->VFP[VFP_FPSCR] = cpu->Reg[rt]; 1033 cpu->VFP[VFP_FPSCR] = cpu->Reg[rt];
1034 } 1034 }
1035 else if (InAPrivilegedMode(cpu)) 1035 else if (cpu->InAPrivilegedMode())
1036 { 1036 {
1037 if (reg == 8) 1037 if (reg == 8)
1038 cpu->VFP[VFP_FPEXC] = cpu->Reg[rt]; 1038 cpu->VFP[VFP_FPEXC] = cpu->Reg[rt];
@@ -1042,7 +1042,7 @@ VMSR_INST:
1042 cpu->VFP[VFP_FPINST2] = cpu->Reg[rt]; 1042 cpu->VFP[VFP_FPINST2] = cpu->Reg[rt];
1043 } 1043 }
1044 } 1044 }
1045 cpu->Reg[15] += GET_INST_SIZE(cpu); 1045 cpu->Reg[15] += cpu->GetInstructionSize();
1046 INC_PC(sizeof(vmsr_inst)); 1046 INC_PC(sizeof(vmsr_inst));
1047 FETCH_INST; 1047 FETCH_INST;
1048 GOTO_NEXT_INST; 1048 GOTO_NEXT_INST;
@@ -1090,7 +1090,7 @@ VMOVBRC_INST:
1090 1090
1091 cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t]; 1091 cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t];
1092 } 1092 }
1093 cpu->Reg[15] += GET_INST_SIZE(cpu); 1093 cpu->Reg[15] += cpu->GetInstructionSize();
1094 INC_PC(sizeof(vmovbrc_inst)); 1094 INC_PC(sizeof(vmovbrc_inst));
1095 FETCH_INST; 1095 FETCH_INST;
1096 GOTO_NEXT_INST; 1096 GOTO_NEXT_INST;
@@ -1163,7 +1163,7 @@ VMRS_INST:
1163 { 1163 {
1164 cpu->Reg[rt] = cpu->VFP[VFP_MVFR0]; 1164 cpu->Reg[rt] = cpu->VFP[VFP_MVFR0];
1165 } 1165 }
1166 else if (InAPrivilegedMode(cpu)) 1166 else if (cpu->InAPrivilegedMode())
1167 { 1167 {
1168 if (reg == 8) 1168 if (reg == 8)
1169 cpu->Reg[rt] = cpu->VFP[VFP_FPEXC]; 1169 cpu->Reg[rt] = cpu->VFP[VFP_FPEXC];
@@ -1173,7 +1173,7 @@ VMRS_INST:
1173 cpu->Reg[rt] = cpu->VFP[VFP_FPINST2]; 1173 cpu->Reg[rt] = cpu->VFP[VFP_FPINST2];
1174 } 1174 }
1175 } 1175 }
1176 cpu->Reg[15] += GET_INST_SIZE(cpu); 1176 cpu->Reg[15] += cpu->GetInstructionSize();
1177 INC_PC(sizeof(vmrs_inst)); 1177 INC_PC(sizeof(vmrs_inst));
1178 FETCH_INST; 1178 FETCH_INST;
1179 GOTO_NEXT_INST; 1179 GOTO_NEXT_INST;
@@ -1221,7 +1221,7 @@ VMOVBCR_INST:
1221 1221
1222 cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index]; 1222 cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index];
1223 } 1223 }
1224 cpu->Reg[15] += GET_INST_SIZE(cpu); 1224 cpu->Reg[15] += cpu->GetInstructionSize();
1225 INC_PC(sizeof(vmovbcr_inst)); 1225 INC_PC(sizeof(vmovbcr_inst));
1226 FETCH_INST; 1226 FETCH_INST;
1227 GOTO_NEXT_INST; 1227 GOTO_NEXT_INST;
@@ -1274,7 +1274,7 @@ VMOVBRRSS_INST:
1274 VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 1274 VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
1275 &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); 1275 &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]);
1276 } 1276 }
1277 cpu->Reg[15] += GET_INST_SIZE(cpu); 1277 cpu->Reg[15] += cpu->GetInstructionSize();
1278 INC_PC(sizeof(vmovbrrss_inst)); 1278 INC_PC(sizeof(vmovbrrss_inst));
1279 FETCH_INST; 1279 FETCH_INST;
1280 GOTO_NEXT_INST; 1280 GOTO_NEXT_INST;
@@ -1322,7 +1322,7 @@ VMOVBRRD_INST:
1322 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 1322 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
1323 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); 1323 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
1324 } 1324 }
1325 cpu->Reg[15] += GET_INST_SIZE(cpu); 1325 cpu->Reg[15] += cpu->GetInstructionSize();
1326 INC_PC(sizeof(vmovbrrd_inst)); 1326 INC_PC(sizeof(vmovbrrd_inst));
1327 FETCH_INST; 1327 FETCH_INST;
1328 GOTO_NEXT_INST; 1328 GOTO_NEXT_INST;
@@ -1378,23 +1378,23 @@ VSTR_INST:
1378 1378
1379 if (inst_cream->single) 1379 if (inst_cream->single)
1380 { 1380 {
1381 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d]); 1381 cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]);
1382 } 1382 }
1383 else 1383 else
1384 { 1384 {
1385 const u32 word1 = cpu->ExtReg[inst_cream->d*2+0]; 1385 const u32 word1 = cpu->ExtReg[inst_cream->d*2+0];
1386 const u32 word2 = cpu->ExtReg[inst_cream->d*2+1]; 1386 const u32 word2 = cpu->ExtReg[inst_cream->d*2+1];
1387 1387
1388 if (InBigEndianMode(cpu)) { 1388 if (cpu->InBigEndianMode()) {
1389 WriteMemory32(cpu, addr + 0, word2); 1389 cpu->WriteMemory32(addr + 0, word2);
1390 WriteMemory32(cpu, addr + 4, word1); 1390 cpu->WriteMemory32(addr + 4, word1);
1391 } else { 1391 } else {
1392 WriteMemory32(cpu, addr + 0, word1); 1392 cpu->WriteMemory32(addr + 0, word1);
1393 WriteMemory32(cpu, addr + 4, word2); 1393 cpu->WriteMemory32(addr + 4, word2);
1394 } 1394 }
1395 } 1395 }
1396 } 1396 }
1397 cpu->Reg[15] += GET_INST_SIZE(cpu); 1397 cpu->Reg[15] += cpu->GetInstructionSize();
1398 INC_PC(sizeof(vstr_inst)); 1398 INC_PC(sizeof(vstr_inst));
1399 FETCH_INST; 1399 FETCH_INST;
1400 GOTO_NEXT_INST; 1400 GOTO_NEXT_INST;
@@ -1444,7 +1444,7 @@ VPUSH_INST:
1444 { 1444 {
1445 if (inst_cream->single) 1445 if (inst_cream->single)
1446 { 1446 {
1447 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]); 1447 cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
1448 addr += 4; 1448 addr += 4;
1449 } 1449 }
1450 else 1450 else
@@ -1452,12 +1452,12 @@ VPUSH_INST:
1452 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; 1452 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
1453 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; 1453 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
1454 1454
1455 if (InBigEndianMode(cpu)) { 1455 if (cpu->InBigEndianMode()) {
1456 WriteMemory32(cpu, addr + 0, word2); 1456 cpu->WriteMemory32(addr + 0, word2);
1457 WriteMemory32(cpu, addr + 4, word1); 1457 cpu->WriteMemory32(addr + 4, word1);
1458 } else { 1458 } else {
1459 WriteMemory32(cpu, addr + 0, word1); 1459 cpu->WriteMemory32(addr + 0, word1);
1460 WriteMemory32(cpu, addr + 4, word2); 1460 cpu->WriteMemory32(addr + 4, word2);
1461 } 1461 }
1462 1462
1463 addr += 8; 1463 addr += 8;
@@ -1466,7 +1466,7 @@ VPUSH_INST:
1466 1466
1467 cpu->Reg[R13] -= inst_cream->imm32; 1467 cpu->Reg[R13] -= inst_cream->imm32;
1468 } 1468 }
1469 cpu->Reg[15] += GET_INST_SIZE(cpu); 1469 cpu->Reg[15] += cpu->GetInstructionSize();
1470 INC_PC(sizeof(vpush_inst)); 1470 INC_PC(sizeof(vpush_inst));
1471 FETCH_INST; 1471 FETCH_INST;
1472 GOTO_NEXT_INST; 1472 GOTO_NEXT_INST;
@@ -1522,7 +1522,7 @@ VSTM_INST: /* encoding 1 */
1522 { 1522 {
1523 if (inst_cream->single) 1523 if (inst_cream->single)
1524 { 1524 {
1525 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]); 1525 cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
1526 addr += 4; 1526 addr += 4;
1527 } 1527 }
1528 else 1528 else
@@ -1530,12 +1530,12 @@ VSTM_INST: /* encoding 1 */
1530 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; 1530 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
1531 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; 1531 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
1532 1532
1533 if (InBigEndianMode(cpu)) { 1533 if (cpu->InBigEndianMode()) {
1534 WriteMemory32(cpu, addr + 0, word2); 1534 cpu->WriteMemory32(addr + 0, word2);
1535 WriteMemory32(cpu, addr + 4, word1); 1535 cpu->WriteMemory32(addr + 4, word1);
1536 } else { 1536 } else {
1537 WriteMemory32(cpu, addr + 0, word1); 1537 cpu->WriteMemory32(addr + 0, word1);
1538 WriteMemory32(cpu, addr + 4, word2); 1538 cpu->WriteMemory32(addr + 4, word2);
1539 } 1539 }
1540 1540
1541 addr += 8; 1541 addr += 8;
@@ -1597,15 +1597,15 @@ VPOP_INST:
1597 { 1597 {
1598 if (inst_cream->single) 1598 if (inst_cream->single)
1599 { 1599 {
1600 cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr); 1600 cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
1601 addr += 4; 1601 addr += 4;
1602 } 1602 }
1603 else 1603 else
1604 { 1604 {
1605 const u32 word1 = ReadMemory32(cpu, addr + 0); 1605 const u32 word1 = cpu->ReadMemory32(addr + 0);
1606 const u32 word2 = ReadMemory32(cpu, addr + 4); 1606 const u32 word2 = cpu->ReadMemory32(addr + 4);
1607 1607
1608 if (InBigEndianMode(cpu)) { 1608 if (cpu->InBigEndianMode()) {
1609 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; 1609 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
1610 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; 1610 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
1611 } else { 1611 } else {
@@ -1618,7 +1618,7 @@ VPOP_INST:
1618 } 1618 }
1619 cpu->Reg[R13] += inst_cream->imm32; 1619 cpu->Reg[R13] += inst_cream->imm32;
1620 } 1620 }
1621 cpu->Reg[15] += GET_INST_SIZE(cpu); 1621 cpu->Reg[15] += cpu->GetInstructionSize();
1622 INC_PC(sizeof(vpop_inst)); 1622 INC_PC(sizeof(vpop_inst));
1623 FETCH_INST; 1623 FETCH_INST;
1624 GOTO_NEXT_INST; 1624 GOTO_NEXT_INST;
@@ -1670,14 +1670,14 @@ VLDR_INST:
1670 1670
1671 if (inst_cream->single) 1671 if (inst_cream->single)
1672 { 1672 {
1673 cpu->ExtReg[inst_cream->d] = ReadMemory32(cpu, addr); 1673 cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr);
1674 } 1674 }
1675 else 1675 else
1676 { 1676 {
1677 const u32 word1 = ReadMemory32(cpu, addr + 0); 1677 const u32 word1 = cpu->ReadMemory32(addr + 0);
1678 const u32 word2 = ReadMemory32(cpu, addr + 4); 1678 const u32 word2 = cpu->ReadMemory32(addr + 4);
1679 1679
1680 if (InBigEndianMode(cpu)) { 1680 if (cpu->InBigEndianMode()) {
1681 cpu->ExtReg[inst_cream->d*2+0] = word2; 1681 cpu->ExtReg[inst_cream->d*2+0] = word2;
1682 cpu->ExtReg[inst_cream->d*2+1] = word1; 1682 cpu->ExtReg[inst_cream->d*2+1] = word1;
1683 } else { 1683 } else {
@@ -1686,7 +1686,7 @@ VLDR_INST:
1686 } 1686 }
1687 } 1687 }
1688 } 1688 }
1689 cpu->Reg[15] += GET_INST_SIZE(cpu); 1689 cpu->Reg[15] += cpu->GetInstructionSize();
1690 INC_PC(sizeof(vldr_inst)); 1690 INC_PC(sizeof(vldr_inst));
1691 FETCH_INST; 1691 FETCH_INST;
1692 GOTO_NEXT_INST; 1692 GOTO_NEXT_INST;
@@ -1742,15 +1742,15 @@ VLDM_INST:
1742 { 1742 {
1743 if (inst_cream->single) 1743 if (inst_cream->single)
1744 { 1744 {
1745 cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr); 1745 cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
1746 addr += 4; 1746 addr += 4;
1747 } 1747 }
1748 else 1748 else
1749 { 1749 {
1750 const u32 word1 = ReadMemory32(cpu, addr + 0); 1750 const u32 word1 = cpu->ReadMemory32(addr + 0);
1751 const u32 word2 = ReadMemory32(cpu, addr + 4); 1751 const u32 word2 = cpu->ReadMemory32(addr + 4);
1752 1752
1753 if (InBigEndianMode(cpu)) { 1753 if (cpu->InBigEndianMode()) {
1754 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; 1754 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
1755 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; 1755 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
1756 } else { 1756 } else {
@@ -1766,7 +1766,7 @@ VLDM_INST:
1766 cpu->Reg[inst_cream->n] - inst_cream->imm32); 1766 cpu->Reg[inst_cream->n] - inst_cream->imm32);
1767 } 1767 }
1768 } 1768 }
1769 cpu->Reg[15] += GET_INST_SIZE(cpu); 1769 cpu->Reg[15] += cpu->GetInstructionSize();
1770 INC_PC(sizeof(vldm_inst)); 1770 INC_PC(sizeof(vldm_inst));
1771 FETCH_INST; 1771 FETCH_INST;
1772 GOTO_NEXT_INST; 1772 GOTO_NEXT_INST;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 8b49fc7df..29ea6d531 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,7 +13,7 @@
13#include "common/thread_queue_list.h" 13#include "common/thread_queue_list.h"
14 14
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/arm/skyeye_common/armdefs.h" 16#include "core/arm/skyeye_common/armstate.h"
17#include "core/core.h" 17#include "core/core.h"
18#include "core/core_timing.h" 18#include "core/core_timing.h"
19#include "core/hle/hle.h" 19#include "core/hle/hle.h"
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 5c7f4ae18..162108301 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -2,7 +2,6 @@ set(SRCS
2 renderer_opengl/generated/gl_3_2_core.c 2 renderer_opengl/generated/gl_3_2_core.c
3 renderer_opengl/gl_rasterizer.cpp 3 renderer_opengl/gl_rasterizer.cpp
4 renderer_opengl/gl_rasterizer_cache.cpp 4 renderer_opengl/gl_rasterizer_cache.cpp
5 renderer_opengl/gl_resource_manager.cpp
6 renderer_opengl/gl_shader_util.cpp 5 renderer_opengl/gl_shader_util.cpp
7 renderer_opengl/gl_state.cpp 6 renderer_opengl/gl_state.cpp
8 renderer_opengl/renderer_opengl.cpp 7 renderer_opengl/renderer_opengl.cpp
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 43ae06181..ef9584abd 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -116,7 +116,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
116 { 116 {
117 Common::Profiling::ScopeTimer scope_timer(category_drawing); 117 Common::Profiling::ScopeTimer scope_timer(category_drawing);
118 118
119#if PICA_LOG_TEV
119 DebugUtils::DumpTevStageConfig(regs.GetTevStages()); 120 DebugUtils::DumpTevStageConfig(regs.GetTevStages());
121#endif
120 122
121 if (g_debug_context) 123 if (g_debug_context)
122 g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); 124 g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
@@ -159,9 +161,11 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
159 const u16* index_address_16 = (u16*)index_address_8; 161 const u16* index_address_16 = (u16*)index_address_8;
160 bool index_u16 = index_info.format != 0; 162 bool index_u16 = index_info.format != 0;
161 163
164#if PICA_DUMP_GEOMETRY
162 DebugUtils::GeometryDumper geometry_dumper; 165 DebugUtils::GeometryDumper geometry_dumper;
163 PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
164 PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value()); 166 PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value());
167#endif
168 PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
165 169
166 if (g_debug_context) { 170 if (g_debug_context) {
167 for (int i = 0; i < 3; ++i) { 171 for (int i = 0; i < 3; ++i) {
@@ -271,6 +275,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
271 if (g_debug_context) 275 if (g_debug_context)
272 g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); 276 g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input);
273 277
278#if PICA_DUMP_GEOMETRY
274 // NOTE: When dumping geometry, we simply assume that the first input attribute 279 // NOTE: When dumping geometry, we simply assume that the first input attribute
275 // corresponds to the position for now. 280 // corresponds to the position for now.
276 DebugUtils::GeometryDumper::Vertex dumped_vertex = { 281 DebugUtils::GeometryDumper::Vertex dumped_vertex = {
@@ -280,6 +285,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
280 dumping_primitive_assembler.SubmitVertex(dumped_vertex, 285 dumping_primitive_assembler.SubmitVertex(dumped_vertex,
281 std::bind(&DebugUtils::GeometryDumper::AddTriangle, 286 std::bind(&DebugUtils::GeometryDumper::AddTriangle,
282 &geometry_dumper, _1, _2, _3)); 287 &geometry_dumper, _1, _2, _3));
288#endif
283 289
284 // Send to vertex shader 290 // Send to vertex shader
285 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes(), g_state.regs.vs, g_state.vs); 291 VertexShader::OutputVertex output = VertexShader::RunShader(input, attribute_config.GetNumTotalAttributes(), g_state.regs.vs, g_state.vs);
@@ -312,7 +318,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
312 VideoCore::g_renderer->hw_rasterizer->DrawTriangles(); 318 VideoCore::g_renderer->hw_rasterizer->DrawTriangles();
313 } 319 }
314 320
321#if PICA_DUMP_GEOMETRY
315 geometry_dumper.Dump(); 322 geometry_dumper.Dump();
323#endif
316 324
317 if (g_debug_context) { 325 if (g_debug_context) {
318 g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); 326 g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index c3f8321c6..e9a858411 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -90,10 +90,6 @@ void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) {
90} 90}
91 91
92void GeometryDumper::Dump() { 92void GeometryDumper::Dump() {
93 // NOTE: Permanently enabling this just trashes the hard disk for no reason.
94 // Hence, this is currently disabled.
95 return;
96
97 static int index = 0; 93 static int index = 0;
98 std::string filename = std::string("geometry_dump") + std::to_string(++index) + ".obj"; 94 std::string filename = std::string("geometry_dump") + std::to_string(++index) + ".obj";
99 95
@@ -116,10 +112,6 @@ void GeometryDumper::Dump() {
116void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, 112void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size,
117 u32 main_offset, const Regs::VSOutputAttributes* output_attributes) 113 u32 main_offset, const Regs::VSOutputAttributes* output_attributes)
118{ 114{
119 // NOTE: Permanently enabling this just trashes hard disks for no reason.
120 // Hence, this is currently disabled.
121 return;
122
123 struct StuffToWrite { 115 struct StuffToWrite {
124 u8* pointer; 116 u8* pointer;
125 u32 size; 117 u32 size;
@@ -565,10 +557,6 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config,
565} 557}
566 558
567void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { 559void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
568 // NOTE: Permanently enabling this just trashes hard disks for no reason.
569 // Hence, this is currently disabled.
570 return;
571
572#ifndef HAVE_PNG 560#ifndef HAVE_PNG
573 return; 561 return;
574#else 562#else
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index 3f109dcb7..81eea30a9 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -157,6 +157,11 @@ extern std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this g
157 157
158namespace DebugUtils { 158namespace DebugUtils {
159 159
160#define PICA_DUMP_GEOMETRY 0
161#define PICA_DUMP_SHADERS 0
162#define PICA_DUMP_TEXTURES 0
163#define PICA_LOG_TEV 0
164
160// Simple utility class for dumping geometry data to an OBJ file 165// Simple utility class for dumping geometry data to an OBJ file
161class GeometryDumper { 166class GeometryDumper {
162public: 167public:
diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp
index 543d9c443..17cb66780 100644
--- a/src/video_core/pica.cpp
+++ b/src/video_core/pica.cpp
@@ -2,7 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <string.h> 5#include <cstring>
6#include <unordered_map>
6 7
7#include "pica.h" 8#include "pica.h"
8 9
@@ -10,6 +11,75 @@ namespace Pica {
10 11
11State g_state; 12State g_state;
12 13
14std::string Regs::GetCommandName(int index) {
15 static std::unordered_map<u32, std::string> map;
16
17 if (map.empty()) {
18 #define ADD_FIELD(name) \
19 map.insert({static_cast<u32>(PICA_REG_INDEX(name)), #name}); \
20 /* TODO: change to Regs::name when VS2015 and other compilers support it */ \
21 for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(Regs().name) / 4; ++i) \
22 map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \
23
24 ADD_FIELD(trigger_irq);
25 ADD_FIELD(cull_mode);
26 ADD_FIELD(viewport_size_x);
27 ADD_FIELD(viewport_size_y);
28 ADD_FIELD(viewport_depth_range);
29 ADD_FIELD(viewport_depth_far_plane);
30 ADD_FIELD(viewport_corner);
31 ADD_FIELD(texture0_enable);
32 ADD_FIELD(texture0);
33 ADD_FIELD(texture0_format);
34 ADD_FIELD(texture1);
35 ADD_FIELD(texture1_format);
36 ADD_FIELD(texture2);
37 ADD_FIELD(texture2_format);
38 ADD_FIELD(tev_stage0);
39 ADD_FIELD(tev_stage1);
40 ADD_FIELD(tev_stage2);
41 ADD_FIELD(tev_stage3);
42 ADD_FIELD(tev_combiner_buffer_input);
43 ADD_FIELD(tev_stage4);
44 ADD_FIELD(tev_stage5);
45 ADD_FIELD(tev_combiner_buffer_color);
46 ADD_FIELD(output_merger);
47 ADD_FIELD(framebuffer);
48 ADD_FIELD(vertex_attributes);
49 ADD_FIELD(index_array);
50 ADD_FIELD(num_vertices);
51 ADD_FIELD(trigger_draw);
52 ADD_FIELD(trigger_draw_indexed);
53 ADD_FIELD(vs_default_attributes_setup);
54 ADD_FIELD(command_buffer);
55 ADD_FIELD(triangle_topology);
56 ADD_FIELD(gs.bool_uniforms);
57 ADD_FIELD(gs.int_uniforms);
58 ADD_FIELD(gs.main_offset);
59 ADD_FIELD(gs.input_register_map);
60 ADD_FIELD(gs.uniform_setup);
61 ADD_FIELD(gs.program);
62 ADD_FIELD(gs.swizzle_patterns);
63 ADD_FIELD(vs.bool_uniforms);
64 ADD_FIELD(vs.int_uniforms);
65 ADD_FIELD(vs.main_offset);
66 ADD_FIELD(vs.input_register_map);
67 ADD_FIELD(vs.uniform_setup);
68 ADD_FIELD(vs.program);
69 ADD_FIELD(vs.swizzle_patterns);
70
71#undef ADD_FIELD
72 }
73
74 // Return empty string if no match is found
75 auto it = map.find(index);
76 if (it != map.end()) {
77 return it->second;
78 } else {
79 return std::string();
80 }
81}
82
13void Init() { 83void Init() {
14} 84}
15 85
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 38599a7a3..34b02b2f8 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -7,7 +7,6 @@
7#include <array> 7#include <array>
8#include <cmath> 8#include <cmath>
9#include <cstddef> 9#include <cstddef>
10#include <map>
11#include <string> 10#include <string>
12 11
13#include "common/assert.h" 12#include "common/assert.h"
@@ -908,69 +907,7 @@ struct Regs {
908 907
909 // Map register indices to names readable by humans 908 // Map register indices to names readable by humans
910 // Used for debugging purposes, so performance is not an issue here 909 // Used for debugging purposes, so performance is not an issue here
911 static std::string GetCommandName(int index) { 910 static std::string GetCommandName(int index);
912 std::map<u32, std::string> map;
913
914 #define ADD_FIELD(name) \
915 do { \
916 map.insert({static_cast<u32>(PICA_REG_INDEX(name)), #name}); \
917 /* TODO: change to Regs::name when VS2015 and other compilers support it */ \
918 for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(Regs().name) / 4; ++i) \
919 map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \
920 } while(false)
921
922 ADD_FIELD(trigger_irq);
923 ADD_FIELD(cull_mode);
924 ADD_FIELD(viewport_size_x);
925 ADD_FIELD(viewport_size_y);
926 ADD_FIELD(viewport_depth_range);
927 ADD_FIELD(viewport_depth_far_plane);
928 ADD_FIELD(viewport_corner);
929 ADD_FIELD(texture0_enable);
930 ADD_FIELD(texture0);
931 ADD_FIELD(texture0_format);
932 ADD_FIELD(texture1);
933 ADD_FIELD(texture1_format);
934 ADD_FIELD(texture2);
935 ADD_FIELD(texture2_format);
936 ADD_FIELD(tev_stage0);
937 ADD_FIELD(tev_stage1);
938 ADD_FIELD(tev_stage2);
939 ADD_FIELD(tev_stage3);
940 ADD_FIELD(tev_combiner_buffer_input);
941 ADD_FIELD(tev_stage4);
942 ADD_FIELD(tev_stage5);
943 ADD_FIELD(tev_combiner_buffer_color);
944 ADD_FIELD(output_merger);
945 ADD_FIELD(framebuffer);
946 ADD_FIELD(vertex_attributes);
947 ADD_FIELD(index_array);
948 ADD_FIELD(num_vertices);
949 ADD_FIELD(trigger_draw);
950 ADD_FIELD(trigger_draw_indexed);
951 ADD_FIELD(vs_default_attributes_setup);
952 ADD_FIELD(command_buffer);
953 ADD_FIELD(triangle_topology);
954 ADD_FIELD(gs.bool_uniforms);
955 ADD_FIELD(gs.int_uniforms);
956 ADD_FIELD(gs.main_offset);
957 ADD_FIELD(gs.input_register_map);
958 ADD_FIELD(gs.uniform_setup);
959 ADD_FIELD(gs.program);
960 ADD_FIELD(gs.swizzle_patterns);
961 ADD_FIELD(vs.bool_uniforms);
962 ADD_FIELD(vs.int_uniforms);
963 ADD_FIELD(vs.main_offset);
964 ADD_FIELD(vs.input_register_map);
965 ADD_FIELD(vs.uniform_setup);
966 ADD_FIELD(vs.program);
967 ADD_FIELD(vs.swizzle_patterns);
968
969 #undef ADD_FIELD
970
971 // Return empty string if no match is found
972 return map[index];
973 }
974 911
975 static inline size_t NumIds() { 912 static inline size_t NumIds() {
976 return sizeof(Regs) / sizeof(u32); 913 return sizeof(Regs) / sizeof(u32);
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index e2b90ad1c..68b7cc05d 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -462,7 +462,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
462 462
463 // TODO: Apply the min and mag filters to the texture 463 // TODO: Apply the min and mag filters to the texture
464 texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info); 464 texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info);
465#if PICA_DUMP_TEXTURES
465 DebugUtils::DumpTexture(texture.config, texture_data); 466 DebugUtils::DumpTexture(texture.config, texture_data);
467#endif
466 } 468 }
467 } 469 }
468 470
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
deleted file mode 100644
index 8f4ae28a4..000000000
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/renderer_opengl/gl_resource_manager.h"
6#include "video_core/renderer_opengl/gl_shader_util.h"
7
8// Textures
9OGLTexture::OGLTexture() : handle(0) {
10}
11
12OGLTexture::~OGLTexture() {
13 Release();
14}
15
16void OGLTexture::Create() {
17 if (handle != 0) {
18 return;
19 }
20
21 glGenTextures(1, &handle);
22}
23
24void OGLTexture::Release() {
25 glDeleteTextures(1, &handle);
26 handle = 0;
27}
28
29// Shaders
30OGLShader::OGLShader() : handle(0) {
31}
32
33OGLShader::~OGLShader() {
34 Release();
35}
36
37void OGLShader::Create(const char* vert_shader, const char* frag_shader) {
38 if (handle != 0) {
39 return;
40 }
41
42 handle = ShaderUtil::LoadShaders(vert_shader, frag_shader);
43}
44
45void OGLShader::Release() {
46 glDeleteProgram(handle);
47 handle = 0;
48}
49
50// Buffer objects
51OGLBuffer::OGLBuffer() : handle(0) {
52}
53
54OGLBuffer::~OGLBuffer() {
55 Release();
56}
57
58void OGLBuffer::Create() {
59 if (handle != 0) {
60 return;
61 }
62
63 glGenBuffers(1, &handle);
64}
65
66void OGLBuffer::Release() {
67 glDeleteBuffers(1, &handle);
68 handle = 0;
69}
70
71// Vertex array objects
72OGLVertexArray::OGLVertexArray() : handle(0) {
73}
74
75OGLVertexArray::~OGLVertexArray() {
76 Release();
77}
78
79void OGLVertexArray::Create() {
80 if (handle != 0) {
81 return;
82 }
83
84 glGenVertexArrays(1, &handle);
85}
86
87void OGLVertexArray::Release() {
88 glDeleteVertexArrays(1, &handle);
89 handle = 0;
90}
91
92// Framebuffers
93OGLFramebuffer::OGLFramebuffer() : handle(0) {
94}
95
96OGLFramebuffer::~OGLFramebuffer() {
97 Release();
98}
99
100void OGLFramebuffer::Create() {
101 if (handle != 0) {
102 return;
103 }
104
105 glGenFramebuffers(1, &handle);
106}
107
108void OGLFramebuffer::Release() {
109 glDeleteFramebuffers(1, &handle);
110 handle = 0;
111}
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 975720d0a..6f9dc012d 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -4,76 +4,124 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <utility>
8
7#include "common/common_types.h" 9#include "common/common_types.h"
8 10
9#include "generated/gl_3_2_core.h" 11#include "video_core/renderer_opengl/generated/gl_3_2_core.h"
12#include "video_core/renderer_opengl/gl_shader_util.h"
10 13
11class OGLTexture : public NonCopyable { 14class OGLTexture : private NonCopyable {
12public: 15public:
13 OGLTexture(); 16 OGLTexture() = default;
14 ~OGLTexture(); 17 OGLTexture(OGLTexture&& o) { std::swap(handle, o.handle); }
18 ~OGLTexture() { Release(); }
19 OGLTexture& operator=(OGLTexture&& o) { std::swap(handle, o.handle); return *this; }
15 20
16 /// Creates a new internal OpenGL resource and stores the handle 21 /// Creates a new internal OpenGL resource and stores the handle
17 void Create(); 22 void Create() {
23 if (handle != 0) return;
24 glGenTextures(1, &handle);
25 }
18 26
19 /// Deletes the internal OpenGL resource 27 /// Deletes the internal OpenGL resource
20 void Release(); 28 void Release() {
29 if (handle == 0) return;
30 glDeleteTextures(1, &handle);
31 handle = 0;
32 }
21 33
22 GLuint handle; 34 GLuint handle = 0;
23}; 35};
24 36
25class OGLShader : public NonCopyable { 37class OGLShader : private NonCopyable {
26public: 38public:
27 OGLShader(); 39 OGLShader() = default;
28 ~OGLShader(); 40 OGLShader(OGLShader&& o) { std::swap(handle, o.handle); }
41 ~OGLShader() { Release(); }
42 OGLShader& operator=(OGLShader&& o) { std::swap(handle, o.handle); return *this; }
29 43
30 /// Creates a new internal OpenGL resource and stores the handle 44 /// Creates a new internal OpenGL resource and stores the handle
31 void Create(const char* vert_shader, const char* frag_shader); 45 void Create(const char* vert_shader, const char* frag_shader) {
46 if (handle != 0) return;
47 handle = ShaderUtil::LoadShaders(vert_shader, frag_shader);
48 }
32 49
33 /// Deletes the internal OpenGL resource 50 /// Deletes the internal OpenGL resource
34 void Release(); 51 void Release() {
52 if (handle == 0) return;
53 glDeleteProgram(handle);
54 handle = 0;
55 }
35 56
36 GLuint handle; 57 GLuint handle = 0;
37}; 58};
38 59
39class OGLBuffer : public NonCopyable { 60class OGLBuffer : private NonCopyable {
40public: 61public:
41 OGLBuffer(); 62 OGLBuffer() = default;
42 ~OGLBuffer(); 63 OGLBuffer(OGLBuffer&& o) { std::swap(handle, o.handle); }
64 ~OGLBuffer() { Release(); }
65 OGLBuffer& operator=(OGLBuffer&& o) { std::swap(handle, o.handle); return *this; }
43 66
44 /// Creates a new internal OpenGL resource and stores the handle 67 /// Creates a new internal OpenGL resource and stores the handle
45 void Create(); 68 void Create() {
69 if (handle != 0) return;
70 glGenBuffers(1, &handle);
71 }
46 72
47 /// Deletes the internal OpenGL resource 73 /// Deletes the internal OpenGL resource
48 void Release(); 74 void Release() {
75 if (handle == 0) return;
76 glDeleteBuffers(1, &handle);
77 handle = 0;
78 }
49 79
50 GLuint handle; 80 GLuint handle = 0;
51}; 81};
52 82
53class OGLVertexArray : public NonCopyable { 83class OGLVertexArray : private NonCopyable {
54public: 84public:
55 OGLVertexArray(); 85 OGLVertexArray() = default;
56 ~OGLVertexArray(); 86 OGLVertexArray(OGLVertexArray&& o) { std::swap(handle, o.handle); }
87 ~OGLVertexArray() { Release(); }
88 OGLVertexArray& operator=(OGLVertexArray&& o) { std::swap(handle, o.handle); return *this; }
57 89
58 /// Creates a new internal OpenGL resource and stores the handle 90 /// Creates a new internal OpenGL resource and stores the handle
59 void Create(); 91 void Create() {
92 if (handle != 0) return;
93 glGenVertexArrays(1, &handle);
94 }
60 95
61 /// Deletes the internal OpenGL resource 96 /// Deletes the internal OpenGL resource
62 void Release(); 97 void Release() {
98 if (handle == 0) return;
99 glDeleteVertexArrays(1, &handle);
100 handle = 0;
101 }
63 102
64 GLuint handle; 103 GLuint handle = 0;
65}; 104};
66 105
67class OGLFramebuffer : public NonCopyable { 106class OGLFramebuffer : private NonCopyable {
68public: 107public:
69 OGLFramebuffer(); 108 OGLFramebuffer() = default;
70 ~OGLFramebuffer(); 109 OGLFramebuffer(OGLFramebuffer&& o) { std::swap(handle, o.handle); }
110 ~OGLFramebuffer() { Release(); }
111 OGLFramebuffer& operator=(OGLFramebuffer&& o) { std::swap(handle, o.handle); return *this; }
71 112
72 /// Creates a new internal OpenGL resource and stores the handle 113 /// Creates a new internal OpenGL resource and stores the handle
73 void Create(); 114 void Create() {
115 if (handle != 0) return;
116 glGenFramebuffers(1, &handle);
117 }
74 118
75 /// Deletes the internal OpenGL resource 119 /// Deletes the internal OpenGL resource
76 void Release(); 120 void Release() {
121 if (handle == 0) return;
122 glDeleteFramebuffers(1, &handle);
123 handle = 0;
124 }
77 125
78 GLuint handle; 126 GLuint handle = 0;
79}; 127};
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp
index b77503806..960ae5779 100644
--- a/src/video_core/vertex_shader.cpp
+++ b/src/video_core/vertex_shader.cpp
@@ -2,8 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <stack> 5#include <boost/container/static_vector.hpp>
6
7#include <boost/range/algorithm.hpp> 6#include <boost/range/algorithm.hpp>
8 7
9#include <common/file_util.h> 8#include <common/file_util.h>
@@ -27,7 +26,7 @@ namespace Pica {
27namespace VertexShader { 26namespace VertexShader {
28 27
29struct VertexShaderState { 28struct VertexShaderState {
30 const u32* program_counter; 29 u32 program_counter;
31 30
32 const float24* input_register_table[16]; 31 const float24* input_register_table[16];
33 Math::Vec4<float24> output_registers[16]; 32 Math::Vec4<float24> output_registers[16];
@@ -53,7 +52,7 @@ struct VertexShaderState {
53 }; 52 };
54 53
55 // TODO: Is there a maximal size for this? 54 // TODO: Is there a maximal size for this?
56 std::stack<CallStackElement> call_stack; 55 boost::container::static_vector<CallStackElement, 16> call_stack;
57 56
58 struct { 57 struct {
59 u32 max_offset; // maximum program counter ever reached 58 u32 max_offset; // maximum program counter ever reached
@@ -71,15 +70,15 @@ static void ProcessShaderCode(VertexShaderState& state) {
71 70
72 while (true) { 71 while (true) {
73 if (!state.call_stack.empty()) { 72 if (!state.call_stack.empty()) {
74 auto& top = state.call_stack.top(); 73 auto& top = state.call_stack.back();
75 if (state.program_counter - program_code.data() == top.final_address) { 74 if (state.program_counter == top.final_address) {
76 state.address_registers[2] += top.loop_increment; 75 state.address_registers[2] += top.loop_increment;
77 76
78 if (top.repeat_counter-- == 0) { 77 if (top.repeat_counter-- == 0) {
79 state.program_counter = &program_code[top.return_address]; 78 state.program_counter = top.return_address;
80 state.call_stack.pop(); 79 state.call_stack.pop_back();
81 } else { 80 } else {
82 state.program_counter = &program_code[top.loop_address]; 81 state.program_counter = top.loop_address;
83 } 82 }
84 83
85 // TODO: Is "trying again" accurate to hardware? 84 // TODO: Is "trying again" accurate to hardware?
@@ -88,17 +87,16 @@ static void ProcessShaderCode(VertexShaderState& state) {
88 } 87 }
89 88
90 bool exit_loop = false; 89 bool exit_loop = false;
91 const Instruction& instr = *(const Instruction*)state.program_counter; 90 const Instruction instr = { program_code[state.program_counter] };
92 const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.common.operand_desc_id]; 91 const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] };
93 92
94 static auto call = [&program_code](VertexShaderState& state, u32 offset, u32 num_instructions, 93 static auto call = [](VertexShaderState& state, u32 offset, u32 num_instructions,
95 u32 return_offset, u8 repeat_count, u8 loop_increment) { 94 u32 return_offset, u8 repeat_count, u8 loop_increment) {
96 state.program_counter = &program_code[offset] - 1; // -1 to make sure when incrementing the PC we end up at the correct offset 95 state.program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset
97 state.call_stack.push({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset }); 96 ASSERT(state.call_stack.size() < state.call_stack.capacity());
97 state.call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset });
98 }; 98 };
99 u32 binary_offset = state.program_counter - program_code.data(); 99 state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + state.program_counter);
100
101 state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + binary_offset);
102 100
103 auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* { 101 auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* {
104 switch (source_reg.GetRegisterType()) { 102 switch (source_reg.GetRegisterType()) {
@@ -442,13 +440,13 @@ static void ProcessShaderCode(VertexShaderState& state) {
442 440
443 case OpCode::Id::JMPC: 441 case OpCode::Id::JMPC:
444 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 442 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
445 state.program_counter = &program_code[instr.flow_control.dest_offset] - 1; 443 state.program_counter = instr.flow_control.dest_offset - 1;
446 } 444 }
447 break; 445 break;
448 446
449 case OpCode::Id::JMPU: 447 case OpCode::Id::JMPU:
450 if (uniforms.b[instr.flow_control.bool_uniform_id]) { 448 if (uniforms.b[instr.flow_control.bool_uniform_id]) {
451 state.program_counter = &program_code[instr.flow_control.dest_offset] - 1; 449 state.program_counter = instr.flow_control.dest_offset - 1;
452 } 450 }
453 break; 451 break;
454 452
@@ -456,7 +454,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
456 call(state, 454 call(state,
457 instr.flow_control.dest_offset, 455 instr.flow_control.dest_offset,
458 instr.flow_control.num_instructions, 456 instr.flow_control.num_instructions,
459 binary_offset + 1, 0, 0); 457 state.program_counter + 1, 0, 0);
460 break; 458 break;
461 459
462 case OpCode::Id::CALLU: 460 case OpCode::Id::CALLU:
@@ -464,7 +462,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
464 call(state, 462 call(state,
465 instr.flow_control.dest_offset, 463 instr.flow_control.dest_offset,
466 instr.flow_control.num_instructions, 464 instr.flow_control.num_instructions,
467 binary_offset + 1, 0, 0); 465 state.program_counter + 1, 0, 0);
468 } 466 }
469 break; 467 break;
470 468
@@ -473,7 +471,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
473 call(state, 471 call(state,
474 instr.flow_control.dest_offset, 472 instr.flow_control.dest_offset,
475 instr.flow_control.num_instructions, 473 instr.flow_control.num_instructions,
476 binary_offset + 1, 0, 0); 474 state.program_counter + 1, 0, 0);
477 } 475 }
478 break; 476 break;
479 477
@@ -483,8 +481,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
483 case OpCode::Id::IFU: 481 case OpCode::Id::IFU:
484 if (uniforms.b[instr.flow_control.bool_uniform_id]) { 482 if (uniforms.b[instr.flow_control.bool_uniform_id]) {
485 call(state, 483 call(state,
486 binary_offset + 1, 484 state.program_counter + 1,
487 instr.flow_control.dest_offset - binary_offset - 1, 485 instr.flow_control.dest_offset - state.program_counter - 1,
488 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); 486 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
489 } else { 487 } else {
490 call(state, 488 call(state,
@@ -501,8 +499,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
501 499
502 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 500 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
503 call(state, 501 call(state,
504 binary_offset + 1, 502 state.program_counter + 1,
505 instr.flow_control.dest_offset - binary_offset - 1, 503 instr.flow_control.dest_offset - state.program_counter - 1,
506 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); 504 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
507 } else { 505 } else {
508 call(state, 506 call(state,
@@ -519,8 +517,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
519 state.address_registers[2] = uniforms.i[instr.flow_control.int_uniform_id].y; 517 state.address_registers[2] = uniforms.i[instr.flow_control.int_uniform_id].y;
520 518
521 call(state, 519 call(state,
522 binary_offset + 1, 520 state.program_counter + 1,
523 instr.flow_control.dest_offset - binary_offset + 1, 521 instr.flow_control.dest_offset - state.program_counter + 1,
524 instr.flow_control.dest_offset + 1, 522 instr.flow_control.dest_offset + 1,
525 uniforms.i[instr.flow_control.int_uniform_id].x, 523 uniforms.i[instr.flow_control.int_uniform_id].x,
526 uniforms.i[instr.flow_control.int_uniform_id].z); 524 uniforms.i[instr.flow_control.int_uniform_id].z);
@@ -551,8 +549,7 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs:
551 549
552 VertexShaderState state; 550 VertexShaderState state;
553 551
554 const u32* main = &setup.program_code[config.main_offset]; 552 state.program_counter = config.main_offset;
555 state.program_counter = (u32*)main;
556 state.debug.max_offset = 0; 553 state.debug.max_offset = 0;
557 state.debug.max_opdesc_id = 0; 554 state.debug.max_opdesc_id = 0;
558 555
@@ -582,9 +579,11 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs:
582 state.conditional_code[1] = false; 579 state.conditional_code[1] = false;
583 580
584 ProcessShaderCode(state); 581 ProcessShaderCode(state);
582#if PICA_DUMP_SHADERS
585 DebugUtils::DumpShader(setup.program_code.data(), state.debug.max_offset, setup.swizzle_data.data(), 583 DebugUtils::DumpShader(setup.program_code.data(), state.debug.max_offset, setup.swizzle_data.data(),
586 state.debug.max_opdesc_id, config.main_offset, 584 state.debug.max_opdesc_id, config.main_offset,
587 g_state.regs.vs_output_attributes); // TODO: Don't hardcode VS here 585 g_state.regs.vs_output_attributes); // TODO: Don't hardcode VS here
586#endif
588 587
589 // Setup output data 588 // Setup output data
590 OutputVertex ret; 589 OutputVertex ret;