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