aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/config.cpp36
-rw-r--r--src/citra/default_ini.h4
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp29
-rw-r--r--src/citra_qt/bootmanager.cpp29
-rw-r--r--src/citra_qt/config.cpp63
-rw-r--r--src/citra_qt/debugger/disassembler.cpp3
-rw-r--r--src/citra_qt/debugger/graphics_breakpoints.cpp112
-rw-r--r--src/citra_qt/debugger/graphics_breakpoints.h6
-rw-r--r--src/citra_qt/debugger/graphics_breakpoints_p.h2
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp36
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp2
-rw-r--r--src/citra_qt/debugger/profiler.cpp2
-rw-r--r--src/citra_qt/main.cpp3
-rw-r--r--src/common/string_util.cpp2
-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.cpp27
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h16
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp502
-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.cpp49
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h30
-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.h252
-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/core_timing.cpp2
-rw-r--r--src/core/hle/function_wrappers.h2
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/service/gsp_gpu.cpp38
-rw-r--r--src/core/hle/service/hid/hid.cpp10
-rw-r--r--src/core/hle/service/hid/hid.h5
-rw-r--r--src/core/hle/service/soc_u.cpp10
-rw-r--r--src/core/hle/svc.cpp4
-rw-r--r--src/core/hw/gpu.cpp4
-rw-r--r--src/core/loader/3dsx.cpp2
-rw-r--r--src/core/loader/loader.cpp18
-rw-r--r--src/core/settings.h54
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/command_processor.cpp16
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp44
-rw-r--r--src/video_core/debug_utils/debug_utils.h12
-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
60 files changed, 1980 insertions, 2276 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 506cb793..2c1407a6 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -40,31 +40,21 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string&
return true;
}
+static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = {
+ GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_Z, GLFW_KEY_X,
+ GLFW_KEY_Q, GLFW_KEY_W, GLFW_KEY_1, GLFW_KEY_2,
+ GLFW_KEY_M, GLFW_KEY_N, GLFW_KEY_B,
+ GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H,
+ GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT,
+ GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L
+};
+
void Config::ReadValues() {
// Controls
- Settings::values.pad_a_key = glfw_config->GetInteger("Controls", "pad_a", GLFW_KEY_A);
- Settings::values.pad_b_key = glfw_config->GetInteger("Controls", "pad_b", GLFW_KEY_S);
- Settings::values.pad_x_key = glfw_config->GetInteger("Controls", "pad_x", GLFW_KEY_Z);
- Settings::values.pad_y_key = glfw_config->GetInteger("Controls", "pad_y", GLFW_KEY_X);
- Settings::values.pad_l_key = glfw_config->GetInteger("Controls", "pad_l", GLFW_KEY_Q);
- Settings::values.pad_r_key = glfw_config->GetInteger("Controls", "pad_r", GLFW_KEY_W);
- Settings::values.pad_zl_key = glfw_config->GetInteger("Controls", "pad_zl", GLFW_KEY_1);
- Settings::values.pad_zr_key = glfw_config->GetInteger("Controls", "pad_zr", GLFW_KEY_2);
- Settings::values.pad_start_key = glfw_config->GetInteger("Controls", "pad_start", GLFW_KEY_M);
- Settings::values.pad_select_key = glfw_config->GetInteger("Controls", "pad_select", GLFW_KEY_N);
- Settings::values.pad_home_key = glfw_config->GetInteger("Controls", "pad_home", GLFW_KEY_B);
- Settings::values.pad_dup_key = glfw_config->GetInteger("Controls", "pad_dup", GLFW_KEY_T);
- Settings::values.pad_ddown_key = glfw_config->GetInteger("Controls", "pad_ddown", GLFW_KEY_G);
- Settings::values.pad_dleft_key = glfw_config->GetInteger("Controls", "pad_dleft", GLFW_KEY_F);
- Settings::values.pad_dright_key = glfw_config->GetInteger("Controls", "pad_dright", GLFW_KEY_H);
- Settings::values.pad_sup_key = glfw_config->GetInteger("Controls", "pad_sup", GLFW_KEY_UP);
- Settings::values.pad_sdown_key = glfw_config->GetInteger("Controls", "pad_sdown", GLFW_KEY_DOWN);
- Settings::values.pad_sleft_key = glfw_config->GetInteger("Controls", "pad_sleft", GLFW_KEY_LEFT);
- Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT);
- Settings::values.pad_cup_key = glfw_config->GetInteger("Controls", "pad_cup", GLFW_KEY_I);
- Settings::values.pad_cdown_key = glfw_config->GetInteger("Controls", "pad_cdown", GLFW_KEY_K);
- Settings::values.pad_cleft_key = glfw_config->GetInteger("Controls", "pad_cleft", GLFW_KEY_J);
- Settings::values.pad_cright_key = glfw_config->GetInteger("Controls", "pad_cright", GLFW_KEY_L);
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ Settings::values.input_mappings[Settings::NativeInput::All[i]] =
+ glfw_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]);
+ }
// Core
Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0);
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index fd5a90d5..1925bece 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -33,10 +33,6 @@ pad_cleft =
pad_cright =
[Core]
-# The refresh rate for the GPU
-# Defaults to 30
-gpu_refresh_rate =
-
# The applied frameskip amount. Must be a power of two.
# 0 (default): No frameskip, 1: x2 frameskip, 2: x4 frameskip, 3: x8 frameskip, etc.
frame_skip =
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 42fb683a..6d6656b5 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -150,32 +150,9 @@ void EmuWindow_GLFW::DoneCurrent() {
}
void EmuWindow_GLFW::ReloadSetKeymaps() {
- KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A);
- KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B);
- KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT);
- KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START);
- KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN);
- KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R);
- KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L);
- KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X);
- KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y);
-
- KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL);
- KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR);
-
- // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH);
-
- KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN);
- KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN);
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]);
+ }
}
void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) {
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index fa7bce46..b12bd858 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -248,32 +248,9 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent *event)
void GRenderWindow::ReloadSetKeymaps()
{
- KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A);
- KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B);
- KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT);
- KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START);
- KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN);
- KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R);
- KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L);
- KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X);
- KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y);
-
- KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL);
- KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR);
-
- // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH);
-
- KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN);
- KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT);
- KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT);
- KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP);
- KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN);
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]);
+ }
}
void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height)
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 5c056446..5716634e 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -21,31 +21,21 @@ Config::Config() {
Reload();
}
+static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults = {
+ Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X,
+ Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2,
+ Qt::Key_M, Qt::Key_N, Qt::Key_B,
+ Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H,
+ Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right,
+ Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L
+};
+
void Config::ReadValues() {
qt_config->beginGroup("Controls");
- Settings::values.pad_a_key = qt_config->value("pad_a", Qt::Key_A).toInt();
- Settings::values.pad_b_key = qt_config->value("pad_b", Qt::Key_S).toInt();
- Settings::values.pad_x_key = qt_config->value("pad_x", Qt::Key_Z).toInt();
- Settings::values.pad_y_key = qt_config->value("pad_y", Qt::Key_X).toInt();
- Settings::values.pad_l_key = qt_config->value("pad_l", Qt::Key_Q).toInt();
- Settings::values.pad_r_key = qt_config->value("pad_r", Qt::Key_W).toInt();
- Settings::values.pad_zl_key = qt_config->value("pad_zl", Qt::Key_1).toInt();
- Settings::values.pad_zr_key = qt_config->value("pad_zr", Qt::Key_2).toInt();
- Settings::values.pad_start_key = qt_config->value("pad_start", Qt::Key_M).toInt();
- Settings::values.pad_select_key = qt_config->value("pad_select", Qt::Key_N).toInt();
- Settings::values.pad_home_key = qt_config->value("pad_home", Qt::Key_B).toInt();
- Settings::values.pad_dup_key = qt_config->value("pad_dup", Qt::Key_T).toInt();
- Settings::values.pad_ddown_key = qt_config->value("pad_ddown", Qt::Key_G).toInt();
- Settings::values.pad_dleft_key = qt_config->value("pad_dleft", Qt::Key_F).toInt();
- Settings::values.pad_dright_key = qt_config->value("pad_dright", Qt::Key_H).toInt();
- Settings::values.pad_sup_key = qt_config->value("pad_sup", Qt::Key_Up).toInt();
- Settings::values.pad_sdown_key = qt_config->value("pad_sdown", Qt::Key_Down).toInt();
- Settings::values.pad_sleft_key = qt_config->value("pad_sleft", Qt::Key_Left).toInt();
- Settings::values.pad_sright_key = qt_config->value("pad_sright", Qt::Key_Right).toInt();
- Settings::values.pad_cup_key = qt_config->value("pad_cup", Qt::Key_I).toInt();
- Settings::values.pad_cdown_key = qt_config->value("pad_cdown", Qt::Key_K).toInt();
- Settings::values.pad_cleft_key = qt_config->value("pad_cleft", Qt::Key_J).toInt();
- Settings::values.pad_cright_key = qt_config->value("pad_cright", Qt::Key_L).toInt();
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ Settings::values.input_mappings[Settings::NativeInput::All[i]] =
+ qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]).toInt();
+ }
qt_config->endGroup();
qt_config->beginGroup("Core");
@@ -75,29 +65,10 @@ void Config::ReadValues() {
void Config::SaveValues() {
qt_config->beginGroup("Controls");
- qt_config->setValue("pad_a", Settings::values.pad_a_key);
- qt_config->setValue("pad_b", Settings::values.pad_b_key);
- qt_config->setValue("pad_x", Settings::values.pad_x_key);
- qt_config->setValue("pad_y", Settings::values.pad_y_key);
- qt_config->setValue("pad_l", Settings::values.pad_l_key);
- qt_config->setValue("pad_r", Settings::values.pad_r_key);
- qt_config->setValue("pad_zl", Settings::values.pad_zl_key);
- qt_config->setValue("pad_zr", Settings::values.pad_zr_key);
- qt_config->setValue("pad_start", Settings::values.pad_start_key);
- qt_config->setValue("pad_select", Settings::values.pad_select_key);
- qt_config->setValue("pad_home", Settings::values.pad_home_key);
- qt_config->setValue("pad_dup", Settings::values.pad_dup_key);
- qt_config->setValue("pad_ddown", Settings::values.pad_ddown_key);
- qt_config->setValue("pad_dleft", Settings::values.pad_dleft_key);
- qt_config->setValue("pad_dright", Settings::values.pad_dright_key);
- qt_config->setValue("pad_sup", Settings::values.pad_sup_key);
- qt_config->setValue("pad_sdown", Settings::values.pad_sdown_key);
- qt_config->setValue("pad_sleft", Settings::values.pad_sleft_key);
- qt_config->setValue("pad_sright", Settings::values.pad_sright_key);
- qt_config->setValue("pad_cup", Settings::values.pad_cup_key);
- qt_config->setValue("pad_cdown", Settings::values.pad_cdown_key);
- qt_config->setValue("pad_cleft", Settings::values.pad_cleft_key);
- qt_config->setValue("pad_cright", Settings::values.pad_cright_key);
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ qt_config->setValue(QString::fromStdString(Settings::NativeInput::Mapping[i]),
+ Settings::values.input_mappings[Settings::NativeInput::All[i]]);
+ }
qt_config->endGroup();
qt_config->beginGroup("Core");
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index b41c40a0..1e5ef529 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -15,7 +15,6 @@
#include "common/break_points.h"
#include "common/symbols.h"
#include "core/arm/arm_interface.h"
-#include "core/arm/skyeye_common/armdefs.h"
#include "core/arm/disassembler/arm_disasm.h"
@@ -219,7 +218,7 @@ void DisassemblerWidget::OnToggleStartStop() {
}
void DisassemblerWidget::OnDebugModeEntered() {
- ARMword next_instr = Core::g_app_core->GetPC();
+ u32 next_instr = Core::g_app_core->GetPC();
if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
emu_thread->SetRunning(false);
diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp
index 1da64f61..5202c168 100644
--- a/src/citra_qt/debugger/graphics_breakpoints.cpp
+++ b/src/citra_qt/debugger/graphics_breakpoints.cpp
@@ -4,7 +4,7 @@
#include <QMetaType>
#include <QPushButton>
-#include <QTreeWidget>
+#include <QTreeView>
#include <QVBoxLayout>
#include <QLabel>
@@ -23,7 +23,7 @@ BreakPointModel::BreakPointModel(std::shared_ptr<Pica::DebugContext> debug_conte
int BreakPointModel::columnCount(const QModelIndex& parent) const
{
- return 2;
+ return 1;
}
int BreakPointModel::rowCount(const QModelIndex& parent) const
@@ -38,29 +38,29 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const
switch (role) {
case Qt::DisplayRole:
{
- switch (index.column()) {
- case 0:
- {
+ if (index.column() == 0) {
static const std::map<Pica::DebugContext::Event, QString> map = {
- { Pica::DebugContext::Event::CommandLoaded, tr("Pica command loaded") },
- { Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed") },
+ { Pica::DebugContext::Event::PicaCommandLoaded, tr("Pica command loaded") },
+ { Pica::DebugContext::Event::PicaCommandProcessed, tr("Pica command processed") },
{ Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") },
{ Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") },
- { Pica::DebugContext::Event::VertexLoaded, tr("Vertex loaded") }
+ { Pica::DebugContext::Event::VertexLoaded, tr("Vertex loaded") },
+ { Pica::DebugContext::Event::IncomingDisplayTransfer, tr("Incoming display transfer") },
+ { Pica::DebugContext::Event::GSPCommandProcessed, tr("GSP command processed") },
+ { Pica::DebugContext::Event::BufferSwapped, tr("Buffers swapped") }
};
DEBUG_ASSERT(map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents));
-
return (map.find(event) != map.end()) ? map.at(event) : QString();
}
- case 1:
- return data(index, Role_IsEnabled).toBool() ? tr("Enabled") : tr("Disabled");
-
- default:
- break;
- }
+ break;
+ }
+ case Qt::CheckStateRole:
+ {
+ if (index.column() == 0)
+ return data(index, Role_IsEnabled).toBool() ? Qt::Checked : Qt::Unchecked;
break;
}
@@ -84,37 +84,34 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const
return QVariant();
}
-QVariant BreakPointModel::headerData(int section, Qt::Orientation orientation, int role) const
+Qt::ItemFlags BreakPointModel::flags(const QModelIndex &index) const
{
- switch(role) {
- case Qt::DisplayRole:
- {
- if (section == 0) {
- return tr("Event");
- } else if (section == 1) {
- return tr("Status");
- }
-
- break;
- }
- }
+ if (!index.isValid())
+ return 0;
- return QVariant();
+ Qt::ItemFlags flags = Qt::ItemIsEnabled;
+ if (index.column() == 0)
+ flags |= Qt::ItemIsUserCheckable;
+ return flags;
}
+
bool BreakPointModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
const auto event = static_cast<Pica::DebugContext::Event>(index.row());
switch (role) {
- case Role_IsEnabled:
+ case Qt::CheckStateRole:
{
+ if (index.column() != 0)
+ return false;
+
auto context = context_weak.lock();
if (!context)
return false;
- context->breakpoints[event].enabled = value.toBool();
- QModelIndex changed_index = createIndex(index.row(), 1);
+ context->breakpoints[event].enabled = value == Qt::Checked;
+ QModelIndex changed_index = createIndex(index.row(), 0);
emit dataChanged(changed_index, changed_index);
return true;
}
@@ -133,7 +130,7 @@ void BreakPointModel::OnBreakPointHit(Pica::DebugContext::Event event)
active_breakpoint = context->active_breakpoint;
at_breakpoint = context->at_breakpoint;
emit dataChanged(createIndex(static_cast<int>(event), 0),
- createIndex(static_cast<int>(event), 1));
+ createIndex(static_cast<int>(event), 0));
}
void BreakPointModel::OnResumed()
@@ -144,7 +141,7 @@ void BreakPointModel::OnResumed()
at_breakpoint = context->at_breakpoint;
emit dataChanged(createIndex(static_cast<int>(active_breakpoint), 0),
- createIndex(static_cast<int>(active_breakpoint), 1));
+ createIndex(static_cast<int>(active_breakpoint), 0));
active_breakpoint = context->active_breakpoint;
}
@@ -162,13 +159,15 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::Debug
breakpoint_model = new BreakPointModel(debug_context, this);
breakpoint_list = new QTreeView;
+ breakpoint_list->setRootIsDecorated(false);
+ breakpoint_list->setHeaderHidden(true);
breakpoint_list->setModel(breakpoint_model);
- toggle_breakpoint_button = new QPushButton(tr("Enable"));
- toggle_breakpoint_button->setEnabled(false);
-
qRegisterMetaType<Pica::DebugContext::Event>("Pica::DebugContext::Event");
+ connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)),
+ this, SLOT(OnItemDoubleClicked(const QModelIndex&)));
+
connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested()));
connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event,void*)),
@@ -184,11 +183,6 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::Debug
connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&,const QModelIndex&)),
breakpoint_model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)));
- connect(breakpoint_list->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(OnBreakpointSelectionChanged(QModelIndex)));
-
- connect(toggle_breakpoint_button, SIGNAL(clicked()), this, SLOT(OnToggleBreakpointEnabled()));
-
QWidget* main_widget = new QWidget;
auto main_layout = new QVBoxLayout;
{
@@ -198,7 +192,6 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::Debug
main_layout->addLayout(sub_layout);
}
main_layout->addWidget(breakpoint_list);
- main_layout->addWidget(toggle_breakpoint_button);
main_widget->setLayout(main_layout);
setWidget(main_widget);
@@ -234,32 +227,15 @@ void GraphicsBreakPointsWidget::OnResumeRequested()
context->Resume();
}
-void GraphicsBreakPointsWidget::OnBreakpointSelectionChanged(const QModelIndex& index)
+void GraphicsBreakPointsWidget::OnItemDoubleClicked(const QModelIndex& index)
{
- if (!index.isValid()) {
- toggle_breakpoint_button->setEnabled(false);
+ if (!index.isValid())
return;
- }
- toggle_breakpoint_button->setEnabled(true);
- UpdateToggleBreakpointButton(index);
-}
-
-void GraphicsBreakPointsWidget::OnToggleBreakpointEnabled()
-{
- QModelIndex index = breakpoint_list->selectionModel()->currentIndex();
- bool new_state = !(breakpoint_model->data(index, BreakPointModel::Role_IsEnabled).toBool());
-
- breakpoint_model->setData(index, new_state,
- BreakPointModel::Role_IsEnabled);
- UpdateToggleBreakpointButton(index);
-}
-
-void GraphicsBreakPointsWidget::UpdateToggleBreakpointButton(const QModelIndex& index)
-{
- if (true == breakpoint_model->data(index, BreakPointModel::Role_IsEnabled).toBool()) {
- toggle_breakpoint_button->setText(tr("Disable"));
- } else {
- toggle_breakpoint_button->setText(tr("Enable"));
- }
+ QModelIndex check_index = breakpoint_list->model()->index(index.row(), 0);
+ QVariant enabled = breakpoint_list->model()->data(check_index, Qt::CheckStateRole);
+ QVariant new_state = Qt::Unchecked;
+ if (enabled == Qt::Unchecked)
+ new_state = Qt::Checked;
+ breakpoint_list->model()->setData(check_index, new_state, Qt::CheckStateRole);
}
diff --git a/src/citra_qt/debugger/graphics_breakpoints.h b/src/citra_qt/debugger/graphics_breakpoints.h
index 5b9ba324..d900729d 100644
--- a/src/citra_qt/debugger/graphics_breakpoints.h
+++ b/src/citra_qt/debugger/graphics_breakpoints.h
@@ -31,10 +31,9 @@ public:
public slots:
void OnBreakPointHit(Pica::DebugContext::Event event, void* data);
+ void OnItemDoubleClicked(const QModelIndex&);
void OnResumeRequested();
void OnResumed();
- void OnBreakpointSelectionChanged(const QModelIndex&);
- void OnToggleBreakpointEnabled();
signals:
void Resumed();
@@ -42,11 +41,8 @@ signals:
void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
private:
- void UpdateToggleBreakpointButton(const QModelIndex& index);
-
QLabel* status_text;
QPushButton* resume_button;
- QPushButton* toggle_breakpoint_button;
BreakPointModel* breakpoint_model;
QTreeView* breakpoint_list;
diff --git a/src/citra_qt/debugger/graphics_breakpoints_p.h b/src/citra_qt/debugger/graphics_breakpoints_p.h
index 34e72e85..00d8d510 100644
--- a/src/citra_qt/debugger/graphics_breakpoints_p.h
+++ b/src/citra_qt/debugger/graphics_breakpoints_p.h
@@ -23,7 +23,7 @@ public:
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index 392ff570..7ac3ea54 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -10,6 +10,7 @@
#include <QPushButton>
#include <QVBoxLayout>
#include <QTreeView>
+#include <QHeaderView>
#include <QSpinBox>
#include <QComboBox>
@@ -170,11 +171,11 @@ GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(p
}
int GPUCommandListModel::rowCount(const QModelIndex& parent) const {
- return pica_trace.writes.size();
+ return static_cast<int>(pica_trace.writes.size());
}
int GPUCommandListModel::columnCount(const QModelIndex& parent) const {
- return 2;
+ return 3;
}
QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const {
@@ -187,14 +188,13 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const {
if (role == Qt::DisplayRole) {
QString content;
- if (index.column() == 0) {
- QString content = QString::fromLatin1(Pica::Regs::GetCommandName(cmd.cmd_id).c_str());
- content.append(" ");
- return content;
- } else if (index.column() == 1) {
- QString content = QString("%1 ").arg(cmd.hex, 8, 16, QLatin1Char('0'));
- content.append(QString("%1 ").arg(val, 8, 16, QLatin1Char('0')));
- return content;
+ switch ( index.column() ) {
+ case 0:
+ return QString::fromLatin1(Pica::Regs::GetCommandName(cmd.cmd_id).c_str());
+ case 1:
+ return QString("%1").arg(cmd.cmd_id, 3, 16, QLatin1Char('0'));
+ case 2:
+ return QString("%1").arg(val, 8, 16, QLatin1Char('0'));
}
} else if (role == CommandIdRole) {
return QVariant::fromValue<int>(cmd.cmd_id.Value());
@@ -207,10 +207,13 @@ QVariant GPUCommandListModel::headerData(int section, Qt::Orientation orientatio
switch(role) {
case Qt::DisplayRole:
{
- if (section == 0) {
+ switch (section) {
+ case 0:
return tr("Command Name");
- } else if (section == 1) {
- return tr("Data");
+ case 1:
+ return tr("Register");
+ case 2:
+ return tr("New Value");
}
break;
@@ -299,6 +302,13 @@ GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pi
list_widget->setModel(model);
list_widget->setFont(QFont("monospace"));
list_widget->setRootIsDecorated(false);
+ list_widget->setUniformRowHeights(true);
+
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ list_widget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+#else
+ list_widget->header()->setResizeMode(QHeaderView::ResizeToContents);
+#endif
connect(list_widget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
this, SLOT(SetCommandInfo(const QModelIndex&)));
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index db622d84..f42a2f4c 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -34,7 +34,7 @@ int GraphicsVertexShaderModel::columnCount(const QModelIndex& parent) const {
}
int GraphicsVertexShaderModel::rowCount(const QModelIndex& parent) const {
- return info.code.size();
+ return static_cast<int>(info.code.size());
}
QVariant GraphicsVertexShaderModel::headerData(int section, Qt::Orientation orientation, int role) const {
diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp
index 2ac1748b..89b28c2f 100644
--- a/src/citra_qt/debugger/profiler.cpp
+++ b/src/citra_qt/debugger/profiler.cpp
@@ -74,7 +74,7 @@ int ProfilerModel::rowCount(const QModelIndex& parent) const
if (parent.isValid()) {
return 0;
} else {
- return results.time_per_category.size() + 2;
+ return static_cast<int>(results.time_per_category.size() + 2);
}
}
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 2746de77..34831f2e 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -263,6 +263,7 @@ void GMainWindow::ShutdownGame() {
// Update the GUI
ui.action_Start->setEnabled(false);
+ ui.action_Start->setText(tr("Start"));
ui.action_Pause->setEnabled(false);
ui.action_Stop->setEnabled(false);
render_window->hide();
@@ -291,6 +292,8 @@ void GMainWindow::OnStartGame()
emu_thread->SetRunning(true);
ui.action_Start->setEnabled(false);
+ ui.action_Start->setText(tr("Continue"));
+
ui.action_Pause->setEnabled(true);
ui.action_Stop->setEnabled(true);
}
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 2e80809a..b2f7f7b1 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -313,7 +313,7 @@ static std::string UTF16ToUTF8(const std::wstring& input)
std::string output;
output.resize(size);
- if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr))
+ if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), &output[0], static_cast<int>(output.size()), nullptr, nullptr))
output.clear();
return output;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8267ee58..6cc60fd5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -4,10 +4,9 @@ set(SRCS
arm/dyncom/arm_dyncom.cpp
arm/dyncom/arm_dyncom_dec.cpp
arm/dyncom/arm_dyncom_interpreter.cpp
- arm/dyncom/arm_dyncom_run.cpp
arm/dyncom/arm_dyncom_thumb.cpp
- arm/interpreter/arminit.cpp
- arm/interpreter/armsupp.cpp
+ arm/skyeye_common/armstate.cpp
+ arm/skyeye_common/armsupp.cpp
arm/skyeye_common/vfp/vfp.cpp
arm/skyeye_common/vfp/vfpdouble.cpp
arm/skyeye_common/vfp/vfpinstr.cpp
@@ -132,8 +131,8 @@ set(HEADERS
arm/dyncom/arm_dyncom_run.h
arm/dyncom/arm_dyncom_thumb.h
arm/skyeye_common/arm_regformat.h
- arm/skyeye_common/armdefs.h
- arm/skyeye_common/armmmu.h
+ arm/skyeye_common/armstate.h
+ arm/skyeye_common/armsupp.h
arm/skyeye_common/vfp/asm_vfp.h
arm/skyeye_common/vfp/vfp.h
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 529c4ac7..c665f706 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -6,7 +6,8 @@
#include "common/make_unique.h"
-#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/armsupp.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
#include "core/arm/dyncom/arm_dyncom.h"
@@ -17,26 +18,7 @@
#include "core/core_timing.h"
ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
- state = Common::make_unique<ARMul_State>();
-
- ARMul_NewState(state.get());
- ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
-
- state->abort_model = ABORT_BASE_RESTORED;
-
- state->bigendSig = LOW;
- state->lateabtSig = LOW;
- state->NirqSig = HIGH;
-
- // Reset the core to initial state
- ARMul_Reset(state.get());
- state->Emulate = RUN;
-
- // Switch to the desired privilege mode.
- switch_mode(state.get(), initial_mode);
-
- state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
- state->Reg[15] = 0x00000000;
+ state = Common::make_unique<ARMul_State>(initial_mode);
}
ARM_DynCom::~ARM_DynCom() {
@@ -100,8 +82,8 @@ void ARM_DynCom::ResetContext(Core::ThreadContext& context, u32 stack_top, u32 e
}
void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
- memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
- memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
+ memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers));
+ memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers));
ctx.sp = state->Reg[13];
ctx.lr = state->Reg[14];
@@ -113,8 +95,8 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
}
void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
- memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
- memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+ memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
+ memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
state->Reg[13] = ctx.sp;
state->Reg[14] = ctx.lr;
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
index cc935572..87ab6908 100644
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -9,8 +9,8 @@
#include "common/common_types.h"
#include "core/arm/arm_interface.h"
-#include "core/arm/skyeye_common/armdefs.h"
#include "core/arm/skyeye_common/arm_regformat.h"
+#include "core/arm/skyeye_common/armstate.h"
namespace Core {
struct ThreadContext;
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 697be955..ee428831 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -2,10 +2,10 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "core/arm/skyeye_common/armdefs.h"
#include "core/arm/dyncom/arm_dyncom_dec.h"
+#include "core/arm/skyeye_common/armsupp.h"
-const ISEITEM arm_instruction[] = {
+const InstructionSetEncodingItem arm_instruction[] = {
{ "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }},
{ "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }},
{ "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }},
@@ -207,7 +207,7 @@ const ISEITEM arm_instruction[] = {
{ "bbl", 1, 0, { 25, 27, 0x00000005 }},
};
-const ISEITEM arm_exclusion_code[] = {
+const InstructionSetEncodingItem arm_exclusion_code[] = {
{ "vmla", 0, ARMVFP2, { 0 }},
{ "vmls", 0, ARMVFP2, { 0 }},
{ "vnmla", 0, ARMVFP2, { 0 }},
@@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = {
{ "invalid", 0, INVALID, { 0 }}
};
-int decode_arm_instr(uint32_t instr, int32_t *idx) {
+ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) {
int n = 0;
int base = 0;
- int ret = DECODE_FAILURE;
- int i = 0;
- int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
+ int instr_slots = sizeof(arm_instruction) / sizeof(InstructionSetEncodingItem);
+ ARMDecodeStatus ret = ARMDecodeStatus::FAILURE;
- for (i = 0; i < instr_slots; i++) {
+ for (int i = 0; i < instr_slots; i++) {
n = arm_instruction[i].attribute_value;
base = 0;
@@ -438,11 +437,11 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) {
n--;
}
- // All conditions is satisfied.
+ // All conditions are satisfied.
if (n == 0)
- ret = DECODE_SUCCESS;
+ ret = ARMDecodeStatus::SUCCESS;
- if (ret == DECODE_SUCCESS) {
+ if (ret == ARMDecodeStatus::SUCCESS) {
n = arm_exclusion_code[i].attribute_value;
if (n != 0) {
base = 0;
@@ -454,13 +453,13 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) {
n--;
}
- // All conditions is satisfied.
+ // All conditions are satisfied.
if (n == 0)
- ret = DECODE_FAILURE;
+ ret = ARMDecodeStatus::FAILURE;
}
}
- if (ret == DECODE_SUCCESS) {
+ if (ret == ARMDecodeStatus::SUCCESS) {
*idx = i;
return ret;
}
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 4b5f5ad7..d7170e0f 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -4,22 +4,22 @@
#pragma once
-int decode_arm_instr(uint32_t instr, int32_t *idx);
+#include "common/common_types.h"
-enum DECODE_STATUS {
- DECODE_SUCCESS,
- DECODE_FAILURE
+enum class ARMDecodeStatus {
+ SUCCESS,
+ FAILURE
};
-struct instruction_set_encoding_item {
+ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx);
+
+struct InstructionSetEncodingItem {
const char *name;
int attribute_value;
int version;
u32 content[21];
};
-typedef struct instruction_set_encoding_item ISEITEM;
-
// ARM versions
enum {
INVALID = 0,
@@ -36,4 +36,4 @@ enum {
ARMV6K,
};
-extern const ISEITEM arm_instruction[];
+extern const InstructionSetEncodingItem arm_instruction[];
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 785f3956..0c20c2bc 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -17,8 +17,8 @@
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
#include "core/arm/dyncom/arm_dyncom_thumb.h"
#include "core/arm/dyncom/arm_dyncom_run.h"
-#include "core/arm/skyeye_common/armdefs.h"
-#include "core/arm/skyeye_common/armmmu.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/armsupp.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
Common::Profiling::TimingCategory profile_execute("DynCom::Execute");
@@ -47,28 +47,6 @@ enum {
typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
-// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
-// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
-// support LDR/STREXD.
-static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
-
-// Exclusive memory access
-static int exclusive_detect(ARMul_State* state, ARMword addr) {
- if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK))
- return 0;
- else
- return -1;
-}
-
-static void add_exclusive_addr(ARMul_State* state, ARMword addr){
- state->exclusive_tag = addr & RESERVATION_GRANULE_MASK;
- return;
-}
-
-static void remove_exclusive(ARMul_State* state, ARMword addr){
- state->exclusive_tag = 0xFFFFFFFF;
-}
-
static int CondPassed(ARMul_State* cpu, unsigned int cond) {
const u32 NFLAG = cpu->NFlag;
const u32 ZFLAG = cpu->ZFlag;
@@ -3490,21 +3468,15 @@ enum {
FETCH_FAILURE
};
-static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
+static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
// Check if in Thumb mode
- tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
- if(ret == t_branch){
- // TODO: FIXME, endian should be judged
- u32 tinstr;
- if((addr & 0x3) != 0)
- tinstr = inst >> 16;
- else
- tinstr = inst & 0xFFFF;
-
+ ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
+ if (ret == ThumbDecodeStatus::BRANCH) {
int inst_index;
int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
+ u32 tinstr = GetThumbInstruction(inst, addr);
- switch((tinstr & 0xF800) >> 11){
+ switch ((tinstr & 0xF800) >> 11) {
case 26:
case 27:
if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
@@ -3537,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s
*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
break;
default:
- ret = t_undefined;
+ ret = ThumbDecodeStatus::UNDEFINED;
break;
}
}
@@ -3549,10 +3521,6 @@ enum {
FETCH_EXCEPTION
};
-typedef struct instruction_set_encoding_item ISEITEM;
-
-extern const ISEITEM arm_instruction[];
-
static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
Common::Profiling::ScopeTimer timer_decode(profile_decode);
@@ -3574,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
size++;
- // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction
+ // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
if (cpu->TFlag) {
uint32_t arm_inst;
- tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
+ ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
- // We have translated the branch instruction of thumb in thumb decoder
- if(state == t_branch){
+ // We have translated the Thumb branch instruction in the Thumb decoder
+ if (state == ThumbDecodeStatus::BRANCH) {
goto translated;
}
inst = arm_inst;
}
- ret = decode_arm_instr(inst, &idx);
- if (ret == DECODE_FAILURE) {
+ if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
@@ -3957,14 +3924,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
adc_inst* const inst_cream = (adc_inst*)inst_base->component;
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
bool carry;
bool overflow;
- RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+ RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -3978,7 +3949,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(adc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -3990,7 +3961,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rn_val = RN;
if (inst_cream->Rn == 15)
- rn_val += 2 * GET_INST_SIZE(cpu);
+ rn_val += 2 * cpu->GetInstructionSize();
bool carry;
bool overflow;
@@ -3999,7 +3970,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4013,22 +3984,28 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(add_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
AND_INST:
{
- and_inst *inst_cream = (and_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ and_inst* const inst_cream = (and_inst*)inst_base->component;
+
u32 lop = RN;
u32 rop = SHIFTER_OPERAND;
+
+ if (inst_cream->Rn == 15)
+ lop += 2 * cpu->GetInstructionSize();
+
RD = lop & rop;
+
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4041,7 +4018,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(and_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4057,7 +4034,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
INC_PC(sizeof(bbl_inst));
goto DISPATCH;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(bbl_inst));
goto DISPATCH;
}
@@ -4067,14 +4044,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
u32 lop = RN;
if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
+ lop += 2 * cpu->GetInstructionSize();
}
u32 rop = SHIFTER_OPERAND;
RD = lop & (~rop);
if ((inst_cream->S) && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4087,7 +4064,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(bic_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4098,7 +4075,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(bkpt_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4109,13 +4086,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
unsigned int inst = inst_cream->inst;
if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+ cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
if(cpu->TFlag)
cpu->Reg[14] |= 0x1;
cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
} else {
- cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+ cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
cpu->TFlag = 0x1;
int signed_int = inst_cream->val.signed_immed_24;
signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
@@ -4125,7 +4102,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
INC_PC(sizeof(blx_inst));
goto DISPATCH;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(blx_inst));
goto DISPATCH;
}
@@ -4147,7 +4124,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 address = RM;
if (inst_cream->Rm == 15)
- address += 2 * GET_INST_SIZE(cpu);
+ address += 2 * cpu->GetInstructionSize();
cpu->TFlag = address & 1;
cpu->Reg[15] = address & 0xfffffffe;
@@ -4155,7 +4132,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
@@ -4167,7 +4144,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->NumInstrsToExecute = 0;
return num_instrs;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(cdp_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4175,10 +4152,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
CLREX_INST:
{
- remove_exclusive(cpu, 0);
- cpu->exclusive_state = 0;
-
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(clrex_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4189,7 +4164,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
clz_inst* inst_cream = (clz_inst*)inst_base->component;
RD = clz(RM);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(clz_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4199,16 +4174,20 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
bool carry;
bool overflow;
- u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow);
+ u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
UPDATE_NFLAG(result);
UPDATE_ZFLAG(result);
cpu->CFlag = carry;
cpu->VFlag = overflow;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(cmn_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4220,7 +4199,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rn_val = RN;
if (inst_cream->Rn == 15)
- rn_val += 2 * GET_INST_SIZE(cpu);
+ rn_val += 2 * cpu->GetInstructionSize();
bool carry;
bool overflow;
@@ -4231,7 +4210,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->CFlag = carry;
cpu->VFlag = overflow;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(cmp_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4241,7 +4220,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cps_inst *inst_cream = (cps_inst *)inst_base->component;
uint32_t aif_val = 0;
uint32_t aif_mask = 0;
- if (InAPrivilegedMode(cpu)) {
+ if (cpu->InAPrivilegedMode()) {
if (inst_cream->imod1) {
if (inst_cream->A) {
aif_val |= (inst_cream->imod0 << 8);
@@ -4260,10 +4239,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
if (inst_cream->mmod) {
cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
- switch_mode(cpu, inst_cream->mode);
+ cpu->ChangePrivilegeMode(inst_cream->mode);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(cps_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4279,7 +4258,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mov_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4291,14 +4270,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 lop = RN;
if (inst_cream->Rn == 15) {
- lop += 2 * GET_INST_SIZE(cpu);
+ lop += 2 * cpu->GetInstructionSize();
}
u32 rop = SHIFTER_OPERAND;
RD = lop ^ rop;
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4311,7 +4290,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(eor_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4320,7 +4299,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
{
// Instruction not implemented
//LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4335,30 +4314,30 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (BIT(inst, 22) && !BIT(inst, 15)) {
for (int i = 0; i < 13; i++) {
if(BIT(inst, i)) {
- cpu->Reg[i] = ReadMemory32(cpu, addr);
+ cpu->Reg[i] = cpu->ReadMemory32(addr);
addr += 4;
}
}
if (BIT(inst, 13)) {
if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = ReadMemory32(cpu, addr);
+ cpu->Reg[13] = cpu->ReadMemory32(addr);
else
- cpu->Reg_usr[0] = ReadMemory32(cpu, addr);
+ cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
addr += 4;
}
if (BIT(inst, 14)) {
if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = ReadMemory32(cpu, addr);
+ cpu->Reg[14] = cpu->ReadMemory32(addr);
else
- cpu->Reg_usr[1] = ReadMemory32(cpu, addr);
+ cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
addr += 4;
}
} else if (!BIT(inst, 22)) {
for(int i = 0; i < 16; i++ ){
if(BIT(inst, i)){
- unsigned int ret = ReadMemory32(cpu, addr);
+ unsigned int ret = cpu->ReadMemory32(addr);
// For armv5t, should enter thumb when bits[0] is non-zero.
if(i == 15){
@@ -4373,18 +4352,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
} else if (BIT(inst, 22) && BIT(inst, 15)) {
for(int i = 0; i < 15; i++ ){
if(BIT(inst, i)){
- cpu->Reg[i] = ReadMemory32(cpu, addr);
+ cpu->Reg[i] = cpu->ReadMemory32(addr);
addr += 4;
}
}
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Cpsr & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
LOAD_NZCVT;
}
- cpu->Reg[15] = ReadMemory32(cpu, addr);
+ cpu->Reg[15] = cpu->ReadMemory32(addr);
}
if (BIT(inst, 15)) {
@@ -4392,7 +4371,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4410,7 +4389,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
RD = operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sxth_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4420,7 +4399,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = ReadMemory32(cpu, addr);
+ unsigned int value = cpu->ReadMemory32(addr);
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4431,7 +4410,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4442,7 +4421,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = ReadMemory32(cpu, addr);
+ unsigned int value = cpu->ReadMemory32(addr);
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4453,7 +4432,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4464,7 +4443,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxth_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4477,7 +4456,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = RN + operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxtah_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4495,7 +4474,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4513,7 +4492,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4527,8 +4506,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
// The 3DS doesn't have LPAE (Large Physical Access Extension), so it
// wouldn't do this as a single read.
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
// No dispatch since this operation should not modify R15
}
@@ -4544,16 +4523,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int read_addr = RN;
- add_exclusive_addr(cpu, read_addr);
- cpu->exclusive_state = 1;
+ cpu->SetExclusiveMemoryAddress(read_addr);
- RD = ReadMemory32(cpu, read_addr);
+ RD = cpu->ReadMemory32(read_addr);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4564,8 +4542,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int read_addr = RN;
- add_exclusive_addr(cpu, read_addr);
- cpu->exclusive_state = 1;
+ cpu->SetExclusiveMemoryAddress(read_addr);
RD = Memory::Read8(read_addr);
if (inst_cream->Rd == 15) {
@@ -4573,7 +4550,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4584,16 +4561,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int read_addr = RN;
- add_exclusive_addr(cpu, read_addr);
- cpu->exclusive_state = 1;
+ cpu->SetExclusiveMemoryAddress(read_addr);
- RD = ReadMemory16(cpu, read_addr);
+ RD = cpu->ReadMemory16(read_addr);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4604,18 +4580,17 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int read_addr = RN;
- add_exclusive_addr(cpu, read_addr);
- cpu->exclusive_state = 1;
+ cpu->SetExclusiveMemoryAddress(read_addr);
- RD = ReadMemory32(cpu, read_addr);
- RD2 = ReadMemory32(cpu, read_addr + 4);
+ RD = cpu->ReadMemory32(read_addr);
+ RD2 = cpu->ReadMemory32(read_addr + 4);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4626,13 +4601,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
if (BITS(inst_cream->inst, 12, 15) == 15) {
INC_PC(sizeof(ldst_inst));
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4652,7 +4627,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4663,7 +4638,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = ReadMemory16(cpu, addr);
+ unsigned int value = cpu->ReadMemory16(addr);
if (BIT(value, 15)) {
value |= 0xffff0000;
}
@@ -4673,7 +4648,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4684,7 +4659,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = ReadMemory32(cpu, addr);
+ unsigned int value = cpu->ReadMemory32(addr);
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4692,7 +4667,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4707,10 +4682,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
DEBUG_MSG;
} else {
if (inst_cream->cp_num == 15)
- WriteCP15Register(cpu, RD, CRn, OPCODE_1, CRm, OPCODE_2);
+ cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mcr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4727,7 +4702,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mcrr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4752,7 +4727,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mla_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4766,7 +4741,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4779,7 +4754,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mov_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4800,10 +4775,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto END;
} else {
if (inst_cream->cp_num == 15)
- RD = ReadCP15Register(cpu, CRn, OPCODE_1, CRm, OPCODE_2);
+ RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mrc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4820,7 +4795,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mcrr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4838,7 +4813,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = cpu->Cpsr;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mrs_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4861,7 +4836,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
| (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
uint32_t mask = 0;
if (!inst_cream->R) {
- if (InAPrivilegedMode(cpu)) {
+ if (cpu->InAPrivilegedMode()) {
if ((operand & StateMask) != 0) {
/// UNPREDICTABLE
DEBUG_MSG;
@@ -4873,7 +4848,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
SAVE_NZCVT;
cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
- switch_mode(cpu, cpu->Cpsr & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
LOAD_NZCVT;
} else {
if (CurrentModeHasSPSR) {
@@ -4882,7 +4857,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(msr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4904,7 +4879,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mul_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4919,7 +4894,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4932,7 +4907,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(mvn_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4944,12 +4919,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 lop = RN;
u32 rop = SHIFTER_OPERAND;
+
+ if (inst_cream->Rn == 15)
+ lop += 2 * cpu->GetInstructionSize();
+
RD = lop | rop;
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -4962,7 +4941,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(orr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4970,7 +4949,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
NOP_INST:
{
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC_STUB;
FETCH_INST;
GOTO_NEXT_INST;
@@ -4982,7 +4961,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(pkh_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -4995,7 +4974,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(pkh_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5005,7 +4984,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
{
// Not implemented. PLD is a hint instruction, so it's optional.
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(pld_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5078,7 +5057,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = result;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5140,7 +5119,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5173,7 +5152,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(rev_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5187,8 +5166,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 address = 0;
inst_cream->get_addr(cpu, inst_cream->inst, address);
- cpu->Cpsr = ReadMemory32(cpu, address);
- cpu->Reg[15] = ReadMemory32(cpu, address + 4);
+ cpu->Cpsr = cpu->ReadMemory32(address);
+ cpu->Reg[15] = cpu->ReadMemory32(address + 4);
INC_PC(sizeof(ldst_inst));
goto DISPATCH;
@@ -5201,7 +5180,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rn_val = RN;
if (inst_cream->Rn == 15)
- rn_val += 2 * GET_INST_SIZE(cpu);
+ rn_val += 2 * cpu->GetInstructionSize();
bool carry;
bool overflow;
@@ -5210,7 +5189,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -5224,7 +5203,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(rsb_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5234,14 +5213,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
bool carry;
bool overflow;
- RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+ RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -5255,7 +5238,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(rsc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5363,7 +5346,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5374,14 +5357,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
bool carry;
bool overflow;
- RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+ RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -5395,7 +5382,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sbc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5434,7 +5421,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = result;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5453,7 +5440,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(setend_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5466,7 +5453,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
LOG_TRACE(Core_ARM11, "SEV executed.");
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC_STUB;
FETCH_INST;
GOTO_NEXT_INST;
@@ -5538,7 +5525,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5563,7 +5550,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (AddOverflow(operand1 * operand2, RN, RD))
cpu->Cpsr |= (1 << 27);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smla_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5619,7 +5606,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlad_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5648,7 +5635,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(umlal_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5678,7 +5665,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RDHI = ((dest >> 32) & 0xFFFFFFFF);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlalxy_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5703,7 +5690,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->Cpsr |= (1 << 27);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlad_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5741,7 +5728,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RDHI = ((result >> 32) & 0xFFFFFFFF);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlald_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5777,7 +5764,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = ((result >> 32) & 0xFFFFFFFF);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlad_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5799,7 +5786,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
RD = operand1 * operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smul_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5825,7 +5812,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(umull_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5841,7 +5828,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
s64 result = (s64)rm * (s64)(s32)RN;
RD = BITS(result, 16, 47);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(smlad_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5855,10 +5842,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 address = 0;
inst_cream->get_addr(cpu, inst_cream->inst, address);
- WriteMemory32(cpu, address + 0, cpu->Reg[14]);
- WriteMemory32(cpu, address + 4, cpu->Spsr_copy);
+ cpu->WriteMemory32(address + 0, cpu->Reg[14]);
+ cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5891,7 +5878,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = rn_val;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ssat_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5913,7 +5900,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->Cpsr |= (1 << 27);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ssat_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5923,7 +5910,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
{
// Instruction not implemented
//LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(stc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5941,36 +5928,36 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (BIT(inst_cream->inst, 22) == 1) {
for (int i = 0; i < 13; i++) {
if (BIT(inst_cream->inst, i)) {
- WriteMemory32(cpu, addr, cpu->Reg[i]);
+ cpu->WriteMemory32(addr, cpu->Reg[i]);
addr += 4;
}
}
if (BIT(inst_cream->inst, 13)) {
if (cpu->Mode == USER32MODE)
- WriteMemory32(cpu, addr, cpu->Reg[13]);
+ cpu->WriteMemory32(addr, cpu->Reg[13]);
else
- WriteMemory32(cpu, addr, cpu->Reg_usr[0]);
+ cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
addr += 4;
}
if (BIT(inst_cream->inst, 14)) {
if (cpu->Mode == USER32MODE)
- WriteMemory32(cpu, addr, cpu->Reg[14]);
+ cpu->WriteMemory32(addr, cpu->Reg[14]);
else
- WriteMemory32(cpu, addr, cpu->Reg_usr[1]);
+ cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
addr += 4;
}
if (BIT(inst_cream->inst, 15)) {
- WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
+ cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
}
} else {
for (int i = 0; i < 15; i++) {
if (BIT(inst_cream->inst, i)) {
if (i == Rn)
- WriteMemory32(cpu, addr, old_RN);
+ cpu->WriteMemory32(addr, old_RN);
else
- WriteMemory32(cpu, addr, cpu->Reg[i]);
+ cpu->WriteMemory32(addr, cpu->Reg[i]);
addr += 4;
}
@@ -5978,10 +5965,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
// Check PC reg
if (BIT(inst_cream->inst, 15))
- WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
+ cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -5999,7 +5986,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
RD = operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sxtb_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6011,9 +5998,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
inst_cream->get_addr(cpu, inst_cream->inst, addr);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- WriteMemory32(cpu, addr, value);
+ cpu->WriteMemory32(addr, value);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6024,7 +6011,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxtb_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6037,7 +6024,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
RD = RN + operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxtab_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6050,7 +6037,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
Memory::Write8(addr, value);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6063,7 +6050,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
Memory::Write8(addr, value);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6076,10 +6063,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
// The 3DS doesn't have the Large Physical Access Extension (LPAE)
// so STRD wouldn't store these as a single write.
- WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
- WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
+ cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
+ cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6090,18 +6077,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
- remove_exclusive(cpu, write_addr);
- cpu->exclusive_state = 0;
-
- WriteMemory32(cpu, write_addr, RM);
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->WriteMemory32(write_addr, RM);
RD = 0;
} else {
// Failed to write due to mutex access
RD = 1;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6112,10 +6097,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
- remove_exclusive(cpu, write_addr);
- cpu->exclusive_state = 0;
-
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
RD = 0;
} else {
@@ -6123,7 +6106,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = 1;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6134,20 +6117,19 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
- remove_exclusive(cpu, write_addr);
- cpu->exclusive_state = 0;
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
const u32 rt = cpu->Reg[inst_cream->Rm + 0];
const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
u64 value;
- if (InBigEndianMode(cpu))
+ if (cpu->InBigEndianMode())
value = (((u64)rt << 32) | rt2);
else
value = (((u64)rt2 << 32) | rt);
- WriteMemory64(cpu, write_addr, value);
+ cpu->WriteMemory64(write_addr, value);
RD = 0;
}
else {
@@ -6155,7 +6137,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = 1;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6166,18 +6148,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
- remove_exclusive(cpu, write_addr);
- cpu->exclusive_state = 0;
-
- WriteMemory16(cpu, write_addr, RM);
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->WriteMemory16(write_addr, RM);
RD = 0;
} else {
// Failed to write due to mutex access
RD = 1;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6189,9 +6169,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
inst_cream->get_addr(cpu, inst_cream->inst, addr);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- WriteMemory16(cpu, addr, value);
+ cpu->WriteMemory16(addr, value);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6203,9 +6183,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
inst_cream->get_addr(cpu, inst_cream->inst, addr);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- WriteMemory32(cpu, addr, value);
+ cpu->WriteMemory32(addr, value);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ldst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6217,7 +6197,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rn_val = RN;
if (inst_cream->Rn == 15)
- rn_val += 8;
+ rn_val += 2 * cpu->GetInstructionSize();
bool carry;
bool overflow;
@@ -6226,7 +6206,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
if (inst_cream->S && (inst_cream->Rd == 15)) {
if (CurrentModeHasSPSR) {
cpu->Cpsr = cpu->Spsr_copy;
- switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
LOAD_NZCVT;
}
} else if (inst_cream->S) {
@@ -6240,7 +6220,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
goto DISPATCH;
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sub_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6252,7 +6232,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
SVC::CallSVC(inst_cream->num & 0xFFFF);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(swi_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6263,12 +6243,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
swp_inst* inst_cream = (swp_inst*)inst_base->component;
addr = RN;
- unsigned int value = ReadMemory32(cpu, addr);
- WriteMemory32(cpu, addr, RM);
+ unsigned int value = cpu->ReadMemory32(addr);
+ cpu->WriteMemory32(addr, RM);
RD = value;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(swp_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6282,7 +6262,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
Memory::Write8(addr, (RM & 0xFF));
RD = value;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(swp_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6298,7 +6278,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
RD = RN + operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxtab_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6331,7 +6311,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sxtab_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6347,7 +6327,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
RD = RN + operand2;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(sxtah_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6362,7 +6342,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rop = SHIFTER_OPERAND;
if (inst_cream->Rn == 15)
- lop += GET_INST_SIZE(cpu) * 2;
+ lop += cpu->GetInstructionSize() * 2;
u32 result = lop ^ rop;
@@ -6370,7 +6350,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
UPDATE_ZFLAG(result);
UPDATE_CFLAG_WITH_SC;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(teq_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6384,7 +6364,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
u32 rop = SHIFTER_OPERAND;
if (inst_cream->Rn == 15)
- lop += GET_INST_SIZE(cpu) * 2;
+ lop += cpu->GetInstructionSize() * 2;
u32 result = lop & rop;
@@ -6392,7 +6372,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
UPDATE_ZFLAG(result);
UPDATE_CFLAG_WITH_SC;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(tst_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6563,7 +6543,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6643,7 +6623,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6662,7 +6642,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RDLO = (result & 0xFFFFFFFF);
RDHI = ((result >> 32) & 0xFFFFFFFF);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(umaal_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6685,7 +6665,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(umlal_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6705,7 +6685,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(umull_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6733,7 +6713,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
{
bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(bl_1_thumb));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6814,7 +6794,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = ((lo_val & 0xFFFF) | hi_val << 16);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6844,7 +6824,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = finalDif;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6877,7 +6857,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
RD = rn_val;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ssat_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6899,7 +6879,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
cpu->Cpsr |= (1 << 27);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(ssat_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6930,7 +6910,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(uxtab_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -6943,7 +6923,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
LOG_TRACE(Core_ARM11, "WFE executed.");
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC_STUB;
FETCH_INST;
GOTO_NEXT_INST;
@@ -6956,7 +6936,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
LOG_TRACE(Core_ARM11, "WFI executed.");
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC_STUB;
FETCH_INST;
GOTO_NEXT_INST;
@@ -6969,7 +6949,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
LOG_TRACE(Core_ARM11, "YIELD executed.");
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC_STUB;
FETCH_INST;
GOTO_NEXT_INST;
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
index 1c324d29..7a46dcc9 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.h
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h
@@ -4,6 +4,6 @@
#pragma once
-#include "core/arm/skyeye_common/armdefs.h"
+struct ARMul_State;
unsigned 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 5a9a6a78..00000000
--- a/src/core/arm/dyncom/arm_dyncom_run.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "core/arm/dyncom/arm_dyncom_run.h"
-#include "core/arm/skyeye_common/armdefs.h"
-
-void switch_mode(ARMul_State* core, uint32_t mode) {
- if (core->Mode == mode)
- return;
-
- if (mode != USERBANK) {
- switch (core->Mode) {
- case SYSTEM32MODE: // Shares registers with user mode
- case USER32MODE:
- core->Reg_usr[0] = core->Reg[13];
- core->Reg_usr[1] = core->Reg[14];
- break;
- case IRQ32MODE:
- core->Reg_irq[0] = core->Reg[13];
- core->Reg_irq[1] = core->Reg[14];
- core->Spsr[IRQBANK] = core->Spsr_copy;
- break;
- case SVC32MODE:
- core->Reg_svc[0] = core->Reg[13];
- core->Reg_svc[1] = core->Reg[14];
- core->Spsr[SVCBANK] = core->Spsr_copy;
- break;
- case ABORT32MODE:
- core->Reg_abort[0] = core->Reg[13];
- core->Reg_abort[1] = core->Reg[14];
- core->Spsr[ABORTBANK] = core->Spsr_copy;
- break;
- case UNDEF32MODE:
- core->Reg_undef[0] = core->Reg[13];
- core->Reg_undef[1] = core->Reg[14];
- core->Spsr[UNDEFBANK] = core->Spsr_copy;
- break;
- case FIQ32MODE:
- core->Reg_firq[0] = core->Reg[13];
- core->Reg_firq[1] = core->Reg[14];
- core->Spsr[FIQBANK] = core->Spsr_copy;
- break;
- }
-
- switch (mode) {
- case USER32MODE:
- core->Reg[13] = core->Reg_usr[0];
- core->Reg[14] = core->Reg_usr[1];
- core->Bank = USERBANK;
- break;
- case IRQ32MODE:
- core->Reg[13] = core->Reg_irq[0];
- core->Reg[14] = core->Reg_irq[1];
- core->Spsr_copy = core->Spsr[IRQBANK];
- core->Bank = IRQBANK;
- break;
- case SVC32MODE:
- core->Reg[13] = core->Reg_svc[0];
- core->Reg[14] = core->Reg_svc[1];
- core->Spsr_copy = core->Spsr[SVCBANK];
- core->Bank = SVCBANK;
- break;
- case ABORT32MODE:
- core->Reg[13] = core->Reg_abort[0];
- core->Reg[14] = core->Reg_abort[1];
- core->Spsr_copy = core->Spsr[ABORTBANK];
- core->Bank = ABORTBANK;
- break;
- case UNDEF32MODE:
- core->Reg[13] = core->Reg_undef[0];
- core->Reg[14] = core->Reg_undef[1];
- core->Spsr_copy = core->Spsr[UNDEFBANK];
- core->Bank = UNDEFBANK;
- break;
- case FIQ32MODE:
- core->Reg[13] = core->Reg_firq[0];
- core->Reg[14] = core->Reg_firq[1];
- core->Spsr_copy = core->Spsr[FIQBANK];
- core->Bank = FIQBANK;
- break;
- case SYSTEM32MODE: // Shares registers with user mode.
- core->Reg[13] = core->Reg_usr[0];
- core->Reg[14] = core->Reg_usr[1];
- core->Bank = SYSTEMBANK;
- break;
- }
-
- // Set the mode bits in the APSR
- core->Cpsr = (core->Cpsr & ~core->Mode) | mode;
- core->Mode = mode;
- }
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index 85774c56..13bef17f 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -18,40 +18,31 @@
#pragma once
-#include "core/arm/skyeye_common/armdefs.h"
-
-void switch_mode(ARMul_State* core, uint32_t mode);
-
-// Note that for the 3DS, a Thumb instruction will only ever be
-// two bytes in size. Thus we don't need to worry about ThumbEE
-// or Thumb-2 where instructions can be 4 bytes in length.
-static inline u32 GET_INST_SIZE(ARMul_State* core) {
- return core->TFlag? 2 : 4;
-}
+#include "core/arm/skyeye_common/armstate.h"
/**
* Checks if the PC is being read, and if so, word-aligns it.
* Used with address calculations.
*
- * @param core The ARM CPU state instance.
+ * @param cpu The ARM CPU state instance.
* @param Rn The register being read.
*
* @return If the PC is being read, then the word-aligned PC value is returned.
* If the PC is not being read, then the value stored in the register is returned.
*/
-static inline u32 CHECK_READ_REG15_WA(ARMul_State* core, int Rn) {
- return (Rn == 15) ? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) {
+ return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
}
/**
* Reads the PC. Used for data processing operations that use the PC.
*
- * @param core The ARM CPU state instance.
+ * @param cpu The ARM CPU state instance.
* @param Rn The register being read.
*
* @return If the PC is being read, then the incremented PC value is returned.
* If the PC is not being read, then the values stored in the register is returned.
*/
-static inline u32 CHECK_READ_REG15(ARMul_State* core, int Rn) {
- return (Rn == 15) ? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline u32 CHECK_READ_REG15(ARMul_State* cpu, int Rn) {
+ return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index f10a5b70..29272fd5 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -6,20 +6,15 @@
// ARM instruction, and using the existing ARM simulator.
#include "core/arm/dyncom/arm_dyncom_thumb.h"
+#include "core/arm/skyeye_common/armsupp.h"
// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field,
// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
// allows easier simulation of the special dual BL instruction.
-tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
- tdstate valid = t_uninitialized;
- ARMword tinstr = instr;
-
- // The endian should be judge here
- if((addr & 0x3) != 0)
- tinstr = instr >> 16;
- else
- tinstr &= 0xFFFF;
+ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
+ ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED;
+ u32 tinstr = GetThumbInstruction(instr, addr);
*ainstr = 0xDEADC0DE; // Debugging to catch non updates
@@ -36,7 +31,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
case 3: // ADD/SUB
{
- static const ARMword subset[4] = {
+ static const u32 subset[4] = {
0xE0900000, // ADDS Rd,Rs,Rn
0xE0500000, // SUBS Rd,Rs,Rn
0xE2900000, // ADDS Rd,Rs,#imm3
@@ -55,7 +50,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
case 6: // ADD
case 7: // SUB
{
- static const ARMword subset[4] = {
+ static const u32 subset[4] = {
0xE3B00000, // MOVS Rd,#imm8
0xE3500000, // CMP Rd,#imm8
0xE2900000, // ADDS Rd,Rd,#imm8
@@ -84,7 +79,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
};
static const struct {
- ARMword opcode;
+ u32 opcode;
otype type;
} subset[16] = {
{ 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs
@@ -129,8 +124,8 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
break;
}
} else {
- ARMword Rd = ((tinstr & 0x0007) >> 0);
- ARMword Rs = ((tinstr & 0x0078) >> 3);
+ u32 Rd = ((tinstr & 0x0007) >> 0);
+ u32 Rs = ((tinstr & 0x0078) >> 3);
if (tinstr & (1 << 7))
Rd += 8;
@@ -184,7 +179,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
case 10:
case 11:
{
- static const ARMword subset[8] = {
+ static const u32 subset[8] = {
0xE7800000, // STR Rd,[Rb,Ro]
0xE18000B0, // STRH Rd,[Rb,Ro]
0xE7C00000, // STRB Rd,[Rb,Ro]
@@ -207,7 +202,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
case 14: // STRB Rd,[Rb,#imm5]
case 15: // LDRB Rd,[Rb,#imm5]
{
- static const ARMword subset[4] = {
+ static const u32 subset[4] = {
0xE5800000, // STR Rd,[Rb,#imm5]
0xE5900000, // LDR Rd,[Rb,#imm5]
0xE5C00000, // STRB Rd,[Rb,#imm5]
@@ -274,7 +269,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
| BITS(tinstr, 0, 3) // imm4 field;
| (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12
} else if ((tinstr & 0x0F00) == 0x0200) {
- static const ARMword subset[4] = {
+ static const u32 subset[4] = {
0xE6BF0070, // SXTH
0xE6AF0070, // SXTB
0xE6FF0070, // UXTH
@@ -298,7 +293,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
| (BIT(tinstr, 4) << 18); // enable bit
}
} else if ((tinstr & 0x0F00) == 0x0a00) {
- static const ARMword subset[3] = {
+ static const u32 subset[3] = {
0xE6BF0F30, // REV
0xE6BF0FB0, // REV16
0xE6FF0FB0, // REVSH
@@ -308,7 +303,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
| (BITS(tinstr, 0, 2) << 12) // Rd
| BITS(tinstr, 3, 5); // Rm
} else {
- static const ARMword subset[4] = {
+ static const u32 subset[4] = {
0xE92D0000, // STMDB sp!,{rlist}
0xE92D4000, // STMDB sp!,{rlist,lr}
0xE8BD0000, // LDMIA sp!,{rlist}
@@ -356,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
else
*ainstr |= (tinstr & 0x00FF);
} else if ((tinstr & 0x0F00) != 0x0E00)
- valid = t_branch;
+ valid = ThumbDecodeStatus::BRANCH;
else // UNDEFINED : cc=1110(AL) uses different format
- valid = t_undefined;
+ valid = ThumbDecodeStatus::UNDEFINED;
break;
case 28: // B
- valid = t_branch;
+ valid = ThumbDecodeStatus::BRANCH;
break;
case 29:
- if(tinstr & 0x1)
- valid = t_undefined;
+ if (tinstr & 0x1)
+ valid = ThumbDecodeStatus::UNDEFINED;
else
- valid = t_branch;
+ valid = ThumbDecodeStatus::BRANCH;
break;
case 30: // BL instruction 1
@@ -379,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
// simulation simple (from the user perspective) we check if the following instruction is
// the second half of this BL, and if it is we simulate it immediately
- valid = t_branch;
+ valid = ThumbDecodeStatus::BRANCH;
break;
case 31: // BL instruction 2
@@ -388,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
// ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
// simulation of it on its own, with undefined results if r14 is not suitably initialised.
- valid = t_branch;
+ valid = ThumbDecodeStatus::BRANCH;
break;
}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 8394ff15..44797436 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -26,22 +26,24 @@
#pragma once
-#include "core/arm/skyeye_common/armdefs.h"
+#include "common/common_types.h"
-enum tdstate {
- t_undefined, // Undefined Thumb instruction
- t_decoded, // Instruction decoded to ARM equivalent
- t_branch, // Thumb branch (already processed)
- t_uninitialized,
+enum class ThumbDecodeStatus {
+ UNDEFINED, // Undefined Thumb instruction
+ DECODED, // Instruction decoded to ARM equivalent
+ BRANCH, // Thumb branch (already processed)
+ UNINITIALIZED,
};
-tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
+// Translates a Thumb mode instruction into its ARM equivalent.
+ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
-static inline u32 get_thumb_instr(u32 instr, u32 pc) {
- u32 tinstr;
- if ((pc & 0x3) != 0)
- tinstr = instr >> 16;
- else
- tinstr = instr & 0xFFFF;
- return tinstr;
+static inline u32 GetThumbInstruction(u32 instr, u32 address) {
+ // Normally you would need to handle instruction endianness,
+ // however, it is fixed to little-endian on the MPCore, so
+ // there's no need to check for this beforehand.
+ if ((address & 0x3) != 0)
+ return instr >> 16;
+
+ return instr & 0xFFFF;
}
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
deleted file mode 100644
index 4f7a48fa..00000000
--- a/src/core/arm/interpreter/arminit.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
- Copyright (C) 1994 Advanced RISC Machines Ltd.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include <cstring>
-#include "core/arm/skyeye_common/armdefs.h"
-#include "core/arm/skyeye_common/vfp/vfp.h"
-
-/***************************************************************************\
-* Returns a new instantiation of the ARMulator's state *
-\***************************************************************************/
-ARMul_State* ARMul_NewState(ARMul_State* state)
-{
- state->Emulate = RUN;
- state->Mode = USER32MODE;
-
- state->lateabtSig = HIGH;
- state->bigendSig = LOW;
-
- return state;
-}
-
-/***************************************************************************\
-* Call this routine to set ARMulator to model a certain processor *
-\***************************************************************************/
-
-void ARMul_SelectProcessor(ARMul_State* state, unsigned properties)
-{
- state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0;
- state->is_v5 = (properties & ARM_v5_Prop) != 0;
- state->is_v5e = (properties & ARM_v5e_Prop) != 0;
- state->is_v6 = (properties & ARM_v6_Prop) != 0;
- state->is_v7 = (properties & ARM_v7_Prop) != 0;
-}
-
-// Resets certain MPCore CP15 values to their ARM-defined reset values.
-static void ResetMPCoreCP15Registers(ARMul_State* cpu)
-{
- // c0
- cpu->CP15[CP15_MAIN_ID] = 0x410FB024;
- cpu->CP15[CP15_TLB_TYPE] = 0x00000800;
- cpu->CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
- cpu->CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
- cpu->CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
- cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
- cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
- cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
- cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
- cpu->CP15[CP15_ISA_FEATURE_0] = 0x00100011;
- cpu->CP15[CP15_ISA_FEATURE_1] = 0x12002111;
- cpu->CP15[CP15_ISA_FEATURE_2] = 0x11221011;
- cpu->CP15[CP15_ISA_FEATURE_3] = 0x01102131;
- cpu->CP15[CP15_ISA_FEATURE_4] = 0x00000141;
-
- // c1
- cpu->CP15[CP15_CONTROL] = 0x00054078;
- cpu->CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
- cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
-
- // c2
- cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
- cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
- cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
-
- // c3
- cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
-
- // c7
- cpu->CP15[CP15_PHYS_ADDRESS] = 0x00000000;
-
- // c9
- cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
-
- // c10
- cpu->CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
- cpu->CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
- cpu->CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
-
- // c13
- cpu->CP15[CP15_PID] = 0x00000000;
- cpu->CP15[CP15_CONTEXT_ID] = 0x00000000;
- cpu->CP15[CP15_THREAD_UPRW] = 0x00000000;
- cpu->CP15[CP15_THREAD_URO] = 0x00000000;
- cpu->CP15[CP15_THREAD_PRW] = 0x00000000;
-
- // c15
- cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
- cpu->CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
-}
-
-/***************************************************************************\
-* Call this routine to set up the initial machine state (or perform a RESET *
-\***************************************************************************/
-void ARMul_Reset(ARMul_State* state)
-{
- VFPInit(state);
-
- state->Reg[15] = 0;
- state->Cpsr = INTBITS | SVC32MODE;
- state->Mode = SVC32MODE;
- state->Bank = SVCBANK;
-
- ResetMPCoreCP15Registers(state);
-
- state->NresetSig = HIGH;
- state->NfiqSig = HIGH;
- state->NirqSig = HIGH;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- state->abortSig = LOW;
-
- state->NumInstrs = 0;
-}
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
deleted file mode 100644
index 83f7f3e2..00000000
--- a/src/core/arm/interpreter/armsupp.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
- Copyright (C) 1994 Advanced RISC Machines Ltd.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "common/logging/log.h"
-
-#include "core/mem_map.h"
-#include "core/arm/skyeye_common/armdefs.h"
-#include "core/arm/skyeye_common/arm_regformat.h"
-
-// Unsigned sum of absolute difference
-u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
-{
- if (left > right)
- return left - right;
-
- return right - left;
-}
-
-// Add with carry, indicates if a carry-out or signed overflow occurred.
-u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred)
-{
- u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in;
- s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in;
- u64 result = (unsigned_sum & 0xFFFFFFFF);
-
- if (carry_out_occurred)
- *carry_out_occurred = (result != unsigned_sum);
-
- if (overflow_occurred)
- *overflow_occurred = ((s64)(s32)result != signed_sum);
-
- return (u32)result;
-}
-
-// Compute whether an addition of A and B, giving RESULT, overflowed.
-bool AddOverflow(ARMword a, ARMword b, ARMword result)
-{
- return ((NEG(a) && NEG(b) && POS(result)) ||
- (POS(a) && POS(b) && NEG(result)));
-}
-
-// Compute whether a subtraction of A and B, giving RESULT, overflowed.
-bool SubOverflow(ARMword a, ARMword b, ARMword result)
-{
- return ((NEG(a) && POS(b) && POS(result)) ||
- (POS(a) && NEG(b) && NEG(result)));
-}
-
-// Returns true if the Q flag should be set as a result of overflow.
-bool ARMul_AddOverflowQ(ARMword a, ARMword b)
-{
- u32 result = a + b;
- if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
- return true;
-
- return false;
-}
-
-// 8-bit signed saturated addition
-u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
-{
- u8 result = left + right;
-
- if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
- if (left & 0x80)
- result = 0x80;
- else
- result = 0x7F;
- }
-
- return result;
-}
-
-// 8-bit signed saturated subtraction
-u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
-{
- u8 result = left - right;
-
- if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
- if (left & 0x80)
- result = 0x80;
- else
- result = 0x7F;
- }
-
- return result;
-}
-
-// 16-bit signed saturated addition
-u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
-{
- u16 result = left + right;
-
- if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
- if (left & 0x8000)
- result = 0x8000;
- else
- result = 0x7FFF;
- }
-
- return result;
-}
-
-// 16-bit signed saturated subtraction
-u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
-{
- u16 result = left - right;
-
- if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
- if (left & 0x8000)
- result = 0x8000;
- else
- result = 0x7FFF;
- }
-
- return result;
-}
-
-// 8-bit unsigned saturated addition
-u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
-{
- u8 result = left + right;
-
- if (result < left)
- result = 0xFF;
-
- return result;
-}
-
-// 16-bit unsigned saturated addition
-u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
-{
- u16 result = left + right;
-
- if (result < left)
- result = 0xFFFF;
-
- return result;
-}
-
-// 8-bit unsigned saturated subtraction
-u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
-{
- if (left <= right)
- return 0;
-
- return left - right;
-}
-
-// 16-bit unsigned saturated subtraction
-u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
-{
- if (left <= right)
- return 0;
-
- return left - right;
-}
-
-// Signed saturation.
-u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
-{
- const u32 max = (1 << shift) - 1;
- const s32 top = (value >> shift);
-
- if (top > 0) {
- *saturation_occurred = true;
- return max;
- }
- else if (top < -1) {
- *saturation_occurred = true;
- return ~max;
- }
-
- *saturation_occurred = false;
- return (u32)value;
-}
-
-// Unsigned saturation
-u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
-{
- const u32 max = (1 << shift) - 1;
-
- if (value < 0) {
- *saturation_occurred = true;
- return 0;
- } else if ((u32)value > max) {
- *saturation_occurred = true;
- return max;
- }
-
- *saturation_occurred = false;
- return (u32)value;
-}
-
-// Whether or not the given CPU is in big endian mode (E bit is set)
-bool InBigEndianMode(ARMul_State* cpu)
-{
- return (cpu->Cpsr & (1 << 9)) != 0;
-}
-
-// Whether or not the given CPU is in a mode other than user mode.
-bool InAPrivilegedMode(ARMul_State* cpu)
-{
- return (cpu->Mode != USER32MODE);
-}
-
-// Reads from the CP15 registers. Used with implementation of the MRC instruction.
-// Note that since the 3DS does not have the hypervisor extensions, these registers
-// are not implemented.
-u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
-{
- // Unprivileged registers
- if (crn == 13 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 2)
- return cpu->CP15[CP15_THREAD_UPRW];
-
- if (opcode_2 == 3)
- return cpu->CP15[CP15_THREAD_URO];
- }
-
- if (InAPrivilegedMode(cpu))
- {
- if (crn == 0 && opcode_1 == 0)
- {
- if (crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_MAIN_ID];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_CACHE_TYPE];
-
- if (opcode_2 == 3)
- return cpu->CP15[CP15_TLB_TYPE];
-
- if (opcode_2 == 5)
- return cpu->CP15[CP15_CPU_ID];
- }
- else if (crm == 1)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_PROCESSOR_FEATURE_0];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_PROCESSOR_FEATURE_1];
-
- if (opcode_2 == 2)
- return cpu->CP15[CP15_DEBUG_FEATURE_0];
-
- if (opcode_2 == 4)
- return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0];
-
- if (opcode_2 == 5)
- return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1];
-
- if (opcode_2 == 6)
- return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2];
-
- if (opcode_2 == 7)
- return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3];
- }
- else if (crm == 2)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_ISA_FEATURE_0];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_ISA_FEATURE_1];
-
- if (opcode_2 == 2)
- return cpu->CP15[CP15_ISA_FEATURE_2];
-
- if (opcode_2 == 3)
- return cpu->CP15[CP15_ISA_FEATURE_3];
-
- if (opcode_2 == 4)
- return cpu->CP15[CP15_ISA_FEATURE_4];
- }
- }
-
- if (crn == 1 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_CONTROL];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_AUXILIARY_CONTROL];
-
- if (opcode_2 == 2)
- return cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
- }
-
- if (crn == 2 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1];
-
- if (opcode_2 == 2)
- return cpu->CP15[CP15_TRANSLATION_BASE_CONTROL];
- }
-
- if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
- return cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL];
-
- if (crn == 5 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_FAULT_STATUS];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_INSTR_FAULT_STATUS];
- }
-
- if (crn == 6 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_FAULT_ADDRESS];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_WFAR];
- }
-
- if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
- return cpu->CP15[CP15_PHYS_ADDRESS];
-
- if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
- return cpu->CP15[CP15_DATA_CACHE_LOCKDOWN];
-
- if (crn == 10 && opcode_1 == 0)
- {
- if (crm == 0 && opcode_2 == 0)
- return cpu->CP15[CP15_TLB_LOCKDOWN];
-
- if (crm == 2)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_PRIMARY_REGION_REMAP];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_NORMAL_REGION_REMAP];
- }
- }
-
- if (crn == 13 && crm == 0)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_PID];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_CONTEXT_ID];
-
- if (opcode_2 == 4)
- return cpu->CP15[CP15_THREAD_PRW];
- }
-
- if (crn == 15)
- {
- if (opcode_1 == 0 && crm == 12)
- {
- if (opcode_2 == 0)
- return cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
-
- if (opcode_2 == 1)
- return cpu->CP15[CP15_CYCLE_COUNTER];
-
- if (opcode_2 == 2)
- return cpu->CP15[CP15_COUNT_0];
-
- if (opcode_2 == 3)
- return cpu->CP15[CP15_COUNT_1];
- }
-
- if (opcode_1 == 5 && opcode_2 == 2)
- {
- if (crm == 5)
- return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
-
- if (crm == 6)
- return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
-
- if (crm == 7)
- return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
- }
-
- if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
- return cpu->CP15[CP15_TLB_DEBUG_CONTROL];
- }
- }
-
- LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
- return 0;
-}
-
-// Write to the CP15 registers. Used with implementation of the MCR instruction.
-// Note that since the 3DS does not have the hypervisor extensions, these registers
-// are not implemented.
-void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
-{
- if (InAPrivilegedMode(cpu))
- {
- if (crn == 1 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_CONTROL] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_AUXILIARY_CONTROL] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
- }
- else if (crn == 2 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
- }
- else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
- {
- cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
- }
- else if (crn == 5 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_FAULT_STATUS] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INSTR_FAULT_STATUS] = value;
- }
- else if (crn == 6 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_FAULT_ADDRESS] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_WFAR] = value;
- }
- else if (crn == 7 && opcode_1 == 0)
- {
- if (crm == 0 && opcode_2 == 4)
- {
- cpu->CP15[CP15_WAIT_FOR_INTERRUPT] = value;
- }
- else if (crm == 4 && opcode_2 == 0)
- {
- // NOTE: Not entirely accurate. This should do permission checks.
- cpu->CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
- }
- else if (crm == 5)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
- else if (opcode_2 == 6)
- cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
- else if (opcode_2 == 7)
- cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
- }
- else if (crm == 6)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_INVALIDATE_DATA_CACHE] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
- }
- else if (crm == 7 && opcode_2 == 0)
- {
- cpu->CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
- }
- else if (crm == 10)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_CLEAN_DATA_CACHE] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
- }
- else if (crm == 14)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
- }
- }
- else if (crn == 8 && opcode_1 == 0)
- {
- LOG_WARNING(Core_ARM11, "TLB operations not fully implemented.");
-
- if (crm == 5)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_INVALIDATE_ITLB] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
- else if (opcode_2 == 3)
- cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
- }
- else if (crm == 6)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_INVALIDATE_DTLB] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
- else if (opcode_2 == 3)
- cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
- }
- else if (crm == 7)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_INVALIDATE_UTLB] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
- else if (opcode_2 == 3)
- cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
- }
- }
- else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
- {
- cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
- }
- else if (crn == 10 && opcode_1 == 0)
- {
- if (crm == 0 && opcode_2 == 0)
- {
- cpu->CP15[CP15_TLB_LOCKDOWN] = value;
- }
- else if (crm == 2)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_PRIMARY_REGION_REMAP] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_NORMAL_REGION_REMAP] = value;
- }
- }
- else if (crn == 13 && opcode_1 == 0 && crm == 0)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_PID] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_CONTEXT_ID] = value;
- else if (opcode_2 == 3)
- cpu->CP15[CP15_THREAD_URO] = value;
- else if (opcode_2 == 4)
- cpu->CP15[CP15_THREAD_PRW] = value;
- }
- else if (crn == 15)
- {
- if (opcode_1 == 0 && crm == 12)
- {
- if (opcode_2 == 0)
- cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
- else if (opcode_2 == 1)
- cpu->CP15[CP15_CYCLE_COUNTER] = value;
- else if (opcode_2 == 2)
- cpu->CP15[CP15_COUNT_0] = value;
- else if (opcode_2 == 3)
- cpu->CP15[CP15_COUNT_1] = value;
- }
- else if (opcode_1 == 5)
- {
- if (crm == 4)
- {
- if (opcode_2 == 2)
- cpu->CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
- else if (opcode_2 == 4)
- cpu->CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
- }
- else if (crm == 5 && opcode_2 == 2)
- {
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
- }
- else if (crm == 6 && opcode_2 == 2)
- {
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
- }
- else if (crm == 7 && opcode_2 == 2)
- {
- cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
- }
- }
- else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
- {
- cpu->CP15[CP15_TLB_DEBUG_CONTROL] = value;
- }
- }
- }
-
- // Unprivileged registers
- if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
- {
- cpu->CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
- }
- else if (crn == 7 && opcode_1 == 0 && crm == 10)
- {
- if (opcode_2 == 4)
- cpu->CP15[CP15_DATA_SYNC_BARRIER] = value;
- else if (opcode_2 == 5)
- cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value;
-
- }
- else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
- {
- cpu->CP15[CP15_THREAD_UPRW] = value;
- }
-}
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
deleted file mode 100644
index d2c90110..00000000
--- a/src/core/arm/skyeye_common/armdefs.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
- Copyright (C) 1994 Advanced RISC Machines Ltd.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#pragma once
-
-#include <unordered_map>
-
-#include "common/common_types.h"
-#include "core/arm/skyeye_common/arm_regformat.h"
-
-#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
-#define BIT(s, n) ((s >> (n)) & 1)
-
-// Signal levels
-enum {
- LOW = 0,
- HIGH = 1,
- LOWHIGH = 1,
- HIGHLOW = 2
-};
-
-// Cache types
-enum {
- NONCACHE = 0,
- DATACACHE = 1,
- INSTCACHE = 2,
-};
-
-// Abort models
-enum {
- ABORT_BASE_RESTORED = 0,
- ABORT_EARLY = 1,
- ABORT_BASE_UPDATED = 2
-};
-
-#define POS(i) ( (~(i)) >> 31 )
-#define NEG(i) ( (i) >> 31 )
-
-typedef u64 ARMdword; // must be 64 bits wide
-typedef u32 ARMword; // must be 32 bits wide
-typedef u16 ARMhword; // must be 16 bits wide
-typedef u8 ARMbyte; // must be 8 bits wide
-
-#define VFP_REG_NUM 64
-struct ARMul_State
-{
- ARMword Emulate; // To start and stop emulation
-
- // Order of the following register should not be modified
- ARMword Reg[16]; // The current register file
- ARMword Cpsr; // The current PSR
- ARMword Spsr_copy;
- ARMword phys_pc;
- ARMword Reg_usr[2];
- ARMword Reg_svc[2]; // R13_SVC R14_SVC
- ARMword Reg_abort[2]; // R13_ABORT R14_ABORT
- ARMword Reg_undef[2]; // R13 UNDEF R14 UNDEF
- ARMword Reg_irq[2]; // R13_IRQ R14_IRQ
- ARMword Reg_firq[7]; // R8---R14 FIRQ
- ARMword Spsr[7]; // The exception psr's
- ARMword Mode; // The current mode
- ARMword Bank; // The current register bank
- ARMword exclusive_tag; // The address for which the local monitor is in exclusive access mode
- ARMword exclusive_state;
- ARMword exclusive_result;
- ARMword CP15[CP15_REGISTER_COUNT];
-
- // FPSID, FPSCR, and FPEXC
- ARMword VFP[VFP_SYSTEM_REGISTER_COUNT];
- // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
- // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
- // and only 32 singleword registers are accessible (S0-S31).
- ARMword ExtReg[VFP_REG_NUM];
- /* ---- End of the ordered registers ---- */
-
- ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
- unsigned int shifter_carry_out;
-
- // Add armv6 flags dyf:2010-08-09
- ARMword GEFlag, EFlag, AFlag, QFlag;
-
- ARMword TFlag; // Thumb state
-
- unsigned long long NumInstrs; // The number of instructions executed
- unsigned NumInstrsToExecute;
-
- unsigned NresetSig; // Reset the processor
- unsigned NfiqSig;
- unsigned NirqSig;
-
- unsigned abortSig;
- unsigned NtransSig;
- unsigned bigendSig;
- unsigned syscallSig;
-
-/* 2004-05-09 chy
-----------------------------------------------------------
-read ARM Architecture Reference Manual
-2.6.5 Data Abort
-There are three Abort Model in ARM arch.
-
-Early Abort Model: used in some ARMv3 and earlier implementations. In this
-model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
-the base register was unchanged for all other instructions. (oldest)
-
-Base Restored Abort Model: If a Data Abort occurs in an instruction which
-specifies base register writeback, the value in the base register is
-unchanged. (strongarm, xscale)
-
-Base Updated Abort Model: If a Data Abort occurs in an instruction which
-specifies base register writeback, the base register writeback still occurs.
-(arm720T)
-
-read PART B
-chap2 The System Control Coprocessor CP15
-2.4 Register1:control register
-L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
-processor could be configured:
-0=early Abort Model Selected(now obsolete)
-1=Late Abort Model selceted(same as Base Updated Abort Model)
-
-on later processors, this bit reads as 1 and ignores writes.
--------------------------------------------------------------
-So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
- if lateabtSig=0, then it means Base Restored Abort Model
-*/
- unsigned lateabtSig;
-
- // For differentiating ARM core emulaiton.
- bool is_v4; // Are we emulating a v4 architecture (or higher)?
- bool is_v5; // Are we emulating a v5 architecture?
- bool is_v5e; // Are we emulating a v5e architecture?
- bool is_v6; // Are we emulating a v6 architecture?
- bool is_v7; // Are we emulating a v7 architecture?
-
- // ARM_ARM A2-18
- // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model
- int abort_model;
-
- // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
- // process for our purposes), not per ARMul_State (which tracks CPU core state).
- std::unordered_map<u32, int> instruction_cache;
-};
-
-/***************************************************************************\
-* Types of ARM we know about *
-\***************************************************************************/
-
-enum {
- ARM_v4_Prop = 0x01,
- ARM_v5_Prop = 0x02,
- ARM_v5e_Prop = 0x04,
- ARM_v6_Prop = 0x08,
- ARM_v7_Prop = 0x10,
-};
-
-/***************************************************************************\
-* The hardware vector addresses *
-\***************************************************************************/
-
-enum {
- ARMResetV = 0,
- ARMUndefinedInstrV = 4,
- ARMSWIV = 8,
- ARMPrefetchAbortV = 12,
- ARMDataAbortV = 16,
- ARMAddrExceptnV = 20,
- ARMIRQV = 24,
- ARMFIQV = 28,
- ARMErrorV = 32, // This is an offset, not an address!
-
- ARMul_ResetV = ARMResetV,
- ARMul_UndefinedInstrV = ARMUndefinedInstrV,
- ARMul_SWIV = ARMSWIV,
- ARMul_PrefetchAbortV = ARMPrefetchAbortV,
- ARMul_DataAbortV = ARMDataAbortV,
- ARMul_AddrExceptnV = ARMAddrExceptnV,
- ARMul_IRQV = ARMIRQV,
- ARMul_FIQV = ARMFIQV
-};
-
-/***************************************************************************\
-* Mode and Bank Constants *
-\***************************************************************************/
-
-enum PrivilegeMode {
- USER32MODE = 16,
- FIQ32MODE = 17,
- IRQ32MODE = 18,
- SVC32MODE = 19,
- ABORT32MODE = 23,
- UNDEF32MODE = 27,
- SYSTEM32MODE = 31
-};
-
-enum {
- USERBANK = 0,
- FIQBANK = 1,
- IRQBANK = 2,
- SVCBANK = 3,
- ABORTBANK = 4,
- UNDEFBANK = 5,
- DUMMYBANK = 6,
- SYSTEMBANK = 7
-};
-
-/***************************************************************************\
-* Definitons of things in the emulator *
-\***************************************************************************/
-extern void ARMul_Reset(ARMul_State* state);
-extern ARMul_State* ARMul_NewState(ARMul_State* state);
-
-/***************************************************************************\
-* Definitons of things in the co-processor interface *
-\***************************************************************************/
-
-enum {
- ARMul_FIRST = 0,
- ARMul_TRANSFER = 1,
- ARMul_BUSY = 2,
- ARMul_DATA = 3,
- ARMul_INTERRUPT = 4,
- ARMul_DONE = 0,
- ARMul_CANT = 1,
- ARMul_INC = 3
-};
-
-/***************************************************************************\
-* Definitons of things in the host environment *
-\***************************************************************************/
-
-enum ConditionCode {
- EQ = 0,
- NE = 1,
- CS = 2,
- CC = 3,
- MI = 4,
- PL = 5,
- VS = 6,
- VC = 7,
- HI = 8,
- LS = 9,
- GE = 10,
- LT = 11,
- GT = 12,
- LE = 13,
- AL = 14,
- NV = 15,
-};
-
-// Flags for use with the APSR.
-enum : u32 {
- NBIT = (1U << 31U),
- ZBIT = (1 << 30),
- CBIT = (1 << 29),
- VBIT = (1 << 28),
- QBIT = (1 << 27),
- JBIT = (1 << 24),
- EBIT = (1 << 9),
- ABIT = (1 << 8),
- IBIT = (1 << 7),
- FBIT = (1 << 6),
- TBIT = (1 << 5),
-
- // Masks for groups of bits in the APSR.
- MODEBITS = 0x1F,
- INTBITS = 0x1C0,
-};
-
-// Values for Emulate.
-enum {
- STOP = 0, // Stop
- CHANGEMODE = 1, // Change mode
- ONCE = 2, // Execute just one iteration
- RUN = 3 // Continuous execution
-};
-
-
-extern bool AddOverflow(ARMword, ARMword, ARMword);
-extern bool SubOverflow(ARMword, ARMword, ARMword);
-
-extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
-
-extern u32 AddWithCarry(u32, u32, u32, bool*, bool*);
-extern bool ARMul_AddOverflowQ(ARMword, ARMword);
-
-extern u8 ARMul_SignedSaturatedAdd8(u8, u8);
-extern u8 ARMul_SignedSaturatedSub8(u8, u8);
-extern u16 ARMul_SignedSaturatedAdd16(u16, u16);
-extern u16 ARMul_SignedSaturatedSub16(u16, u16);
-
-extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
-extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
-extern u8 ARMul_UnsignedSaturatedSub8(u8, u8);
-extern u16 ARMul_UnsignedSaturatedSub16(u16, u16);
-extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
-extern u32 ARMul_SignedSatQ(s32, u8, bool*);
-extern u32 ARMul_UnsignedSatQ(s32, u8, bool*);
-
-extern bool InBigEndianMode(ARMul_State*);
-extern bool InAPrivilegedMode(ARMul_State*);
-
-extern u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
-extern void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
deleted file mode 100644
index c67d7209..00000000
--- a/src/core/arm/skyeye_common/armmmu.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- armmmu.c - Memory Management Unit emulation.
- ARMulator extensions for the ARM7100 family.
- Copyright (C) 1999 Ben Williamson
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#pragma once
-
-#include "common/swap.h"
-
-#include "core/memory.h"
-#include "core/arm/skyeye_common/armdefs.h"
-
-// Register numbers in the MMU
-enum
-{
- MMU_ID = 0,
- MMU_CONTROL = 1,
- MMU_TRANSLATION_TABLE_BASE = 2,
- MMU_DOMAIN_ACCESS_CONTROL = 3,
- MMU_FAULT_STATUS = 5,
- MMU_FAULT_ADDRESS = 6,
- MMU_CACHE_OPS = 7,
- MMU_TLB_OPS = 8,
- MMU_CACHE_LOCKDOWN = 9,
- MMU_TLB_LOCKDOWN = 10,
- MMU_PID = 13,
-
- // MMU_V4
- MMU_V4_CACHE_OPS = 7,
- MMU_V4_TLB_OPS = 8,
-
- // MMU_V3
- MMU_V3_FLUSH_TLB = 5,
- MMU_V3_FLUSH_TLB_ENTRY = 6,
- MMU_V3_FLUSH_CACHE = 7,
-};
-
-// Reads data in big/little endian format based on the
-// state of the E (endian) bit in the emulated CPU's APSR.
-inline u16 ReadMemory16(ARMul_State* cpu, u32 address) {
- u16 data = Memory::Read16(address);
-
- if (InBigEndianMode(cpu))
- data = Common::swap16(data);
-
- return data;
-}
-
-inline u32 ReadMemory32(ARMul_State* cpu, u32 address) {
- u32 data = Memory::Read32(address);
-
- if (InBigEndianMode(cpu))
- data = Common::swap32(data);
-
- return data;
-}
-
-inline u64 ReadMemory64(ARMul_State* cpu, u32 address) {
- u64 data = Memory::Read64(address);
-
- if (InBigEndianMode(cpu))
- data = Common::swap64(data);
-
- return data;
-}
-
-// Writes data in big/little endian format based on the
-// state of the E (endian) bit in the emulated CPU's APSR.
-inline void WriteMemory16(ARMul_State* cpu, u32 address, u16 data) {
- if (InBigEndianMode(cpu))
- data = Common::swap16(data);
-
- Memory::Write16(address, data);
-}
-
-inline void WriteMemory32(ARMul_State* cpu, u32 address, u32 data) {
- if (InBigEndianMode(cpu))
- data = Common::swap32(data);
-
- Memory::Write32(address, data);
-}
-
-inline void WriteMemory64(ARMul_State* cpu, u32 address, u64 data) {
- if (InBigEndianMode(cpu))
- data = Common::swap64(data);
-
- Memory::Write64(address, data);
-}
diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp
new file mode 100644
index 00000000..ccb2eb0e
--- /dev/null
+++ b/src/core/arm/skyeye_common/armstate.cpp
@@ -0,0 +1,657 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/swap.h"
+#include "common/logging/log.h"
+#include "core/mem_map.h"
+#include "core/memory.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/vfp/vfp.h"
+
+ARMul_State::ARMul_State(PrivilegeMode initial_mode)
+{
+ Reset();
+ ChangePrivilegeMode(initial_mode);
+}
+
+void ARMul_State::ChangePrivilegeMode(u32 new_mode)
+{
+ if (Mode == new_mode)
+ return;
+
+ if (new_mode != USERBANK) {
+ switch (Mode) {
+ case SYSTEM32MODE: // Shares registers with user mode
+ case USER32MODE:
+ Reg_usr[0] = Reg[13];
+ Reg_usr[1] = Reg[14];
+ break;
+ case IRQ32MODE:
+ Reg_irq[0] = Reg[13];
+ Reg_irq[1] = Reg[14];
+ Spsr[IRQBANK] = Spsr_copy;
+ break;
+ case SVC32MODE:
+ Reg_svc[0] = Reg[13];
+ Reg_svc[1] = Reg[14];
+ Spsr[SVCBANK] = Spsr_copy;
+ break;
+ case ABORT32MODE:
+ Reg_abort[0] = Reg[13];
+ Reg_abort[1] = Reg[14];
+ Spsr[ABORTBANK] = Spsr_copy;
+ break;
+ case UNDEF32MODE:
+ Reg_undef[0] = Reg[13];
+ Reg_undef[1] = Reg[14];
+ Spsr[UNDEFBANK] = Spsr_copy;
+ break;
+ case FIQ32MODE:
+ Reg_firq[0] = Reg[13];
+ Reg_firq[1] = Reg[14];
+ Spsr[FIQBANK] = Spsr_copy;
+ break;
+ }
+
+ switch (new_mode) {
+ case USER32MODE:
+ Reg[13] = Reg_usr[0];
+ Reg[14] = Reg_usr[1];
+ Bank = USERBANK;
+ break;
+ case IRQ32MODE:
+ Reg[13] = Reg_irq[0];
+ Reg[14] = Reg_irq[1];
+ Spsr_copy = Spsr[IRQBANK];
+ Bank = IRQBANK;
+ break;
+ case SVC32MODE:
+ Reg[13] = Reg_svc[0];
+ Reg[14] = Reg_svc[1];
+ Spsr_copy = Spsr[SVCBANK];
+ Bank = SVCBANK;
+ break;
+ case ABORT32MODE:
+ Reg[13] = Reg_abort[0];
+ Reg[14] = Reg_abort[1];
+ Spsr_copy = Spsr[ABORTBANK];
+ Bank = ABORTBANK;
+ break;
+ case UNDEF32MODE:
+ Reg[13] = Reg_undef[0];
+ Reg[14] = Reg_undef[1];
+ Spsr_copy = Spsr[UNDEFBANK];
+ Bank = UNDEFBANK;
+ break;
+ case FIQ32MODE:
+ Reg[13] = Reg_firq[0];
+ Reg[14] = Reg_firq[1];
+ Spsr_copy = Spsr[FIQBANK];
+ Bank = FIQBANK;
+ break;
+ case SYSTEM32MODE: // Shares registers with user mode.
+ Reg[13] = Reg_usr[0];
+ Reg[14] = Reg_usr[1];
+ Bank = SYSTEMBANK;
+ break;
+ }
+
+ // Set the mode bits in the APSR
+ Cpsr = (Cpsr & ~Mode) | new_mode;
+ Mode = new_mode;
+ }
+}
+
+// Performs a reset
+void ARMul_State::Reset()
+{
+ VFPInit(this);
+
+ // Set stack pointer to the top of the stack
+ Reg[13] = 0x10000000;
+ Reg[15] = 0;
+
+ Cpsr = INTBITS | SVC32MODE;
+ Mode = SVC32MODE;
+ Bank = SVCBANK;
+
+ ResetMPCoreCP15Registers();
+
+ NresetSig = HIGH;
+ NfiqSig = HIGH;
+ NirqSig = HIGH;
+ NtransSig = (Mode & 3) ? HIGH : LOW;
+ abortSig = LOW;
+
+ NumInstrs = 0;
+ Emulate = RUN;
+}
+
+// Resets certain MPCore CP15 values to their ARM-defined reset values.
+void ARMul_State::ResetMPCoreCP15Registers()
+{
+ // c0
+ CP15[CP15_MAIN_ID] = 0x410FB024;
+ CP15[CP15_TLB_TYPE] = 0x00000800;
+ CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
+ CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
+ CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
+ CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
+ CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
+ CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
+ CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
+ CP15[CP15_ISA_FEATURE_0] = 0x00100011;
+ CP15[CP15_ISA_FEATURE_1] = 0x12002111;
+ CP15[CP15_ISA_FEATURE_2] = 0x11221011;
+ CP15[CP15_ISA_FEATURE_3] = 0x01102131;
+ CP15[CP15_ISA_FEATURE_4] = 0x00000141;
+
+ // c1
+ CP15[CP15_CONTROL] = 0x00054078;
+ CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
+ CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
+
+ // c2
+ CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
+ CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
+ CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
+
+ // c3
+ CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
+
+ // c7
+ CP15[CP15_PHYS_ADDRESS] = 0x00000000;
+
+ // c9
+ CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
+
+ // c10
+ CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
+ CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
+ CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
+
+ // c13
+ CP15[CP15_PID] = 0x00000000;
+ CP15[CP15_CONTEXT_ID] = 0x00000000;
+ CP15[CP15_THREAD_UPRW] = 0x00000000;
+ CP15[CP15_THREAD_URO] = 0x00000000;
+ CP15[CP15_THREAD_PRW] = 0x00000000;
+
+ // c15
+ CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
+ CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
+ CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
+ CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
+ CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
+}
+
+u16 ARMul_State::ReadMemory16(u32 address) const
+{
+ u16 data = Memory::Read16(address);
+
+ if (InBigEndianMode())
+ data = Common::swap16(data);
+
+ return data;
+}
+
+u32 ARMul_State::ReadMemory32(u32 address) const
+{
+ u32 data = Memory::Read32(address);
+
+ if (InBigEndianMode())
+ data = Common::swap32(data);
+
+ return data;
+}
+
+u64 ARMul_State::ReadMemory64(u32 address) const
+{
+ u64 data = Memory::Read64(address);
+
+ if (InBigEndianMode())
+ data = Common::swap64(data);
+
+ return data;
+}
+
+void ARMul_State::WriteMemory16(u32 address, u16 data)
+{
+ if (InBigEndianMode())
+ data = Common::swap16(data);
+
+ Memory::Write16(address, data);
+}
+
+void ARMul_State::WriteMemory32(u32 address, u32 data)
+{
+ if (InBigEndianMode())
+ data = Common::swap32(data);
+
+ Memory::Write32(address, data);
+}
+
+void ARMul_State::WriteMemory64(u32 address, u64 data)
+{
+ if (InBigEndianMode())
+ data = Common::swap64(data);
+
+ Memory::Write64(address, data);
+}
+
+
+// Reads from the CP15 registers. Used with implementation of the MRC instruction.
+// Note that since the 3DS does not have the hypervisor extensions, these registers
+// are not implemented.
+u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const
+{
+ // Unprivileged registers
+ if (crn == 13 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 2)
+ return CP15[CP15_THREAD_UPRW];
+
+ if (opcode_2 == 3)
+ return CP15[CP15_THREAD_URO];
+ }
+
+ if (InAPrivilegedMode())
+ {
+ if (crn == 0 && opcode_1 == 0)
+ {
+ if (crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_MAIN_ID];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_CACHE_TYPE];
+
+ if (opcode_2 == 3)
+ return CP15[CP15_TLB_TYPE];
+
+ if (opcode_2 == 5)
+ return CP15[CP15_CPU_ID];
+ }
+ else if (crm == 1)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_PROCESSOR_FEATURE_0];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_PROCESSOR_FEATURE_1];
+
+ if (opcode_2 == 2)
+ return CP15[CP15_DEBUG_FEATURE_0];
+
+ if (opcode_2 == 4)
+ return CP15[CP15_MEMORY_MODEL_FEATURE_0];
+
+ if (opcode_2 == 5)
+ return CP15[CP15_MEMORY_MODEL_FEATURE_1];
+
+ if (opcode_2 == 6)
+ return CP15[CP15_MEMORY_MODEL_FEATURE_2];
+
+ if (opcode_2 == 7)
+ return CP15[CP15_MEMORY_MODEL_FEATURE_3];
+ }
+ else if (crm == 2)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_ISA_FEATURE_0];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_ISA_FEATURE_1];
+
+ if (opcode_2 == 2)
+ return CP15[CP15_ISA_FEATURE_2];
+
+ if (opcode_2 == 3)
+ return CP15[CP15_ISA_FEATURE_3];
+
+ if (opcode_2 == 4)
+ return CP15[CP15_ISA_FEATURE_4];
+ }
+ }
+
+ if (crn == 1 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_CONTROL];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_AUXILIARY_CONTROL];
+
+ if (opcode_2 == 2)
+ return CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
+ }
+
+ if (crn == 2 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_TRANSLATION_BASE_TABLE_0];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_TRANSLATION_BASE_TABLE_1];
+
+ if (opcode_2 == 2)
+ return CP15[CP15_TRANSLATION_BASE_CONTROL];
+ }
+
+ if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+ return CP15[CP15_DOMAIN_ACCESS_CONTROL];
+
+ if (crn == 5 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_FAULT_STATUS];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_INSTR_FAULT_STATUS];
+ }
+
+ if (crn == 6 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_FAULT_ADDRESS];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_WFAR];
+ }
+
+ if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
+ return CP15[CP15_PHYS_ADDRESS];
+
+ if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+ return CP15[CP15_DATA_CACHE_LOCKDOWN];
+
+ if (crn == 10 && opcode_1 == 0)
+ {
+ if (crm == 0 && opcode_2 == 0)
+ return CP15[CP15_TLB_LOCKDOWN];
+
+ if (crm == 2)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_PRIMARY_REGION_REMAP];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_NORMAL_REGION_REMAP];
+ }
+ }
+
+ if (crn == 13 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_PID];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_CONTEXT_ID];
+
+ if (opcode_2 == 4)
+ return CP15[CP15_THREAD_PRW];
+ }
+
+ if (crn == 15)
+ {
+ if (opcode_1 == 0 && crm == 12)
+ {
+ if (opcode_2 == 0)
+ return CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
+
+ if (opcode_2 == 1)
+ return CP15[CP15_CYCLE_COUNTER];
+
+ if (opcode_2 == 2)
+ return CP15[CP15_COUNT_0];
+
+ if (opcode_2 == 3)
+ return CP15[CP15_COUNT_1];
+ }
+
+ if (opcode_1 == 5 && opcode_2 == 2)
+ {
+ if (crm == 5)
+ return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
+
+ if (crm == 6)
+ return CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
+
+ if (crm == 7)
+ return CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
+ }
+
+ if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
+ return CP15[CP15_TLB_DEBUG_CONTROL];
+ }
+ }
+
+ LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
+ return 0;
+}
+
+// Write to the CP15 registers. Used with implementation of the MCR instruction.
+// Note that since the 3DS does not have the hypervisor extensions, these registers
+// are not implemented.
+void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
+{
+ if (InAPrivilegedMode())
+ {
+ if (crn == 1 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_CONTROL] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_AUXILIARY_CONTROL] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
+ }
+ else if (crn == 2 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
+ }
+ else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+ {
+ CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
+ }
+ else if (crn == 5 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_FAULT_STATUS] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INSTR_FAULT_STATUS] = value;
+ }
+ else if (crn == 6 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_FAULT_ADDRESS] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_WFAR] = value;
+ }
+ else if (crn == 7 && opcode_1 == 0)
+ {
+ if (crm == 0 && opcode_2 == 4)
+ {
+ CP15[CP15_WAIT_FOR_INTERRUPT] = value;
+ }
+ else if (crm == 4 && opcode_2 == 0)
+ {
+ // NOTE: Not entirely accurate. This should do permission checks.
+ CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
+ }
+ else if (crm == 5)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
+ else if (opcode_2 == 6)
+ CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
+ else if (opcode_2 == 7)
+ CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
+ }
+ else if (crm == 6)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_INVALIDATE_DATA_CACHE] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
+ }
+ else if (crm == 7 && opcode_2 == 0)
+ {
+ CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
+ }
+ else if (crm == 10)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_CLEAN_DATA_CACHE] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
+ }
+ else if (crm == 14)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
+ }
+ }
+ else if (crn == 8 && opcode_1 == 0)
+ {
+ if (crm == 5)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_INVALIDATE_ITLB] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
+ else if (opcode_2 == 3)
+ CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
+ }
+ else if (crm == 6)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_INVALIDATE_DTLB] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
+ else if (opcode_2 == 3)
+ CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
+ }
+ else if (crm == 7)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_INVALIDATE_UTLB] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
+ else if (opcode_2 == 3)
+ CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
+ }
+ }
+ else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
+ {
+ CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
+ }
+ else if (crn == 10 && opcode_1 == 0)
+ {
+ if (crm == 0 && opcode_2 == 0)
+ {
+ CP15[CP15_TLB_LOCKDOWN] = value;
+ }
+ else if (crm == 2)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_PRIMARY_REGION_REMAP] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_NORMAL_REGION_REMAP] = value;
+ }
+ }
+ else if (crn == 13 && opcode_1 == 0 && crm == 0)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_PID] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_CONTEXT_ID] = value;
+ else if (opcode_2 == 3)
+ CP15[CP15_THREAD_URO] = value;
+ else if (opcode_2 == 4)
+ CP15[CP15_THREAD_PRW] = value;
+ }
+ else if (crn == 15)
+ {
+ if (opcode_1 == 0 && crm == 12)
+ {
+ if (opcode_2 == 0)
+ CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
+ else if (opcode_2 == 1)
+ CP15[CP15_CYCLE_COUNTER] = value;
+ else if (opcode_2 == 2)
+ CP15[CP15_COUNT_0] = value;
+ else if (opcode_2 == 3)
+ CP15[CP15_COUNT_1] = value;
+ }
+ else if (opcode_1 == 5)
+ {
+ if (crm == 4)
+ {
+ if (opcode_2 == 2)
+ CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
+ else if (opcode_2 == 4)
+ CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
+ }
+ else if (crm == 5 && opcode_2 == 2)
+ {
+ CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
+ }
+ else if (crm == 6 && opcode_2 == 2)
+ {
+ CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
+ }
+ else if (crm == 7 && opcode_2 == 2)
+ {
+ CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
+ }
+ }
+ else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
+ {
+ CP15[CP15_TLB_DEBUG_CONTROL] = value;
+ }
+ }
+ }
+
+ // Unprivileged registers
+ if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
+ {
+ CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
+ }
+ else if (crn == 7 && opcode_1 == 0 && crm == 10)
+ {
+ if (opcode_2 == 4)
+ CP15[CP15_DATA_SYNC_BARRIER] = value;
+ else if (opcode_2 == 5)
+ CP15[CP15_DATA_MEMORY_BARRIER] = value;
+ }
+ else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
+ {
+ CP15[CP15_THREAD_UPRW] = value;
+ }
+}
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h
new file mode 100644
index 00000000..b364e262
--- /dev/null
+++ b/src/core/arm/skyeye_common/armstate.h
@@ -0,0 +1,252 @@
+/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#pragma once
+
+#include <array>
+#include <unordered_map>
+
+#include "common/common_types.h"
+#include "core/arm/skyeye_common/arm_regformat.h"
+
+// Signal levels
+enum {
+ LOW = 0,
+ HIGH = 1,
+ LOWHIGH = 1,
+ HIGHLOW = 2
+};
+
+// Cache types
+enum {
+ NONCACHE = 0,
+ DATACACHE = 1,
+ INSTCACHE = 2,
+};
+
+// ARM privilege modes
+enum PrivilegeMode {
+ USER32MODE = 16,
+ FIQ32MODE = 17,
+ IRQ32MODE = 18,
+ SVC32MODE = 19,
+ ABORT32MODE = 23,
+ UNDEF32MODE = 27,
+ SYSTEM32MODE = 31
+};
+
+// ARM privilege mode register banks
+enum {
+ USERBANK = 0,
+ FIQBANK = 1,
+ IRQBANK = 2,
+ SVCBANK = 3,
+ ABORTBANK = 4,
+ UNDEFBANK = 5,
+ DUMMYBANK = 6,
+ SYSTEMBANK = 7
+};
+
+// Hardware vector addresses
+enum {
+ ARMResetV = 0,
+ ARMUndefinedInstrV = 4,
+ ARMSWIV = 8,
+ ARMPrefetchAbortV = 12,
+ ARMDataAbortV = 16,
+ ARMAddrExceptnV = 20,
+ ARMIRQV = 24,
+ ARMFIQV = 28,
+ ARMErrorV = 32, // This is an offset, not an address!
+
+ ARMul_ResetV = ARMResetV,
+ ARMul_UndefinedInstrV = ARMUndefinedInstrV,
+ ARMul_SWIV = ARMSWIV,
+ ARMul_PrefetchAbortV = ARMPrefetchAbortV,
+ ARMul_DataAbortV = ARMDataAbortV,
+ ARMul_AddrExceptnV = ARMAddrExceptnV,
+ ARMul_IRQV = ARMIRQV,
+ ARMul_FIQV = ARMFIQV
+};
+
+// Coprocessor status values
+enum {
+ ARMul_FIRST = 0,
+ ARMul_TRANSFER = 1,
+ ARMul_BUSY = 2,
+ ARMul_DATA = 3,
+ ARMul_INTERRUPT = 4,
+ ARMul_DONE = 0,
+ ARMul_CANT = 1,
+ ARMul_INC = 3
+};
+
+// Instruction condition codes
+enum ConditionCode {
+ EQ = 0,
+ NE = 1,
+ CS = 2,
+ CC = 3,
+ MI = 4,
+ PL = 5,
+ VS = 6,
+ VC = 7,
+ HI = 8,
+ LS = 9,
+ GE = 10,
+ LT = 11,
+ GT = 12,
+ LE = 13,
+ AL = 14,
+ NV = 15,
+};
+
+// Flags for use with the APSR.
+enum : u32 {
+ NBIT = (1U << 31U),
+ ZBIT = (1 << 30),
+ CBIT = (1 << 29),
+ VBIT = (1 << 28),
+ QBIT = (1 << 27),
+ JBIT = (1 << 24),
+ EBIT = (1 << 9),
+ ABIT = (1 << 8),
+ IBIT = (1 << 7),
+ FBIT = (1 << 6),
+ TBIT = (1 << 5),
+
+ // Masks for groups of bits in the APSR.
+ MODEBITS = 0x1F,
+ INTBITS = 0x1C0,
+};
+
+// Values for Emulate.
+enum {
+ STOP = 0, // Stop
+ CHANGEMODE = 1, // Change mode
+ ONCE = 2, // Execute just one iteration
+ RUN = 3 // Continuous execution
+};
+
+
+struct ARMul_State final
+{
+public:
+ explicit ARMul_State(PrivilegeMode initial_mode);
+
+ void ChangePrivilegeMode(u32 new_mode);
+ void Reset();
+
+ // Reads/writes data in big/little endian format based on the
+ // state of the E (endian) bit in the APSR.
+ u16 ReadMemory16(u32 address) const;
+ u32 ReadMemory32(u32 address) const;
+ u64 ReadMemory64(u32 address) const;
+ void WriteMemory16(u32 address, u16 data);
+ void WriteMemory32(u32 address, u32 data);
+ void WriteMemory64(u32 address, u64 data);
+
+ u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const;
+ void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
+
+ // Exclusive memory access functions
+ bool IsExclusiveMemoryAccess(u32 address) const {
+ return exclusive_state && exclusive_tag == (address & RESERVATION_GRANULE_MASK);
+ }
+ void SetExclusiveMemoryAddress(u32 address) {
+ exclusive_tag = address & RESERVATION_GRANULE_MASK;
+ exclusive_state = true;
+ }
+ void UnsetExclusiveMemoryAddress() {
+ exclusive_tag = 0xFFFFFFFF;
+ exclusive_state = false;
+ }
+
+ // Whether or not the given CPU is in big endian mode (E bit is set)
+ bool InBigEndianMode() const {
+ return (Cpsr & (1 << 9)) != 0;
+ }
+ // Whether or not the given CPU is in a mode other than user mode.
+ bool InAPrivilegedMode() const {
+ return (Mode != USER32MODE);
+ }
+ // Note that for the 3DS, a Thumb instruction will only ever be
+ // two bytes in size. Thus we don't need to worry about ThumbEE
+ // or Thumb-2 where instructions can be 4 bytes in length.
+ u32 GetInstructionSize() const {
+ return TFlag ? 2 : 4;
+ }
+
+ std::array<u32, 16> Reg; // The current register file
+ std::array<u32, 2> Reg_usr;
+ std::array<u32, 2> Reg_svc; // R13_SVC R14_SVC
+ std::array<u32, 2> Reg_abort; // R13_ABORT R14_ABORT
+ std::array<u32, 2> Reg_undef; // R13 UNDEF R14 UNDEF
+ std::array<u32, 2> Reg_irq; // R13_IRQ R14_IRQ
+ std::array<u32, 7> Reg_firq; // R8---R14 FIRQ
+ std::array<u32, 7> Spsr; // The exception psr's
+ std::array<u32, CP15_REGISTER_COUNT> CP15;
+
+ // FPSID, FPSCR, and FPEXC
+ std::array<u32, VFP_SYSTEM_REGISTER_COUNT> VFP;
+
+ // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
+ // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
+ // and only 32 singleword registers are accessible (S0-S31).
+ std::array<u32, 64> ExtReg;
+
+ u32 Emulate; // To start and stop emulation
+ u32 Cpsr; // The current PSR
+ u32 Spsr_copy;
+ u32 phys_pc;
+
+ u32 Mode; // The current mode
+ u32 Bank; // The current register bank
+
+ u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
+ unsigned int shifter_carry_out;
+
+ u32 TFlag; // Thumb state
+
+ unsigned long long NumInstrs; // The number of instructions executed
+ unsigned NumInstrsToExecute;
+
+ unsigned NresetSig; // Reset the processor
+ unsigned NfiqSig;
+ unsigned NirqSig;
+
+ unsigned abortSig;
+ unsigned NtransSig;
+ unsigned bigendSig;
+ unsigned syscallSig;
+
+ // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per
+ // process for our purposes), not per ARMul_State (which tracks CPU core state).
+ std::unordered_map<u32, int> instruction_cache;
+
+private:
+ void ResetMPCoreCP15Registers();
+
+ // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
+ // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
+ // support LDR/STREXD.
+ static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
+
+ u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
+ u32 exclusive_result;
+ bool exclusive_state;
+};
diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp
new file mode 100644
index 00000000..d31fb944
--- /dev/null
+++ b/src/core/arm/skyeye_common/armsupp.cpp
@@ -0,0 +1,208 @@
+/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
+ Copyright (C) 1994 Advanced RISC Machines Ltd.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "common/logging/log.h"
+
+#include "core/mem_map.h"
+#include "core/arm/skyeye_common/arm_regformat.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/armsupp.h"
+
+// Unsigned sum of absolute difference
+u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
+{
+ if (left > right)
+ return left - right;
+
+ return right - left;
+}
+
+// Add with carry, indicates if a carry-out or signed overflow occurred.
+u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred)
+{
+ u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in;
+ s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in;
+ u64 result = (unsigned_sum & 0xFFFFFFFF);
+
+ if (carry_out_occurred)
+ *carry_out_occurred = (result != unsigned_sum);
+
+ if (overflow_occurred)
+ *overflow_occurred = ((s64)(s32)result != signed_sum);
+
+ return (u32)result;
+}
+
+// Compute whether an addition of A and B, giving RESULT, overflowed.
+bool AddOverflow(u32 a, u32 b, u32 result)
+{
+ return ((NEG(a) && NEG(b) && POS(result)) ||
+ (POS(a) && POS(b) && NEG(result)));
+}
+
+// Compute whether a subtraction of A and B, giving RESULT, overflowed.
+bool SubOverflow(u32 a, u32 b, u32 result)
+{
+ return ((NEG(a) && POS(b) && POS(result)) ||
+ (POS(a) && NEG(b) && NEG(result)));
+}
+
+// Returns true if the Q flag should be set as a result of overflow.
+bool ARMul_AddOverflowQ(u32 a, u32 b)
+{
+ u32 result = a + b;
+ if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
+ return true;
+
+ return false;
+}
+
+// 8-bit signed saturated addition
+u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
+{
+ u8 result = left + right;
+
+ if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
+ if (left & 0x80)
+ result = 0x80;
+ else
+ result = 0x7F;
+ }
+
+ return result;
+}
+
+// 8-bit signed saturated subtraction
+u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
+{
+ u8 result = left - right;
+
+ if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
+ if (left & 0x80)
+ result = 0x80;
+ else
+ result = 0x7F;
+ }
+
+ return result;
+}
+
+// 16-bit signed saturated addition
+u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
+{
+ u16 result = left + right;
+
+ if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
+ if (left & 0x8000)
+ result = 0x8000;
+ else
+ result = 0x7FFF;
+ }
+
+ return result;
+}
+
+// 16-bit signed saturated subtraction
+u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
+{
+ u16 result = left - right;
+
+ if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
+ if (left & 0x8000)
+ result = 0x8000;
+ else
+ result = 0x7FFF;
+ }
+
+ return result;
+}
+
+// 8-bit unsigned saturated addition
+u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
+{
+ u8 result = left + right;
+
+ if (result < left)
+ result = 0xFF;
+
+ return result;
+}
+
+// 16-bit unsigned saturated addition
+u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
+{
+ u16 result = left + right;
+
+ if (result < left)
+ result = 0xFFFF;
+
+ return result;
+}
+
+// 8-bit unsigned saturated subtraction
+u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
+{
+ if (left <= right)
+ return 0;
+
+ return left - right;
+}
+
+// 16-bit unsigned saturated subtraction
+u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
+{
+ if (left <= right)
+ return 0;
+
+ return left - right;
+}
+
+// Signed saturation.
+u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
+{
+ const u32 max = (1 << shift) - 1;
+ const s32 top = (value >> shift);
+
+ if (top > 0) {
+ *saturation_occurred = true;
+ return max;
+ }
+ else if (top < -1) {
+ *saturation_occurred = true;
+ return ~max;
+ }
+
+ *saturation_occurred = false;
+ return (u32)value;
+}
+
+// Unsigned saturation
+u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
+{
+ const u32 max = (1 << shift) - 1;
+
+ if (value < 0) {
+ *saturation_occurred = true;
+ return 0;
+ } else if ((u32)value > max) {
+ *saturation_occurred = true;
+ return max;
+ }
+
+ *saturation_occurred = false;
+ return (u32)value;
+}
diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h
new file mode 100644
index 00000000..391309fa
--- /dev/null
+++ b/src/core/arm/skyeye_common/armsupp.h
@@ -0,0 +1,32 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/common_types.h"
+
+#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
+#define BIT(s, n) ((s >> (n)) & 1)
+
+#define POS(i) ( (~(i)) >> 31 )
+#define NEG(i) ( (i) >> 31 )
+
+bool AddOverflow(u32, u32, u32);
+bool SubOverflow(u32, u32, u32);
+
+u32 AddWithCarry(u32, u32, u32, bool*, bool*);
+bool ARMul_AddOverflowQ(u32, u32);
+
+u8 ARMul_SignedSaturatedAdd8(u8, u8);
+u8 ARMul_SignedSaturatedSub8(u8, u8);
+u16 ARMul_SignedSaturatedAdd16(u16, u16);
+u16 ARMul_SignedSaturatedSub16(u16, u16);
+
+u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
+u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
+u8 ARMul_UnsignedSaturatedSub8(u8, u8);
+u16 ARMul_UnsignedSaturatedSub16(u16, u16);
+u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
+u32 ARMul_SignedSatQ(s32, u8, bool*);
+u32 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 1ffc1f9a..26f303de 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -23,7 +23,7 @@
#include "common/common_funcs.h"
#include "common/logging/log.h"
-#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armstate.h"
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
@@ -43,7 +43,7 @@ void VFPInit(ARMul_State* state)
state->VFP[VFP_MVFR1] = 0;
}
-void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
+void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value)
{
if (to_arm)
{
@@ -55,7 +55,7 @@ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword*
}
}
-void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
+void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2)
{
if (to_arm)
{
@@ -68,7 +68,7 @@ void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword
state->ExtReg[n*2] = *value1;
}
}
-void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
+void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2)
{
if (to_arm)
{
@@ -82,7 +82,7 @@ void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMwor
}
}
-void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
+void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm)
{
if (single)
{
@@ -95,7 +95,7 @@ void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
state->ExtReg[d*2] = 0;
}
}
-void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m)
+void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m)
{
if (single)
{
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index 80ca93cc..88908da9 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
u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
-void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value);
-void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
-void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2);
-void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
-void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm);
+void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value);
+void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2);
+void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2);
+void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm);
+void 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 2007d6dc..91a8d4d5 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 @@
#include <cstdio>
#include "common/common_types.h"
-#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armstate.h"
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
#define do_div(n, base) {n/=base;}
@@ -415,7 +415,7 @@ struct op {
u32 flags;
};
-static inline u32 fls(ARMword x)
+static inline u32 fls(u32 x)
{
int r = 32;
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
index f9104958..1d844a66 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)
static void vfp_double_normalise_denormal(struct vfp_double *vd)
{
- int bits = 31 - fls((ARMword)(vd->significand >> 32));
+ int bits = 31 - fls((u32)(vd->significand >> 32));
if (bits == 31)
- bits = 63 - fls((ARMword)vd->significand);
+ bits = 63 - fls((u32)vd->significand);
vfp_double_dump("normalise_denormal: in", vd);
@@ -109,9 +109,9 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd,
exponent = vd->exponent;
significand = vd->significand;
- shift = 32 - fls((ARMword)(significand >> 32));
+ shift = 32 - fls((u32)(significand >> 32));
if (shift == 32)
- shift = 64 - fls((ARMword)significand);
+ shift = 64 - fls((u32)significand);
if (shift) {
exponent -= shift;
significand <<= shift;
@@ -566,7 +566,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32
/*
* 2^0 <= m < 2^32-2^8
*/
- d = (ARMword)((vdm.significand << 1) >> shift);
+ d = (u32)((vdm.significand << 1) >> shift);
rem = vdm.significand << (65 - shift);
if (rmode == FPSCR_ROUND_NEAREST) {
@@ -647,7 +647,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32
int shift = 1023 + 63 - vdm.exponent; /* 58 */
u64 rem, incr = 0;
- d = (ARMword)((vdm.significand << 1) >> shift);
+ d = (u32)((vdm.significand << 1) >> shift);
rem = vdm.significand << (65 - shift);
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 8efcbab1..9b99fc5b 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -51,7 +51,7 @@ VMLA_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmla_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -100,7 +100,7 @@ VMLS_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmls_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -149,7 +149,7 @@ VNMLA_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vnmla_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -199,7 +199,7 @@ VNMLS_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vnmls_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -248,7 +248,7 @@ VNMUL_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vnmul_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -297,7 +297,7 @@ VMUL_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmul_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -346,7 +346,7 @@ VADD_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vadd_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -395,7 +395,7 @@ VSUB_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vsub_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -444,7 +444,7 @@ VDIV_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vdiv_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -492,7 +492,7 @@ VMOVI_INST:
VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovi_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -536,7 +536,7 @@ VMOVR_INST:
VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -585,7 +585,7 @@ VABS_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vabs_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -635,7 +635,7 @@ VNEG_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vneg_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -684,7 +684,7 @@ VSQRT_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vsqrt_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -733,7 +733,7 @@ VCMP_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vcmp_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -782,7 +782,7 @@ VCMP2_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vcmp2_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -831,7 +831,7 @@ VCVTBDS_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vcvtbds_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -882,7 +882,7 @@ VCVTBFF_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vcvtbff_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -931,7 +931,7 @@ VCVTBFI_INST:
CHECK_VFP_CDP_RET;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vcvtbfi_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -981,7 +981,7 @@ VMOVBRS_INST:
VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovbrs_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1032,7 +1032,7 @@ VMSR_INST:
{
cpu->VFP[VFP_FPSCR] = cpu->Reg[rt];
}
- else if (InAPrivilegedMode(cpu))
+ else if (cpu->InAPrivilegedMode())
{
if (reg == 8)
cpu->VFP[VFP_FPEXC] = cpu->Reg[rt];
@@ -1042,7 +1042,7 @@ VMSR_INST:
cpu->VFP[VFP_FPINST2] = cpu->Reg[rt];
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmsr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1090,7 +1090,7 @@ VMOVBRC_INST:
cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t];
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovbrc_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1163,7 +1163,7 @@ VMRS_INST:
{
cpu->Reg[rt] = cpu->VFP[VFP_MVFR0];
}
- else if (InAPrivilegedMode(cpu))
+ else if (cpu->InAPrivilegedMode())
{
if (reg == 8)
cpu->Reg[rt] = cpu->VFP[VFP_FPEXC];
@@ -1173,7 +1173,7 @@ VMRS_INST:
cpu->Reg[rt] = cpu->VFP[VFP_FPINST2];
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmrs_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1221,7 +1221,7 @@ VMOVBCR_INST:
cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index];
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovbcr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1274,7 +1274,7 @@ VMOVBRRSS_INST:
VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
&cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]);
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovbrrss_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1322,7 +1322,7 @@ VMOVBRRD_INST:
VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
&(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vmovbrrd_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1378,23 +1378,23 @@ VSTR_INST:
if (inst_cream->single)
{
- WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d]);
+ cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]);
}
else
{
const u32 word1 = cpu->ExtReg[inst_cream->d*2+0];
const u32 word2 = cpu->ExtReg[inst_cream->d*2+1];
- if (InBigEndianMode(cpu)) {
- WriteMemory32(cpu, addr + 0, word2);
- WriteMemory32(cpu, addr + 4, word1);
+ if (cpu->InBigEndianMode()) {
+ cpu->WriteMemory32(addr + 0, word2);
+ cpu->WriteMemory32(addr + 4, word1);
} else {
- WriteMemory32(cpu, addr + 0, word1);
- WriteMemory32(cpu, addr + 4, word2);
+ cpu->WriteMemory32(addr + 0, word1);
+ cpu->WriteMemory32(addr + 4, word2);
}
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vstr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1444,7 +1444,7 @@ VPUSH_INST:
{
if (inst_cream->single)
{
- WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
+ cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
addr += 4;
}
else
@@ -1452,12 +1452,12 @@ VPUSH_INST:
const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
- if (InBigEndianMode(cpu)) {
- WriteMemory32(cpu, addr + 0, word2);
- WriteMemory32(cpu, addr + 4, word1);
+ if (cpu->InBigEndianMode()) {
+ cpu->WriteMemory32(addr + 0, word2);
+ cpu->WriteMemory32(addr + 4, word1);
} else {
- WriteMemory32(cpu, addr + 0, word1);
- WriteMemory32(cpu, addr + 4, word2);
+ cpu->WriteMemory32(addr + 0, word1);
+ cpu->WriteMemory32(addr + 4, word2);
}
addr += 8;
@@ -1466,7 +1466,7 @@ VPUSH_INST:
cpu->Reg[R13] -= inst_cream->imm32;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vpush_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1522,7 +1522,7 @@ VSTM_INST: /* encoding 1 */
{
if (inst_cream->single)
{
- WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
+ cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
addr += 4;
}
else
@@ -1530,12 +1530,12 @@ VSTM_INST: /* encoding 1 */
const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
- if (InBigEndianMode(cpu)) {
- WriteMemory32(cpu, addr + 0, word2);
- WriteMemory32(cpu, addr + 4, word1);
+ if (cpu->InBigEndianMode()) {
+ cpu->WriteMemory32(addr + 0, word2);
+ cpu->WriteMemory32(addr + 4, word1);
} else {
- WriteMemory32(cpu, addr + 0, word1);
- WriteMemory32(cpu, addr + 4, word2);
+ cpu->WriteMemory32(addr + 0, word1);
+ cpu->WriteMemory32(addr + 4, word2);
}
addr += 8;
@@ -1597,15 +1597,15 @@ VPOP_INST:
{
if (inst_cream->single)
{
- cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
+ cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
addr += 4;
}
else
{
- const u32 word1 = ReadMemory32(cpu, addr + 0);
- const u32 word2 = ReadMemory32(cpu, addr + 4);
+ const u32 word1 = cpu->ReadMemory32(addr + 0);
+ const u32 word2 = cpu->ReadMemory32(addr + 4);
- if (InBigEndianMode(cpu)) {
+ if (cpu->InBigEndianMode()) {
cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
} else {
@@ -1618,7 +1618,7 @@ VPOP_INST:
}
cpu->Reg[R13] += inst_cream->imm32;
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vpop_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1670,14 +1670,14 @@ VLDR_INST:
if (inst_cream->single)
{
- cpu->ExtReg[inst_cream->d] = ReadMemory32(cpu, addr);
+ cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr);
}
else
{
- const u32 word1 = ReadMemory32(cpu, addr + 0);
- const u32 word2 = ReadMemory32(cpu, addr + 4);
+ const u32 word1 = cpu->ReadMemory32(addr + 0);
+ const u32 word2 = cpu->ReadMemory32(addr + 4);
- if (InBigEndianMode(cpu)) {
+ if (cpu->InBigEndianMode()) {
cpu->ExtReg[inst_cream->d*2+0] = word2;
cpu->ExtReg[inst_cream->d*2+1] = word1;
} else {
@@ -1686,7 +1686,7 @@ VLDR_INST:
}
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vldr_inst));
FETCH_INST;
GOTO_NEXT_INST;
@@ -1742,15 +1742,15 @@ VLDM_INST:
{
if (inst_cream->single)
{
- cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
+ cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
addr += 4;
}
else
{
- const u32 word1 = ReadMemory32(cpu, addr + 0);
- const u32 word2 = ReadMemory32(cpu, addr + 4);
+ const u32 word1 = cpu->ReadMemory32(addr + 0);
+ const u32 word2 = cpu->ReadMemory32(addr + 4);
- if (InBigEndianMode(cpu)) {
+ if (cpu->InBigEndianMode()) {
cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
} else {
@@ -1766,7 +1766,7 @@ VLDM_INST:
cpu->Reg[inst_cream->n] - inst_cream->imm32);
}
}
- cpu->Reg[15] += GET_INST_SIZE(cpu);
+ cpu->Reg[15] += cpu->GetInstructionSize();
INC_PC(sizeof(vldm_inst));
FETCH_INST;
GOTO_NEXT_INST;
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 72006a53..20f2da0f 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -502,7 +502,7 @@ void Advance() {
Core::g_app_core->down_count += diff;
}
if (advance_callback)
- advance_callback(cycles_executed);
+ advance_callback(static_cast<int>(cycles_executed));
}
void LogPendingEvents() {
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 9294789e..1a051892 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -133,7 +133,7 @@ template<ResultCode func(u32)> void Wrap() {
FuncReturn(func(PARAM(0)).raw);
}
-template<ResultCode func(s64*, u32, u32*, s32)> void Wrap(){
+template<ResultCode func(s64*, u32, u32*, u32)> void Wrap(){
FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)),
(s32)PARAM(3)).raw);
}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 8b49fc7d..29ea6d53 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,7 +13,7 @@
#include "common/thread_queue_list.h"
#include "core/arm/arm_interface.h"
-#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armstate.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/hle.h"
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 8b40ba37..e93c1b43 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -14,6 +14,7 @@
#include "core/hw/lcd.h"
#include "video_core/gpu_debugger.h"
+#include "video_core/debug_utils/debug_utils.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
@@ -226,6 +227,9 @@ void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
&info.format);
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 4,
&info.shown_fb);
+
+ if (Pica::g_debug_context)
+ Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr);
}
/**
@@ -391,19 +395,24 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
case CommandId::SET_MEMORY_FILL:
{
auto& params = command.memory_fill;
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)),
- Memory::VirtualToPhysicalAddress(params.start1) >> 3);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)),
- Memory::VirtualToPhysicalAddress(params.end1) >> 3);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1);
-
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)),
- Memory::VirtualToPhysicalAddress(params.start2) >> 3);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)),
- Memory::VirtualToPhysicalAddress(params.end2) >> 3);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2);
- WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2);
+
+ if (params.start1 != 0) {
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)),
+ Memory::VirtualToPhysicalAddress(params.start1) >> 3);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)),
+ Memory::VirtualToPhysicalAddress(params.end1) >> 3);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1);
+ }
+
+ if (params.start2 != 0) {
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)),
+ Memory::VirtualToPhysicalAddress(params.start2) >> 3);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)),
+ Memory::VirtualToPhysicalAddress(params.end2) >> 3);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2);
+ WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2);
+ }
break;
}
@@ -448,6 +457,9 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
default:
LOG_ERROR(Service_GSP, "unknown command 0x%08X", (int)command.id.Value());
}
+
+ if (Pica::g_debug_context)
+ Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, (void*)&command);
}
/**
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 70caa7d8..c35b13b2 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -35,6 +35,16 @@ static Kernel::SharedPtr<Kernel::Event> event_debug_pad;
static u32 next_pad_index;
static u32 next_touch_index;
+const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {
+ Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
+ Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
+ Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE,
+ Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
+ Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT,
+ Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT
+};
+
+
// TODO(peachum):
// Add a method for setting analog input from joystick device for the circle Pad.
//
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index d50d479f..517f4f2a 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -9,7 +9,7 @@
#ifndef _MSC_VER
#include <cstddef>
#endif
-
+#include "core/settings.h"
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
@@ -157,6 +157,9 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
const PadState PAD_CIRCLE_UP = {{1u << 30}};
const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
+
+extern const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping;
+
/**
* HID::GetIPCHandles service function
* Inputs:
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index d0e166fd..d768a3fc 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -481,11 +481,17 @@ static void GetHostId(Service::Interface* self) {
char name[128];
gethostname(name, sizeof(name));
- hostent* host = gethostbyname(name);
- in_addr* addr = reinterpret_cast<in_addr*>(host->h_addr);
+ addrinfo hints = {};
+ addrinfo* res;
+
+ hints.ai_family = AF_INET;
+ getaddrinfo(name, NULL, &hints, &res);
+ sockaddr_in* sock_addr = reinterpret_cast<sockaddr_in*>(res->ai_addr);
+ in_addr* addr = &sock_addr->sin_addr;
cmd_buffer[2] = addr->s_addr;
cmd_buffer[1] = 0;
+ freeaddrinfo(res);
}
static void Close(Service::Interface* self) {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index bdede964..bb64fdfb 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -334,7 +334,7 @@ static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle
/// Get resource limit current values
static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names,
- s32 name_count) {
+ u32 name_count) {
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
resource_limit_handle, names, name_count);
@@ -350,7 +350,7 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_lim
/// Get resource limit max values
static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names,
- s32 name_count) {
+ u32 name_count) {
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
resource_limit_handle, names, name_count);
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 2a338e8f..3ccbc03b 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -151,6 +151,10 @@ inline void Write(u32 addr, const T data) {
{
const auto& config = g_regs.display_transfer_config;
if (config.trigger & 1) {
+
+ if (Pica::g_debug_context)
+ Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, nullptr);
+
u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress());
u8* dst_pointer = Memory::GetPhysicalPointer(config.GetPhysicalOutputAddress());
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index d043fa9b..530837d0 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -191,7 +191,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
*pos = (addr);
break;
case 1:
- *pos = (addr - in_addr);
+ *pos = static_cast<u32>(addr - in_addr);
break;
default:
break; //this should never happen
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 9ef2f890..f5b349a7 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -56,18 +56,18 @@ static FileType IdentifyFile(FileUtil::IOFile& file) {
static FileType GuessFromExtension(const std::string& extension_) {
std::string extension = Common::ToLower(extension_);
- if (extension == ".elf")
+ if (extension == ".elf" || extension == ".axf")
return FileType::ELF;
- else if (extension == ".axf")
- return FileType::ELF;
- else if (extension == ".cxi")
- return FileType::CXI;
- else if (extension == ".cci")
- return FileType::CCI;
- else if (extension == ".3ds")
+
+ if (extension == ".cci" || extension == ".3ds")
return FileType::CCI;
- else if (extension == ".3dsx")
+
+ if (extension == ".cxi")
+ return FileType::CXI;
+
+ if (extension == ".3dsx")
return FileType::THREEDSX;
+
return FileType::Unknown;
}
diff --git a/src/core/settings.h b/src/core/settings.h
index 5a70d157..2775ee25 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -5,34 +5,42 @@
#pragma once
#include <string>
+#include <array>
namespace Settings {
+namespace NativeInput {
+enum Values {
+ A, B, X, Y,
+ L, R, ZL, ZR,
+ START, SELECT, HOME,
+ DUP, DDOWN, DLEFT, DRIGHT,
+ SUP, SDOWN, SLEFT, SRIGHT,
+ CUP, CDOWN, CLEFT, CRIGHT,
+ NUM_INPUTS
+};
+static const std::array<const char*, NUM_INPUTS> Mapping = {
+ "pad_a", "pad_b", "pad_x", "pad_y",
+ "pad_l", "pad_r", "pad_zl", "pad_zr",
+ "pad_start", "pad_select", "pad_home",
+ "pad_dup", "pad_ddown", "pad_dleft", "pad_dright",
+ "pad_sup", "pad_sdown", "pad_sleft", "pad_sright",
+ "pad_cup", "pad_cdown", "pad_cleft", "pad_cright"
+};
+static const std::array<Values, NUM_INPUTS> All = {
+ A, B, X, Y,
+ L, R, ZL, ZR,
+ START, SELECT, HOME,
+ DUP, DDOWN, DLEFT, DRIGHT,
+ SUP, SDOWN, SLEFT, SRIGHT,
+ CUP, CDOWN, CLEFT, CRIGHT
+};
+}
+
+
struct Values {
// Controls
- int pad_a_key;
- int pad_b_key;
- int pad_x_key;
- int pad_y_key;
- int pad_l_key;
- int pad_r_key;
- int pad_zl_key;
- int pad_zr_key;
- int pad_start_key;
- int pad_select_key;
- int pad_home_key;
- int pad_dup_key;
- int pad_ddown_key;
- int pad_dleft_key;
- int pad_dright_key;
- int pad_sup_key;
- int pad_sdown_key;
- int pad_sleft_key;
- int pad_sright_key;
- int pad_cup_key;
- int pad_cdown_key;
- int pad_cleft_key;
- int pad_cright_key;
+ std::array<int, NativeInput::NUM_INPUTS> input_mappings;
// Core
int frame_skip;
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 5c7f4ae1..16210830 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -2,7 +2,6 @@ set(SRCS
renderer_opengl/generated/gl_3_2_core.c
renderer_opengl/gl_rasterizer.cpp
renderer_opengl/gl_rasterizer_cache.cpp
- renderer_opengl/gl_resource_manager.cpp
renderer_opengl/gl_shader_util.cpp
renderer_opengl/gl_state.cpp
renderer_opengl/renderer_opengl.cpp
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 8b10d734..ef9584ab 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -50,7 +50,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
regs[id] = (old_value & ~mask) | (value & mask);
if (g_debug_context)
- g_debug_context->OnEvent(DebugContext::Event::CommandLoaded, reinterpret_cast<void*>(&id));
+ g_debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded, reinterpret_cast<void*>(&id));
DebugUtils::OnPicaRegWrite(id, regs[id]);
@@ -103,7 +103,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c):
case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d):
{
- unsigned index = id - PICA_REG_INDEX(command_buffer.trigger[0]);
+ unsigned index = static_cast<unsigned>(id - PICA_REG_INDEX(command_buffer.trigger[0]));
u32* head_ptr = (u32*)Memory::GetPhysicalPointer(regs.command_buffer.GetPhysicalAddress(index));
g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr;
g_state.cmd_list.length = regs.command_buffer.GetSize(index) / sizeof(u32);
@@ -116,7 +116,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
{
Common::Profiling::ScopeTimer scope_timer(category_drawing);
+#if PICA_LOG_TEV
DebugUtils::DumpTevStageConfig(regs.GetTevStages());
+#endif
if (g_debug_context)
g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
@@ -159,9 +161,11 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
const u16* index_address_16 = (u16*)index_address_8;
bool index_u16 = index_info.format != 0;
+#if PICA_DUMP_GEOMETRY
DebugUtils::GeometryDumper geometry_dumper;
- PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value());
+#endif
+ PrimitiveAssembler<VertexShader::OutputVertex> primitive_assembler(regs.triangle_topology.Value());
if (g_debug_context) {
for (int i = 0; i < 3; ++i) {
@@ -271,6 +275,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
if (g_debug_context)
g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input);
+#if PICA_DUMP_GEOMETRY
// NOTE: When dumping geometry, we simply assume that the first input attribute
// corresponds to the position for now.
DebugUtils::GeometryDumper::Vertex dumped_vertex = {
@@ -280,6 +285,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
dumping_primitive_assembler.SubmitVertex(dumped_vertex,
std::bind(&DebugUtils::GeometryDumper::AddTriangle,
&geometry_dumper, _1, _2, _3));
+#endif
// Send to vertex shader
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) {
VideoCore::g_renderer->hw_rasterizer->DrawTriangles();
}
+#if PICA_DUMP_GEOMETRY
geometry_dumper.Dump();
+#endif
if (g_debug_context) {
g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
@@ -428,7 +436,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
VideoCore::g_renderer->hw_rasterizer->NotifyPicaRegisterChanged(id);
if (g_debug_context)
- g_debug_context->OnEvent(DebugContext::Event::CommandProcessed, reinterpret_cast<void*>(&id));
+ g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id));
}
void ProcessCommandList(const u32* list, u32 size) {
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index d24c0f11..e9a85841 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -85,15 +85,11 @@ void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) {
vertices.push_back(v1);
vertices.push_back(v2);
- int num_vertices = vertices.size();
+ int num_vertices = (int)vertices.size();
faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 });
}
void GeometryDumper::Dump() {
- // NOTE: Permanently enabling this just trashes the hard disk for no reason.
- // Hence, this is currently disabled.
- return;
-
static int index = 0;
std::string filename = std::string("geometry_dump") + std::to_string(++index) + ".obj";
@@ -116,10 +112,6 @@ void GeometryDumper::Dump() {
void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size,
u32 main_offset, const Regs::VSOutputAttributes* output_attributes)
{
- // NOTE: Permanently enabling this just trashes hard disks for no reason.
- // Hence, this is currently disabled.
- return;
-
struct StuffToWrite {
u8* pointer;
u32 size;
@@ -241,8 +233,8 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data
dvle.main_offset_words = main_offset;
dvle.output_register_table_offset = write_offset - dvlb.dvle_offset;
- dvle.output_register_table_size = output_info_table.size();
- QueueForWriting((u8*)output_info_table.data(), output_info_table.size() * sizeof(OutputRegisterInfo));
+ dvle.output_register_table_size = static_cast<uint32_t>(output_info_table.size());
+ QueueForWriting((u8*)output_info_table.data(), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo)));
// TODO: Create a label table for "main"
@@ -497,31 +489,31 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
// Lookup base value
Math::Vec3<int> ret;
if (differential_mode) {
- ret.r() = differential.r;
- ret.g() = differential.g;
- ret.b() = differential.b;
+ ret.r() = static_cast<int>(differential.r);
+ ret.g() = static_cast<int>(differential.g);
+ ret.b() = static_cast<int>(differential.b);
if (x >= 2) {
- ret.r() += differential.dr;
- ret.g() += differential.dg;
- ret.b() += differential.db;
+ ret.r() += static_cast<int>(differential.dr);
+ ret.g() += static_cast<int>(differential.dg);
+ ret.b() += static_cast<int>(differential.db);
}
ret.r() = Color::Convert5To8(ret.r());
ret.g() = Color::Convert5To8(ret.g());
ret.b() = Color::Convert5To8(ret.b());
} else {
if (x < 2) {
- ret.r() = Color::Convert4To8(separate.r1);
- ret.g() = Color::Convert4To8(separate.g1);
- ret.b() = Color::Convert4To8(separate.b1);
+ ret.r() = Color::Convert4To8(static_cast<u8>(separate.r1));
+ ret.g() = Color::Convert4To8(static_cast<u8>(separate.g1));
+ ret.b() = Color::Convert4To8(static_cast<u8>(separate.b1));
} else {
- ret.r() = Color::Convert4To8(separate.r2);
- ret.g() = Color::Convert4To8(separate.g2);
- ret.b() = Color::Convert4To8(separate.b2);
+ ret.r() = Color::Convert4To8(static_cast<u8>(separate.r2));
+ ret.g() = Color::Convert4To8(static_cast<u8>(separate.g2));
+ ret.b() = Color::Convert4To8(static_cast<u8>(separate.b2));
}
}
// Add modifier
- unsigned table_index = (x < 2) ? table_index_1.Value() : table_index_2.Value();
+ unsigned table_index = static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value());
static const std::array<std::array<u8, 2>, 8> etc1_modifier_table = {{
{ 2, 8 }, { 5, 17 }, { 9, 29 }, { 13, 42 },
@@ -565,10 +557,6 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config,
}
void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
- // NOTE: Permanently enabling this just trashes hard disks for no reason.
- // Hence, this is currently disabled.
- return;
-
#ifndef HAVE_PNG
return;
#else
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index 2573292e..81eea30a 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -25,11 +25,14 @@ public:
enum class Event {
FirstEvent = 0,
- CommandLoaded = FirstEvent,
- CommandProcessed,
+ PicaCommandLoaded = FirstEvent,
+ PicaCommandProcessed,
IncomingPrimitiveBatch,
FinishedPrimitiveBatch,
VertexLoaded,
+ IncomingDisplayTransfer,
+ GSPCommandProcessed,
+ BufferSwapped,
NumEvents
};
@@ -154,6 +157,11 @@ extern std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this g
namespace DebugUtils {
+#define PICA_DUMP_GEOMETRY 0
+#define PICA_DUMP_SHADERS 0
+#define PICA_DUMP_TEXTURES 0
+#define PICA_LOG_TEV 0
+
// Simple utility class for dumping geometry data to an OBJ file
class GeometryDumper {
public:
diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp
index 543d9c44..17cb6678 100644
--- a/src/video_core/pica.cpp
+++ b/src/video_core/pica.cpp
@@ -2,7 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <string.h>
+#include <cstring>
+#include <unordered_map>
#include "pica.h"
@@ -10,6 +11,75 @@ namespace Pica {
State g_state;
+std::string Regs::GetCommandName(int index) {
+ static std::unordered_map<u32, std::string> map;
+
+ if (map.empty()) {
+ #define ADD_FIELD(name) \
+ map.insert({static_cast<u32>(PICA_REG_INDEX(name)), #name}); \
+ /* TODO: change to Regs::name when VS2015 and other compilers support it */ \
+ for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(Regs().name) / 4; ++i) \
+ map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \
+
+ ADD_FIELD(trigger_irq);
+ ADD_FIELD(cull_mode);
+ ADD_FIELD(viewport_size_x);
+ ADD_FIELD(viewport_size_y);
+ ADD_FIELD(viewport_depth_range);
+ ADD_FIELD(viewport_depth_far_plane);
+ ADD_FIELD(viewport_corner);
+ ADD_FIELD(texture0_enable);
+ ADD_FIELD(texture0);
+ ADD_FIELD(texture0_format);
+ ADD_FIELD(texture1);
+ ADD_FIELD(texture1_format);
+ ADD_FIELD(texture2);
+ ADD_FIELD(texture2_format);
+ ADD_FIELD(tev_stage0);
+ ADD_FIELD(tev_stage1);
+ ADD_FIELD(tev_stage2);
+ ADD_FIELD(tev_stage3);
+ ADD_FIELD(tev_combiner_buffer_input);
+ ADD_FIELD(tev_stage4);
+ ADD_FIELD(tev_stage5);
+ ADD_FIELD(tev_combiner_buffer_color);
+ ADD_FIELD(output_merger);
+ ADD_FIELD(framebuffer);
+ ADD_FIELD(vertex_attributes);
+ ADD_FIELD(index_array);
+ ADD_FIELD(num_vertices);
+ ADD_FIELD(trigger_draw);
+ ADD_FIELD(trigger_draw_indexed);
+ ADD_FIELD(vs_default_attributes_setup);
+ ADD_FIELD(command_buffer);
+ ADD_FIELD(triangle_topology);
+ ADD_FIELD(gs.bool_uniforms);
+ ADD_FIELD(gs.int_uniforms);
+ ADD_FIELD(gs.main_offset);
+ ADD_FIELD(gs.input_register_map);
+ ADD_FIELD(gs.uniform_setup);
+ ADD_FIELD(gs.program);
+ ADD_FIELD(gs.swizzle_patterns);
+ ADD_FIELD(vs.bool_uniforms);
+ ADD_FIELD(vs.int_uniforms);
+ ADD_FIELD(vs.main_offset);
+ ADD_FIELD(vs.input_register_map);
+ ADD_FIELD(vs.uniform_setup);
+ ADD_FIELD(vs.program);
+ ADD_FIELD(vs.swizzle_patterns);
+
+#undef ADD_FIELD
+ }
+
+ // Return empty string if no match is found
+ auto it = map.find(index);
+ if (it != map.end()) {
+ return it->second;
+ } else {
+ return std::string();
+ }
+}
+
void Init() {
}
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index aec6f066..34b02b2f 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -7,7 +7,6 @@
#include <array>
#include <cmath>
#include <cstddef>
-#include <map>
#include <string>
#include "common/assert.h"
@@ -908,69 +907,7 @@ struct Regs {
// Map register indices to names readable by humans
// Used for debugging purposes, so performance is not an issue here
- static std::string GetCommandName(int index) {
- std::map<u32, std::string> map;
-
- #define ADD_FIELD(name) \
- do { \
- map.insert({PICA_REG_INDEX(name), #name}); \
- /* TODO: change to Regs::name when VS2015 and other compilers support it */ \
- for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(Regs().name) / 4; ++i) \
- map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \
- } while(false)
-
- ADD_FIELD(trigger_irq);
- ADD_FIELD(cull_mode);
- ADD_FIELD(viewport_size_x);
- ADD_FIELD(viewport_size_y);
- ADD_FIELD(viewport_depth_range);
- ADD_FIELD(viewport_depth_far_plane);
- ADD_FIELD(viewport_corner);
- ADD_FIELD(texture0_enable);
- ADD_FIELD(texture0);
- ADD_FIELD(texture0_format);
- ADD_FIELD(texture1);
- ADD_FIELD(texture1_format);
- ADD_FIELD(texture2);
- ADD_FIELD(texture2_format);
- ADD_FIELD(tev_stage0);
- ADD_FIELD(tev_stage1);
- ADD_FIELD(tev_stage2);
- ADD_FIELD(tev_stage3);
- ADD_FIELD(tev_combiner_buffer_input);
- ADD_FIELD(tev_stage4);
- ADD_FIELD(tev_stage5);
- ADD_FIELD(tev_combiner_buffer_color);
- ADD_FIELD(output_merger);
- ADD_FIELD(framebuffer);
- ADD_FIELD(vertex_attributes);
- ADD_FIELD(index_array);
- ADD_FIELD(num_vertices);
- ADD_FIELD(trigger_draw);
- ADD_FIELD(trigger_draw_indexed);
- ADD_FIELD(vs_default_attributes_setup);
- ADD_FIELD(command_buffer);
- ADD_FIELD(triangle_topology);
- ADD_FIELD(gs.bool_uniforms);
- ADD_FIELD(gs.int_uniforms);
- ADD_FIELD(gs.main_offset);
- ADD_FIELD(gs.input_register_map);
- ADD_FIELD(gs.uniform_setup);
- ADD_FIELD(gs.program);
- ADD_FIELD(gs.swizzle_patterns);
- ADD_FIELD(vs.bool_uniforms);
- ADD_FIELD(vs.int_uniforms);
- ADD_FIELD(vs.main_offset);
- ADD_FIELD(vs.input_register_map);
- ADD_FIELD(vs.uniform_setup);
- ADD_FIELD(vs.program);
- ADD_FIELD(vs.swizzle_patterns);
-
- #undef ADD_FIELD
-
- // Return empty string if no match is found
- return map[index];
- }
+ static std::string GetCommandName(int index);
static inline size_t NumIds() {
return sizeof(Regs) / sizeof(u32);
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index e2b90ad1..68b7cc05 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -462,7 +462,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
// TODO: Apply the min and mag filters to the texture
texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info);
+#if PICA_DUMP_TEXTURES
DebugUtils::DumpTexture(texture.config, texture_data);
+#endif
}
}
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 8f4ae28a..00000000
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "video_core/renderer_opengl/gl_resource_manager.h"
-#include "video_core/renderer_opengl/gl_shader_util.h"
-
-// Textures
-OGLTexture::OGLTexture() : handle(0) {
-}
-
-OGLTexture::~OGLTexture() {
- Release();
-}
-
-void OGLTexture::Create() {
- if (handle != 0) {
- return;
- }
-
- glGenTextures(1, &handle);
-}
-
-void OGLTexture::Release() {
- glDeleteTextures(1, &handle);
- handle = 0;
-}
-
-// Shaders
-OGLShader::OGLShader() : handle(0) {
-}
-
-OGLShader::~OGLShader() {
- Release();
-}
-
-void OGLShader::Create(const char* vert_shader, const char* frag_shader) {
- if (handle != 0) {
- return;
- }
-
- handle = ShaderUtil::LoadShaders(vert_shader, frag_shader);
-}
-
-void OGLShader::Release() {
- glDeleteProgram(handle);
- handle = 0;
-}
-
-// Buffer objects
-OGLBuffer::OGLBuffer() : handle(0) {
-}
-
-OGLBuffer::~OGLBuffer() {
- Release();
-}
-
-void OGLBuffer::Create() {
- if (handle != 0) {
- return;
- }
-
- glGenBuffers(1, &handle);
-}
-
-void OGLBuffer::Release() {
- glDeleteBuffers(1, &handle);
- handle = 0;
-}
-
-// Vertex array objects
-OGLVertexArray::OGLVertexArray() : handle(0) {
-}
-
-OGLVertexArray::~OGLVertexArray() {
- Release();
-}
-
-void OGLVertexArray::Create() {
- if (handle != 0) {
- return;
- }
-
- glGenVertexArrays(1, &handle);
-}
-
-void OGLVertexArray::Release() {
- glDeleteVertexArrays(1, &handle);
- handle = 0;
-}
-
-// Framebuffers
-OGLFramebuffer::OGLFramebuffer() : handle(0) {
-}
-
-OGLFramebuffer::~OGLFramebuffer() {
- Release();
-}
-
-void OGLFramebuffer::Create() {
- if (handle != 0) {
- return;
- }
-
- glGenFramebuffers(1, &handle);
-}
-
-void OGLFramebuffer::Release() {
- glDeleteFramebuffers(1, &handle);
- handle = 0;
-}
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 975720d0..6f9dc012 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 @@
#pragma once
+#include <utility>
+
#include "common/common_types.h"
-#include "generated/gl_3_2_core.h"
+#include "video_core/renderer_opengl/generated/gl_3_2_core.h"
+#include "video_core/renderer_opengl/gl_shader_util.h"
-class OGLTexture : public NonCopyable {
+class OGLTexture : private NonCopyable {
public:
- OGLTexture();
- ~OGLTexture();
+ OGLTexture() = default;
+ OGLTexture(OGLTexture&& o) { std::swap(handle, o.handle); }
+ ~OGLTexture() { Release(); }
+ OGLTexture& operator=(OGLTexture&& o) { std::swap(handle, o.handle); return *this; }
/// Creates a new internal OpenGL resource and stores the handle
- void Create();
+ void Create() {
+ if (handle != 0) return;
+ glGenTextures(1, &handle);
+ }
/// Deletes the internal OpenGL resource
- void Release();
+ void Release() {
+ if (handle == 0) return;
+ glDeleteTextures(1, &handle);
+ handle = 0;
+ }
- GLuint handle;
+ GLuint handle = 0;
};
-class OGLShader : public NonCopyable {
+class OGLShader : private NonCopyable {
public:
- OGLShader();
- ~OGLShader();
+ OGLShader() = default;
+ OGLShader(OGLShader&& o) { std::swap(handle, o.handle); }
+ ~OGLShader() { Release(); }
+ OGLShader& operator=(OGLShader&& o) { std::swap(handle, o.handle); return *this; }
/// Creates a new internal OpenGL resource and stores the handle
- void Create(const char* vert_shader, const char* frag_shader);
+ void Create(const char* vert_shader, const char* frag_shader) {
+ if (handle != 0) return;
+ handle = ShaderUtil::LoadShaders(vert_shader, frag_shader);
+ }
/// Deletes the internal OpenGL resource
- void Release();
+ void Release() {
+ if (handle == 0) return;
+ glDeleteProgram(handle);
+ handle = 0;
+ }
- GLuint handle;
+ GLuint handle = 0;
};
-class OGLBuffer : public NonCopyable {
+class OGLBuffer : private NonCopyable {
public:
- OGLBuffer();
- ~OGLBuffer();
+ OGLBuffer() = default;
+ OGLBuffer(OGLBuffer&& o) { std::swap(handle, o.handle); }
+ ~OGLBuffer() { Release(); }
+ OGLBuffer& operator=(OGLBuffer&& o) { std::swap(handle, o.handle); return *this; }
/// Creates a new internal OpenGL resource and stores the handle
- void Create();
+ void Create() {
+ if (handle != 0) return;
+ glGenBuffers(1, &handle);
+ }
/// Deletes the internal OpenGL resource
- void Release();
+ void Release() {
+ if (handle == 0) return;
+ glDeleteBuffers(1, &handle);
+ handle = 0;
+ }
- GLuint handle;
+ GLuint handle = 0;
};
-class OGLVertexArray : public NonCopyable {
+class OGLVertexArray : private NonCopyable {
public:
- OGLVertexArray();
- ~OGLVertexArray();
+ OGLVertexArray() = default;
+ OGLVertexArray(OGLVertexArray&& o) { std::swap(handle, o.handle); }
+ ~OGLVertexArray() { Release(); }
+ OGLVertexArray& operator=(OGLVertexArray&& o) { std::swap(handle, o.handle); return *this; }
/// Creates a new internal OpenGL resource and stores the handle
- void Create();
+ void Create() {
+ if (handle != 0) return;
+ glGenVertexArrays(1, &handle);
+ }
/// Deletes the internal OpenGL resource
- void Release();
+ void Release() {
+ if (handle == 0) return;
+ glDeleteVertexArrays(1, &handle);
+ handle = 0;
+ }
- GLuint handle;
+ GLuint handle = 0;
};
-class OGLFramebuffer : public NonCopyable {
+class OGLFramebuffer : private NonCopyable {
public:
- OGLFramebuffer();
- ~OGLFramebuffer();
+ OGLFramebuffer() = default;
+ OGLFramebuffer(OGLFramebuffer&& o) { std::swap(handle, o.handle); }
+ ~OGLFramebuffer() { Release(); }
+ OGLFramebuffer& operator=(OGLFramebuffer&& o) { std::swap(handle, o.handle); return *this; }
/// Creates a new internal OpenGL resource and stores the handle
- void Create();
+ void Create() {
+ if (handle != 0) return;
+ glGenFramebuffers(1, &handle);
+ }
/// Deletes the internal OpenGL resource
- void Release();
+ void Release() {
+ if (handle == 0) return;
+ glDeleteFramebuffers(1, &handle);
+ handle = 0;
+ }
- GLuint handle;
+ GLuint handle = 0;
};
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp
index b7750380..960ae577 100644
--- a/src/video_core/vertex_shader.cpp
+++ b/src/video_core/vertex_shader.cpp
@@ -2,8 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <stack>
-
+#include <boost/container/static_vector.hpp>
#include <boost/range/algorithm.hpp>
#include <common/file_util.h>
@@ -27,7 +26,7 @@ namespace Pica {
namespace VertexShader {
struct VertexShaderState {
- const u32* program_counter;
+ u32 program_counter;
const float24* input_register_table[16];
Math::Vec4<float24> output_registers[16];
@@ -53,7 +52,7 @@ struct VertexShaderState {
};
// TODO: Is there a maximal size for this?
- std::stack<CallStackElement> call_stack;
+ boost::container::static_vector<CallStackElement, 16> call_stack;
struct {
u32 max_offset; // maximum program counter ever reached
@@ -71,15 +70,15 @@ static void ProcessShaderCode(VertexShaderState& state) {
while (true) {
if (!state.call_stack.empty()) {
- auto& top = state.call_stack.top();
- if (state.program_counter - program_code.data() == top.final_address) {
+ auto& top = state.call_stack.back();
+ if (state.program_counter == top.final_address) {
state.address_registers[2] += top.loop_increment;
if (top.repeat_counter-- == 0) {
- state.program_counter = &program_code[top.return_address];
- state.call_stack.pop();
+ state.program_counter = top.return_address;
+ state.call_stack.pop_back();
} else {
- state.program_counter = &program_code[top.loop_address];
+ state.program_counter = top.loop_address;
}
// TODO: Is "trying again" accurate to hardware?
@@ -88,17 +87,16 @@ static void ProcessShaderCode(VertexShaderState& state) {
}
bool exit_loop = false;
- const Instruction& instr = *(const Instruction*)state.program_counter;
- const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.common.operand_desc_id];
+ const Instruction instr = { program_code[state.program_counter] };
+ const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] };
- static auto call = [&program_code](VertexShaderState& state, u32 offset, u32 num_instructions,
+ static auto call = [](VertexShaderState& state, u32 offset, u32 num_instructions,
u32 return_offset, u8 repeat_count, u8 loop_increment) {
- state.program_counter = &program_code[offset] - 1; // -1 to make sure when incrementing the PC we end up at the correct offset
- state.call_stack.push({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset });
+ state.program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset
+ ASSERT(state.call_stack.size() < state.call_stack.capacity());
+ state.call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset });
};
- u32 binary_offset = state.program_counter - program_code.data();
-
- state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + binary_offset);
+ state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + state.program_counter);
auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* {
switch (source_reg.GetRegisterType()) {
@@ -442,13 +440,13 @@ static void ProcessShaderCode(VertexShaderState& state) {
case OpCode::Id::JMPC:
if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
- state.program_counter = &program_code[instr.flow_control.dest_offset] - 1;
+ state.program_counter = instr.flow_control.dest_offset - 1;
}
break;
case OpCode::Id::JMPU:
if (uniforms.b[instr.flow_control.bool_uniform_id]) {
- state.program_counter = &program_code[instr.flow_control.dest_offset] - 1;
+ state.program_counter = instr.flow_control.dest_offset - 1;
}
break;
@@ -456,7 +454,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
call(state,
instr.flow_control.dest_offset,
instr.flow_control.num_instructions,
- binary_offset + 1, 0, 0);
+ state.program_counter + 1, 0, 0);
break;
case OpCode::Id::CALLU:
@@ -464,7 +462,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
call(state,
instr.flow_control.dest_offset,
instr.flow_control.num_instructions,
- binary_offset + 1, 0, 0);
+ state.program_counter + 1, 0, 0);
}
break;
@@ -473,7 +471,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
call(state,
instr.flow_control.dest_offset,
instr.flow_control.num_instructions,
- binary_offset + 1, 0, 0);
+ state.program_counter + 1, 0, 0);
}
break;
@@ -483,8 +481,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
case OpCode::Id::IFU:
if (uniforms.b[instr.flow_control.bool_uniform_id]) {
call(state,
- binary_offset + 1,
- instr.flow_control.dest_offset - binary_offset - 1,
+ state.program_counter + 1,
+ instr.flow_control.dest_offset - state.program_counter - 1,
instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
} else {
call(state,
@@ -501,8 +499,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
call(state,
- binary_offset + 1,
- instr.flow_control.dest_offset - binary_offset - 1,
+ state.program_counter + 1,
+ instr.flow_control.dest_offset - state.program_counter - 1,
instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
} else {
call(state,
@@ -519,8 +517,8 @@ static void ProcessShaderCode(VertexShaderState& state) {
state.address_registers[2] = uniforms.i[instr.flow_control.int_uniform_id].y;
call(state,
- binary_offset + 1,
- instr.flow_control.dest_offset - binary_offset + 1,
+ state.program_counter + 1,
+ instr.flow_control.dest_offset - state.program_counter + 1,
instr.flow_control.dest_offset + 1,
uniforms.i[instr.flow_control.int_uniform_id].x,
uniforms.i[instr.flow_control.int_uniform_id].z);
@@ -551,8 +549,7 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs:
VertexShaderState state;
- const u32* main = &setup.program_code[config.main_offset];
- state.program_counter = (u32*)main;
+ state.program_counter = config.main_offset;
state.debug.max_offset = 0;
state.debug.max_opdesc_id = 0;
@@ -582,9 +579,11 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs:
state.conditional_code[1] = false;
ProcessShaderCode(state);
+#if PICA_DUMP_SHADERS
DebugUtils::DumpShader(setup.program_code.data(), state.debug.max_offset, setup.swizzle_data.data(),
state.debug.max_opdesc_id, config.main_offset,
g_state.regs.vs_output_attributes); // TODO: Don't hardcode VS here
+#endif
// Setup output data
OutputVertex ret;