summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/citra.cpp2
-rw-r--r--src/citra/default_ini.h2
-rw-r--r--src/citra_qt/bootmanager.cpp3
-rw-r--r--src/citra_qt/bootmanager.hxx4
-rw-r--r--src/citra_qt/config/controller_config.cpp4
-rw-r--r--src/citra_qt/config/controller_config.hxx4
-rw-r--r--src/citra_qt/config/controller_config_util.cpp4
-rw-r--r--src/citra_qt/config/controller_config_util.hxx4
-rw-r--r--src/citra_qt/debugger/callstack.cpp10
-rw-r--r--src/citra_qt/debugger/callstack.hxx4
-rw-r--r--src/citra_qt/debugger/callstack.ui2
-rw-r--r--src/citra_qt/debugger/disassembler.cpp4
-rw-r--r--src/citra_qt/debugger/disassembler.hxx4
-rw-r--r--src/citra_qt/debugger/graphics.cpp2
-rw-r--r--src/citra_qt/debugger/graphics_breakpoints.cpp2
-rw-r--r--src/citra_qt/debugger/graphics_cmdlists.cpp4
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.cpp28
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.hxx4
-rw-r--r--src/citra_qt/debugger/ramview.cpp4
-rw-r--r--src/citra_qt/debugger/ramview.hxx4
-rw-r--r--src/citra_qt/debugger/registers.cpp4
-rw-r--r--src/citra_qt/debugger/registers.hxx4
-rw-r--r--src/citra_qt/debugger/registers.ui2
-rw-r--r--src/citra_qt/hotkeys.cpp4
-rw-r--r--src/citra_qt/hotkeys.hxx4
-rw-r--r--src/citra_qt/main.cpp20
-rw-r--r--src/citra_qt/main.hxx4
-rw-r--r--src/citra_qt/main.ui10
-rw-r--r--src/citra_qt/version.h4
-rw-r--r--src/common/common_paths.h1
-rw-r--r--src/common/file_util.cpp2
-rw-r--r--src/common/file_util.h1
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp11
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h216
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp1197
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h12
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h8
-rw-r--r--src/core/arm/interpreter/armemu.cpp92
-rw-r--r--src/core/arm/interpreter/armsupp.cpp28
-rw-r--r--src/core/arm/skyeye_common/armdefs.h7
-rw-r--r--src/core/arm/skyeye_common/armemu.h7
-rw-r--r--src/core/arm/skyeye_common/skyeye_types.h30
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp5063
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/file_sys/archive_backend.h3
-rw-r--r--src/core/file_sys/archive_romfs.cpp47
-rw-r--r--src/core/file_sys/archive_romfs.h76
-rw-r--r--src/core/file_sys/archive_savedatacheck.cpp41
-rw-r--r--src/core/file_sys/archive_savedatacheck.h31
-rw-r--r--src/core/file_sys/directory_romfs.cpp32
-rw-r--r--src/core/file_sys/directory_romfs.h43
-rw-r--r--src/core/file_sys/disk_archive.cpp11
-rw-r--r--src/core/file_sys/disk_archive.h6
-rw-r--r--src/core/file_sys/file_romfs.cpp43
-rw-r--r--src/core/file_sys/file_romfs.h73
-rw-r--r--src/core/file_sys/ivfc_archive.cpp88
-rw-r--r--src/core/file_sys/ivfc_archive.h66
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp11
-rw-r--r--src/core/hle/kernel/mutex.cpp4
-rw-r--r--src/core/hle/service/dsp_dsp.cpp22
-rw-r--r--src/core/hle/service/dsp_dsp.h3
-rw-r--r--src/core/hle/service/fs/archive.cpp44
-rw-r--r--src/core/hle/service/fs/archive.h3
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/soc_u.cpp10
-rw-r--r--src/core/hle/service/y2r_u.cpp45
-rw-r--r--src/core/hle/service/y2r_u.h23
-rw-r--r--src/core/hw/gpu.cpp14
-rw-r--r--src/core/hw/gpu.h3
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/loader.cpp2
-rw-r--r--src/video_core/color.h32
-rw-r--r--src/video_core/command_processor.cpp28
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp48
-rw-r--r--src/video_core/pica.h84
-rw-r--r--src/video_core/rasterizer.cpp241
-rw-r--r--src/video_core/utils.h26
-rw-r--r--src/video_core/vertex_shader.cpp27
-rw-r--r--src/video_core/vertex_shader.h1
81 files changed, 4442 insertions, 3639 deletions
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index f6a52758b..69f0b35b3 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -51,6 +51,8 @@ int __cdecl main(int argc, char **argv) {
51 Core::RunLoop(); 51 Core::RunLoop();
52 } 52 }
53 53
54 System::Shutdown();
55
54 delete emu_window; 56 delete emu_window;
55 57
56 return 0; 58 return 0;
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index f41020f7b..ebe2e9767 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -27,7 +27,7 @@ pad_sleft =
27pad_sright = 27pad_sright =
28 28
29[Core] 29[Core]
30cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) 30cpu_core = ## 0: Interpreter (default), 1: OldInterpreter (may work better, soon to be deprecated)
31gpu_refresh_rate = ## 30 (default) 31gpu_refresh_rate = ## 30 (default)
32frame_skip = ## 0: No frameskip (default), 1 : 2x frameskip, 2 : 4x frameskip, etc. 32frame_skip = ## 0: No frameskip (default), 1 : 2x frameskip, 2 : 4x frameskip, etc.
33 33
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 6d08d6afc..e753ea108 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -13,6 +13,7 @@
13 13
14#include "core/core.h" 14#include "core/core.h"
15#include "core/settings.h" 15#include "core/settings.h"
16#include "core/system.h"
16 17
17#include "video_core/debug_utils/debug_utils.h" 18#include "video_core/debug_utils/debug_utils.h"
18 19
@@ -89,6 +90,8 @@ void EmuThread::Stop()
89 } 90 }
90 } 91 }
91 LOG_INFO(Frontend, "EmuThread stopped"); 92 LOG_INFO(Frontend, "EmuThread stopped");
93
94 System::Shutdown();
92} 95}
93 96
94 97
diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx
index 5f69f15ea..1c893384c 100644
--- a/src/citra_qt/bootmanager.hxx
+++ b/src/citra_qt/bootmanager.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <atomic> 5#include <atomic>
2 6
3#include <QThread> 7#include <QThread>
diff --git a/src/citra_qt/config/controller_config.cpp b/src/citra_qt/config/controller_config.cpp
index 52dfb627c..41000e29b 100644
--- a/src/citra_qt/config/controller_config.cpp
+++ b/src/citra_qt/config/controller_config.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QDialogButtonBox> 5#include <QDialogButtonBox>
2 6
3#include "controller_config.hxx" 7#include "controller_config.hxx"
diff --git a/src/citra_qt/config/controller_config.hxx b/src/citra_qt/config/controller_config.hxx
index 0e423ee50..451593de1 100644
--- a/src/citra_qt/config/controller_config.hxx
+++ b/src/citra_qt/config/controller_config.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#ifndef _CONTROLLER_CONFIG_HXX_ 5#ifndef _CONTROLLER_CONFIG_HXX_
2#define _CONTROLLER_CONFIG_HXX_ 6#define _CONTROLLER_CONFIG_HXX_
3 7
diff --git a/src/citra_qt/config/controller_config_util.cpp b/src/citra_qt/config/controller_config_util.cpp
index aee3f8616..272e8d41e 100644
--- a/src/citra_qt/config/controller_config_util.cpp
+++ b/src/citra_qt/config/controller_config_util.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QPushButton> 5#include <QPushButton>
2#include <QStyle> 6#include <QStyle>
3#include <QGridLayout> 7#include <QGridLayout>
diff --git a/src/citra_qt/config/controller_config_util.hxx b/src/citra_qt/config/controller_config_util.hxx
index af38f126c..15e025b57 100644
--- a/src/citra_qt/config/controller_config_util.hxx
+++ b/src/citra_qt/config/controller_config_util.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#ifndef _CONTROLLER_CONFIG_UTIL_HXX_ 5#ifndef _CONTROLLER_CONFIG_UTIL_HXX_
2#define _CONTROLLER_CONFIG_UTIL_HXX_ 6#define _CONTROLLER_CONFIG_UTIL_HXX_
3 7
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp
index a9ec2f7fe..4a47ad468 100644
--- a/src/citra_qt/debugger/callstack.cpp
+++ b/src/citra_qt/debugger/callstack.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QStandardItemModel> 5#include <QStandardItemModel>
2 6
3#include "callstack.hxx" 7#include "callstack.hxx"
@@ -14,9 +18,9 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
14 18
15 callstack_model = new QStandardItemModel(this); 19 callstack_model = new QStandardItemModel(this);
16 callstack_model->setColumnCount(4); 20 callstack_model->setColumnCount(4);
17 callstack_model->setHeaderData(0, Qt::Horizontal, "Stack pointer"); 21 callstack_model->setHeaderData(0, Qt::Horizontal, "Stack Pointer");
18 callstack_model->setHeaderData(2, Qt::Horizontal, "Return address"); 22 callstack_model->setHeaderData(2, Qt::Horizontal, "Return Address");
19 callstack_model->setHeaderData(1, Qt::Horizontal, "Call address"); 23 callstack_model->setHeaderData(1, Qt::Horizontal, "Call Address");
20 callstack_model->setHeaderData(3, Qt::Horizontal, "Function"); 24 callstack_model->setHeaderData(3, Qt::Horizontal, "Function");
21 ui.treeView->setModel(callstack_model); 25 ui.treeView->setModel(callstack_model);
22} 26}
diff --git a/src/citra_qt/debugger/callstack.hxx b/src/citra_qt/debugger/callstack.hxx
index 680a73b6d..4f4f74823 100644
--- a/src/citra_qt/debugger/callstack.hxx
+++ b/src/citra_qt/debugger/callstack.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QDockWidget> 5#include <QDockWidget>
2#include "ui_callstack.h" 6#include "ui_callstack.h"
3 7
diff --git a/src/citra_qt/debugger/callstack.ui b/src/citra_qt/debugger/callstack.ui
index b3c4db632..b0e31120f 100644
--- a/src/citra_qt/debugger/callstack.ui
+++ b/src/citra_qt/debugger/callstack.ui
@@ -11,7 +11,7 @@
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
14 <string>Call stack</string> 14 <string>Call Stack</string>
15 </property> 15 </property>
16 <widget class="QWidget" name="dockWidgetContents"> 16 <widget class="QWidget" name="dockWidgetContents">
17 <layout class="QVBoxLayout" name="verticalLayout"> 17 <layout class="QVBoxLayout" name="verticalLayout">
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index 14745f3bb..636a0f187 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include "disassembler.hxx" 5#include "disassembler.hxx"
2 6
3#include "../bootmanager.hxx" 7#include "../bootmanager.hxx"
diff --git a/src/citra_qt/debugger/disassembler.hxx b/src/citra_qt/debugger/disassembler.hxx
index a842da956..6d3cef108 100644
--- a/src/citra_qt/debugger/disassembler.hxx
+++ b/src/citra_qt/debugger/disassembler.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QAbstractItemModel> 5#include <QAbstractItemModel>
2#include <QDockWidget> 6#include <QDockWidget>
3#include "ui_disassembler.h" 7#include "ui_disassembler.h"
diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics.cpp
index 6ff4c290d..9633d367e 100644
--- a/src/citra_qt/debugger/graphics.cpp
+++ b/src/citra_qt/debugger/graphics.cpp
@@ -72,7 +72,7 @@ void GPUCommandStreamItemModel::OnGXCommandFinishedInternal(int total_command_co
72 72
73GPUCommandStreamWidget::GPUCommandStreamWidget(QWidget* parent) : QDockWidget(tr("Graphics Debugger"), parent) 73GPUCommandStreamWidget::GPUCommandStreamWidget(QWidget* parent) : QDockWidget(tr("Graphics Debugger"), parent)
74{ 74{
75 // TODO: set objectName! 75 setObjectName("GraphicsDebugger");
76 76
77 GPUCommandStreamItemModel* command_model = new GPUCommandStreamItemModel(this); 77 GPUCommandStreamItemModel* command_model = new GPUCommandStreamItemModel(this);
78 g_debugger.RegisterObserver(command_model); 78 g_debugger.RegisterObserver(command_model);
diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp
index 9486f06cc..170aa736d 100644
--- a/src/citra_qt/debugger/graphics_breakpoints.cpp
+++ b/src/citra_qt/debugger/graphics_breakpoints.cpp
@@ -44,7 +44,7 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const
44 { Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed") }, 44 { Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed") },
45 { Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") }, 45 { Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") },
46 { Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") }, 46 { Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") },
47 { Pica::DebugContext::Event::VertexLoaded, tr("Vertex Loaded") } 47 { Pica::DebugContext::Event::VertexLoaded, tr("Vertex loaded") }
48 }; 48 };
49 49
50 _dbg_assert_(Debug_GPU, map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); 50 _dbg_assert_(Debug_GPU, map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents));
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp
index 753cc25da..708b805a7 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics_cmdlists.cpp
@@ -229,7 +229,7 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace&
229 cmd_id < PICA_REG_INDEX(reg_name) + sizeof(decltype(Pica::registers.reg_name)) / 4) 229 cmd_id < PICA_REG_INDEX(reg_name) + sizeof(decltype(Pica::registers.reg_name)) / 4)
230 230
231void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { 231void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) {
232 const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); 232 const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt();
233 if (COMMAND_IN_RANGE(command_id, texture0) || 233 if (COMMAND_IN_RANGE(command_id, texture0) ||
234 COMMAND_IN_RANGE(command_id, texture1) || 234 COMMAND_IN_RANGE(command_id, texture1) ||
235 COMMAND_IN_RANGE(command_id, texture2)) { 235 COMMAND_IN_RANGE(command_id, texture2)) {
@@ -255,7 +255,7 @@ void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) {
255void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { 255void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
256 QWidget* new_info_widget; 256 QWidget* new_info_widget;
257 257
258 const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); 258 const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt();
259 if (COMMAND_IN_RANGE(command_id, texture0) || 259 if (COMMAND_IN_RANGE(command_id, texture0) ||
260 COMMAND_IN_RANGE(command_id, texture1) || 260 COMMAND_IN_RANGE(command_id, texture1) ||
261 COMMAND_IN_RANGE(command_id, texture2)) { 261 COMMAND_IN_RANGE(command_id, texture2)) {
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp
index dd41c3880..7ef699f37 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.cpp
+++ b/src/citra_qt/debugger/graphics_framebuffer.cpp
@@ -10,6 +10,7 @@
10#include <QPushButton> 10#include <QPushButton>
11#include <QSpinBox> 11#include <QSpinBox>
12 12
13#include "video_core/color.h"
13#include "video_core/pica.h" 14#include "video_core/pica.h"
14 15
15#include "graphics_framebuffer.hxx" 16#include "graphics_framebuffer.hxx"
@@ -157,7 +158,7 @@ void GraphicsFramebufferWidget::OnFramebufferAddressChanged(qint64 new_value)
157 } 158 }
158} 159}
159 160
160void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value) 161void GraphicsFramebufferWidget::OnFramebufferWidthChanged(unsigned int new_value)
161{ 162{
162 if (framebuffer_width != new_value) { 163 if (framebuffer_width != new_value) {
163 framebuffer_width = new_value; 164 framebuffer_width = new_value;
@@ -167,7 +168,7 @@ void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value)
167 } 168 }
168} 169}
169 170
170void GraphicsFramebufferWidget::OnFramebufferHeightChanged(int new_value) 171void GraphicsFramebufferWidget::OnFramebufferHeightChanged(unsigned int new_value)
171{ 172{
172 if (framebuffer_height != new_value) { 173 if (framebuffer_height != new_value) {
173 framebuffer_height = new_value; 174 framebuffer_height = new_value;
@@ -202,7 +203,8 @@ void GraphicsFramebufferWidget::OnUpdate()
202 framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); 203 framebuffer_address = framebuffer.GetColorBufferPhysicalAddress();
203 framebuffer_width = framebuffer.GetWidth(); 204 framebuffer_width = framebuffer.GetWidth();
204 framebuffer_height = framebuffer.GetHeight(); 205 framebuffer_height = framebuffer.GetHeight();
205 framebuffer_format = static_cast<Format>(framebuffer.color_format); 206 // TODO: It's unknown how this format is actually specified
207 framebuffer_format = Format::RGBA8;
206 208
207 break; 209 break;
208 } 210 }
@@ -225,8 +227,8 @@ void GraphicsFramebufferWidget::OnUpdate()
225 { 227 {
226 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); 228 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
227 u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); 229 u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address));
228 for (unsigned y = 0; y < framebuffer_height; ++y) { 230 for (unsigned int y = 0; y < framebuffer_height; ++y) {
229 for (unsigned x = 0; x < framebuffer_width; ++x) { 231 for (unsigned int x = 0; x < framebuffer_width; ++x) {
230 u32 value = *(color_buffer + x + y * framebuffer_width); 232 u32 value = *(color_buffer + x + y * framebuffer_width);
231 233
232 decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/)); 234 decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/));
@@ -240,8 +242,8 @@ void GraphicsFramebufferWidget::OnUpdate()
240 { 242 {
241 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); 243 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
242 u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); 244 u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address));
243 for (unsigned y = 0; y < framebuffer_height; ++y) { 245 for (unsigned int y = 0; y < framebuffer_height; ++y) {
244 for (unsigned x = 0; x < framebuffer_width; ++x) { 246 for (unsigned int x = 0; x < framebuffer_width; ++x) {
245 u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width; 247 u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width;
246 248
247 decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/)); 249 decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/));
@@ -255,13 +257,13 @@ void GraphicsFramebufferWidget::OnUpdate()
255 { 257 {
256 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); 258 QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
257 u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); 259 u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address));
258 for (unsigned y = 0; y < framebuffer_height; ++y) { 260 for (unsigned int y = 0; y < framebuffer_height; ++y) {
259 for (unsigned x = 0; x < framebuffer_width; ++x) { 261 for (unsigned int x = 0; x < framebuffer_width; ++x) {
260 u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2); 262 u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2);
261 u8 r = (value >> 11) & 0x1F; 263 u8 r = Color::Convert5To8((value >> 11) & 0x1F);
262 u8 g = (value >> 6) & 0x1F; 264 u8 g = Color::Convert5To8((value >> 6) & 0x1F);
263 u8 b = (value >> 1) & 0x1F; 265 u8 b = Color::Convert5To8((value >> 1) & 0x1F);
264 u8 a = value & 1; 266 u8 a = Color::Convert1To8(value & 1);
265 267
266 decoded_image.setPixel(x, y, qRgba(r, g, b, 255/*a*/)); 268 decoded_image.setPixel(x, y, qRgba(r, g, b, 255/*a*/));
267 } 269 }
diff --git a/src/citra_qt/debugger/graphics_framebuffer.hxx b/src/citra_qt/debugger/graphics_framebuffer.hxx
index 56215761e..02813525c 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.hxx
+++ b/src/citra_qt/debugger/graphics_framebuffer.hxx
@@ -62,8 +62,8 @@ public:
62public slots: 62public slots:
63 void OnFramebufferSourceChanged(int new_value); 63 void OnFramebufferSourceChanged(int new_value);
64 void OnFramebufferAddressChanged(qint64 new_value); 64 void OnFramebufferAddressChanged(qint64 new_value);
65 void OnFramebufferWidthChanged(int new_value); 65 void OnFramebufferWidthChanged(unsigned int new_value);
66 void OnFramebufferHeightChanged(int new_value); 66 void OnFramebufferHeightChanged(unsigned int new_value);
67 void OnFramebufferFormatChanged(int new_value); 67 void OnFramebufferFormatChanged(int new_value);
68 void OnUpdate(); 68 void OnUpdate();
69 69
diff --git a/src/citra_qt/debugger/ramview.cpp b/src/citra_qt/debugger/ramview.cpp
index 3f899b95e..d3ff69a61 100644
--- a/src/citra_qt/debugger/ramview.cpp
+++ b/src/citra_qt/debugger/ramview.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include "ramview.hxx" 5#include "ramview.hxx"
2 6
3#include "common/common.h" 7#include "common/common.h"
diff --git a/src/citra_qt/debugger/ramview.hxx b/src/citra_qt/debugger/ramview.hxx
index 1db1546aa..18423036f 100644
--- a/src/citra_qt/debugger/ramview.hxx
+++ b/src/citra_qt/debugger/ramview.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include "qhexedit.h" 5#include "qhexedit.h"
2 6
3class GRamView : public QHexEdit 7class GRamView : public QHexEdit
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp
index ed17ee4b4..f798495b2 100644
--- a/src/citra_qt/debugger/registers.cpp
+++ b/src/citra_qt/debugger/registers.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include "registers.hxx" 5#include "registers.hxx"
2 6
3#include "core/core.h" 7#include "core/core.h"
diff --git a/src/citra_qt/debugger/registers.hxx b/src/citra_qt/debugger/registers.hxx
index 4cca957ce..ac8429f2b 100644
--- a/src/citra_qt/debugger/registers.hxx
+++ b/src/citra_qt/debugger/registers.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include "ui_registers.h" 5#include "ui_registers.h"
2 6
3#include <QDockWidget> 7#include <QDockWidget>
diff --git a/src/citra_qt/debugger/registers.ui b/src/citra_qt/debugger/registers.ui
index 6537c9cd6..c81ae03f9 100644
--- a/src/citra_qt/debugger/registers.ui
+++ b/src/citra_qt/debugger/registers.ui
@@ -11,7 +11,7 @@
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
14 <string>ARM registers</string> 14 <string>ARM Registers</string>
15 </property> 15 </property>
16 <widget class="QWidget" name="dockWidgetContents"> 16 <widget class="QWidget" name="dockWidgetContents">
17 <layout class="QVBoxLayout" name="verticalLayout"> 17 <layout class="QVBoxLayout" name="verticalLayout">
diff --git a/src/citra_qt/hotkeys.cpp b/src/citra_qt/hotkeys.cpp
index 5d0b52e4f..08be7ff74 100644
--- a/src/citra_qt/hotkeys.cpp
+++ b/src/citra_qt/hotkeys.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QKeySequence> 5#include <QKeySequence>
2#include <QSettings> 6#include <QSettings>
3#include "hotkeys.hxx" 7#include "hotkeys.hxx"
diff --git a/src/citra_qt/hotkeys.hxx b/src/citra_qt/hotkeys.hxx
index 66ef7bb4e..75c7cc625 100644
--- a/src/citra_qt/hotkeys.hxx
+++ b/src/citra_qt/hotkeys.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <QShortcut> 5#include <QShortcut>
2#include <QDialog> 6#include <QDialog>
3#include "ui_hotkeys.h" 7#include "ui_hotkeys.h"
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index b12e6a02b..64e389f25 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#include <thread> 5#include <thread>
2 6
3#include <QtGui> 7#include <QtGui>
@@ -107,7 +111,7 @@ GMainWindow::GMainWindow()
107 restoreState(settings.value("state").toByteArray()); 111 restoreState(settings.value("state").toByteArray());
108 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray()); 112 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray());
109 113
110 ui.action_Popout_Window_Mode->setChecked(settings.value("popoutWindowMode", true).toBool()); 114 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", true).toBool());
111 ToggleWindowMode(); 115 ToggleWindowMode();
112 116
113 // Setup connections 117 // Setup connections
@@ -116,7 +120,7 @@ GMainWindow::GMainWindow()
116 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame())); 120 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
117 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame())); 121 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
118 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); 122 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
119 connect(ui.action_Popout_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode())); 123 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
120 connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog())); 124 connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
121 125
122 // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues 126 // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
@@ -175,13 +179,13 @@ void GMainWindow::BootGame(std::string filename)
175 179
176void GMainWindow::OnMenuLoadFile() 180void GMainWindow::OnMenuLoadFile()
177{ 181{
178 QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS executable (*.3dsx *.elf *.axf *.bin *.cci *.cxi)")); 182 QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), QString(), tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.bin *.cci *.cxi)"));
179 if (filename.size()) 183 if (filename.size())
180 BootGame(filename.toLatin1().data()); 184 BootGame(filename.toLatin1().data());
181} 185}
182 186
183void GMainWindow::OnMenuLoadSymbolMap() { 187void GMainWindow::OnMenuLoadSymbolMap() {
184 QString filename = QFileDialog::getOpenFileName(this, tr("Load symbol map"), QString(), tr("Symbol map (*)")); 188 QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), QString(), tr("Symbol map (*)"));
185 if (filename.size()) 189 if (filename.size())
186 LoadSymbolMap(filename.toLatin1().data()); 190 LoadSymbolMap(filename.toLatin1().data());
187} 191}
@@ -223,8 +227,8 @@ void GMainWindow::OnOpenHotkeysDialog()
223 227
224void GMainWindow::ToggleWindowMode() 228void GMainWindow::ToggleWindowMode()
225{ 229{
226 bool enable = ui.action_Popout_Window_Mode->isChecked(); 230 bool enable = ui.action_Single_Window_Mode->isChecked();
227 if (enable && render_window->parent() != nullptr) 231 if (!enable && render_window->parent() != nullptr)
228 { 232 {
229 ui.horizontalLayout->removeWidget(render_window); 233 ui.horizontalLayout->removeWidget(render_window);
230 render_window->setParent(nullptr); 234 render_window->setParent(nullptr);
@@ -232,7 +236,7 @@ void GMainWindow::ToggleWindowMode()
232 render_window->RestoreGeometry(); 236 render_window->RestoreGeometry();
233 render_window->setFocusPolicy(Qt::NoFocus); 237 render_window->setFocusPolicy(Qt::NoFocus);
234 } 238 }
235 else if (!enable && render_window->parent() == nullptr) 239 else if (enable && render_window->parent() == nullptr)
236 { 240 {
237 render_window->BackupGeometry(); 241 render_window->BackupGeometry();
238 ui.horizontalLayout->addWidget(render_window); 242 ui.horizontalLayout->addWidget(render_window);
@@ -254,7 +258,7 @@ void GMainWindow::closeEvent(QCloseEvent* event)
254 settings.setValue("geometry", saveGeometry()); 258 settings.setValue("geometry", saveGeometry());
255 settings.setValue("state", saveState()); 259 settings.setValue("state", saveState());
256 settings.setValue("geometryRenderWindow", render_window->saveGeometry()); 260 settings.setValue("geometryRenderWindow", render_window->saveGeometry());
257 settings.setValue("popoutWindowMode", ui.action_Popout_Window_Mode->isChecked()); 261 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked());
258 settings.setValue("firstStart", false); 262 settings.setValue("firstStart", false);
259 SaveHotkeys(settings); 263 SaveHotkeys(settings);
260 264
diff --git a/src/citra_qt/main.hxx b/src/citra_qt/main.hxx
index b1b40df46..72df17c50 100644
--- a/src/citra_qt/main.hxx
+++ b/src/citra_qt/main.hxx
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1#ifndef _CITRA_QT_MAIN_HXX_ 5#ifndef _CITRA_QT_MAIN_HXX_
2#define _CITRA_QT_MAIN_HXX_ 6#define _CITRA_QT_MAIN_HXX_
3 7
diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui
index f3596716f..d06c207a0 100644
--- a/src/citra_qt/main.ui
+++ b/src/citra_qt/main.ui
@@ -58,7 +58,7 @@
58 <property name="title"> 58 <property name="title">
59 <string>&amp;View</string> 59 <string>&amp;View</string>
60 </property> 60 </property>
61 <addaction name="action_Popout_Window_Mode"/> 61 <addaction name="action_Single_Window_Mode"/>
62 <addaction name="action_Hotkeys"/> 62 <addaction name="action_Hotkeys"/>
63 </widget> 63 </widget>
64 <widget class="QMenu" name="menu_Help"> 64 <widget class="QMenu" name="menu_Help">
@@ -75,12 +75,12 @@
75 <widget class="QStatusBar" name="statusbar"/> 75 <widget class="QStatusBar" name="statusbar"/>
76 <action name="action_Load_File"> 76 <action name="action_Load_File">
77 <property name="text"> 77 <property name="text">
78 <string>Load file...</string> 78 <string>Load File...</string>
79 </property> 79 </property>
80 </action> 80 </action>
81 <action name="action_Load_Symbol_Map"> 81 <action name="action_Load_Symbol_Map">
82 <property name="text"> 82 <property name="text">
83 <string>Load symbol map...</string> 83 <string>Load Symbol Map...</string>
84 </property> 84 </property>
85 </action> 85 </action>
86 <action name="action_Exit"> 86 <action name="action_Exit">
@@ -114,12 +114,12 @@
114 <string>About Citra</string> 114 <string>About Citra</string>
115 </property> 115 </property>
116 </action> 116 </action>
117 <action name="action_Popout_Window_Mode"> 117 <action name="action_Single_Window_Mode">
118 <property name="checkable"> 118 <property name="checkable">
119 <bool>true</bool> 119 <bool>true</bool>
120 </property> 120 </property>
121 <property name="text"> 121 <property name="text">
122 <string>Popout window</string> 122 <string>Single Window Mode</string>
123 </property> 123 </property>
124 </action> 124 </action>
125 <action name="action_Hotkeys"> 125 <action name="action_Hotkeys">
diff --git a/src/citra_qt/version.h b/src/citra_qt/version.h
index 07022de5c..9d5a2b1a2 100644
--- a/src/citra_qt/version.h
+++ b/src/citra_qt/version.h
@@ -1,3 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
1// TODO: Supposed to be generated... 5// TODO: Supposed to be generated...
2// GENERATED - Do not edit! 6// GENERATED - Do not edit!
3#ifndef VERSION_H_ 7#ifndef VERSION_H_
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index d3f0702bc..e692e5492 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -42,6 +42,7 @@
42#define SDMC_DIR "sdmc" 42#define SDMC_DIR "sdmc"
43#define EXTSAVEDATA_DIR "extsavedata" 43#define EXTSAVEDATA_DIR "extsavedata"
44#define SAVEDATA_DIR "savedata" 44#define SAVEDATA_DIR "savedata"
45#define SAVEDATACHECK_DIR "savedatacheck"
45#define SYSDATA_DIR "sysdata" 46#define SYSDATA_DIR "sysdata"
46#define SYSSAVEDATA_DIR "syssavedata" 47#define SYSSAVEDATA_DIR "syssavedata"
47#define SHADERCACHE_DIR "shader_cache" 48#define SHADERCACHE_DIR "shader_cache"
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index c44ad4ca1..0a6cd80c8 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -678,6 +678,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
678 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 678 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
679 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; 679 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
680 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; 680 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
681 paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
681 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; 682 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
682 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; 683 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
683 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 684 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
@@ -723,6 +724,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
723 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 724 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
724 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; 725 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
725 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; 726 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
727 paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
726 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; 728 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
727 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 729 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
728 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; 730 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
diff --git a/src/common/file_util.h b/src/common/file_util.h
index ec2415473..c83ecd87d 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -29,6 +29,7 @@ enum {
29 D_SDMC_IDX, 29 D_SDMC_IDX,
30 D_EXTSAVEDATA, 30 D_EXTSAVEDATA,
31 D_SAVEDATA_IDX, 31 D_SAVEDATA_IDX,
32 D_SAVEDATACHECK_IDX,
32 D_SYSDATA_IDX, 33 D_SYSDATA_IDX,
33 D_SYSSAVEDATA_IDX, 34 D_SYSSAVEDATA_IDX,
34 D_HIRESTEXTURES_IDX, 35 D_HIRESTEXTURES_IDX,
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 89ea70d23..b67226d8d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -20,11 +20,11 @@ set(SRCS
20 file_sys/archive_extsavedata.cpp 20 file_sys/archive_extsavedata.cpp
21 file_sys/archive_romfs.cpp 21 file_sys/archive_romfs.cpp
22 file_sys/archive_savedata.cpp 22 file_sys/archive_savedata.cpp
23 file_sys/archive_savedatacheck.cpp
23 file_sys/archive_sdmc.cpp 24 file_sys/archive_sdmc.cpp
24 file_sys/archive_systemsavedata.cpp 25 file_sys/archive_systemsavedata.cpp
25 file_sys/disk_archive.cpp 26 file_sys/disk_archive.cpp
26 file_sys/file_romfs.cpp 27 file_sys/ivfc_archive.cpp
27 file_sys/directory_romfs.cpp
28 hle/kernel/address_arbiter.cpp 28 hle/kernel/address_arbiter.cpp
29 hle/kernel/event.cpp 29 hle/kernel/event.cpp
30 hle/kernel/kernel.cpp 30 hle/kernel/kernel.cpp
@@ -66,6 +66,7 @@ set(SRCS
66 hle/service/soc_u.cpp 66 hle/service/soc_u.cpp
67 hle/service/srv.cpp 67 hle/service/srv.cpp
68 hle/service/ssl_c.cpp 68 hle/service/ssl_c.cpp
69 hle/service/y2r_u.cpp
69 hle/config_mem.cpp 70 hle/config_mem.cpp
70 hle/hle.cpp 71 hle/hle.cpp
71 hle/svc.cpp 72 hle/svc.cpp
@@ -108,13 +109,13 @@ set(HEADERS
108 file_sys/archive_extsavedata.h 109 file_sys/archive_extsavedata.h
109 file_sys/archive_romfs.h 110 file_sys/archive_romfs.h
110 file_sys/archive_savedata.h 111 file_sys/archive_savedata.h
112 file_sys/archive_savedatacheck.h
111 file_sys/archive_sdmc.h 113 file_sys/archive_sdmc.h
112 file_sys/archive_systemsavedata.h 114 file_sys/archive_systemsavedata.h
113 file_sys/disk_archive.h 115 file_sys/disk_archive.h
114 file_sys/file_backend.h 116 file_sys/file_backend.h
115 file_sys/file_romfs.h 117 file_sys/ivfc_archive.h
116 file_sys/directory_backend.h 118 file_sys/directory_backend.h
117 file_sys/directory_romfs.h
118 hle/kernel/address_arbiter.h 119 hle/kernel/address_arbiter.h
119 hle/kernel/event.h 120 hle/kernel/event.h
120 hle/kernel/kernel.h 121 hle/kernel/kernel.h
@@ -157,6 +158,7 @@ set(HEADERS
157 hle/service/soc_u.h 158 hle/service/soc_u.h
158 hle/service/srv.h 159 hle/service/srv.h
159 hle/service/ssl_c.h 160 hle/service/ssl_c.h
161 hle/service/y2r_u.h
160 hle/config_mem.h 162 hle/config_mem.h
161 hle/result.h 163 hle/result.h
162 hle/function_wrappers.h 164 hle/function_wrappers.h
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 333b40f54..0927eece1 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -136,7 +136,6 @@ const ISEITEM arm_instruction[] = {
136 { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, 136 { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 },
137 { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, 137 { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 },
138 { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, 138 { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 },
139 // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
140 { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, 139 { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 },
141 { "mcrr", 1, 6, 20, 27, 0x000000c4 }, 140 { "mcrr", 1, 6, 20, 27, 0x000000c4 },
142 { "mrrc", 1, 6, 20, 27, 0x000000c5 }, 141 { "mrrc", 1, 6, 20, 27, 0x000000c5 },
@@ -194,6 +193,10 @@ const ISEITEM arm_instruction[] = {
194 { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, 193 { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 },
195 { "swi", 1, 0, 24, 27, 0x0000000f }, 194 { "swi", 1, 0, 24, 27, 0x0000000f },
196 { "bbl", 1, 0, 25, 27, 0x00000005 }, 195 { "bbl", 1, 0, 25, 27, 0x00000005 },
196 { "ldrexd", 2, ARMV6K, 20, 27, 0x0000001B, 4, 7, 0x00000009 },
197 { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 },
198 { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 },
199 { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 },
197}; 200};
198 201
199const ISEITEM arm_exclusion_code[] = { 202const ISEITEM arm_exclusion_code[] = {
@@ -383,6 +386,11 @@ const ISEITEM arm_exclusion_code[] = {
383 { "ldc", 0, 0, 0 }, 386 { "ldc", 0, 0, 0 },
384 { "swi", 0, 0, 0 }, 387 { "swi", 0, 0, 0 },
385 { "bbl", 0, 0, 0 }, 388 { "bbl", 0, 0, 0 },
389 { "ldrexd", 0, ARMV6K, 0 },
390 { "strexd", 0, ARMV6K, 0 },
391 { "ldrexh", 0, ARMV6K, 0 },
392 { "strexh", 0, ARMV6K, 0 },
393
386 { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] 394 { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4]
387 { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] 395 { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3]
388 { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2] 396 { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2]
@@ -395,6 +403,7 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) {
395 int ret = DECODE_FAILURE; 403 int ret = DECODE_FAILURE;
396 int i = 0; 404 int i = 0;
397 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); 405 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
406
398 for (i = 0; i < instr_slots; i++) { 407 for (i = 0; i < instr_slots; i++) {
399 n = arm_instruction[i].attribute_value; 408 n = arm_instruction[i].attribute_value;
400 base = 0; 409 base = 0;
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 70eb96e93..58784aeea 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -1,153 +1,117 @@
1/* Copyright (C) 1// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
2* 2012 - Michael.Kang blackfin.kang@gmail.com 2// Licensed under GPLv2 or any later version
3* This program is free software; you can redistribute it and/or 3// Refer to the license.txt file included.
4* modify it under the terms of the GNU General Public License 4
5* as published by the Free Software Foundation; either version 2 5#pragma once
6* of the License, or (at your option) any later version. 6
7* 7#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
8* This program is distributed in the hope that it will be useful, 8#define BIT(n) ((instr >> (n)) & 1)
9* but WITHOUT ANY WARRANTY; without even the implied warranty of 9#define BAD do { printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); } while(0);
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10#define ptr_N cpu->ptr_N
11* GNU General Public License for more details. 11#define ptr_Z cpu->ptr_Z
12* 12#define ptr_C cpu->ptr_C
13* You should have received a copy of the GNU General Public License 13#define ptr_V cpu->ptr_V
14* along with this program; if not, write to the Free Software 14#define ptr_I cpu->ptr_I
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15#define ptr_T cpu->ptr_T
16* 16#define ptr_CPSR cpu->ptr_gpr[16]
17*/ 17
18 18// For MUL instructions
19/** 19#define RDHi ((instr >> 16) & 0xF)
20* @file arm_dyncom_dec.h 20#define RDLo ((instr >> 12) & 0xF)
21* @brief Some common utility for arm instruction decoder 21#define MUL_RD ((instr >> 16) & 0xF)
22* @author Michael.Kang blackfin.kang@gmail.com 22#define MUL_RN ((instr >> 12) & 0xF)
23* @version 7849 23#define RS ((instr >> 8) & 0xF)
24* @date 2012-03-15 24#define RD ((instr >> 12) & 0xF)
25*/ 25#define RN ((instr >> 16) & 0xF)
26 26#define RM (instr & 0xF)
27#ifndef __ARM_DYNCOM_DEC__ 27
28#define __ARM_DYNCOM_DEC__ 28// CP15 registers
29 29#define OPCODE_1 BITS(21, 23)
30#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) 30#define CRn BITS(16, 19)
31#define BIT(n) ((instr >> (n)) & 1) 31#define CRm BITS(0, 3)
32#define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0); 32#define OPCODE_2 BITS(5, 7)
33#define ptr_N cpu->ptr_N 33
34#define ptr_Z cpu->ptr_Z 34#define I BIT(25)
35#define ptr_C cpu->ptr_C 35#define S BIT(20)
36#define ptr_V cpu->ptr_V 36
37#define ptr_I cpu->ptr_I 37#define SHIFT BITS(5,6)
38#define ptr_T cpu->ptr_T 38#define SHIFT_IMM BITS(7,11)
39#define ptr_CPSR cpu->ptr_gpr[16] 39#define IMMH BITS(8,11)
40 40#define IMML BITS(0,3)
41/* for MUL instructions */ 41
42/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ 42#define LSPBIT BIT(24)
43#define RDHi ((instr >> 16) & 0xF) 43#define LSUBIT BIT(23)
44/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ 44#define LSBBIT BIT(22)
45#define RDLo ((instr >> 12) & 0xF) 45#define LSWBIT BIT(21)
46/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ 46#define LSLBIT BIT(20)
47#define MUL_RD ((instr >> 16) & 0xF) 47#define LSSHBITS BITS(5,6)
48/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ 48#define OFFSET12 BITS(0,11)
49#define MUL_RN ((instr >> 12) & 0xF) 49#define SBIT BIT(20)
50/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */ 50#define DESTReg (BITS (12, 15))
51#define RS ((instr >> 8) & 0xF) 51
52 52// They are in unused state, give a corrent value when using
53/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
54#define RD ((instr >> 12) & 0xF)
55/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
56#define RN ((instr >> 16) & 0xF)
57/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
58#define RM (instr & 0xF)
59
60/* CP15 registers */
61#define OPCODE_1 BITS(21, 23)
62#define CRn BITS(16, 19)
63#define CRm BITS(0, 3)
64#define OPCODE_2 BITS(5, 7)
65
66/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */
67#define I BIT(25)
68/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */
69#define S BIT(20)
70
71#define SHIFT BITS(5,6)
72#define SHIFT_IMM BITS(7,11)
73#define IMMH BITS(8,11)
74#define IMML BITS(0,3)
75
76#define LSPBIT BIT(24)
77#define LSUBIT BIT(23)
78#define LSBBIT BIT(22)
79#define LSWBIT BIT(21)
80#define LSLBIT BIT(20)
81#define LSSHBITS BITS(5,6)
82#define OFFSET12 BITS(0,11)
83#define SBIT BIT(20)
84#define DESTReg (BITS (12, 15))
85
86/* they are in unused state, give a corrent value when using */
87#define IS_V5E 0 53#define IS_V5E 0
88#define IS_V5 0 54#define IS_V5 0
89#define IS_V6 0 55#define IS_V6 0
90#define LHSReg 0 56#define LHSReg 0
91 57
92/* temp define the using the pc reg need implement a flow */ 58// Temp define the using the pc reg need implement a flow
93#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) 59#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2))
94 60
95#define OPERAND operand(cpu,instr,bb,NULL) 61#define OPERAND operand(cpu,instr,bb,NULL)
96#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) 62#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
97#define BOPERAND boperand(instr) 63#define BOPERAND boperand(instr)
98 64
99#define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN)) 65#define CHECK_RN_PC (RN == 15 ? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)) : R(RN))
100#define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN)) 66#define CHECK_RN_PC_WA (RN == 15 ? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)) : R(RN))
101 67
102#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) 68#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
103 69
104int decode_arm_instr(uint32_t instr, int32_t *idx); 70int decode_arm_instr(uint32_t instr, int32_t *idx);
105 71
106enum DECODE_STATUS { 72enum DECODE_STATUS {
107 DECODE_SUCCESS, 73 DECODE_SUCCESS,
108 DECODE_FAILURE 74 DECODE_FAILURE
109}; 75};
110 76
111struct instruction_set_encoding_item { 77struct instruction_set_encoding_item {
112 const char *name; 78 const char *name;
113 int attribute_value; 79 int attribute_value;
114 int version; 80 int version;
115 u32 content[21]; 81 u32 content[21];
116}; 82};
117 83
118typedef struct instruction_set_encoding_item ISEITEM; 84typedef struct instruction_set_encoding_item ISEITEM;
119 85
120#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;} 86#define RECORD_WB(value, flag) { cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag; }
121#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag) 87#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag)
122 88
123#define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \ 89#define EXECUTE_WB(base_reg) { if(cpu->dyncom_engine->wb_flag) LET(base_reg, cpu->dyncom_engine->wb_value); }
124 LET(base_reg, cpu->dyncom_engine->wb_value);} 90
125inline int get_reg_count(uint32_t instr){ 91inline int get_reg_count(uint32_t instr) {
126 int i = BITS(0,15); 92 int i = BITS(0, 15);
127 int count = 0; 93 int count = 0;
128 while(i){ 94 while (i) {
129 if(i & 1) 95 if (i & 1)
130 count ++; 96 count++;
131 i = i >> 1; 97 i = i >> 1;
132 } 98 }
133 return count; 99 return count;
134} 100}
135 101
136enum ARMVER { 102enum ARMVER {
137 INVALID = 0, 103 INVALID = 0,
138 ARMALL, 104 ARMALL,
139 ARMV4, 105 ARMV4,
140 ARMV4T, 106 ARMV4T,
141 ARMV5T, 107 ARMV5T,
142 ARMV5TE, 108 ARMV5TE,
143 ARMV5TEJ, 109 ARMV5TEJ,
144 ARMV6, 110 ARMV6,
145 ARM1176JZF_S, 111 ARM1176JZF_S,
146 ARMVFP2, 112 ARMVFP2,
147 ARMVFP3 113 ARMVFP3,
114 ARMV6K,
148}; 115};
149 116
150//extern const INSTRACT arm_instruction_action[];
151extern const ISEITEM arm_instruction[]; 117extern const ISEITEM arm_instruction[];
152
153#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index c61ae0053..593e0eabd 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -622,9 +622,7 @@ void LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int
622 } 622 }
623 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); 623 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
624 unsigned int start_addr = rn - count * 4 + 4; 624 unsigned int start_addr = rn - count * 4 + 4;
625 unsigned int end_addr = rn;
626 625
627 virt_addr = end_addr;
628 virt_addr = start_addr; 626 virt_addr = start_addr;
629 627
630 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { 628 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
@@ -873,6 +871,8 @@ typedef struct _mvn_inst {
873typedef struct _rev_inst { 871typedef struct _rev_inst {
874 unsigned int Rd; 872 unsigned int Rd;
875 unsigned int Rm; 873 unsigned int Rm;
874 unsigned int op1;
875 unsigned int op2;
876} rev_inst; 876} rev_inst;
877 877
878typedef struct _rsb_inst { 878typedef struct _rsb_inst {
@@ -930,6 +930,8 @@ typedef struct _smlad_inst {
930 unsigned int Rd; 930 unsigned int Rd;
931 unsigned int Ra; 931 unsigned int Ra;
932 unsigned int Rn; 932 unsigned int Rn;
933 unsigned int op1;
934 unsigned int op2;
933} smlad_inst; 935} smlad_inst;
934 936
935typedef struct _smla_inst { 937typedef struct _smla_inst {
@@ -972,6 +974,16 @@ typedef struct _smlal_inst {
972 unsigned int RdLo; 974 unsigned int RdLo;
973} smlal_inst; 975} smlal_inst;
974 976
977typedef struct smlald_inst {
978 unsigned int RdLo;
979 unsigned int RdHi;
980 unsigned int Rm;
981 unsigned int Rn;
982 unsigned int swap;
983 unsigned int op1;
984 unsigned int op2;
985} smlald_inst;
986
975typedef struct _mla_inst { 987typedef struct _mla_inst {
976 unsigned int S; 988 unsigned int S;
977 unsigned int Rn; 989 unsigned int Rn;
@@ -1067,7 +1079,7 @@ typedef struct _cdp_inst {
1067 unsigned int cp_num; 1079 unsigned int cp_num;
1068 unsigned int opcode_2; 1080 unsigned int opcode_2;
1069 unsigned int CRm; 1081 unsigned int CRm;
1070 uint32 inst; 1082 unsigned int inst;
1071}cdp_inst; 1083}cdp_inst;
1072 1084
1073typedef struct _uxtb_inst { 1085typedef struct _uxtb_inst {
@@ -1102,10 +1114,10 @@ typedef struct _blx_1_thumb {
1102}blx_1_thumb; 1114}blx_1_thumb;
1103 1115
1104typedef struct _pkh_inst { 1116typedef struct _pkh_inst {
1105 u32 Rm; 1117 unsigned int Rm;
1106 u32 Rn; 1118 unsigned int Rn;
1107 u32 Rd; 1119 unsigned int Rd;
1108 u8 imm; 1120 unsigned char imm;
1109} pkh_inst; 1121} pkh_inst;
1110 1122
1111typedef arm_inst * ARM_INST_PTR; 1123typedef arm_inst * ARM_INST_PTR;
@@ -1407,15 +1419,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
1407 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); 1419 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
1408 bx_inst *inst_cream = (bx_inst *)inst_base->component; 1420 bx_inst *inst_cream = (bx_inst *)inst_base->component;
1409 1421
1410 inst_base->cond = BITS(inst, 28, 31); 1422 inst_base->cond = BITS(inst, 28, 31);
1411 inst_base->idx = index; 1423 inst_base->idx = index;
1412 inst_base->br = INDIRECT_BRANCH; 1424 inst_base->br = INDIRECT_BRANCH;
1413 1425
1414 inst_cream->Rm = BITS(inst, 0, 3); 1426 inst_cream->Rm = BITS(inst, 0, 3);
1415 1427
1416 return inst_base; 1428 return inst_base;
1417} 1429}
1418ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } 1430ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
1431{
1432 return INTERPRETER_TRANSLATE(bx)(inst, index);
1433}
1434
1419ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ 1435ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
1420 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); 1436 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
1421 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 1437 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -1738,40 +1754,31 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
1738 1754
1739 return inst_base; 1755 return inst_base;
1740} 1756}
1741
1742ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) 1757ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
1743{ 1758{
1744 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1759 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
1745 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1760 generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
1746 1761
1747 inst_base->cond = BITS(inst, 28, 31); 1762 inst_base->cond = BITS(inst, 28, 31);
1748 inst_base->idx = index; 1763 inst_base->idx = index;
1749 inst_base->br = NON_BRANCH; 1764 inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15
1750 1765
1751 inst_cream->inst = inst; 1766 inst_cream->Rn = BITS(inst, 16, 19);
1752 //inst_cream->get_addr = get_calc_addr_op(inst); 1767 inst_cream->Rd = BITS(inst, 12, 15);
1753 1768
1754 if (BITS(inst, 12, 15) == 15) {
1755 inst_base->br = INDIRECT_BRANCH;
1756 }
1757 return inst_base; 1769 return inst_base;
1758} 1770}
1759ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) 1771ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
1760{ 1772{
1761 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 1773 return INTERPRETER_TRANSLATE(ldrex)(inst, index);
1762 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 1774}
1763 1775ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index)
1764 inst_base->cond = BITS(inst, 28, 31); 1776{
1765 inst_base->idx = index; 1777 return INTERPRETER_TRANSLATE(ldrex)(inst, index);
1766 inst_base->br = NON_BRANCH; 1778}
1767 1779ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index)
1768 inst_cream->inst = inst; 1780{
1769 inst_cream->get_addr = get_calc_addr_op(inst); 1781 return INTERPRETER_TRANSLATE(ldrex)(inst, index);
1770
1771 if (BITS(inst, 12, 15) == 15) {
1772 inst_base->br = INDIRECT_BRANCH;
1773 }
1774 return inst_base;
1775} 1782}
1776ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) 1783ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
1777{ 1784{
@@ -2050,7 +2057,37 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2050 2057
2051 return inst_base; 2058 return inst_base;
2052} 2059}
2053ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } 2060
2061ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
2062{
2063 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2064 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2065
2066 inst_base->cond = BITS(inst, 28, 31);
2067 inst_base->idx = index;
2068 inst_base->br = NON_BRANCH;
2069 inst_base->load_r15 = 0;
2070
2071 inst_cream->op1 = BITS(inst, 21, 22);
2072 inst_cream->Rm = BITS(inst, 0, 3);
2073 inst_cream->Rn = BITS(inst, 16, 19);
2074 inst_cream->Rd = BITS(inst, 12, 15);
2075
2076 return inst_base;
2077}
2078ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
2079{
2080 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2081}
2082ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
2083{
2084 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2085}
2086ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
2087{
2088 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2089}
2090
2054ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) 2091ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
2055{ 2092{
2056 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); 2093 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
@@ -2077,9 +2114,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
2077{ 2114{
2078 return INTERPRETER_TRANSLATE(qadd8)(inst, index); 2115 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2079} 2116}
2080ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
2081ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
2082ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
2083ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) 2117ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
2084{ 2118{
2085 return INTERPRETER_TRANSLATE(qadd8)(inst, index); 2119 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
@@ -2092,36 +2126,33 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
2092{ 2126{
2093 return INTERPRETER_TRANSLATE(qadd8)(inst, index); 2127 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2094} 2128}
2129
2095ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) 2130ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2096{ 2131{
2097 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2132 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2098 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2133 rev_inst* const inst_cream = (rev_inst*)inst_base->component;
2099 2134
2100 inst_base->cond = BITS(inst, 28, 31); 2135 inst_base->cond = BITS(inst, 28, 31);
2101 inst_base->idx = index; 2136 inst_base->idx = index;
2102 inst_base->br = NON_BRANCH; 2137 inst_base->br = NON_BRANCH;
2103 inst_base->load_r15 = 0; 2138 inst_base->load_r15 = 0;
2104 2139
2105 inst_cream->Rm = BITS(inst, 0, 3); 2140 inst_cream->Rm = BITS(inst, 0, 3);
2106 inst_cream->Rd = BITS(inst, 12, 15); 2141 inst_cream->Rd = BITS(inst, 12, 15);
2142 inst_cream->op1 = BITS(inst, 20, 22);
2143 inst_cream->op2 = BITS(inst, 5, 7);
2107 2144
2108 return inst_base; 2145 return inst_base;
2109} 2146}
2110ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ 2147ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
2111 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2148{
2112 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2149 return INTERPRETER_TRANSLATE(rev)(inst, index);
2113
2114 inst_base->cond = BITS(inst, 28, 31);
2115 inst_base->idx = index;
2116 inst_base->br = NON_BRANCH;
2117 inst_base->load_r15 = 0;
2118
2119 inst_cream->Rm = BITS(inst, 0, 3);
2120 inst_cream->Rd = BITS(inst, 12, 15);
2121
2122 return inst_base;
2123} 2150}
2124ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } 2151ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
2152{
2153 return INTERPRETER_TRANSLATE(rev)(inst, index);
2154}
2155
2125ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } 2156ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); }
2126ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) 2157ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
2127{ 2158{
@@ -2171,29 +2202,45 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
2171 } 2202 }
2172 return inst_base; 2203 return inst_base;
2173} 2204}
2174ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } 2205ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index)
2175ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
2176{ 2206{
2177 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); 2207 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2178 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; 2208 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2179 2209
2180 inst_base->cond = BITS(inst, 28, 31); 2210 inst_base->cond = BITS(inst, 28, 31);
2181 inst_base->idx = index; 2211 inst_base->idx = index;
2182 inst_base->br = NON_BRANCH; 2212 inst_base->br = NON_BRANCH;
2183 inst_base->load_r15 = 0; 2213 inst_base->load_r15 = 0;
2184 2214
2185 inst_cream->Rm = BITS(inst, 0, 3); 2215 inst_cream->Rm = BITS(inst, 0, 3);
2186 inst_cream->Rn = BITS(inst, 16, 19); 2216 inst_cream->Rn = BITS(inst, 16, 19);
2187 inst_cream->Rd = BITS(inst, 12, 15); 2217 inst_cream->Rd = BITS(inst, 12, 15);
2188 inst_cream->op1 = BITS(inst, 20, 21); 2218 inst_cream->op1 = BITS(inst, 20, 21);
2189 inst_cream->op2 = BITS(inst, 5, 7); 2219 inst_cream->op2 = BITS(inst, 5, 7);
2190 2220
2191 return inst_base; 2221 return inst_base;
2192} 2222}
2223ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
2224{
2225 return INTERPRETER_TRANSLATE(sadd8)(inst, index);
2226}
2193ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) 2227ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
2194{ 2228{
2195 return INTERPRETER_TRANSLATE(sadd16)(inst, index); 2229 return INTERPRETER_TRANSLATE(sadd8)(inst, index);
2196} 2230}
2231ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index)
2232{
2233 return INTERPRETER_TRANSLATE(sadd8)(inst, index);
2234}
2235ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
2236{
2237 return INTERPRETER_TRANSLATE(sadd8)(inst, index);
2238}
2239ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
2240{
2241 return INTERPRETER_TRANSLATE(sadd8)(inst, index);
2242}
2243
2197ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) 2244ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
2198{ 2245{
2199 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); 2246 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
@@ -2236,13 +2283,48 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
2236 2283
2237 return inst_base; 2284 return inst_base;
2238} 2285}
2286
2239ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } 2287ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); }
2240ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); } 2288
2241ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); } 2289ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
2242ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); } 2290{
2243ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); } 2291 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2244ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); } 2292 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
2245ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } 2293
2294 inst_base->cond = BITS(inst, 28, 31);
2295 inst_base->idx = index;
2296 inst_base->br = NON_BRANCH;
2297 inst_base->load_r15 = 0;
2298
2299 inst_cream->op1 = BITS(inst, 20, 21);
2300 inst_cream->op2 = BITS(inst, 5, 7);
2301 inst_cream->Rm = BITS(inst, 0, 3);
2302 inst_cream->Rn = BITS(inst, 16, 19);
2303 inst_cream->Rd = BITS(inst, 12, 15);
2304
2305 return inst_base;
2306}
2307ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index)
2308{
2309 return INTERPRETER_TRANSLATE(shadd8)(inst, index);
2310}
2311ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index)
2312{
2313 return INTERPRETER_TRANSLATE(shadd8)(inst, index);
2314}
2315ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index)
2316{
2317 return INTERPRETER_TRANSLATE(shadd8)(inst, index);
2318}
2319ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index)
2320{
2321 return INTERPRETER_TRANSLATE(shadd8)(inst, index);
2322}
2323ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index)
2324{
2325 return INTERPRETER_TRANSLATE(shadd8)(inst, index);
2326}
2327
2246ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) 2328ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
2247{ 2329{
2248 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); 2330 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
@@ -2262,25 +2344,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
2262 2344
2263 return inst_base; 2345 return inst_base;
2264} 2346}
2265ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
2266 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2267 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2268 2347
2269 inst_base->cond = BITS(inst, 28, 31); 2348ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index)
2270 inst_base->idx = index; 2349{
2271 inst_base->br = NON_BRANCH; 2350 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2351 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
2352
2353 inst_base->cond = BITS(inst, 28, 31);
2354 inst_base->idx = index;
2355 inst_base->br = NON_BRANCH;
2272 inst_base->load_r15 = 0; 2356 inst_base->load_r15 = 0;
2273 2357
2274 inst_cream->m = BIT(inst, 4); 2358 inst_cream->m = BIT(inst, 5);
2275 inst_cream->Rn = BITS(inst, 0, 3); 2359 inst_cream->Rn = BITS(inst, 0, 3);
2276 inst_cream->Rm = BITS(inst, 8, 11); 2360 inst_cream->Rm = BITS(inst, 8, 11);
2277 inst_cream->Rd = BITS(inst, 16, 19); 2361 inst_cream->Rd = BITS(inst, 16, 19);
2278 inst_cream->Ra = BITS(inst, 12, 15); 2362 inst_cream->Ra = BITS(inst, 12, 15);
2363 inst_cream->op1 = BITS(inst, 20, 22);
2364 inst_cream->op2 = BITS(inst, 5, 7);
2279 2365
2280 if (CHECK_RM )
2281 inst_base->load_r15 = 1;
2282 return inst_base; 2366 return inst_base;
2283} 2367}
2368ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index)
2369{
2370 return INTERPRETER_TRANSLATE(smlad)(inst, index);
2371}
2372ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index)
2373{
2374 return INTERPRETER_TRANSLATE(smlad)(inst, index);
2375}
2376ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index)
2377{
2378 return INTERPRETER_TRANSLATE(smlad)(inst, index);
2379}
2380
2284ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) 2381ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2285{ 2382{
2286 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); 2383 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
@@ -2301,15 +2398,82 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2301 inst_base->load_r15 = 1; 2398 inst_base->load_r15 = 1;
2302 return inst_base; 2399 return inst_base;
2303} 2400}
2401
2304ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } 2402ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
2305ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); } 2403
2306ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); } 2404ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
2307ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSD"); } 2405{
2308ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSLD"); } 2406 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2309ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLA"); } 2407 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
2310ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLS"); } 2408
2311ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMUL"); } 2409 inst_base->cond = BITS(inst, 28, 31);
2312ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); } 2410 inst_base->idx = index;
2411 inst_base->br = NON_BRANCH;
2412 inst_base->load_r15 = 0;
2413
2414 inst_cream->Ra = BITS(inst, 12, 15);
2415 inst_cream->Rm = BITS(inst, 8, 11);
2416 inst_cream->Rn = BITS(inst, 0, 3);
2417 inst_cream->Rd = BITS(inst, 16, 19);
2418 inst_cream->m = BIT(inst, 6);
2419
2420 return inst_base;
2421}
2422
2423ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
2424{
2425 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
2426 smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
2427
2428 inst_base->cond = BITS(inst, 28, 31);
2429 inst_base->idx = index;
2430 inst_base->br = NON_BRANCH;
2431 inst_base->load_r15 = 0;
2432
2433 inst_cream->Rm = BITS(inst, 8, 11);
2434 inst_cream->Rn = BITS(inst, 0, 3);
2435 inst_cream->RdLo = BITS(inst, 12, 15);
2436 inst_cream->RdHi = BITS(inst, 16, 19);
2437 inst_cream->swap = BIT(inst, 5);
2438 inst_cream->op1 = BITS(inst, 20, 22);
2439 inst_cream->op2 = BITS(inst, 5, 7);
2440
2441 return inst_base;
2442}
2443ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index)
2444{
2445 return INTERPRETER_TRANSLATE(smlald)(inst, index);
2446}
2447
2448ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index)
2449{
2450 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2451 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
2452
2453 inst_base->cond = BITS(inst, 28, 31);
2454 inst_base->idx = index;
2455 inst_base->br = NON_BRANCH;
2456 inst_base->load_r15 = 0;
2457
2458 inst_cream->m = BIT(inst, 5);
2459 inst_cream->Ra = BITS(inst, 12, 15);
2460 inst_cream->Rm = BITS(inst, 8, 11);
2461 inst_cream->Rn = BITS(inst, 0, 3);
2462 inst_cream->Rd = BITS(inst, 16, 19);
2463 inst_cream->op1 = BITS(inst, 20, 22);
2464 inst_cream->op2 = BITS(inst, 5, 7);
2465
2466 return inst_base;
2467}
2468ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index)
2469{
2470 return INTERPRETER_TRANSLATE(smmla)(inst, index);
2471}
2472ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index)
2473{
2474 return INTERPRETER_TRANSLATE(smmla)(inst, index);
2475}
2476
2313ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) 2477ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
2314{ 2478{
2315 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); 2479 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
@@ -2372,7 +2536,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
2372 inst_base->load_r15 = 1; 2536 inst_base->load_r15 = 1;
2373 return inst_base; 2537 return inst_base;
2374} 2538}
2375ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); }
2376ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); } 2539ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); }
2377ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) 2540ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
2378{ 2541{
@@ -2408,15 +2571,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index)
2408 2571
2409 return inst_base; 2572 return inst_base;
2410} 2573}
2411ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } 2574
2412ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
2413{
2414 return INTERPRETER_TRANSLATE(sadd16)(inst, index);
2415}
2416ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
2417{
2418 return INTERPRETER_TRANSLATE(sadd16)(inst, index);
2419}
2420ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) 2575ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
2421{ 2576{
2422 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); 2577 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
@@ -2566,37 +2721,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
2566} 2721}
2567ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) 2722ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
2568{ 2723{
2569 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2724 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
2570 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2725 generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
2571 2726
2572 inst_base->cond = BITS(inst, 28, 31); 2727 inst_base->cond = BITS(inst, 28, 31);
2573 inst_base->idx = index; 2728 inst_base->idx = index;
2574 inst_base->br = NON_BRANCH; 2729 inst_base->br = NON_BRANCH;
2575 2730
2576 inst_cream->inst = inst; 2731 inst_cream->Rn = BITS(inst, 16, 19);
2577 inst_cream->get_addr = get_calc_addr_op(inst); 2732 inst_cream->Rd = BITS(inst, 12, 15);
2733 inst_cream->Rm = BITS(inst, 0, 3);
2578 2734
2579 if (BITS(inst, 12, 15) == 15) {
2580 inst_base->br = INDIRECT_BRANCH;
2581 }
2582 return inst_base; 2735 return inst_base;
2583} 2736}
2584ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) 2737ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
2585{ 2738{
2586 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); 2739 return INTERPRETER_TRANSLATE(strex)(inst, index);
2587 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 2740}
2588 2741ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index)
2589 inst_base->cond = BITS(inst, 28, 31); 2742{
2590 inst_base->idx = index; 2743 return INTERPRETER_TRANSLATE(strex)(inst, index);
2591 inst_base->br = NON_BRANCH; 2744}
2592 2745ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index)
2593 inst_cream->inst = inst; 2746{
2594 inst_cream->get_addr = get_calc_addr_op(inst); 2747 return INTERPRETER_TRANSLATE(strex)(inst, index);
2595
2596 if (BITS(inst, 12, 15) == 15) {
2597 inst_base->br = INDIRECT_BRANCH;
2598 }
2599 return inst_base;
2600} 2748}
2601ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) 2749ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
2602{ 2750{
@@ -2723,7 +2871,29 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
2723 2871
2724 return inst_base; 2872 return inst_base;
2725} 2873}
2726ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); } 2874
2875ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index)
2876{
2877 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
2878 sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
2879
2880 inst_base->cond = BITS(inst, 28, 31);
2881 inst_base->idx = index;
2882 inst_base->br = NON_BRANCH;
2883 inst_base->load_r15 = 0;
2884
2885 inst_cream->Rm = BITS(inst, 0, 3);
2886 inst_cream->Rn = BITS(inst, 16, 19);
2887 inst_cream->Rd = BITS(inst, 12, 15);
2888 inst_cream->rotate = BITS(inst, 10, 11);
2889
2890 return inst_base;
2891}
2892ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index)
2893{
2894 return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
2895}
2896
2727ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ 2897ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
2728 LOG_WARNING(Core_ARM11, "SXTAH untested"); 2898 LOG_WARNING(Core_ARM11, "SXTAH untested");
2729 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); 2899 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
@@ -2741,7 +2911,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
2741 2911
2742 return inst_base; 2912 return inst_base;
2743} 2913}
2744ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); } 2914
2745ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) 2915ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
2746{ 2916{
2747 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); 2917 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
@@ -3276,6 +3446,11 @@ const transop_fp_t arm_instruction_trans[] = {
3276 INTERPRETER_TRANSLATE(ldc), 3446 INTERPRETER_TRANSLATE(ldc),
3277 INTERPRETER_TRANSLATE(swi), 3447 INTERPRETER_TRANSLATE(swi),
3278 INTERPRETER_TRANSLATE(bbl), 3448 INTERPRETER_TRANSLATE(bbl),
3449 INTERPRETER_TRANSLATE(ldrexd),
3450 INTERPRETER_TRANSLATE(strexd),
3451 INTERPRETER_TRANSLATE(ldrexh),
3452 INTERPRETER_TRANSLATE(strexh),
3453
3279 // All the thumb instructions should be placed the end of table 3454 // All the thumb instructions should be placed the end of table
3280 INTERPRETER_TRANSLATE(b_2_thumb), 3455 INTERPRETER_TRANSLATE(b_2_thumb),
3281 INTERPRETER_TRANSLATE(b_cond_thumb), 3456 INTERPRETER_TRANSLATE(b_cond_thumb),
@@ -3314,7 +3489,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
3314 tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); 3489 tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
3315 if(ret == t_branch){ 3490 if(ret == t_branch){
3316 // TODO: FIXME, endian should be judged 3491 // TODO: FIXME, endian should be judged
3317 uint32 tinstr; 3492 u32 tinstr;
3318 if((addr & 0x3) != 0) 3493 if((addr & 0x3) != 0)
3319 tinstr = inst >> 16; 3494 tinstr = inst >> 16;
3320 else 3495 else
@@ -3327,7 +3502,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
3327 case 26: 3502 case 26:
3328 case 27: 3503 case 27:
3329 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ 3504 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
3330 uint32 cond = (tinstr & 0x0F00) >> 8; 3505 u32 cond = (tinstr & 0x0F00) >> 8;
3331 inst_index = table_length - 4; 3506 inst_index = table_length - 4;
3332 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3507 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3333 } else { 3508 } else {
@@ -3364,8 +3539,6 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
3364 return ret; 3539 return ret;
3365} 3540}
3366 3541
3367unsigned int *InstLength;
3368
3369enum { 3542enum {
3370 KEEP_GOING, 3543 KEEP_GOING,
3371 FETCH_EXCEPTION 3544 FETCH_EXCEPTION
@@ -3450,28 +3623,6 @@ translated:
3450 3623
3451#define LOG_IN_CLR skyeye_printf_in_color 3624#define LOG_IN_CLR skyeye_printf_in_color
3452 3625
3453int cmp(const void *x, const void *y) {
3454 return *(unsigned long long int*)x - *(unsigned long long int *)y;
3455}
3456
3457void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) {
3458 int array_size = size / sizeof(void *);
3459 unsigned long long int *InstLabel = new unsigned long long int[array_size];
3460 memcpy(InstLabel, ptr, size);
3461 qsort(InstLabel, array_size, sizeof(void *), cmp);
3462 InstLength = new unsigned int[array_size - 4];
3463 for (int i = 0; i < array_size - 4; i++) {
3464 for (int j = 0; j < array_size; j++) {
3465 if (ptr[i] == InstLabel[j]) {
3466 InstLength[i] = InstLabel[j + 1] - InstLabel[j];
3467 break;
3468 }
3469 }
3470 }
3471 for (int i = 0; i < array_size - 4; i++)
3472 LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]);
3473}
3474
3475int clz(unsigned int x) { 3626int clz(unsigned int x) {
3476 int n; 3627 int n;
3477 if (x == 0) return (32); 3628 if (x == 0) return (32);
@@ -3496,6 +3647,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
3496 #define CRm inst_cream->crm 3647 #define CRm inst_cream->crm
3497 #define CP15_REG(n) cpu->CP15[CP15(n)] 3648 #define CP15_REG(n) cpu->CP15[CP15(n)]
3498 #define RD cpu->Reg[inst_cream->Rd] 3649 #define RD cpu->Reg[inst_cream->Rd]
3650 #define RD2 cpu->Reg[inst_cream->Rd + 1]
3499 #define RN cpu->Reg[inst_cream->Rn] 3651 #define RN cpu->Reg[inst_cream->Rn]
3500 #define RM cpu->Reg[inst_cream->Rm] 3652 #define RM cpu->Reg[inst_cream->Rm]
3501 #define RS cpu->Reg[inst_cream->Rs] 3653 #define RS cpu->Reg[inst_cream->Rs]
@@ -3707,14 +3859,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
3707 case 182: goto LDC_INST; \ 3859 case 182: goto LDC_INST; \
3708 case 183: goto SWI_INST; \ 3860 case 183: goto SWI_INST; \
3709 case 184: goto BBL_INST; \ 3861 case 184: goto BBL_INST; \
3710 case 185: goto B_2_THUMB ; \ 3862 case 185: goto LDREXD_INST; \
3711 case 186: goto B_COND_THUMB ; \ 3863 case 186: goto STREXD_INST; \
3712 case 187: goto BL_1_THUMB ; \ 3864 case 187: goto LDREXH_INST; \
3713 case 188: goto BL_2_THUMB ; \ 3865 case 188: goto STREXH_INST; \
3714 case 189: goto BLX_1_THUMB ; \ 3866 case 189: goto B_2_THUMB ; \
3715 case 190: goto DISPATCH; \ 3867 case 190: goto B_COND_THUMB ; \
3716 case 191: goto INIT_INST_LENGTH; \ 3868 case 191: goto BL_1_THUMB ; \
3717 case 192: goto END; \ 3869 case 192: goto BL_2_THUMB ; \
3870 case 193: goto BLX_1_THUMB ; \
3871 case 194: goto DISPATCH; \
3872 case 195: goto INIT_INST_LENGTH; \
3873 case 196: goto END; \
3718 } 3874 }
3719#endif 3875#endif
3720 3876
@@ -3775,8 +3931,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
3775 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, 3931 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
3776 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, 3932 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
3777 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, 3933 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
3778 &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB, 3934 &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&LDREXD_INST,
3779 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END 3935 &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST,&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
3936 &&INIT_INST_LENGTH,&&END
3780 }; 3937 };
3781#endif 3938#endif
3782 arm_inst * inst_base; 3939 arm_inst * inst_base;
@@ -3976,22 +4133,35 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
3976 INC_PC(sizeof(blx_inst)); 4133 INC_PC(sizeof(blx_inst));
3977 goto DISPATCH; 4134 goto DISPATCH;
3978 } 4135 }
4136
3979 BX_INST: 4137 BX_INST:
4138 BXJ_INST:
3980 { 4139 {
3981 bx_inst *inst_cream = (bx_inst *)inst_base->component; 4140 // Note that only the 'fail' case of BXJ is emulated. This is because
3982 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4141 // the facilities for Jazelle emulation are not implemented.
4142 //
4143 // According to the ARM documentation on BXJ, if setting the J bit in the APSR
4144 // fails, then BXJ functions identically like a regular BX instruction.
4145 //
4146 // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
4147
4148 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4149 bx_inst* const inst_cream = (bx_inst*)inst_base->component;
4150
3983 if (inst_cream->Rm == 15) 4151 if (inst_cream->Rm == 15)
3984 LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); 4152 LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
4153
3985 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; 4154 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
3986 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; 4155 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
3987 INC_PC(sizeof(bx_inst)); 4156 INC_PC(sizeof(bx_inst));
3988 goto DISPATCH; 4157 goto DISPATCH;
3989 } 4158 }
4159
3990 cpu->Reg[15] += GET_INST_SIZE(cpu); 4160 cpu->Reg[15] += GET_INST_SIZE(cpu);
3991 INC_PC(sizeof(bx_inst)); 4161 INC_PC(sizeof(bx_inst));
3992 goto DISPATCH; 4162 goto DISPATCH;
3993 } 4163 }
3994 BXJ_INST: 4164
3995 CDP_INST: 4165 CDP_INST:
3996 { 4166 {
3997 cdp_inst *inst_cream = (cdp_inst *)inst_base->component; 4167 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -4377,45 +4547,84 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4377 4547
4378 LDREX_INST: 4548 LDREX_INST:
4379 { 4549 {
4380 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4550 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4381 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4551 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4382 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 4552 unsigned int read_addr = RN;
4383 4553
4384 unsigned int value = Memory::Read32(addr); 4554 add_exclusive_addr(cpu, read_addr);
4385
4386 add_exclusive_addr(cpu, addr);
4387 cpu->exclusive_state = 1; 4555 cpu->exclusive_state = 1;
4388 4556
4389 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4557 RD = Memory::Read32(read_addr);
4390 if (BITS(inst_cream->inst, 12, 15) == 15) { 4558 if (inst_cream->Rd == 15) {
4391 INC_PC(sizeof(ldst_inst)); 4559 INC_PC(sizeof(generic_arm_inst));
4392 goto DISPATCH; 4560 goto DISPATCH;
4393 } 4561 }
4394 } 4562 }
4395 cpu->Reg[15] += GET_INST_SIZE(cpu); 4563 cpu->Reg[15] += GET_INST_SIZE(cpu);
4396 INC_PC(sizeof(ldst_inst)); 4564 INC_PC(sizeof(generic_arm_inst));
4397 FETCH_INST; 4565 FETCH_INST;
4398 GOTO_NEXT_INST; 4566 GOTO_NEXT_INST;
4399 } 4567 }
4400 LDREXB_INST: 4568 LDREXB_INST:
4401 { 4569 {
4402 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4570 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4403 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4571 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4404 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 4572 unsigned int read_addr = RN;
4405 4573
4406 unsigned int value = Memory::Read8(addr); 4574 add_exclusive_addr(cpu, read_addr);
4575 cpu->exclusive_state = 1;
4576
4577 RD = Memory::Read8(read_addr);
4578 if (inst_cream->Rd == 15) {
4579 INC_PC(sizeof(generic_arm_inst));
4580 goto DISPATCH;
4581 }
4582 }
4583 cpu->Reg[15] += GET_INST_SIZE(cpu);
4584 INC_PC(sizeof(generic_arm_inst));
4585 FETCH_INST;
4586 GOTO_NEXT_INST;
4587 }
4588 LDREXH_INST:
4589 {
4590 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4591 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4592 unsigned int read_addr = RN;
4407 4593
4408 add_exclusive_addr(cpu, addr); 4594 add_exclusive_addr(cpu, read_addr);
4409 cpu->exclusive_state = 1; 4595 cpu->exclusive_state = 1;
4410 4596
4411 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4597 RD = Memory::Read16(read_addr);
4412 if (BITS(inst_cream->inst, 12, 15) == 15) { 4598 if (inst_cream->Rd == 15) {
4413 INC_PC(sizeof(ldst_inst)); 4599 INC_PC(sizeof(generic_arm_inst));
4414 goto DISPATCH; 4600 goto DISPATCH;
4415 } 4601 }
4416 } 4602 }
4417 cpu->Reg[15] += GET_INST_SIZE(cpu); 4603 cpu->Reg[15] += GET_INST_SIZE(cpu);
4418 INC_PC(sizeof(ldst_inst)); 4604 INC_PC(sizeof(generic_arm_inst));
4605 FETCH_INST;
4606 GOTO_NEXT_INST;
4607 }
4608 LDREXD_INST:
4609 {
4610 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4611 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4612 unsigned int read_addr = RN;
4613
4614 add_exclusive_addr(cpu, read_addr);
4615 cpu->exclusive_state = 1;
4616 // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive?
4617
4618 RD = Memory::Read32(read_addr);
4619 RD2 = Memory::Read32(read_addr + 4);
4620
4621 if (inst_cream->Rd == 15) {
4622 INC_PC(sizeof(generic_arm_inst));
4623 goto DISPATCH;
4624 }
4625 }
4626 cpu->Reg[15] += GET_INST_SIZE(cpu);
4627 INC_PC(sizeof(generic_arm_inst));
4419 FETCH_INST; 4628 FETCH_INST;
4420 GOTO_NEXT_INST; 4629 GOTO_NEXT_INST;
4421 } 4630 }
@@ -4877,6 +5086,78 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4877 } 5086 }
4878 5087
4879 QADD_INST: 5088 QADD_INST:
5089 QDADD_INST:
5090 QDSUB_INST:
5091 QSUB_INST:
5092 {
5093 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5094 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5095 const u8 op1 = inst_cream->op1;
5096 const u32 rm_val = RM;
5097 const u32 rn_val = RN;
5098
5099 u32 result = 0;
5100
5101 // QADD
5102 if (op1 == 0x00) {
5103 result = rm_val + rn_val;
5104
5105 if (AddOverflow(rm_val, rn_val, result)) {
5106 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
5107 cpu->Cpsr |= (1 << 27);
5108 }
5109 }
5110 // QSUB
5111 else if (op1 == 0x01) {
5112 result = rm_val - rn_val;
5113
5114 if (SubOverflow(rm_val, rn_val, result)) {
5115 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
5116 cpu->Cpsr |= (1 << 27);
5117 }
5118 }
5119 // QDADD
5120 else if (op1 == 0x02) {
5121 u32 mul = (rn_val * 2);
5122
5123 if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
5124 mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
5125 cpu->Cpsr |= (1 << 27);
5126 }
5127
5128 result = mul + rm_val;
5129
5130 if (AddOverflow(rm_val, mul, result)) {
5131 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
5132 cpu->Cpsr |= (1 << 27);
5133 }
5134 }
5135 // QDSUB
5136 else if (op1 == 0x03) {
5137 u32 mul = (rn_val * 2);
5138
5139 if (AddOverflow(rn_val, rn_val, mul)) {
5140 mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
5141 cpu->Cpsr |= (1 << 27);
5142 }
5143
5144 result = rm_val - mul;
5145
5146 if (SubOverflow(rm_val, mul, result)) {
5147 result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
5148 cpu->Cpsr |= (1 << 27);
5149 }
5150 }
5151
5152 RD = result;
5153 }
5154
5155 cpu->Reg[15] += GET_INST_SIZE(cpu);
5156 INC_PC(sizeof(generic_arm_inst));
5157 FETCH_INST;
5158 GOTO_NEXT_INST;
5159 }
5160
4880 QADD8_INST: 5161 QADD8_INST:
4881 QADD16_INST: 5162 QADD16_INST:
4882 QADDSUBX_INST: 5163 QADDSUBX_INST:
@@ -4939,42 +5220,39 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4939 GOTO_NEXT_INST; 5220 GOTO_NEXT_INST;
4940 } 5221 }
4941 5222
4942 QDADD_INST:
4943 QDSUB_INST:
4944 QSUB_INST:
4945 REV_INST: 5223 REV_INST:
4946 {
4947 rev_inst *inst_cream = (rev_inst *)inst_base->component;
4948 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4949 RD = ((RM & 0xff) << 24) |
4950 (((RM >> 8) & 0xff) << 16) |
4951 (((RM >> 16) & 0xff) << 8) |
4952 ((RM >> 24) & 0xff);
4953 if (inst_cream->Rm == 15) {
4954 LOG_ERROR(Core_ARM11, "invalid operand for REV");
4955 CITRA_IGNORE_EXIT(-1);
4956 }
4957 }
4958 cpu->Reg[15] += GET_INST_SIZE(cpu);
4959 INC_PC(sizeof(rev_inst));
4960 FETCH_INST;
4961 GOTO_NEXT_INST;
4962 }
4963 REV16_INST: 5224 REV16_INST:
5225 REVSH_INST:
4964 { 5226 {
4965 rev_inst *inst_cream = (rev_inst *)inst_base->component; 5227
4966 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5228 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4967 RD = (BITS(RM, 0, 7) << 8) | 5229 rev_inst* const inst_cream = (rev_inst*)inst_base->component;
4968 BITS(RM, 8, 15) | 5230
4969 (BITS(RM, 16, 23) << 24) | 5231 const u8 op1 = inst_cream->op1;
4970 (BITS(RM, 24, 31) << 16); 5232 const u8 op2 = inst_cream->op2;
5233
5234 // REV
5235 if (op1 == 0x03 && op2 == 0x01) {
5236 RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF);
5237 }
5238 // REV16
5239 else if (op1 == 0x03 && op2 == 0x05) {
5240 RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8);
5241 }
5242 // REVSH
5243 else if (op1 == 0x07 && op2 == 0x05) {
5244 RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
5245 if (RD & 0x8000)
5246 RD |= 0xffff0000;
5247 }
4971 } 5248 }
5249
4972 cpu->Reg[15] += GET_INST_SIZE(cpu); 5250 cpu->Reg[15] += GET_INST_SIZE(cpu);
4973 INC_PC(sizeof(rev_inst)); 5251 INC_PC(sizeof(rev_inst));
4974 FETCH_INST; 5252 FETCH_INST;
4975 GOTO_NEXT_INST; 5253 GOTO_NEXT_INST;
4976 } 5254 }
4977 REVSH_INST: 5255
4978 RFE_INST: 5256 RFE_INST:
4979 RSB_INST: 5257 RSB_INST:
4980 { 5258 {
@@ -5039,6 +5317,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5039 } 5317 }
5040 5318
5041 SADD8_INST: 5319 SADD8_INST:
5320 SSUB8_INST:
5042 SADD16_INST: 5321 SADD16_INST:
5043 SADDSUBX_INST: 5322 SADDSUBX_INST:
5044 SSUBADDX_INST: 5323 SSUBADDX_INST:
@@ -5046,52 +5325,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5046 { 5325 {
5047 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5326 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5048 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; 5327 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5328 const u8 op2 = inst_cream->op2;
5049 5329
5050 const s16 rn_lo = (RN & 0xFFFF); 5330 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
5051 const s16 rn_hi = ((RN >> 16) & 0xFFFF); 5331 const s16 rn_lo = (RN & 0xFFFF);
5052 const s16 rm_lo = (RM & 0xFFFF); 5332 const s16 rn_hi = ((RN >> 16) & 0xFFFF);
5053 const s16 rm_hi = ((RM >> 16) & 0xFFFF); 5333 const s16 rm_lo = (RM & 0xFFFF);
5334 const s16 rm_hi = ((RM >> 16) & 0xFFFF);
5054 5335
5055 s32 lo_result = 0; 5336 s32 lo_result = 0;
5056 s32 hi_result = 0; 5337 s32 hi_result = 0;
5057 5338
5058 // SADD16 5339 // SADD16
5059 if (inst_cream->op2 == 0x00) { 5340 if (inst_cream->op2 == 0x00) {
5060 lo_result = (rn_lo + rm_lo); 5341 lo_result = (rn_lo + rm_lo);
5061 hi_result = (rn_hi + rm_hi); 5342 hi_result = (rn_hi + rm_hi);
5062 } 5343 }
5063 // SASX 5344 // SASX
5064 else if (inst_cream->op2 == 0x01) { 5345 else if (op2 == 0x01) {
5065 lo_result = (rn_lo - rm_hi); 5346 lo_result = (rn_lo - rm_hi);
5066 hi_result = (rn_hi + rm_lo); 5347 hi_result = (rn_hi + rm_lo);
5067 } 5348 }
5068 // SSAX 5349 // SSAX
5069 else if (inst_cream->op2 == 0x02) { 5350 else if (op2 == 0x02) {
5070 lo_result = (rn_lo + rm_hi); 5351 lo_result = (rn_lo + rm_hi);
5071 hi_result = (rn_hi - rm_lo); 5352 hi_result = (rn_hi - rm_lo);
5072 } 5353 }
5073 // SSUB16 5354 // SSUB16
5074 else if (inst_cream->op2 == 0x03) { 5355 else if (op2 == 0x03) {
5075 lo_result = (rn_lo - rm_lo); 5356 lo_result = (rn_lo - rm_lo);
5076 hi_result = (rn_hi - rm_hi); 5357 hi_result = (rn_hi - rm_hi);
5077 } 5358 }
5078 5359
5079 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); 5360 RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5080 5361
5081 if (lo_result >= 0) { 5362 if (lo_result >= 0) {
5082 cpu->Cpsr |= (1 << 16); 5363 cpu->Cpsr |= (1 << 16);
5083 cpu->Cpsr |= (1 << 17); 5364 cpu->Cpsr |= (1 << 17);
5084 } else { 5365 } else {
5085 cpu->Cpsr &= ~(1 << 16); 5366 cpu->Cpsr &= ~(1 << 16);
5086 cpu->Cpsr &= ~(1 << 17); 5367 cpu->Cpsr &= ~(1 << 17);
5368 }
5369
5370 if (hi_result >= 0) {
5371 cpu->Cpsr |= (1 << 18);
5372 cpu->Cpsr |= (1 << 19);
5373 } else {
5374 cpu->Cpsr &= ~(1 << 18);
5375 cpu->Cpsr &= ~(1 << 19);
5376 }
5087 } 5377 }
5378 else if (op2 == 0x04 || op2 == 0x07) {
5379 s32 lo_val1, lo_val2;
5380 s32 hi_val1, hi_val2;
5088 5381
5089 if (hi_result >= 0) { 5382 // SADD8
5090 cpu->Cpsr |= (1 << 18); 5383 if (op2 == 0x04) {
5091 cpu->Cpsr |= (1 << 19); 5384 lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
5092 } else { 5385 lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
5093 cpu->Cpsr &= ~(1 << 18); 5386 hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
5094 cpu->Cpsr &= ~(1 << 19); 5387 hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
5388 }
5389 // SSUB8
5390 else {
5391 lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
5392 lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
5393 hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
5394 hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
5395 }
5396
5397 RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
5398
5399 if (lo_val1 >= 0)
5400 cpu->Cpsr |= (1 << 16);
5401 else
5402 cpu->Cpsr &= ~(1 << 16);
5403
5404 if (lo_val2 >= 0)
5405 cpu->Cpsr |= (1 << 17);
5406 else
5407 cpu->Cpsr &= ~(1 << 17);
5408
5409 if (hi_val1 >= 0)
5410 cpu->Cpsr |= (1 << 18);
5411 else
5412 cpu->Cpsr &= ~(1 << 18);
5413
5414 if (hi_val2 >= 0)
5415 cpu->Cpsr |= (1 << 19);
5416 else
5417 cpu->Cpsr &= ~(1 << 19);
5095 } 5418 }
5096 } 5419 }
5097 5420
@@ -5176,12 +5499,79 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5176 } 5499 }
5177 5500
5178 SETEND_INST: 5501 SETEND_INST:
5179 SHADD16_INST: 5502
5180 SHADD8_INST: 5503 SHADD8_INST:
5504 SHADD16_INST:
5181 SHADDSUBX_INST: 5505 SHADDSUBX_INST:
5182 SHSUB16_INST:
5183 SHSUB8_INST: 5506 SHSUB8_INST:
5507 SHSUB16_INST:
5184 SHSUBADDX_INST: 5508 SHSUBADDX_INST:
5509 {
5510 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5511 generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
5512
5513 const u8 op2 = inst_cream->op2;
5514 const u32 rm_val = RM;
5515 const u32 rn_val = RN;
5516
5517 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
5518 s32 lo_result = 0;
5519 s32 hi_result = 0;
5520
5521 // SHADD16
5522 if (op2 == 0x00) {
5523 lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
5524 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
5525 }
5526 // SHASX
5527 else if (op2 == 0x01) {
5528 lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
5529 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
5530 }
5531 // SHSAX
5532 else if (op2 == 0x02) {
5533 lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
5534 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
5535 }
5536 // SHSUB16
5537 else if (op2 == 0x03) {
5538 lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
5539 hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
5540 }
5541
5542 RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
5543 }
5544 else if (op2 == 0x04 || op2 == 0x07) {
5545 s16 lo_val1, lo_val2;
5546 s16 hi_val1, hi_val2;
5547
5548 // SHADD8
5549 if (op2 == 0x04) {
5550 lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
5551 lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
5552
5553 hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
5554 hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
5555 }
5556 // SHSUB8
5557 else {
5558 lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
5559 lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
5560
5561 hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
5562 hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
5563 }
5564
5565 RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24);
5566 }
5567 }
5568
5569 cpu->Reg[15] += GET_INST_SIZE(cpu);
5570 INC_PC(sizeof(generic_arm_inst));
5571 FETCH_INST;
5572 GOTO_NEXT_INST;
5573 }
5574
5185 SMLA_INST: 5575 SMLA_INST:
5186 { 5576 {
5187 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5577 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -5198,51 +5588,67 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5198 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); 5588 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5199 RD = operand1 * operand2 + RN; 5589 RD = operand1 * operand2 + RN;
5200 5590
5201 // TODO: FIXME: UPDATE Q FLAGS 5591 if (AddOverflow(operand1 * operand2, RN, RD))
5592 cpu->Cpsr |= (1 << 27);
5202 } 5593 }
5203 cpu->Reg[15] += GET_INST_SIZE(cpu); 5594 cpu->Reg[15] += GET_INST_SIZE(cpu);
5204 INC_PC(sizeof(smla_inst)); 5595 INC_PC(sizeof(smla_inst));
5205 FETCH_INST; 5596 FETCH_INST;
5206 GOTO_NEXT_INST; 5597 GOTO_NEXT_INST;
5207 } 5598 }
5599
5208 SMLAD_INST: 5600 SMLAD_INST:
5601 SMLSD_INST:
5602 SMUAD_INST:
5603 SMUSD_INST:
5209 { 5604 {
5210 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5605 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5211 smlad_inst *inst_cream = (smlad_inst *)inst_base->component; 5606 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
5212 long long int rm = cpu->Reg[inst_cream->Rm]; 5607 const u8 op2 = inst_cream->op2;
5213 long long int rn = cpu->Reg[inst_cream->Rn];
5214 long long int ra = cpu->Reg[inst_cream->Ra];
5215 5608
5216 // See SMUAD 5609 u32 rm_val = cpu->Reg[inst_cream->Rm];
5217 if(inst_cream->Ra == 15) 5610 const u32 rn_val = cpu->Reg[inst_cream->Rn];
5218 CITRA_IGNORE_EXIT(-1);
5219 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
5220 int half_rn, half_operand2;
5221 5611
5222 half_rn = rn & 0xFFFF; 5612 if (inst_cream->m)
5223 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; 5613 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5224 5614
5225 half_operand2 = operand2 & 0xFFFF; 5615 const s16 rm_lo = (rm_val & 0xFFFF);
5226 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; 5616 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
5617 const s16 rn_lo = (rn_val & 0xFFFF);
5618 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
5227 5619
5228 long long int product1 = half_rn * half_operand2; 5620 const u32 product1 = (rn_lo * rm_lo);
5621 const u32 product2 = (rn_hi * rm_hi);
5229 5622
5230 half_rn = (rn & 0xFFFF0000) >> 16; 5623 // SMUAD and SMLAD
5231 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; 5624 if (BIT(op2, 1) == 0) {
5625 RD = (product1 + product2);
5232 5626
5233 half_operand2 = (operand2 & 0xFFFF0000) >> 16; 5627 if (inst_cream->Ra != 15) {
5234 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; 5628 RD += cpu->Reg[inst_cream->Ra];
5235 5629
5236 long long int product2 = half_rn * half_operand2; 5630 if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
5631 cpu->Cpsr |= (1 << 27);
5632 }
5237 5633
5238 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; 5634 if (ARMul_AddOverflowQ(product1, product2))
5239 long long int result = product1 + product2 + signed_ra; 5635 cpu->Cpsr |= (1 << 27);
5240 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; 5636 }
5637 // SMUSD and SMLSD
5638 else {
5639 RD = (product1 - product2);
5640
5641 if (inst_cream->Ra != 15) {
5642 RD += cpu->Reg[inst_cream->Ra];
5241 5643
5242 // TODO: FIXME should check Signed overflow 5644 if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
5645 cpu->Cpsr |= (1 << 27);
5646 }
5647 }
5243 } 5648 }
5649
5244 cpu->Reg[15] += GET_INST_SIZE(cpu); 5650 cpu->Reg[15] += GET_INST_SIZE(cpu);
5245 INC_PC(sizeof(umlal_inst)); 5651 INC_PC(sizeof(smlad_inst));
5246 FETCH_INST; 5652 FETCH_INST;
5247 GOTO_NEXT_INST; 5653 GOTO_NEXT_INST;
5248 } 5654 }
@@ -5275,15 +5681,108 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5275 FETCH_INST; 5681 FETCH_INST;
5276 GOTO_NEXT_INST; 5682 GOTO_NEXT_INST;
5277 } 5683 }
5684
5278 SMLALXY_INST: 5685 SMLALXY_INST:
5279 SMLALD_INST: 5686
5280 SMLAW_INST: 5687 SMLAW_INST:
5281 SMLSD_INST: 5688 {
5689 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5690 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
5691
5692 const u32 rm_val = RM;
5693 const u32 rn_val = RN;
5694 const u32 ra_val = cpu->Reg[inst_cream->Ra];
5695 const bool high = (inst_cream->m == 1);
5696
5697 const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
5698 const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
5699
5700 RD = (result & (0xFFFFFFFFFFFFFFFFLL >> 15)) >> 16;
5701
5702 if ((result >> 16) != (s32)RD)
5703 cpu->Cpsr |= (1 << 27);
5704 }
5705
5706 cpu->Reg[15] += GET_INST_SIZE(cpu);
5707 INC_PC(sizeof(smlad_inst));
5708 FETCH_INST;
5709 GOTO_NEXT_INST;
5710 }
5711
5712 SMLALD_INST:
5282 SMLSLD_INST: 5713 SMLSLD_INST:
5714 {
5715 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5716 smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
5717
5718 const bool do_swap = (inst_cream->swap == 1);
5719 const u32 rdlo_val = RDLO;
5720 const u32 rdhi_val = RDHI;
5721 const u32 rn_val = RN;
5722 u32 rm_val = RM;
5723
5724 if (do_swap)
5725 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5726
5727 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
5728 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
5729 s64 result;
5730
5731 // SMLALD
5732 if (BIT(inst_cream->op2, 1) == 0) {
5733 result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
5734 }
5735 // SMLSLD
5736 else {
5737 result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
5738 }
5739
5740 RDLO = (result & 0xFFFFFFFF);
5741 RDHI = ((result >> 32) & 0xFFFFFFFF);
5742 }
5743
5744 cpu->Reg[15] += GET_INST_SIZE(cpu);
5745 INC_PC(sizeof(smlald_inst));
5746 FETCH_INST;
5747 GOTO_NEXT_INST;
5748 }
5749
5283 SMMLA_INST: 5750 SMMLA_INST:
5284 SMMLS_INST: 5751 SMMLS_INST:
5285 SMMUL_INST: 5752 SMMUL_INST:
5286 SMUAD_INST: 5753 {
5754 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5755 smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
5756
5757 const u32 rm_val = RM;
5758 const u32 rn_val = RN;
5759 const bool do_round = (inst_cream->m == 1);
5760
5761 // Assume SMMUL by default.
5762 s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
5763
5764 if (inst_cream->Ra != 15) {
5765 const u32 ra_val = cpu->Reg[inst_cream->Ra];
5766
5767 // SMMLA, otherwise SMMLS
5768 if (BIT(inst_cream->op2, 1) == 0)
5769 result += ((s64)ra_val << 32);
5770 else
5771 result = ((s64)ra_val << 32) - result;
5772 }
5773
5774 if (do_round)
5775 result += 0x80000000;
5776
5777 RD = ((result >> 32) & 0xFFFFFFFF);
5778 }
5779
5780 cpu->Reg[15] += GET_INST_SIZE(cpu);
5781 INC_PC(sizeof(smlad_inst));
5782 FETCH_INST;
5783 GOTO_NEXT_INST;
5784 }
5785
5287 SMUL_INST: 5786 SMUL_INST:
5288 { 5787 {
5289 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5788 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -5351,8 +5850,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5351 GOTO_NEXT_INST; 5850 GOTO_NEXT_INST;
5352 } 5851 }
5353 5852
5354 SMUSD_INST:
5355 SRS_INST: 5853 SRS_INST:
5854
5356 SSAT_INST: 5855 SSAT_INST:
5357 { 5856 {
5358 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5857 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
@@ -5407,7 +5906,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5407 FETCH_INST; 5906 FETCH_INST;
5408 GOTO_NEXT_INST; 5907 GOTO_NEXT_INST;
5409 } 5908 }
5410 SSUB8_INST: 5909
5411 STC_INST: 5910 STC_INST:
5412 { 5911 {
5413 // Instruction not implemented 5912 // Instruction not implemented
@@ -5580,46 +6079,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5580 } 6079 }
5581 STREX_INST: 6080 STREX_INST:
5582 { 6081 {
5583 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 6082 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6083
5584 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6084 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5585 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 6085 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
5586 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
5587 6086
5588 int dest_reg = BITS(inst_cream->inst, 12, 15); 6087 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
5589 if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ 6088 remove_exclusive(cpu, write_addr);
5590 remove_exclusive(cpu, addr);
5591 cpu->Reg[dest_reg] = 0;
5592 cpu->exclusive_state = 0; 6089 cpu->exclusive_state = 0;
5593 6090
5594 Memory::Write32(addr, value); 6091 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
6092 RD = 0;
5595 } else { 6093 } else {
5596 // Failed to write due to mutex access 6094 // Failed to write due to mutex access
5597 cpu->Reg[dest_reg] = 1; 6095 RD = 1;
5598 } 6096 }
5599 } 6097 }
5600 cpu->Reg[15] += GET_INST_SIZE(cpu); 6098 cpu->Reg[15] += GET_INST_SIZE(cpu);
5601 INC_PC(sizeof(ldst_inst)); 6099 INC_PC(sizeof(generic_arm_inst));
5602 FETCH_INST; 6100 FETCH_INST;
5603 GOTO_NEXT_INST; 6101 GOTO_NEXT_INST;
5604 } 6102 }
5605 STREXB_INST: 6103 STREXB_INST:
5606 { 6104 {
5607 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 6105 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6106
5608 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6107 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5609 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; 6108 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
5610 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; 6109
5611 int dest_reg = BITS(inst_cream->inst, 12, 15); 6110 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
5612 if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ 6111 remove_exclusive(cpu, write_addr);
5613 remove_exclusive(cpu, addr);
5614 cpu->Reg[dest_reg] = 0;
5615 cpu->exclusive_state = 0; 6112 cpu->exclusive_state = 0;
5616 Memory::Write8(addr, value); 6113
6114 Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
6115 RD = 0;
5617 } else { 6116 } else {
5618 cpu->Reg[dest_reg] = 1; 6117 // Failed to write due to mutex access
6118 RD = 1;
5619 } 6119 }
5620 } 6120 }
5621 cpu->Reg[15] += GET_INST_SIZE(cpu); 6121 cpu->Reg[15] += GET_INST_SIZE(cpu);
5622 INC_PC(sizeof(ldst_inst)); 6122 INC_PC(sizeof(generic_arm_inst));
6123 FETCH_INST;
6124 GOTO_NEXT_INST;
6125 }
6126 STREXD_INST:
6127 {
6128 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6129
6130 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6131 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6132
6133 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
6134 remove_exclusive(cpu, write_addr);
6135 cpu->exclusive_state = 0;
6136 // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD
6137
6138 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
6139 Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
6140 RD = 0;
6141 }
6142 else {
6143 // Failed to write due to mutex access
6144 RD = 1;
6145 }
6146 }
6147 cpu->Reg[15] += GET_INST_SIZE(cpu);
6148 INC_PC(sizeof(generic_arm_inst));
6149 FETCH_INST;
6150 GOTO_NEXT_INST;
6151 }
6152 STREXH_INST:
6153 {
6154 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6155
6156 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6157 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6158
6159 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
6160 remove_exclusive(cpu, write_addr);
6161 cpu->exclusive_state = 0;
6162
6163 Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]);
6164 RD = 0;
6165 } else {
6166 // Failed to write due to mutex access
6167 RD = 1;
6168 }
6169 }
6170 cpu->Reg[15] += GET_INST_SIZE(cpu);
6171 INC_PC(sizeof(generic_arm_inst));
5623 FETCH_INST; 6172 FETCH_INST;
5624 GOTO_NEXT_INST; 6173 GOTO_NEXT_INST;
5625 } 6174 }
@@ -5741,7 +6290,40 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5741 FETCH_INST; 6290 FETCH_INST;
5742 GOTO_NEXT_INST; 6291 GOTO_NEXT_INST;
5743 } 6292 }
6293
5744 SXTAB16_INST: 6294 SXTAB16_INST:
6295 SXTB16_INST:
6296 {
6297 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6298 sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
6299
6300 const u8 rotation = inst_cream->rotate * 8;
6301 u32 rm_val = RM;
6302 u32 rn_val = RN;
6303
6304 if (rotation)
6305 rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
6306
6307 // SXTB16
6308 if (inst_cream->Rn == 15) {
6309 u32 lo = (u32)(s8)rm_val;
6310 u32 hi = (u32)(s8)(rm_val >> 16);
6311 RD = (lo | (hi << 16));
6312 }
6313 // SXTAB16
6314 else {
6315 u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
6316 u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
6317 RD = (lo | (hi << 16));
6318 }
6319 }
6320
6321 cpu->Reg[15] += GET_INST_SIZE(cpu);
6322 INC_PC(sizeof(sxtab_inst));
6323 FETCH_INST;
6324 GOTO_NEXT_INST;
6325 }
6326
5745 SXTAH_INST: 6327 SXTAH_INST:
5746 { 6328 {
5747 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; 6329 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
@@ -5760,7 +6342,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5760 FETCH_INST; 6342 FETCH_INST;
5761 GOTO_NEXT_INST; 6343 GOTO_NEXT_INST;
5762 } 6344 }
5763 SXTB16_INST: 6345
5764 TEQ_INST: 6346 TEQ_INST:
5765 { 6347 {
5766 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6348 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -6156,7 +6738,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6156 BLX_1_THUMB: 6738 BLX_1_THUMB:
6157 { 6739 {
6158 // BLX 1 for armv5t and above 6740 // BLX 1 for armv5t and above
6159 uint32 tmp = cpu->Reg[15]; 6741 u32 tmp = cpu->Reg[15];
6160 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; 6742 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
6161 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; 6743 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
6162 cpu->Reg[14] = ((tmp + 2) | 1); 6744 cpu->Reg[14] = ((tmp + 2) | 1);
@@ -6354,9 +6936,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6354 } 6936 }
6355 INIT_INST_LENGTH: 6937 INIT_INST_LENGTH:
6356 { 6938 {
6357#if defined __GNUC__ || defined __clang__
6358 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
6359#endif
6360 cpu->NumInstrsToExecute = 0; 6939 cpu->NumInstrsToExecute = 0;
6361 return num_instrs; 6940 return num_instrs;
6362 } 6941 }
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index aeabeac16..c70522274 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -24,8 +24,8 @@
24void switch_mode(arm_core_t *core, uint32_t mode); 24void switch_mode(arm_core_t *core, uint32_t mode);
25 25
26/* FIXME, we temporarily think thumb instruction is always 16 bit */ 26/* FIXME, we temporarily think thumb instruction is always 16 bit */
27static inline uint32 GET_INST_SIZE(arm_core_t* core){ 27static inline u32 GET_INST_SIZE(arm_core_t* core) {
28 return core->TFlag? 2 : 4; 28 return core->TFlag? 2 : 4;
29} 29}
30 30
31/** 31/**
@@ -36,8 +36,8 @@ static inline uint32 GET_INST_SIZE(arm_core_t* core){
36* 36*
37* @return 37* @return
38*/ 38*/
39static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){ 39static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn) {
40 return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; 40 return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
41} 41}
42 42
43/** 43/**
@@ -48,8 +48,8 @@ static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
48* 48*
49* @return 49* @return
50*/ 50*/
51static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){ 51static inline u32 CHECK_READ_REG15(arm_core_t* core, int Rn) {
52 return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; 52 return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
53} 53}
54 54
55#endif 55#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 5541de9d1..bf69b2fd4 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -37,10 +37,10 @@ enum tdstate {
37 t_uninitialized, 37 t_uninitialized,
38}; 38};
39 39
40tdstate 40tdstate thumb_translate(addr_t addr, u32 instr, u32* ainstr, u32* inst_size);
41thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size); 41
42static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){ 42static inline u32 get_thumb_instr(u32 instr, addr_t pc) {
43 uint32 tinstr; 43 u32 tinstr;
44 if ((pc & 0x3) != 0) 44 if ((pc & 0x3) != 0)
45 tinstr = instr >> 16; 45 tinstr = instr >> 16;
46 else 46 else
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index b9c2aa6c2..12166bf79 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5881,67 +5881,45 @@ L_stm_s_takeabort:
5881 const u32 rm_val = state->Reg[rm_idx]; 5881 const u32 rm_val = state->Reg[rm_idx];
5882 const u32 rn_val = state->Reg[rn_idx]; 5882 const u32 rn_val = state->Reg[rn_idx];
5883 5883
5884 u8 lo_val1; 5884 s32 lo_val1, lo_val2;
5885 u8 lo_val2; 5885 s32 hi_val1, hi_val2;
5886 u8 hi_val1;
5887 u8 hi_val2;
5888 5886
5889 // SADD8 5887 // SADD8
5890 if ((instr & 0xFF0) == 0xf90) { 5888 if ((instr & 0xFF0) == 0xf90) {
5891 lo_val1 = (u8)((rn_val & 0xFF) + (rm_val & 0xFF)); 5889 lo_val1 = (s32)(s8)(rn_val & 0xFF) + (s32)(s8)(rm_val & 0xFF);
5892 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF)); 5890 lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) + (s32)(s8)((rm_val >> 8) & 0xFF);
5893 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF)); 5891 hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) + (s32)(s8)((rm_val >> 16) & 0xFF);
5894 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF)); 5892 hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) + (s32)(s8)((rm_val >> 24) & 0xFF);
5895
5896 if (lo_val1 & 0x80)
5897 state->GEFlag |= (1 << 16);
5898 else
5899 state->GEFlag &= ~(1 << 16);
5900
5901 if (lo_val2 & 0x80)
5902 state->GEFlag |= (1 << 17);
5903 else
5904 state->GEFlag &= ~(1 << 17);
5905
5906 if (hi_val1 & 0x80)
5907 state->GEFlag |= (1 << 18);
5908 else
5909 state->GEFlag &= ~(1 << 18);
5910
5911 if (hi_val2 & 0x80)
5912 state->GEFlag |= (1 << 19);
5913 else
5914 state->GEFlag &= ~(1 << 19);
5915 } 5893 }
5916 // SSUB8 5894 // SSUB8
5917 else { 5895 else {
5918 lo_val1 = (u8)((rn_val & 0xFF) - (rm_val & 0xFF)); 5896 lo_val1 = (s32)(s8)(rn_val & 0xFF) - (s32)(s8)(rm_val & 0xFF);
5919 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF)); 5897 lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) - (s32)(s8)((rm_val >> 8) & 0xFF);
5920 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF)); 5898 hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) - (s32)(s8)((rm_val >> 16) & 0xFF);
5921 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF)); 5899 hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) - (s32)(s8)((rm_val >> 24) & 0xFF);
5900 }
5922 5901
5923 if (!(lo_val1 & 0x80)) 5902 if (lo_val1 >= 0)
5924 state->GEFlag |= (1 << 16); 5903 state->GEFlag |= (1 << 16);
5925 else 5904 else
5926 state->GEFlag &= ~(1 << 16); 5905 state->GEFlag &= ~(1 << 16);
5927 5906
5928 if (!(lo_val2 & 0x80)) 5907 if (lo_val2 >= 0)
5929 state->GEFlag |= (1 << 17); 5908 state->GEFlag |= (1 << 17);
5930 else 5909 else
5931 state->GEFlag &= ~(1 << 17); 5910 state->GEFlag &= ~(1 << 17);
5932 5911
5933 if (!(hi_val1 & 0x80)) 5912 if (hi_val1 >= 0)
5934 state->GEFlag |= (1 << 18); 5913 state->GEFlag |= (1 << 18);
5935 else 5914 else
5936 state->GEFlag &= ~(1 << 18); 5915 state->GEFlag &= ~(1 << 18);
5937 5916
5938 if (!(hi_val2 & 0x80)) 5917 if (hi_val2 >= 0)
5939 state->GEFlag |= (1 << 19); 5918 state->GEFlag |= (1 << 19);
5940 else 5919 else
5941 state->GEFlag &= ~(1 << 19); 5920 state->GEFlag &= ~(1 << 19);
5942 }
5943 5921
5944 state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); 5922 state->Reg[rd_idx] = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
5945 return 1; 5923 return 1;
5946 } 5924 }
5947 else { 5925 else {
@@ -6492,17 +6470,23 @@ L_stm_s_takeabort:
6492 6470
6493 if (BITS(12, 15) != 15) { 6471 if (BITS(12, 15) != 15) {
6494 state->Reg[rd_idx] += state->Reg[ra_idx]; 6472 state->Reg[rd_idx] += state->Reg[ra_idx];
6495 ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]); 6473 if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx]))
6474 SETQ;
6496 } 6475 }
6497 6476
6498 ARMul_AddOverflowQ(state, product1, product2); 6477 if (ARMul_AddOverflowQ(product1, product2))
6478 SETQ;
6499 } 6479 }
6500 // SMUSD and SMLSD 6480 // SMUSD and SMLSD
6501 else { 6481 else {
6502 state->Reg[rd_idx] = product1 - product2; 6482 state->Reg[rd_idx] = product1 - product2;
6503 6483
6504 if (BITS(12, 15) != 15) 6484 if (BITS(12, 15) != 15) {
6505 state->Reg[rd_idx] += state->Reg[ra_idx]; 6485 state->Reg[rd_idx] += state->Reg[ra_idx];
6486
6487 if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx]))
6488 SETQ;
6489 }
6506 } 6490 }
6507 6491
6508 return 1; 6492 return 1;
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 426b67831..68ac2a0ce 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -418,22 +418,18 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
418 } 418 }
419} 419}
420 420
421/* Compute whether an addition of A and B, giving RESULT, overflowed. */ 421// Compute whether an addition of A and B, giving RESULT, overflowed.
422 422bool AddOverflow(ARMword a, ARMword b, ARMword result)
423int
424AddOverflow (ARMword a, ARMword b, ARMword result)
425{ 423{
426 return ((NEG (a) && NEG (b) && POS (result)) 424 return ((NEG(a) && NEG(b) && POS(result)) ||
427 || (POS (a) && POS (b) && NEG (result))); 425 (POS(a) && POS(b) && NEG(result)));
428} 426}
429 427
430/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */ 428// Compute whether a subtraction of A and B, giving RESULT, overflowed.
431 429bool SubOverflow(ARMword a, ARMword b, ARMword result)
432int
433SubOverflow (ARMword a, ARMword b, ARMword result)
434{ 430{
435 return ((NEG (a) && POS (b) && POS (result)) 431 return ((NEG(a) && POS(b) && POS(result)) ||
436 || (POS (a) && NEG (b) && NEG (result))); 432 (POS(a) && NEG(b) && NEG(result)));
437} 433}
438 434
439/* Assigns the C flag after an addition of a and b to give result. */ 435/* Assigns the C flag after an addition of a and b to give result. */
@@ -453,12 +449,14 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
453 ASSIGNV (AddOverflow (a, b, result)); 449 ASSIGNV (AddOverflow (a, b, result));
454} 450}
455 451
456/* Assigns the Q flag if the given result is considered an overflow from the addition of a and b */ 452// Returns true if the Q flag should be set as a result of overflow.
457void ARMul_AddOverflowQ(ARMul_State* state, ARMword a, ARMword b) 453bool ARMul_AddOverflowQ(ARMword a, ARMword b)
458{ 454{
459 u32 result = a + b; 455 u32 result = a + b;
460 if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) 456 if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
461 SETQ; 457 return true;
458
459 return false;
462} 460}
463 461
464/* Assigns the C flag after an subtraction of a and b to give result. */ 462/* Assigns the C flag after an subtraction of a and b to give result. */
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 8611d7392..3100d7adc 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -70,6 +70,9 @@
70#define DATACACHE 1 70#define DATACACHE 1
71#define INSTCACHE 2 71#define INSTCACHE 2
72 72
73#define POS(i) ( (~(i)) >> 31 )
74#define NEG(i) ( (i) >> 31 )
75
73#ifndef __STDC__ 76#ifndef __STDC__
74typedef char *VoidStar; 77typedef char *VoidStar;
75#endif 78#endif
@@ -783,6 +786,8 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
783//#define PXA250 0x69052903 786//#define PXA250 0x69052903
784// 0x69052903; //PXA250 B1 from intel 278522-001.pdf 787// 0x69052903; //PXA250 B1 from intel 278522-001.pdf
785 788
789extern bool AddOverflow(ARMword, ARMword, ARMword);
790extern bool SubOverflow(ARMword, ARMword, ARMword);
786 791
787extern void ARMul_UndefInstr(ARMul_State*, ARMword); 792extern void ARMul_UndefInstr(ARMul_State*, ARMword);
788extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); 793extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
@@ -790,6 +795,8 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
790extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); 795extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
791extern void ARMul_SelectProcessor(ARMul_State*, unsigned); 796extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
792 797
798extern bool ARMul_AddOverflowQ(ARMword, ARMword);
799
793extern u8 ARMul_SignedSaturatedAdd8(u8, u8); 800extern u8 ARMul_SignedSaturatedAdd8(u8, u8);
794extern u8 ARMul_SignedSaturatedSub8(u8, u8); 801extern u8 ARMul_SignedSaturatedSub8(u8, u8);
795extern u16 ARMul_SignedSaturatedAdd16(u16, u16); 802extern u16 ARMul_SignedSaturatedAdd16(u16, u16);
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
index 3ea14b5a3..1dfcc635a 100644
--- a/src/core/arm/skyeye_common/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -42,9 +42,6 @@
42#define R15FBIT (1L << 26) 42#define R15FBIT (1L << 26)
43#define R15IFBITS (3L << 26) 43#define R15IFBITS (3L << 26)
44 44
45#define POS(i) ( (~(i)) >> 31 )
46#define NEG(i) ( (i) >> 31 )
47
48#ifdef MODET /* Thumb support. */ 45#ifdef MODET /* Thumb support. */
49/* ??? This bit is actually in the low order bit of the PC in the hardware. 46/* ??? This bit is actually in the low order bit of the PC in the hardware.
50 It isn't clear if the simulator needs to model that or not. */ 47 It isn't clear if the simulator needs to model that or not. */
@@ -561,8 +558,7 @@ tdstate;
561 558
562/* Prototypes for exported functions. */ 559/* Prototypes for exported functions. */
563extern unsigned ARMul_NthReg (ARMword, unsigned); 560extern unsigned ARMul_NthReg (ARMword, unsigned);
564extern int AddOverflow (ARMword, ARMword, ARMword); 561
565extern int SubOverflow (ARMword, ARMword, ARMword);
566/* Prototypes for exported functions. */ 562/* Prototypes for exported functions. */
567#ifdef __cplusplus 563#ifdef __cplusplus
568 extern "C" { 564 extern "C" {
@@ -602,7 +598,6 @@ extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
602extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); 598extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
603extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); 599extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
604extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); 600extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
605extern void ARMul_AddOverflowQ(ARMul_State*, ARMword, ARMword);
606extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); 601extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
607extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); 602extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
608extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *); 603extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
index e7f022f19..fc7d8d922 100644
--- a/src/core/arm/skyeye_common/skyeye_types.h
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -22,34 +22,10 @@
22 * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com> 22 * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com>
23 */ 23 */
24 24
25#ifndef __SKYEYE_TYPES_H 25#pragma once
26#define __SKYEYE_TYPES_H
27 26
28#include <stdint.h> 27#include <cstdint>
29
30/*default machine word length */
31
32#ifndef __BEOS__
33/* To avoid the type conflict with the qemu */
34#ifndef QEMU
35typedef uint8_t uint8;
36typedef uint16_t uint16;
37typedef uint32_t uint32;
38typedef uint64_t uint64;
39
40typedef int8_t sint8;
41typedef int16_t sint16;
42typedef int32_t sint32;
43typedef int64_t sint64;
44#endif
45 28
46typedef uint32_t address_t; 29typedef uint32_t address_t;
47typedef uint32_t uinteger_t;
48typedef int32_t integer_t;
49
50typedef uint32_t physical_address_t; 30typedef uint32_t physical_address_t;
51typedef uint32_t generic_address_t; 31typedef uint32_t generic_address_t;
52
53#endif
54
55#endif
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index b5fcbac86..2c1218c30 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -1,22 +1,6 @@
1/* 1// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
2 vfp/vfpinstr.c - ARM VFPv3 emulation unit - Individual instructions data 2// Licensed under GPLv2 or any later version
3 Copyright (C) 2003 Skyeye Develop Group 3// Refer to the license.txt file included.
4 for help please send mail to <skyeye-developer@lists.gro.clinux.org>
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 4
21/* Notice: this file should not be compiled as is, and is meant to be 5/* Notice: this file should not be compiled as is, and is meant to be
22 included in other files only. */ 6 included in other files only. */
@@ -30,52 +14,52 @@
30/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */ 14/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
31#ifdef VFP_INTERPRETER_STRUCT 15#ifdef VFP_INTERPRETER_STRUCT
32typedef struct _vmla_inst { 16typedef struct _vmla_inst {
33 unsigned int instr; 17 unsigned int instr;
34 unsigned int dp_operation; 18 unsigned int dp_operation;
35} vmla_inst; 19} vmla_inst;
36#endif 20#endif
37#ifdef VFP_INTERPRETER_TRANS 21#ifdef VFP_INTERPRETER_TRANS
38ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) 22ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
39{ 23{
40 VFP_DEBUG_TRANSLATE; 24 VFP_DEBUG_TRANSLATE;
41 25
42 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); 26 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst));
43 vmla_inst *inst_cream = (vmla_inst *)inst_base->component; 27 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
44 28
45 inst_base->cond = BITS(inst, 28, 31); 29 inst_base->cond = BITS(inst, 28, 31);
46 inst_base->idx = index; 30 inst_base->idx = index;
47 inst_base->br = NON_BRANCH; 31 inst_base->br = NON_BRANCH;
48 inst_base->load_r15 = 0; 32 inst_base->load_r15 = 0;
49 33
50 inst_cream->dp_operation = BIT(inst, 8); 34 inst_cream->dp_operation = BIT(inst, 8);
51 inst_cream->instr = inst; 35 inst_cream->instr = inst;
52 36
53 return inst_base; 37 return inst_base;
54} 38}
55#endif 39#endif
56#ifdef VFP_INTERPRETER_IMPL 40#ifdef VFP_INTERPRETER_IMPL
57VMLA_INST: 41VMLA_INST:
58{ 42{
59 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 43 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
60 CHECK_VFP_ENABLED; 44 CHECK_VFP_ENABLED;
61 45
62 DBG("VMLA :\n"); 46 DBG("VMLA :\n");
63
64 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
65 47
66 int ret; 48 vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
67
68 if (inst_cream->dp_operation)
69 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
70 else
71 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
72 49
73 CHECK_VFP_CDP_RET; 50 int ret;
74 } 51
75 cpu->Reg[15] += GET_INST_SIZE(cpu); 52 if (inst_cream->dp_operation)
76 INC_PC(sizeof(vmla_inst)); 53 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
77 FETCH_INST; 54 else
78 GOTO_NEXT_INST; 55 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
56
57 CHECK_VFP_CDP_RET;
58 }
59 cpu->Reg[15] += GET_INST_SIZE(cpu);
60 INC_PC(sizeof(vmla_inst));
61 FETCH_INST;
62 GOTO_NEXT_INST;
79} 63}
80#endif 64#endif
81 65
@@ -85,66 +69,66 @@ DYNCOM_FILL_ACTION(vmla),
85#ifdef VFP_DYNCOM_TAG 69#ifdef VFP_DYNCOM_TAG
86int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 70int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
87{ 71{
88 int instr_size = INSTR_SIZE; 72 int instr_size = INSTR_SIZE;
89 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 73 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
90 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 74 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
91 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 75 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
92 return instr_size; 76 return instr_size;
93} 77}
94#endif 78#endif
95#ifdef VFP_DYNCOM_TRANS 79#ifdef VFP_DYNCOM_TRANS
96int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 80int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
97 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 81 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
98 //arch_arm_undef(cpu, bb, instr); 82 //arch_arm_undef(cpu, bb, instr);
99 int m; 83 int m;
100 int n; 84 int n;
101 int d ; 85 int d ;
102 int add = (BIT(6) == 0); 86 int add = (BIT(6) == 0);
103 int s = BIT(8) == 0; 87 int s = BIT(8) == 0;
104 Value *mm; 88 Value *mm;
105 Value *nn; 89 Value *nn;
106 Value *tmp; 90 Value *tmp;
107 if(s){ 91 if(s){
108 m = BIT(5) | BITS(0,3) << 1; 92 m = BIT(5) | BITS(0,3) << 1;
109 n = BIT(7) | BITS(16,19) << 1; 93 n = BIT(7) | BITS(16,19) << 1;
110 d = BIT(22) | BITS(12,15) << 1; 94 d = BIT(22) | BITS(12,15) << 1;
111 mm = FR32(m); 95 mm = FR32(m);
112 nn = FR32(n); 96 nn = FR32(n);
113 tmp = FPMUL(nn,mm); 97 tmp = FPMUL(nn,mm);
114 if(!add) 98 if(!add)
115 tmp = FPNEG32(tmp); 99 tmp = FPNEG32(tmp);
116 mm = FR32(d); 100 mm = FR32(d);
117 tmp = FPADD(mm,tmp); 101 tmp = FPADD(mm,tmp);
118 //LETS(d,tmp); 102 //LETS(d,tmp);
119 LETFPS(d,tmp); 103 LETFPS(d,tmp);
120 }else { 104 }else {
121 m = BITS(0,3) | BIT(5) << 4; 105 m = BITS(0,3) | BIT(5) << 4;
122 n = BITS(16,19) | BIT(7) << 4; 106 n = BITS(16,19) | BIT(7) << 4;
123 d = BIT(22) << 4 | BITS(12,15); 107 d = BIT(22) << 4 | BITS(12,15);
124 //mm = SITOFP(32,RSPR(m)); 108 //mm = SITOFP(32,RSPR(m));
125 //LETS(d,tmp); 109 //LETS(d,tmp);
126 mm = ZEXT64(IBITCAST32(FR32(2 * m))); 110 mm = ZEXT64(IBITCAST32(FR32(2 * m)));
127 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); 111 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
128 tmp = OR(SHL(nn,CONST64(32)),mm); 112 tmp = OR(SHL(nn,CONST64(32)),mm);
129 mm = FPBITCAST64(tmp); 113 mm = FPBITCAST64(tmp);
130 tmp = ZEXT64(IBITCAST32(FR32(2 * n))); 114 tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
131 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); 115 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
132 nn = OR(SHL(nn,CONST64(32)),tmp); 116 nn = OR(SHL(nn,CONST64(32)),tmp);
133 nn = FPBITCAST64(nn); 117 nn = FPBITCAST64(nn);
134 tmp = FPMUL(nn,mm); 118 tmp = FPMUL(nn,mm);
135 if(!add) 119 if(!add)
136 tmp = FPNEG64(tmp); 120 tmp = FPNEG64(tmp);
137 mm = ZEXT64(IBITCAST32(FR32(2 * d))); 121 mm = ZEXT64(IBITCAST32(FR32(2 * d)));
138 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); 122 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
139 mm = OR(SHL(nn,CONST64(32)),mm); 123 mm = OR(SHL(nn,CONST64(32)),mm);
140 mm = FPBITCAST64(mm); 124 mm = FPBITCAST64(mm);
141 tmp = FPADD(mm,tmp); 125 tmp = FPADD(mm,tmp);
142 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); 126 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
143 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); 127 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
144 LETFPS(2*d ,FPBITCAST32(nn)); 128 LETFPS(2*d ,FPBITCAST32(nn));
145 LETFPS(d*2 + 1 , FPBITCAST32(mm)); 129 LETFPS(d*2 + 1 , FPBITCAST32(mm));
146 } 130 }
147 return No_exp; 131 return No_exp;
148} 132}
149#endif 133#endif
150 134
@@ -153,52 +137,52 @@ int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
153/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */ 137/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
154#ifdef VFP_INTERPRETER_STRUCT 138#ifdef VFP_INTERPRETER_STRUCT
155typedef struct _vmls_inst { 139typedef struct _vmls_inst {
156 unsigned int instr; 140 unsigned int instr;
157 unsigned int dp_operation; 141 unsigned int dp_operation;
158} vmls_inst; 142} vmls_inst;
159#endif 143#endif
160#ifdef VFP_INTERPRETER_TRANS 144#ifdef VFP_INTERPRETER_TRANS
161ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) 145ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
162{ 146{
163 VFP_DEBUG_TRANSLATE; 147 VFP_DEBUG_TRANSLATE;
164 148
165 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); 149 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
166 vmls_inst *inst_cream = (vmls_inst *)inst_base->component; 150 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
151
152 inst_base->cond = BITS(inst, 28, 31);
153 inst_base->idx = index;
154 inst_base->br = NON_BRANCH;
155 inst_base->load_r15 = 0;
167 156
168 inst_base->cond = BITS(inst, 28, 31); 157 inst_cream->dp_operation = BIT(inst, 8);
169 inst_base->idx = index; 158 inst_cream->instr = inst;
170 inst_base->br = NON_BRANCH;
171 inst_base->load_r15 = 0;
172 159
173 inst_cream->dp_operation = BIT(inst, 8); 160 return inst_base;
174 inst_cream->instr = inst;
175
176 return inst_base;
177} 161}
178#endif 162#endif
179#ifdef VFP_INTERPRETER_IMPL 163#ifdef VFP_INTERPRETER_IMPL
180VMLS_INST: 164VMLS_INST:
181{ 165{
182 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 166 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
183 CHECK_VFP_ENABLED; 167 CHECK_VFP_ENABLED;
184
185 DBG("VMLS :\n");
186
187 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
188 168
189 int ret; 169 DBG("VMLS :\n");
190
191 if (inst_cream->dp_operation)
192 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
193 else
194 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
195 170
196 CHECK_VFP_CDP_RET; 171 vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
197 } 172
198 cpu->Reg[15] += GET_INST_SIZE(cpu); 173 int ret;
199 INC_PC(sizeof(vmls_inst)); 174
200 FETCH_INST; 175 if (inst_cream->dp_operation)
201 GOTO_NEXT_INST; 176 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
177 else
178 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
179
180 CHECK_VFP_CDP_RET;
181 }
182 cpu->Reg[15] += GET_INST_SIZE(cpu);
183 INC_PC(sizeof(vmls_inst));
184 FETCH_INST;
185 GOTO_NEXT_INST;
202} 186}
203#endif 187#endif
204 188
@@ -208,66 +192,66 @@ DYNCOM_FILL_ACTION(vmls),
208#ifdef VFP_DYNCOM_TAG 192#ifdef VFP_DYNCOM_TAG
209int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 193int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
210{ 194{
211 int instr_size = INSTR_SIZE; 195 int instr_size = INSTR_SIZE;
212 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 196 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
213 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 197 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
214 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 198 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
215 return instr_size; 199 return instr_size;
216} 200}
217#endif 201#endif
218#ifdef VFP_DYNCOM_TRANS 202#ifdef VFP_DYNCOM_TRANS
219int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 203int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
220 DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); 204 DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
221 //arch_arm_undef(cpu, bb, instr); 205 //arch_arm_undef(cpu, bb, instr);
222 int m; 206 int m;
223 int n; 207 int n;
224 int d ; 208 int d ;
225 int add = (BIT(6) == 0); 209 int add = (BIT(6) == 0);
226 int s = BIT(8) == 0; 210 int s = BIT(8) == 0;
227 Value *mm; 211 Value *mm;
228 Value *nn; 212 Value *nn;
229 Value *tmp; 213 Value *tmp;
230 if(s){ 214 if(s){
231 m = BIT(5) | BITS(0,3) << 1; 215 m = BIT(5) | BITS(0,3) << 1;
232 n = BIT(7) | BITS(16,19) << 1; 216 n = BIT(7) | BITS(16,19) << 1;
233 d = BIT(22) | BITS(12,15) << 1; 217 d = BIT(22) | BITS(12,15) << 1;
234 mm = FR32(m); 218 mm = FR32(m);
235 nn = FR32(n); 219 nn = FR32(n);
236 tmp = FPMUL(nn,mm); 220 tmp = FPMUL(nn,mm);
237 if(!add) 221 if(!add)
238 tmp = FPNEG32(tmp); 222 tmp = FPNEG32(tmp);
239 mm = FR32(d); 223 mm = FR32(d);
240 tmp = FPADD(mm,tmp); 224 tmp = FPADD(mm,tmp);
241 //LETS(d,tmp); 225 //LETS(d,tmp);
242 LETFPS(d,tmp); 226 LETFPS(d,tmp);
243 }else { 227 }else {
244 m = BITS(0,3) | BIT(5) << 4; 228 m = BITS(0,3) | BIT(5) << 4;
245 n = BITS(16,19) | BIT(7) << 4; 229 n = BITS(16,19) | BIT(7) << 4;
246 d = BIT(22) << 4 | BITS(12,15); 230 d = BIT(22) << 4 | BITS(12,15);
247 //mm = SITOFP(32,RSPR(m)); 231 //mm = SITOFP(32,RSPR(m));
248 //LETS(d,tmp); 232 //LETS(d,tmp);
249 mm = ZEXT64(IBITCAST32(FR32(2 * m))); 233 mm = ZEXT64(IBITCAST32(FR32(2 * m)));
250 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); 234 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
251 tmp = OR(SHL(nn,CONST64(32)),mm); 235 tmp = OR(SHL(nn,CONST64(32)),mm);
252 mm = FPBITCAST64(tmp); 236 mm = FPBITCAST64(tmp);
253 tmp = ZEXT64(IBITCAST32(FR32(2 * n))); 237 tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
254 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); 238 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
255 nn = OR(SHL(nn,CONST64(32)),tmp); 239 nn = OR(SHL(nn,CONST64(32)),tmp);
256 nn = FPBITCAST64(nn); 240 nn = FPBITCAST64(nn);
257 tmp = FPMUL(nn,mm); 241 tmp = FPMUL(nn,mm);
258 if(!add) 242 if(!add)
259 tmp = FPNEG64(tmp); 243 tmp = FPNEG64(tmp);
260 mm = ZEXT64(IBITCAST32(FR32(2 * d))); 244 mm = ZEXT64(IBITCAST32(FR32(2 * d)));
261 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); 245 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
262 mm = OR(SHL(nn,CONST64(32)),mm); 246 mm = OR(SHL(nn,CONST64(32)),mm);
263 mm = FPBITCAST64(mm); 247 mm = FPBITCAST64(mm);
264 tmp = FPADD(mm,tmp); 248 tmp = FPADD(mm,tmp);
265 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); 249 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
266 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); 250 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
267 LETFPS(2*d ,FPBITCAST32(nn)); 251 LETFPS(2*d ,FPBITCAST32(nn));
268 LETFPS(d*2 + 1 , FPBITCAST32(mm)); 252 LETFPS(d*2 + 1 , FPBITCAST32(mm));
269 } 253 }
270 return No_exp; 254 return No_exp;
271} 255}
272#endif 256#endif
273 257
@@ -276,52 +260,52 @@ int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
276/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */ 260/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
277#ifdef VFP_INTERPRETER_STRUCT 261#ifdef VFP_INTERPRETER_STRUCT
278typedef struct _vnmla_inst { 262typedef struct _vnmla_inst {
279 unsigned int instr; 263 unsigned int instr;
280 unsigned int dp_operation; 264 unsigned int dp_operation;
281} vnmla_inst; 265} vnmla_inst;
282#endif 266#endif
283#ifdef VFP_INTERPRETER_TRANS 267#ifdef VFP_INTERPRETER_TRANS
284ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) 268ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
285{ 269{
286 VFP_DEBUG_TRANSLATE; 270 VFP_DEBUG_TRANSLATE;
287 271
288 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); 272 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
289 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; 273 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
290 274
291 inst_base->cond = BITS(inst, 28, 31); 275 inst_base->cond = BITS(inst, 28, 31);
292 inst_base->idx = index; 276 inst_base->idx = index;
293 inst_base->br = NON_BRANCH; 277 inst_base->br = NON_BRANCH;
294 inst_base->load_r15 = 0; 278 inst_base->load_r15 = 0;
295 279
296 inst_cream->dp_operation = BIT(inst, 8); 280 inst_cream->dp_operation = BIT(inst, 8);
297 inst_cream->instr = inst; 281 inst_cream->instr = inst;
298 282
299 return inst_base; 283 return inst_base;
300} 284}
301#endif 285#endif
302#ifdef VFP_INTERPRETER_IMPL 286#ifdef VFP_INTERPRETER_IMPL
303VNMLA_INST: 287VNMLA_INST:
304{ 288{
305 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 289 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
306 CHECK_VFP_ENABLED; 290 CHECK_VFP_ENABLED;
307 291
308 DBG("VNMLA :\n"); 292 DBG("VNMLA :\n");
293
294 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
309 295
310 vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; 296 int ret;
311 297
312 int ret; 298 if (inst_cream->dp_operation)
313 299 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
314 if (inst_cream->dp_operation) 300 else
315 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 301 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
316 else
317 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
318 302
319 CHECK_VFP_CDP_RET; 303 CHECK_VFP_CDP_RET;
320 } 304 }
321 cpu->Reg[15] += GET_INST_SIZE(cpu); 305 cpu->Reg[15] += GET_INST_SIZE(cpu);
322 INC_PC(sizeof(vnmla_inst)); 306 INC_PC(sizeof(vnmla_inst));
323 FETCH_INST; 307 FETCH_INST;
324 GOTO_NEXT_INST; 308 GOTO_NEXT_INST;
325} 309}
326#endif 310#endif
327 311
@@ -332,66 +316,66 @@ DYNCOM_FILL_ACTION(vnmla),
332#ifdef VFP_DYNCOM_TAG 316#ifdef VFP_DYNCOM_TAG
333int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 317int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
334{ 318{
335 int instr_size = INSTR_SIZE; 319 int instr_size = INSTR_SIZE;
336 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 320 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
337 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 321 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
338 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 322 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
339 return instr_size; 323 return instr_size;
340} 324}
341#endif 325#endif
342#ifdef VFP_DYNCOM_TRANS 326#ifdef VFP_DYNCOM_TRANS
343int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 327int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
344 DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); 328 DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
345 //arch_arm_undef(cpu, bb, instr); 329 //arch_arm_undef(cpu, bb, instr);
346 int m; 330 int m;
347 int n; 331 int n;
348 int d ; 332 int d ;
349 int add = (BIT(6) == 0); 333 int add = (BIT(6) == 0);
350 int s = BIT(8) == 0; 334 int s = BIT(8) == 0;
351 Value *mm; 335 Value *mm;
352 Value *nn; 336 Value *nn;
353 Value *tmp; 337 Value *tmp;
354 if(s){ 338 if(s){
355 m = BIT(5) | BITS(0,3) << 1; 339 m = BIT(5) | BITS(0,3) << 1;
356 n = BIT(7) | BITS(16,19) << 1; 340 n = BIT(7) | BITS(16,19) << 1;
357 d = BIT(22) | BITS(12,15) << 1; 341 d = BIT(22) | BITS(12,15) << 1;
358 mm = FR32(m); 342 mm = FR32(m);
359 nn = FR32(n); 343 nn = FR32(n);
360 tmp = FPMUL(nn,mm); 344 tmp = FPMUL(nn,mm);
361 if(!add) 345 if(!add)
362 tmp = FPNEG32(tmp); 346 tmp = FPNEG32(tmp);
363 mm = FR32(d); 347 mm = FR32(d);
364 tmp = FPADD(FPNEG32(mm),tmp); 348 tmp = FPADD(FPNEG32(mm),tmp);
365 //LETS(d,tmp); 349 //LETS(d,tmp);
366 LETFPS(d,tmp); 350 LETFPS(d,tmp);
367 }else { 351 }else {
368 m = BITS(0,3) | BIT(5) << 4; 352 m = BITS(0,3) | BIT(5) << 4;
369 n = BITS(16,19) | BIT(7) << 4; 353 n = BITS(16,19) | BIT(7) << 4;
370 d = BIT(22) << 4 | BITS(12,15); 354 d = BIT(22) << 4 | BITS(12,15);
371 //mm = SITOFP(32,RSPR(m)); 355 //mm = SITOFP(32,RSPR(m));
372 //LETS(d,tmp); 356 //LETS(d,tmp);
373 mm = ZEXT64(IBITCAST32(FR32(2 * m))); 357 mm = ZEXT64(IBITCAST32(FR32(2 * m)));
374 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); 358 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
375 tmp = OR(SHL(nn,CONST64(32)),mm); 359 tmp = OR(SHL(nn,CONST64(32)),mm);
376 mm = FPBITCAST64(tmp); 360 mm = FPBITCAST64(tmp);
377 tmp = ZEXT64(IBITCAST32(FR32(2 * n))); 361 tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
378 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); 362 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
379 nn = OR(SHL(nn,CONST64(32)),tmp); 363 nn = OR(SHL(nn,CONST64(32)),tmp);
380 nn = FPBITCAST64(nn); 364 nn = FPBITCAST64(nn);
381 tmp = FPMUL(nn,mm); 365 tmp = FPMUL(nn,mm);
382 if(!add) 366 if(!add)
383 tmp = FPNEG64(tmp); 367 tmp = FPNEG64(tmp);
384 mm = ZEXT64(IBITCAST32(FR32(2 * d))); 368 mm = ZEXT64(IBITCAST32(FR32(2 * d)));
385 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); 369 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
386 mm = OR(SHL(nn,CONST64(32)),mm); 370 mm = OR(SHL(nn,CONST64(32)),mm);
387 mm = FPBITCAST64(mm); 371 mm = FPBITCAST64(mm);
388 tmp = FPADD(FPNEG64(mm),tmp); 372 tmp = FPADD(FPNEG64(mm),tmp);
389 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); 373 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
390 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); 374 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
391 LETFPS(2*d ,FPBITCAST32(nn)); 375 LETFPS(2*d ,FPBITCAST32(nn));
392 LETFPS(d*2 + 1 , FPBITCAST32(mm)); 376 LETFPS(d*2 + 1 , FPBITCAST32(mm));
393 } 377 }
394 return No_exp; 378 return No_exp;
395} 379}
396#endif 380#endif
397 381
@@ -401,52 +385,52 @@ int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
401 385
402#ifdef VFP_INTERPRETER_STRUCT 386#ifdef VFP_INTERPRETER_STRUCT
403typedef struct _vnmls_inst { 387typedef struct _vnmls_inst {
404 unsigned int instr; 388 unsigned int instr;
405 unsigned int dp_operation; 389 unsigned int dp_operation;
406} vnmls_inst; 390} vnmls_inst;
407#endif 391#endif
408#ifdef VFP_INTERPRETER_TRANS 392#ifdef VFP_INTERPRETER_TRANS
409ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) 393ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
410{ 394{
411 VFP_DEBUG_TRANSLATE; 395 VFP_DEBUG_TRANSLATE;
412
413 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
414 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
415 396
416 inst_base->cond = BITS(inst, 28, 31); 397 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
417 inst_base->idx = index; 398 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
418 inst_base->br = NON_BRANCH;
419 inst_base->load_r15 = 0;
420 399
421 inst_cream->dp_operation = BIT(inst, 8); 400 inst_base->cond = BITS(inst, 28, 31);
422 inst_cream->instr = inst; 401 inst_base->idx = index;
423 402 inst_base->br = NON_BRANCH;
424 return inst_base; 403 inst_base->load_r15 = 0;
404
405 inst_cream->dp_operation = BIT(inst, 8);
406 inst_cream->instr = inst;
407
408 return inst_base;
425} 409}
426#endif 410#endif
427#ifdef VFP_INTERPRETER_IMPL 411#ifdef VFP_INTERPRETER_IMPL
428VNMLS_INST: 412VNMLS_INST:
429{ 413{
430 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 414 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
431 CHECK_VFP_ENABLED; 415 CHECK_VFP_ENABLED;
432 416
433 DBG("VNMLS :\n"); 417 DBG("VNMLS :\n");
418
419 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
434 420
435 vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; 421 int ret;
436 422
437 int ret; 423 if (inst_cream->dp_operation)
438 424 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
439 if (inst_cream->dp_operation) 425 else
440 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 426 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
441 else
442 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
443 427
444 CHECK_VFP_CDP_RET; 428 CHECK_VFP_CDP_RET;
445 } 429 }
446 cpu->Reg[15] += GET_INST_SIZE(cpu); 430 cpu->Reg[15] += GET_INST_SIZE(cpu);
447 INC_PC(sizeof(vnmls_inst)); 431 INC_PC(sizeof(vnmls_inst));
448 FETCH_INST; 432 FETCH_INST;
449 GOTO_NEXT_INST; 433 GOTO_NEXT_INST;
450} 434}
451#endif 435#endif
452 436
@@ -456,66 +440,66 @@ DYNCOM_FILL_ACTION(vnmls),
456#ifdef VFP_DYNCOM_TAG 440#ifdef VFP_DYNCOM_TAG
457int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 441int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
458{ 442{
459 int instr_size = INSTR_SIZE; 443 int instr_size = INSTR_SIZE;
460 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 444 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
461 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 445 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
462 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 446 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
463 return instr_size; 447 return instr_size;
464} 448}
465#endif 449#endif
466#ifdef VFP_DYNCOM_TRANS 450#ifdef VFP_DYNCOM_TRANS
467int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 451int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
468 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 452 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
469 //arch_arm_undef(cpu, bb, instr); 453 //arch_arm_undef(cpu, bb, instr);
470 int m; 454 int m;
471 int n; 455 int n;
472 int d ; 456 int d ;
473 int add = (BIT(6) == 0); 457 int add = (BIT(6) == 0);
474 int s = BIT(8) == 0; 458 int s = BIT(8) == 0;
475 Value *mm; 459 Value *mm;
476 Value *nn; 460 Value *nn;
477 Value *tmp; 461 Value *tmp;
478 if(s){ 462 if(s){
479 m = BIT(5) | BITS(0,3) << 1; 463 m = BIT(5) | BITS(0,3) << 1;
480 n = BIT(7) | BITS(16,19) << 1; 464 n = BIT(7) | BITS(16,19) << 1;
481 d = BIT(22) | BITS(12,15) << 1; 465 d = BIT(22) | BITS(12,15) << 1;
482 mm = FR32(m); 466 mm = FR32(m);
483 nn = FR32(n); 467 nn = FR32(n);
484 tmp = FPMUL(nn,mm); 468 tmp = FPMUL(nn,mm);
485 if(!add) 469 if(!add)
486 tmp = FPNEG32(tmp); 470 tmp = FPNEG32(tmp);
487 mm = FR32(d); 471 mm = FR32(d);
488 tmp = FPADD(FPNEG32(mm),tmp); 472 tmp = FPADD(FPNEG32(mm),tmp);
489 //LETS(d,tmp); 473 //LETS(d,tmp);
490 LETFPS(d,tmp); 474 LETFPS(d,tmp);
491 }else { 475 }else {
492 m = BITS(0,3) | BIT(5) << 4; 476 m = BITS(0,3) | BIT(5) << 4;
493 n = BITS(16,19) | BIT(7) << 4; 477 n = BITS(16,19) | BIT(7) << 4;
494 d = BIT(22) << 4 | BITS(12,15); 478 d = BIT(22) << 4 | BITS(12,15);
495 //mm = SITOFP(32,RSPR(m)); 479 //mm = SITOFP(32,RSPR(m));
496 //LETS(d,tmp); 480 //LETS(d,tmp);
497 mm = ZEXT64(IBITCAST32(FR32(2 * m))); 481 mm = ZEXT64(IBITCAST32(FR32(2 * m)));
498 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); 482 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
499 tmp = OR(SHL(nn,CONST64(32)),mm); 483 tmp = OR(SHL(nn,CONST64(32)),mm);
500 mm = FPBITCAST64(tmp); 484 mm = FPBITCAST64(tmp);
501 tmp = ZEXT64(IBITCAST32(FR32(2 * n))); 485 tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
502 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); 486 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
503 nn = OR(SHL(nn,CONST64(32)),tmp); 487 nn = OR(SHL(nn,CONST64(32)),tmp);
504 nn = FPBITCAST64(nn); 488 nn = FPBITCAST64(nn);
505 tmp = FPMUL(nn,mm); 489 tmp = FPMUL(nn,mm);
506 if(!add) 490 if(!add)
507 tmp = FPNEG64(tmp); 491 tmp = FPNEG64(tmp);
508 mm = ZEXT64(IBITCAST32(FR32(2 * d))); 492 mm = ZEXT64(IBITCAST32(FR32(2 * d)));
509 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); 493 nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
510 mm = OR(SHL(nn,CONST64(32)),mm); 494 mm = OR(SHL(nn,CONST64(32)),mm);
511 mm = FPBITCAST64(mm); 495 mm = FPBITCAST64(mm);
512 tmp = FPADD(FPNEG64(mm),tmp); 496 tmp = FPADD(FPNEG64(mm),tmp);
513 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); 497 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
514 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); 498 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
515 LETFPS(2*d ,FPBITCAST32(nn)); 499 LETFPS(2*d ,FPBITCAST32(nn));
516 LETFPS(d*2 + 1 , FPBITCAST32(mm)); 500 LETFPS(d*2 + 1 , FPBITCAST32(mm));
517 } 501 }
518 return No_exp; 502 return No_exp;
519} 503}
520#endif 504#endif
521 505
@@ -524,52 +508,52 @@ int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
524/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 508/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
525#ifdef VFP_INTERPRETER_STRUCT 509#ifdef VFP_INTERPRETER_STRUCT
526typedef struct _vnmul_inst { 510typedef struct _vnmul_inst {
527 unsigned int instr; 511 unsigned int instr;
528 unsigned int dp_operation; 512 unsigned int dp_operation;
529} vnmul_inst; 513} vnmul_inst;
530#endif 514#endif
531#ifdef VFP_INTERPRETER_TRANS 515#ifdef VFP_INTERPRETER_TRANS
532ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) 516ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
533{ 517{
534 VFP_DEBUG_TRANSLATE; 518 VFP_DEBUG_TRANSLATE;
535
536 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
537 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
538 519
539 inst_base->cond = BITS(inst, 28, 31); 520 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
540 inst_base->idx = index; 521 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
541 inst_base->br = NON_BRANCH;
542 inst_base->load_r15 = 0;
543 522
544 inst_cream->dp_operation = BIT(inst, 8); 523 inst_base->cond = BITS(inst, 28, 31);
545 inst_cream->instr = inst; 524 inst_base->idx = index;
546 525 inst_base->br = NON_BRANCH;
547 return inst_base; 526 inst_base->load_r15 = 0;
527
528 inst_cream->dp_operation = BIT(inst, 8);
529 inst_cream->instr = inst;
530
531 return inst_base;
548} 532}
549#endif 533#endif
550#ifdef VFP_INTERPRETER_IMPL 534#ifdef VFP_INTERPRETER_IMPL
551VNMUL_INST: 535VNMUL_INST:
552{ 536{
553 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 537 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
554 CHECK_VFP_ENABLED; 538 CHECK_VFP_ENABLED;
555 539
556 DBG("VNMUL :\n"); 540 DBG("VNMUL :\n");
541
542 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
557 543
558 vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; 544 int ret;
559 545
560 int ret; 546 if (inst_cream->dp_operation)
561 547 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
562 if (inst_cream->dp_operation) 548 else
563 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 549 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
564 else
565 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
566 550
567 CHECK_VFP_CDP_RET; 551 CHECK_VFP_CDP_RET;
568 } 552 }
569 cpu->Reg[15] += GET_INST_SIZE(cpu); 553 cpu->Reg[15] += GET_INST_SIZE(cpu);
570 INC_PC(sizeof(vnmul_inst)); 554 INC_PC(sizeof(vnmul_inst));
571 FETCH_INST; 555 FETCH_INST;
572 GOTO_NEXT_INST; 556 GOTO_NEXT_INST;
573} 557}
574#endif 558#endif
575 559
@@ -579,56 +563,56 @@ DYNCOM_FILL_ACTION(vnmul),
579#ifdef VFP_DYNCOM_TAG 563#ifdef VFP_DYNCOM_TAG
580int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 564int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
581{ 565{
582 int instr_size = INSTR_SIZE; 566 int instr_size = INSTR_SIZE;
583 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 567 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
584 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 568 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
585 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 569 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
586 return instr_size; 570 return instr_size;
587} 571}
588#endif 572#endif
589#ifdef VFP_DYNCOM_TRANS 573#ifdef VFP_DYNCOM_TRANS
590int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 574int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
591 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 575 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
592 //arch_arm_undef(cpu, bb, instr); 576 //arch_arm_undef(cpu, bb, instr);
593 int m; 577 int m;
594 int n; 578 int n;
595 int d ; 579 int d ;
596 int add = (BIT(6) == 0); 580 int add = (BIT(6) == 0);
597 int s = BIT(8) == 0; 581 int s = BIT(8) == 0;
598 Value *mm; 582 Value *mm;
599 Value *nn; 583 Value *nn;
600 Value *tmp; 584 Value *tmp;
601 if(s){ 585 if(s){
602 m = BIT(5) | BITS(0,3) << 1; 586 m = BIT(5) | BITS(0,3) << 1;
603 n = BIT(7) | BITS(16,19) << 1; 587 n = BIT(7) | BITS(16,19) << 1;
604 d = BIT(22) | BITS(12,15) << 1; 588 d = BIT(22) | BITS(12,15) << 1;
605 mm = FR32(m); 589 mm = FR32(m);
606 nn = FR32(n); 590 nn = FR32(n);
607 tmp = FPMUL(nn,mm); 591 tmp = FPMUL(nn,mm);
608 //LETS(d,tmp); 592 //LETS(d,tmp);
609 LETFPS(d,FPNEG32(tmp)); 593 LETFPS(d,FPNEG32(tmp));
610 }else { 594 }else {
611 m = BITS(0,3) | BIT(5) << 4; 595 m = BITS(0,3) | BIT(5) << 4;
612 n = BITS(16,19) | BIT(7) << 4; 596 n = BITS(16,19) | BIT(7) << 4;
613 d = BIT(22) << 4 | BITS(12,15); 597 d = BIT(22) << 4 | BITS(12,15);
614 //mm = SITOFP(32,RSPR(m)); 598 //mm = SITOFP(32,RSPR(m));
615 //LETS(d,tmp); 599 //LETS(d,tmp);
616 mm = ZEXT64(IBITCAST32(FR32(2 * m))); 600 mm = ZEXT64(IBITCAST32(FR32(2 * m)));
617 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); 601 nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
618 tmp = OR(SHL(nn,CONST64(32)),mm); 602 tmp = OR(SHL(nn,CONST64(32)),mm);
619 mm = FPBITCAST64(tmp); 603 mm = FPBITCAST64(tmp);
620 tmp = ZEXT64(IBITCAST32(FR32(2 * n))); 604 tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
621 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); 605 nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
622 nn = OR(SHL(nn,CONST64(32)),tmp); 606 nn = OR(SHL(nn,CONST64(32)),tmp);
623 nn = FPBITCAST64(nn); 607 nn = FPBITCAST64(nn);
624 tmp = FPMUL(nn,mm); 608 tmp = FPMUL(nn,mm);
625 tmp = FPNEG64(tmp); 609 tmp = FPNEG64(tmp);
626 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); 610 mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
627 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); 611 nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
628 LETFPS(2*d ,FPBITCAST32(nn)); 612 LETFPS(2*d ,FPBITCAST32(nn));
629 LETFPS(d*2 + 1 , FPBITCAST32(mm)); 613 LETFPS(d*2 + 1 , FPBITCAST32(mm));
630 } 614 }
631 return No_exp; 615 return No_exp;
632} 616}
633#endif 617#endif
634 618
@@ -638,52 +622,52 @@ int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
638/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ 622/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
639#ifdef VFP_INTERPRETER_STRUCT 623#ifdef VFP_INTERPRETER_STRUCT
640typedef struct _vmul_inst { 624typedef struct _vmul_inst {
641 unsigned int instr; 625 unsigned int instr;
642 unsigned int dp_operation; 626 unsigned int dp_operation;
643} vmul_inst; 627} vmul_inst;
644#endif 628#endif
645#ifdef VFP_INTERPRETER_TRANS 629#ifdef VFP_INTERPRETER_TRANS
646ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) 630ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
647{ 631{
648 VFP_DEBUG_TRANSLATE; 632 VFP_DEBUG_TRANSLATE;
649
650 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
651 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
652 633
653 inst_base->cond = BITS(inst, 28, 31); 634 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
654 inst_base->idx = index; 635 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
655 inst_base->br = NON_BRANCH;
656 inst_base->load_r15 = 0;
657 636
658 inst_cream->dp_operation = BIT(inst, 8); 637 inst_base->cond = BITS(inst, 28, 31);
659 inst_cream->instr = inst; 638 inst_base->idx = index;
660 639 inst_base->br = NON_BRANCH;
661 return inst_base; 640 inst_base->load_r15 = 0;
641
642 inst_cream->dp_operation = BIT(inst, 8);
643 inst_cream->instr = inst;
644
645 return inst_base;
662} 646}
663#endif 647#endif
664#ifdef VFP_INTERPRETER_IMPL 648#ifdef VFP_INTERPRETER_IMPL
665VMUL_INST: 649VMUL_INST:
666{ 650{
667 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 651 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
668 CHECK_VFP_ENABLED; 652 CHECK_VFP_ENABLED;
669 653
670 DBG("VMUL :\n"); 654 DBG("VMUL :\n");
655
656 vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
671 657
672 vmul_inst *inst_cream = (vmul_inst *)inst_base->component; 658 int ret;
673 659
674 int ret; 660 if (inst_cream->dp_operation)
675 661 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
676 if (inst_cream->dp_operation) 662 else
677 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 663 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
678 else
679 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
680 664
681 CHECK_VFP_CDP_RET; 665 CHECK_VFP_CDP_RET;
682 } 666 }
683 cpu->Reg[15] += GET_INST_SIZE(cpu); 667 cpu->Reg[15] += GET_INST_SIZE(cpu);
684 INC_PC(sizeof(vmul_inst)); 668 INC_PC(sizeof(vmul_inst));
685 FETCH_INST; 669 FETCH_INST;
686 GOTO_NEXT_INST; 670 GOTO_NEXT_INST;
687} 671}
688#endif 672#endif
689 673
@@ -693,70 +677,70 @@ DYNCOM_FILL_ACTION(vmul),
693#ifdef VFP_DYNCOM_TAG 677#ifdef VFP_DYNCOM_TAG
694int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 678int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
695{ 679{
696 int instr_size = INSTR_SIZE; 680 int instr_size = INSTR_SIZE;
697 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 681 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
698 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 682 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
699 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 683 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
700 return instr_size; 684 return instr_size;
701} 685}
702#endif 686#endif
703#ifdef VFP_DYNCOM_TRANS 687#ifdef VFP_DYNCOM_TRANS
704int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 688int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
705 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 689 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
706 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); 690 //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__);
707 //arch_arm_undef(cpu, bb, instr); 691 //arch_arm_undef(cpu, bb, instr);
708 int m; 692 int m;
709 int n; 693 int n;
710 int d ; 694 int d ;
711 int s = BIT(8) == 0; 695 int s = BIT(8) == 0;
712 Value *mm; 696 Value *mm;
713 Value *nn; 697 Value *nn;
714 Value *tmp; 698 Value *tmp;
715 if(s){ 699 if(s){
716 m = BIT(5) | BITS(0,3) << 1; 700 m = BIT(5) | BITS(0,3) << 1;
717 n = BIT(7) | BITS(16,19) << 1; 701 n = BIT(7) | BITS(16,19) << 1;
718 d = BIT(22) | BITS(12,15) << 1; 702 d = BIT(22) | BITS(12,15) << 1;
719 //mm = SITOFP(32,FR(m)); 703 //mm = SITOFP(32,FR(m));
720 //nn = SITOFP(32,FRn)); 704 //nn = SITOFP(32,FRn));
721 mm = FR32(m); 705 mm = FR32(m);
722 nn = FR32(n); 706 nn = FR32(n);
723 tmp = FPMUL(nn,mm); 707 tmp = FPMUL(nn,mm);
724 //LETS(d,tmp); 708 //LETS(d,tmp);
725 LETFPS(d,tmp); 709 LETFPS(d,tmp);
726 }else { 710 }else {
727 m = BITS(0,3) | BIT(5) << 4; 711 m = BITS(0,3) | BIT(5) << 4;
728 n = BITS(16,19) | BIT(7) << 4; 712 n = BITS(16,19) | BIT(7) << 4;
729 d = BIT(22) << 4 | BITS(12,15); 713 d = BIT(22) << 4 | BITS(12,15);
730 //mm = SITOFP(32,RSPR(m)); 714 //mm = SITOFP(32,RSPR(m));
731 //LETS(d,tmp); 715 //LETS(d,tmp);
732 Value *lo = FR32(2 * m); 716 Value *lo = FR32(2 * m);
733 Value *hi = FR32(2 * m + 1); 717 Value *hi = FR32(2 * m + 1);
734 hi = IBITCAST32(hi); 718 hi = IBITCAST32(hi);
735 lo = IBITCAST32(lo); 719 lo = IBITCAST32(lo);
736 Value *hi64 = ZEXT64(hi); 720 Value *hi64 = ZEXT64(hi);
737 Value* lo64 = ZEXT64(lo); 721 Value* lo64 = ZEXT64(lo);
738 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 722 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
739 Value* m0 = FPBITCAST64(v64); 723 Value* m0 = FPBITCAST64(v64);
740 lo = FR32(2 * n); 724 lo = FR32(2 * n);
741 hi = FR32(2 * n + 1); 725 hi = FR32(2 * n + 1);
742 hi = IBITCAST32(hi); 726 hi = IBITCAST32(hi);
743 lo = IBITCAST32(lo); 727 lo = IBITCAST32(lo);
744 hi64 = ZEXT64(hi); 728 hi64 = ZEXT64(hi);
745 lo64 = ZEXT64(lo); 729 lo64 = ZEXT64(lo);
746 v64 = OR(SHL(hi64,CONST64(32)),lo64); 730 v64 = OR(SHL(hi64,CONST64(32)),lo64);
747 Value *n0 = FPBITCAST64(v64); 731 Value *n0 = FPBITCAST64(v64);
748 tmp = FPMUL(n0,m0); 732 tmp = FPMUL(n0,m0);
749 Value *val64 = IBITCAST64(tmp); 733 Value *val64 = IBITCAST64(tmp);
750 hi = LSHR(val64,CONST64(32)); 734 hi = LSHR(val64,CONST64(32));
751 lo = AND(val64,CONST64(0xffffffff)); 735 lo = AND(val64,CONST64(0xffffffff));
752 hi = TRUNC32(hi); 736 hi = TRUNC32(hi);
753 lo = TRUNC32(lo); 737 lo = TRUNC32(lo);
754 hi = FPBITCAST32(hi); 738 hi = FPBITCAST32(hi);
755 lo = FPBITCAST32(lo); 739 lo = FPBITCAST32(lo);
756 LETFPS(2*d ,lo); 740 LETFPS(2*d ,lo);
757 LETFPS(d*2 + 1 , hi); 741 LETFPS(d*2 + 1 , hi);
758 } 742 }
759 return No_exp; 743 return No_exp;
760} 744}
761#endif 745#endif
762 746
@@ -765,52 +749,52 @@ int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
765/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */ 749/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
766#ifdef VFP_INTERPRETER_STRUCT 750#ifdef VFP_INTERPRETER_STRUCT
767typedef struct _vadd_inst { 751typedef struct _vadd_inst {
768 unsigned int instr; 752 unsigned int instr;
769 unsigned int dp_operation; 753 unsigned int dp_operation;
770} vadd_inst; 754} vadd_inst;
771#endif 755#endif
772#ifdef VFP_INTERPRETER_TRANS 756#ifdef VFP_INTERPRETER_TRANS
773ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) 757ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
774{ 758{
775 VFP_DEBUG_TRANSLATE; 759 VFP_DEBUG_TRANSLATE;
776
777 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
778 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
779 760
780 inst_base->cond = BITS(inst, 28, 31); 761 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
781 inst_base->idx = index; 762 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
782 inst_base->br = NON_BRANCH;
783 inst_base->load_r15 = 0;
784 763
785 inst_cream->dp_operation = BIT(inst, 8); 764 inst_base->cond = BITS(inst, 28, 31);
786 inst_cream->instr = inst; 765 inst_base->idx = index;
787 766 inst_base->br = NON_BRANCH;
788 return inst_base; 767 inst_base->load_r15 = 0;
768
769 inst_cream->dp_operation = BIT(inst, 8);
770 inst_cream->instr = inst;
771
772 return inst_base;
789} 773}
790#endif 774#endif
791#ifdef VFP_INTERPRETER_IMPL 775#ifdef VFP_INTERPRETER_IMPL
792VADD_INST: 776VADD_INST:
793{ 777{
794 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 778 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
795 CHECK_VFP_ENABLED; 779 CHECK_VFP_ENABLED;
796 780
797 DBG("VADD :\n"); 781 DBG("VADD :\n");
798 782
799 vadd_inst *inst_cream = (vadd_inst *)inst_base->component; 783 vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
800 784
801 int ret; 785 int ret;
802
803 if (inst_cream->dp_operation)
804 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
805 else
806 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
807 786
808 CHECK_VFP_CDP_RET; 787 if (inst_cream->dp_operation)
809 } 788 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
810 cpu->Reg[15] += GET_INST_SIZE(cpu); 789 else
811 INC_PC(sizeof(vadd_inst)); 790 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
812 FETCH_INST; 791
813 GOTO_NEXT_INST; 792 CHECK_VFP_CDP_RET;
793 }
794 cpu->Reg[15] += GET_INST_SIZE(cpu);
795 INC_PC(sizeof(vadd_inst));
796 FETCH_INST;
797 GOTO_NEXT_INST;
814} 798}
815#endif 799#endif
816 800
@@ -820,64 +804,64 @@ DYNCOM_FILL_ACTION(vadd),
820#ifdef VFP_DYNCOM_TAG 804#ifdef VFP_DYNCOM_TAG
821int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 805int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
822{ 806{
823 int instr_size = INSTR_SIZE; 807 int instr_size = INSTR_SIZE;
824 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 808 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
825 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 809 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
826 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 810 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
827 return instr_size; 811 return instr_size;
828} 812}
829#endif 813#endif
830#ifdef VFP_DYNCOM_TRANS 814#ifdef VFP_DYNCOM_TRANS
831int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 815int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
832 DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); 816 DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
833 //arch_arm_undef(cpu, bb, instr); 817 //arch_arm_undef(cpu, bb, instr);
834 int m; 818 int m;
835 int n; 819 int n;
836 int d ; 820 int d ;
837 int s = BIT(8) == 0; 821 int s = BIT(8) == 0;
838 Value *mm; 822 Value *mm;
839 Value *nn; 823 Value *nn;
840 Value *tmp; 824 Value *tmp;
841 if(s){ 825 if(s){
842 m = BIT(5) | BITS(0,3) << 1; 826 m = BIT(5) | BITS(0,3) << 1;
843 n = BIT(7) | BITS(16,19) << 1; 827 n = BIT(7) | BITS(16,19) << 1;
844 d = BIT(22) | BITS(12,15) << 1; 828 d = BIT(22) | BITS(12,15) << 1;
845 mm = FR32(m); 829 mm = FR32(m);
846 nn = FR32(n); 830 nn = FR32(n);
847 tmp = FPADD(nn,mm); 831 tmp = FPADD(nn,mm);
848 LETFPS(d,tmp); 832 LETFPS(d,tmp);
849 }else { 833 }else {
850 m = BITS(0,3) | BIT(5) << 4; 834 m = BITS(0,3) | BIT(5) << 4;
851 n = BITS(16,19) | BIT(7) << 4; 835 n = BITS(16,19) | BIT(7) << 4;
852 d = BIT(22) << 4 | BITS(12,15); 836 d = BIT(22) << 4 | BITS(12,15);
853 Value *lo = FR32(2 * m); 837 Value *lo = FR32(2 * m);
854 Value *hi = FR32(2 * m + 1); 838 Value *hi = FR32(2 * m + 1);
855 hi = IBITCAST32(hi); 839 hi = IBITCAST32(hi);
856 lo = IBITCAST32(lo); 840 lo = IBITCAST32(lo);
857 Value *hi64 = ZEXT64(hi); 841 Value *hi64 = ZEXT64(hi);
858 Value* lo64 = ZEXT64(lo); 842 Value* lo64 = ZEXT64(lo);
859 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 843 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
860 Value* m0 = FPBITCAST64(v64); 844 Value* m0 = FPBITCAST64(v64);
861 lo = FR32(2 * n); 845 lo = FR32(2 * n);
862 hi = FR32(2 * n + 1); 846 hi = FR32(2 * n + 1);
863 hi = IBITCAST32(hi); 847 hi = IBITCAST32(hi);
864 lo = IBITCAST32(lo); 848 lo = IBITCAST32(lo);
865 hi64 = ZEXT64(hi); 849 hi64 = ZEXT64(hi);
866 lo64 = ZEXT64(lo); 850 lo64 = ZEXT64(lo);
867 v64 = OR(SHL(hi64,CONST64(32)),lo64); 851 v64 = OR(SHL(hi64,CONST64(32)),lo64);
868 Value *n0 = FPBITCAST64(v64); 852 Value *n0 = FPBITCAST64(v64);
869 tmp = FPADD(n0,m0); 853 tmp = FPADD(n0,m0);
870 Value *val64 = IBITCAST64(tmp); 854 Value *val64 = IBITCAST64(tmp);
871 hi = LSHR(val64,CONST64(32)); 855 hi = LSHR(val64,CONST64(32));
872 lo = AND(val64,CONST64(0xffffffff)); 856 lo = AND(val64,CONST64(0xffffffff));
873 hi = TRUNC32(hi); 857 hi = TRUNC32(hi);
874 lo = TRUNC32(lo); 858 lo = TRUNC32(lo);
875 hi = FPBITCAST32(hi); 859 hi = FPBITCAST32(hi);
876 lo = FPBITCAST32(lo); 860 lo = FPBITCAST32(lo);
877 LETFPS(2*d ,lo); 861 LETFPS(2*d ,lo);
878 LETFPS(d*2 + 1 , hi); 862 LETFPS(d*2 + 1 , hi);
879 } 863 }
880 return No_exp; 864 return No_exp;
881} 865}
882#endif 866#endif
883 867
@@ -886,52 +870,52 @@ int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
886/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */ 870/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
887#ifdef VFP_INTERPRETER_STRUCT 871#ifdef VFP_INTERPRETER_STRUCT
888typedef struct _vsub_inst { 872typedef struct _vsub_inst {
889 unsigned int instr; 873 unsigned int instr;
890 unsigned int dp_operation; 874 unsigned int dp_operation;
891} vsub_inst; 875} vsub_inst;
892#endif 876#endif
893#ifdef VFP_INTERPRETER_TRANS 877#ifdef VFP_INTERPRETER_TRANS
894ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) 878ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
895{ 879{
896 VFP_DEBUG_TRANSLATE; 880 VFP_DEBUG_TRANSLATE;
897 881
898 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); 882 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
899 vsub_inst *inst_cream = (vsub_inst *)inst_base->component; 883 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
900 884
901 inst_base->cond = BITS(inst, 28, 31); 885 inst_base->cond = BITS(inst, 28, 31);
902 inst_base->idx = index; 886 inst_base->idx = index;
903 inst_base->br = NON_BRANCH; 887 inst_base->br = NON_BRANCH;
904 inst_base->load_r15 = 0; 888 inst_base->load_r15 = 0;
905 889
906 inst_cream->dp_operation = BIT(inst, 8); 890 inst_cream->dp_operation = BIT(inst, 8);
907 inst_cream->instr = inst; 891 inst_cream->instr = inst;
908 892
909 return inst_base; 893 return inst_base;
910} 894}
911#endif 895#endif
912#ifdef VFP_INTERPRETER_IMPL 896#ifdef VFP_INTERPRETER_IMPL
913VSUB_INST: 897VSUB_INST:
914{ 898{
915 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 899 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
916 CHECK_VFP_ENABLED; 900 CHECK_VFP_ENABLED;
917 901
918 DBG("VSUB :\n"); 902 DBG("VSUB :\n");
919 903
920 vsub_inst *inst_cream = (vsub_inst *)inst_base->component; 904 vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
921 905
922 int ret; 906 int ret;
923
924 if (inst_cream->dp_operation)
925 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
926 else
927 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
928 907
929 CHECK_VFP_CDP_RET; 908 if (inst_cream->dp_operation)
930 } 909 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
931 cpu->Reg[15] += GET_INST_SIZE(cpu); 910 else
932 INC_PC(sizeof(vsub_inst)); 911 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
933 FETCH_INST; 912
934 GOTO_NEXT_INST; 913 CHECK_VFP_CDP_RET;
914 }
915 cpu->Reg[15] += GET_INST_SIZE(cpu);
916 INC_PC(sizeof(vsub_inst));
917 FETCH_INST;
918 GOTO_NEXT_INST;
935} 919}
936#endif 920#endif
937#ifdef VFP_DYNCOM_TABLE 921#ifdef VFP_DYNCOM_TABLE
@@ -940,63 +924,63 @@ DYNCOM_FILL_ACTION(vsub),
940#ifdef VFP_DYNCOM_TAG 924#ifdef VFP_DYNCOM_TAG
941int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 925int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
942{ 926{
943 int instr_size = INSTR_SIZE; 927 int instr_size = INSTR_SIZE;
944 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 928 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
945 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 929 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
946 return instr_size; 930 return instr_size;
947} 931}
948#endif 932#endif
949#ifdef VFP_DYNCOM_TRANS 933#ifdef VFP_DYNCOM_TRANS
950int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 934int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
951 DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); 935 DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
952 //arch_arm_undef(cpu, bb, instr); 936 //arch_arm_undef(cpu, bb, instr);
953 int m; 937 int m;
954 int n; 938 int n;
955 int d ; 939 int d ;
956 int s = BIT(8) == 0; 940 int s = BIT(8) == 0;
957 Value *mm; 941 Value *mm;
958 Value *nn; 942 Value *nn;
959 Value *tmp; 943 Value *tmp;
960 if(s){ 944 if(s){
961 m = BIT(5) | BITS(0,3) << 1; 945 m = BIT(5) | BITS(0,3) << 1;
962 n = BIT(7) | BITS(16,19) << 1; 946 n = BIT(7) | BITS(16,19) << 1;
963 d = BIT(22) | BITS(12,15) << 1; 947 d = BIT(22) | BITS(12,15) << 1;
964 mm = FR32(m); 948 mm = FR32(m);
965 nn = FR32(n); 949 nn = FR32(n);
966 tmp = FPSUB(nn,mm); 950 tmp = FPSUB(nn,mm);
967 LETFPS(d,tmp); 951 LETFPS(d,tmp);
968 }else { 952 }else {
969 m = BITS(0,3) | BIT(5) << 4; 953 m = BITS(0,3) | BIT(5) << 4;
970 n = BITS(16,19) | BIT(7) << 4; 954 n = BITS(16,19) | BIT(7) << 4;
971 d = BIT(22) << 4 | BITS(12,15); 955 d = BIT(22) << 4 | BITS(12,15);
972 Value *lo = FR32(2 * m); 956 Value *lo = FR32(2 * m);
973 Value *hi = FR32(2 * m + 1); 957 Value *hi = FR32(2 * m + 1);
974 hi = IBITCAST32(hi); 958 hi = IBITCAST32(hi);
975 lo = IBITCAST32(lo); 959 lo = IBITCAST32(lo);
976 Value *hi64 = ZEXT64(hi); 960 Value *hi64 = ZEXT64(hi);
977 Value* lo64 = ZEXT64(lo); 961 Value* lo64 = ZEXT64(lo);
978 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 962 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
979 Value* m0 = FPBITCAST64(v64); 963 Value* m0 = FPBITCAST64(v64);
980 lo = FR32(2 * n); 964 lo = FR32(2 * n);
981 hi = FR32(2 * n + 1); 965 hi = FR32(2 * n + 1);
982 hi = IBITCAST32(hi); 966 hi = IBITCAST32(hi);
983 lo = IBITCAST32(lo); 967 lo = IBITCAST32(lo);
984 hi64 = ZEXT64(hi); 968 hi64 = ZEXT64(hi);
985 lo64 = ZEXT64(lo); 969 lo64 = ZEXT64(lo);
986 v64 = OR(SHL(hi64,CONST64(32)),lo64); 970 v64 = OR(SHL(hi64,CONST64(32)),lo64);
987 Value *n0 = FPBITCAST64(v64); 971 Value *n0 = FPBITCAST64(v64);
988 tmp = FPSUB(n0,m0); 972 tmp = FPSUB(n0,m0);
989 Value *val64 = IBITCAST64(tmp); 973 Value *val64 = IBITCAST64(tmp);
990 hi = LSHR(val64,CONST64(32)); 974 hi = LSHR(val64,CONST64(32));
991 lo = AND(val64,CONST64(0xffffffff)); 975 lo = AND(val64,CONST64(0xffffffff));
992 hi = TRUNC32(hi); 976 hi = TRUNC32(hi);
993 lo = TRUNC32(lo); 977 lo = TRUNC32(lo);
994 hi = FPBITCAST32(hi); 978 hi = FPBITCAST32(hi);
995 lo = FPBITCAST32(lo); 979 lo = FPBITCAST32(lo);
996 LETFPS(2*d ,lo); 980 LETFPS(2*d ,lo);
997 LETFPS(d*2 + 1 , hi); 981 LETFPS(d*2 + 1 , hi);
998 } 982 }
999 return No_exp; 983 return No_exp;
1000} 984}
1001#endif 985#endif
1002 986
@@ -1005,52 +989,52 @@ int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1005/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */ 989/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
1006#ifdef VFP_INTERPRETER_STRUCT 990#ifdef VFP_INTERPRETER_STRUCT
1007typedef struct _vdiv_inst { 991typedef struct _vdiv_inst {
1008 unsigned int instr; 992 unsigned int instr;
1009 unsigned int dp_operation; 993 unsigned int dp_operation;
1010} vdiv_inst; 994} vdiv_inst;
1011#endif 995#endif
1012#ifdef VFP_INTERPRETER_TRANS 996#ifdef VFP_INTERPRETER_TRANS
1013ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) 997ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
1014{ 998{
1015 VFP_DEBUG_TRANSLATE; 999 VFP_DEBUG_TRANSLATE;
1016 1000
1017 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); 1001 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
1018 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; 1002 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1019 1003
1020 inst_base->cond = BITS(inst, 28, 31); 1004 inst_base->cond = BITS(inst, 28, 31);
1021 inst_base->idx = index; 1005 inst_base->idx = index;
1022 inst_base->br = NON_BRANCH; 1006 inst_base->br = NON_BRANCH;
1023 inst_base->load_r15 = 0; 1007 inst_base->load_r15 = 0;
1024 1008
1025 inst_cream->dp_operation = BIT(inst, 8); 1009 inst_cream->dp_operation = BIT(inst, 8);
1026 inst_cream->instr = inst; 1010 inst_cream->instr = inst;
1027 1011
1028 return inst_base; 1012 return inst_base;
1029} 1013}
1030#endif 1014#endif
1031#ifdef VFP_INTERPRETER_IMPL 1015#ifdef VFP_INTERPRETER_IMPL
1032VDIV_INST: 1016VDIV_INST:
1033{ 1017{
1034 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1018 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1035 CHECK_VFP_ENABLED; 1019 CHECK_VFP_ENABLED;
1036 1020
1037 DBG("VDIV :\n"); 1021 DBG("VDIV :\n");
1038 1022
1039 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; 1023 vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
1040 1024
1041 int ret; 1025 int ret;
1042
1043 if (inst_cream->dp_operation)
1044 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1045 else
1046 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1047 1026
1048 CHECK_VFP_CDP_RET; 1027 if (inst_cream->dp_operation)
1049 } 1028 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1050 cpu->Reg[15] += GET_INST_SIZE(cpu); 1029 else
1051 INC_PC(sizeof(vdiv_inst)); 1030 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1052 FETCH_INST; 1031
1053 GOTO_NEXT_INST; 1032 CHECK_VFP_CDP_RET;
1033 }
1034 cpu->Reg[15] += GET_INST_SIZE(cpu);
1035 INC_PC(sizeof(vdiv_inst));
1036 FETCH_INST;
1037 GOTO_NEXT_INST;
1054} 1038}
1055#endif 1039#endif
1056 1040
@@ -1060,64 +1044,64 @@ DYNCOM_FILL_ACTION(vdiv),
1060#ifdef VFP_DYNCOM_TAG 1044#ifdef VFP_DYNCOM_TAG
1061int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1045int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1062{ 1046{
1063 int instr_size = INSTR_SIZE; 1047 int instr_size = INSTR_SIZE;
1064 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1048 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1065 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1049 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1066 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1050 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1067 return instr_size; 1051 return instr_size;
1068} 1052}
1069#endif 1053#endif
1070#ifdef VFP_DYNCOM_TRANS 1054#ifdef VFP_DYNCOM_TRANS
1071int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1055int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1072 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1056 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1073 //arch_arm_undef(cpu, bb, instr); 1057 //arch_arm_undef(cpu, bb, instr);
1074 int m; 1058 int m;
1075 int n; 1059 int n;
1076 int d ; 1060 int d ;
1077 int s = BIT(8) == 0; 1061 int s = BIT(8) == 0;
1078 Value *mm; 1062 Value *mm;
1079 Value *nn; 1063 Value *nn;
1080 Value *tmp; 1064 Value *tmp;
1081 if(s){ 1065 if(s){
1082 m = BIT(5) | BITS(0,3) << 1; 1066 m = BIT(5) | BITS(0,3) << 1;
1083 n = BIT(7) | BITS(16,19) << 1; 1067 n = BIT(7) | BITS(16,19) << 1;
1084 d = BIT(22) | BITS(12,15) << 1; 1068 d = BIT(22) | BITS(12,15) << 1;
1085 mm = FR32(m); 1069 mm = FR32(m);
1086 nn = FR32(n); 1070 nn = FR32(n);
1087 tmp = FPDIV(nn,mm); 1071 tmp = FPDIV(nn,mm);
1088 LETFPS(d,tmp); 1072 LETFPS(d,tmp);
1089 }else { 1073 }else {
1090 m = BITS(0,3) | BIT(5) << 4; 1074 m = BITS(0,3) | BIT(5) << 4;
1091 n = BITS(16,19) | BIT(7) << 4; 1075 n = BITS(16,19) | BIT(7) << 4;
1092 d = BIT(22) << 4 | BITS(12,15); 1076 d = BIT(22) << 4 | BITS(12,15);
1093 Value *lo = FR32(2 * m); 1077 Value *lo = FR32(2 * m);
1094 Value *hi = FR32(2 * m + 1); 1078 Value *hi = FR32(2 * m + 1);
1095 hi = IBITCAST32(hi); 1079 hi = IBITCAST32(hi);
1096 lo = IBITCAST32(lo); 1080 lo = IBITCAST32(lo);
1097 Value *hi64 = ZEXT64(hi); 1081 Value *hi64 = ZEXT64(hi);
1098 Value* lo64 = ZEXT64(lo); 1082 Value* lo64 = ZEXT64(lo);
1099 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 1083 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
1100 Value* m0 = FPBITCAST64(v64); 1084 Value* m0 = FPBITCAST64(v64);
1101 lo = FR32(2 * n); 1085 lo = FR32(2 * n);
1102 hi = FR32(2 * n + 1); 1086 hi = FR32(2 * n + 1);
1103 hi = IBITCAST32(hi); 1087 hi = IBITCAST32(hi);
1104 lo = IBITCAST32(lo); 1088 lo = IBITCAST32(lo);
1105 hi64 = ZEXT64(hi); 1089 hi64 = ZEXT64(hi);
1106 lo64 = ZEXT64(lo); 1090 lo64 = ZEXT64(lo);
1107 v64 = OR(SHL(hi64,CONST64(32)),lo64); 1091 v64 = OR(SHL(hi64,CONST64(32)),lo64);
1108 Value *n0 = FPBITCAST64(v64); 1092 Value *n0 = FPBITCAST64(v64);
1109 tmp = FPDIV(n0,m0); 1093 tmp = FPDIV(n0,m0);
1110 Value *val64 = IBITCAST64(tmp); 1094 Value *val64 = IBITCAST64(tmp);
1111 hi = LSHR(val64,CONST64(32)); 1095 hi = LSHR(val64,CONST64(32));
1112 lo = AND(val64,CONST64(0xffffffff)); 1096 lo = AND(val64,CONST64(0xffffffff));
1113 hi = TRUNC32(hi); 1097 hi = TRUNC32(hi);
1114 lo = TRUNC32(lo); 1098 lo = TRUNC32(lo);
1115 hi = FPBITCAST32(hi); 1099 hi = FPBITCAST32(hi);
1116 lo = FPBITCAST32(lo); 1100 lo = FPBITCAST32(lo);
1117 LETFPS(2*d ,lo); 1101 LETFPS(2*d ,lo);
1118 LETFPS(d*2 + 1 , hi); 1102 LETFPS(d*2 + 1 , hi);
1119 } 1103 }
1120 return No_exp; 1104 return No_exp;
1121} 1105}
1122#endif 1106#endif
1123 1107
@@ -1127,48 +1111,48 @@ int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1127/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1111/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
1128#ifdef VFP_INTERPRETER_STRUCT 1112#ifdef VFP_INTERPRETER_STRUCT
1129typedef struct _vmovi_inst { 1113typedef struct _vmovi_inst {
1130 unsigned int single; 1114 unsigned int single;
1131 unsigned int d; 1115 unsigned int d;
1132 unsigned int imm; 1116 unsigned int imm;
1133} vmovi_inst; 1117} vmovi_inst;
1134#endif 1118#endif
1135#ifdef VFP_INTERPRETER_TRANS 1119#ifdef VFP_INTERPRETER_TRANS
1136ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) 1120ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
1137{ 1121{
1138 VFP_DEBUG_TRANSLATE; 1122 VFP_DEBUG_TRANSLATE;
1139 1123
1140 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); 1124 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
1141 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; 1125 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1142 1126
1143 inst_base->cond = BITS(inst, 28, 31); 1127 inst_base->cond = BITS(inst, 28, 31);
1144 inst_base->idx = index; 1128 inst_base->idx = index;
1145 inst_base->br = NON_BRANCH; 1129 inst_base->br = NON_BRANCH;
1146 inst_base->load_r15 = 0; 1130 inst_base->load_r15 = 0;
1147 1131
1148 inst_cream->single = BIT(inst, 8) == 0; 1132 inst_cream->single = BIT(inst, 8) == 0;
1149 inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); 1133 inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
1150 unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3); 1134 unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3);
1151 if (inst_cream->single) 1135 if (inst_cream->single)
1152 inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19; 1136 inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19;
1153 else 1137 else
1154 inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16; 1138 inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16;
1155 return inst_base; 1139 return inst_base;
1156} 1140}
1157#endif 1141#endif
1158#ifdef VFP_INTERPRETER_IMPL 1142#ifdef VFP_INTERPRETER_IMPL
1159VMOVI_INST: 1143VMOVI_INST:
1160{ 1144{
1161 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1145 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1162 CHECK_VFP_ENABLED; 1146 CHECK_VFP_ENABLED;
1163
1164 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1165 1147
1166 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); 1148 vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
1167 } 1149
1168 cpu->Reg[15] += GET_INST_SIZE(cpu); 1150 VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
1169 INC_PC(sizeof(vmovi_inst)); 1151 }
1170 FETCH_INST; 1152 cpu->Reg[15] += GET_INST_SIZE(cpu);
1171 GOTO_NEXT_INST; 1153 INC_PC(sizeof(vmovi_inst));
1154 FETCH_INST;
1155 GOTO_NEXT_INST;
1172} 1156}
1173#endif 1157#endif
1174 1158
@@ -1178,37 +1162,37 @@ DYNCOM_FILL_ACTION(vmovi),
1178#ifdef VFP_DYNCOM_TAG 1162#ifdef VFP_DYNCOM_TAG
1179int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1163int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1180{ 1164{
1181 int instr_size = INSTR_SIZE; 1165 int instr_size = INSTR_SIZE;
1182 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1166 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1183 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1167 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1184 return instr_size; 1168 return instr_size;
1185} 1169}
1186#endif 1170#endif
1187#ifdef VFP_DYNCOM_TRANS 1171#ifdef VFP_DYNCOM_TRANS
1188int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1172int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1189 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1173 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1190 //arch_arm_undef(cpu, bb, instr); 1174 //arch_arm_undef(cpu, bb, instr);
1191 int single = (BIT(8) == 0); 1175 int single = (BIT(8) == 0);
1192 int d; 1176 int d;
1193 int imm32; 1177 int imm32;
1194 Value *v; 1178 Value *v;
1195 Value *tmp; 1179 Value *tmp;
1196 v = CONST32(BITS(0,3) | BITS(16,19) << 4); 1180 v = CONST32(BITS(0,3) | BITS(16,19) << 4);
1197 //v = CONST64(0x3ff0000000000000); 1181 //v = CONST64(0x3ff0000000000000);
1198 if(single){ 1182 if(single){
1199 d = BIT(22) | BITS(12,15) << 1; 1183 d = BIT(22) | BITS(12,15) << 1;
1200 }else { 1184 }else {
1201 d = BITS(12,15) | BIT(22) << 4; 1185 d = BITS(12,15) | BIT(22) << 4;
1202 } 1186 }
1203 if(single){ 1187 if(single){
1204 LETFPS(d,FPBITCAST32(v)); 1188 LETFPS(d,FPBITCAST32(v));
1205 }else { 1189 }else {
1206 //v = UITOFP(64,v); 1190 //v = UITOFP(64,v);
1207 //tmp = IBITCAST64(v); 1191 //tmp = IBITCAST64(v);
1208 LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))))); 1192 LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))));
1209 LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))))); 1193 LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))));
1210 } 1194 }
1211 return No_exp; 1195 return No_exp;
1212} 1196}
1213#endif 1197#endif
1214 1198
@@ -1218,45 +1202,44 @@ int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1218/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ 1202/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
1219#ifdef VFP_INTERPRETER_STRUCT 1203#ifdef VFP_INTERPRETER_STRUCT
1220typedef struct _vmovr_inst { 1204typedef struct _vmovr_inst {
1221 unsigned int single; 1205 unsigned int single;
1222 unsigned int d; 1206 unsigned int d;
1223 unsigned int m; 1207 unsigned int m;
1224} vmovr_inst; 1208} vmovr_inst;
1225#endif 1209#endif
1226#ifdef VFP_INTERPRETER_TRANS 1210#ifdef VFP_INTERPRETER_TRANS
1227ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) 1211ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
1228{ 1212{
1229 VFP_DEBUG_TRANSLATE; 1213 VFP_DEBUG_TRANSLATE;
1230 VFP_DEBUG_UNTESTED(VMOVR); 1214
1231 1215 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
1232 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); 1216 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1233 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; 1217
1218 inst_base->cond = BITS(inst, 28, 31);
1219 inst_base->idx = index;
1220 inst_base->br = NON_BRANCH;
1221 inst_base->load_r15 = 0;
1234 1222
1235 inst_base->cond = BITS(inst, 28, 31); 1223 inst_cream->single = BIT(inst, 8) == 0;
1236 inst_base->idx = index; 1224 inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
1237 inst_base->br = NON_BRANCH; 1225 inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
1238 inst_base->load_r15 = 0; 1226 return inst_base;
1239
1240 inst_cream->single = BIT(inst, 8) == 0;
1241 inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
1242 inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
1243 return inst_base;
1244} 1227}
1245#endif 1228#endif
1246#ifdef VFP_INTERPRETER_IMPL 1229#ifdef VFP_INTERPRETER_IMPL
1247VMOVR_INST: 1230VMOVR_INST:
1248{ 1231{
1249 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1232 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1250 CHECK_VFP_ENABLED; 1233 CHECK_VFP_ENABLED;
1251
1252 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1253 1234
1254 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); 1235 vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
1255 } 1236
1256 cpu->Reg[15] += GET_INST_SIZE(cpu); 1237 VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
1257 INC_PC(sizeof(vmovr_inst)); 1238 }
1258 FETCH_INST; 1239 cpu->Reg[15] += GET_INST_SIZE(cpu);
1259 GOTO_NEXT_INST; 1240 INC_PC(sizeof(vmovr_inst));
1241 FETCH_INST;
1242 GOTO_NEXT_INST;
1260} 1243}
1261#endif 1244#endif
1262 1245
@@ -1266,33 +1249,33 @@ DYNCOM_FILL_ACTION(vmovr),
1266#ifdef VFP_DYNCOM_TAG 1249#ifdef VFP_DYNCOM_TAG
1267int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1250int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1268{ 1251{
1269 int instr_size = INSTR_SIZE; 1252 int instr_size = INSTR_SIZE;
1270 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1253 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1271 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 1254 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
1272 if(instr >> 28 != 0xe) 1255 if(instr >> 28 != 0xe)
1273 *tag |= TAG_CONDITIONAL; 1256 *tag |= TAG_CONDITIONAL;
1274 1257
1275 return instr_size; 1258 return instr_size;
1276} 1259}
1277#endif 1260#endif
1278#ifdef VFP_DYNCOM_TRANS 1261#ifdef VFP_DYNCOM_TRANS
1279int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1262int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1280 DBG("\t\tin %s VMOV \n", __FUNCTION__); 1263 DBG("\t\tin %s VMOV \n", __FUNCTION__);
1281 int single = BIT(8) == 0; 1264 int single = BIT(8) == 0;
1282 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); 1265 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
1283 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); 1266 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
1284 1267
1285 if (single) 1268 if (single)
1286 { 1269 {
1287 LETFPS(d, FR32(m)); 1270 LETFPS(d, FR32(m));
1288 } 1271 }
1289 else 1272 else
1290 { 1273 {
1291 /* Check endian please */ 1274 /* Check endian please */
1292 LETFPS((d*2 + 1), FR32(m*2 + 1)); 1275 LETFPS((d*2 + 1), FR32(m*2 + 1));
1293 LETFPS((d * 2), FR32(m * 2)); 1276 LETFPS((d * 2), FR32(m * 2));
1294 } 1277 }
1295 return No_exp; 1278 return No_exp;
1296} 1279}
1297#endif 1280#endif
1298 1281
@@ -1301,52 +1284,50 @@ int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1301/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */ 1284/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
1302#ifdef VFP_INTERPRETER_STRUCT 1285#ifdef VFP_INTERPRETER_STRUCT
1303typedef struct _vabs_inst { 1286typedef struct _vabs_inst {
1304 unsigned int instr; 1287 unsigned int instr;
1305 unsigned int dp_operation; 1288 unsigned int dp_operation;
1306} vabs_inst; 1289} vabs_inst;
1307#endif 1290#endif
1308#ifdef VFP_INTERPRETER_TRANS 1291#ifdef VFP_INTERPRETER_TRANS
1309ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) 1292ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
1310{ 1293{
1311 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS); 1294 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
1312 1295 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1313 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); 1296
1314 vabs_inst *inst_cream = (vabs_inst *)inst_base->component; 1297 inst_base->cond = BITS(inst, 28, 31);
1298 inst_base->idx = index;
1299 inst_base->br = NON_BRANCH;
1300 inst_base->load_r15 = 0;
1315 1301
1316 inst_base->cond = BITS(inst, 28, 31); 1302 inst_cream->dp_operation = BIT(inst, 8);
1317 inst_base->idx = index; 1303 inst_cream->instr = inst;
1318 inst_base->br = NON_BRANCH;
1319 inst_base->load_r15 = 0;
1320 1304
1321 inst_cream->dp_operation = BIT(inst, 8); 1305 return inst_base;
1322 inst_cream->instr = inst;
1323
1324 return inst_base;
1325} 1306}
1326#endif 1307#endif
1327#ifdef VFP_INTERPRETER_IMPL 1308#ifdef VFP_INTERPRETER_IMPL
1328VABS_INST: 1309VABS_INST:
1329{ 1310{
1330 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1311 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1331 CHECK_VFP_ENABLED; 1312 CHECK_VFP_ENABLED;
1332 1313
1333 DBG("VABS :\n"); 1314 DBG("VABS :\n");
1315
1316 vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
1334 1317
1335 vabs_inst *inst_cream = (vabs_inst *)inst_base->component; 1318 int ret;
1336 1319
1337 int ret; 1320 if (inst_cream->dp_operation)
1338 1321 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1339 if (inst_cream->dp_operation) 1322 else
1340 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 1323 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1341 else
1342 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1343 1324
1344 CHECK_VFP_CDP_RET; 1325 CHECK_VFP_CDP_RET;
1345 } 1326 }
1346 cpu->Reg[15] += GET_INST_SIZE(cpu); 1327 cpu->Reg[15] += GET_INST_SIZE(cpu);
1347 INC_PC(sizeof(vabs_inst)); 1328 INC_PC(sizeof(vabs_inst));
1348 FETCH_INST; 1329 FETCH_INST;
1349 GOTO_NEXT_INST; 1330 GOTO_NEXT_INST;
1350} 1331}
1351#endif 1332#endif
1352 1333
@@ -1356,50 +1337,50 @@ DYNCOM_FILL_ACTION(vabs),
1356#ifdef VFP_DYNCOM_TAG 1337#ifdef VFP_DYNCOM_TAG
1357int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1338int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1358{ 1339{
1359 int instr_size = INSTR_SIZE; 1340 int instr_size = INSTR_SIZE;
1360 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1341 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1361 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1342 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1362 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1343 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1363 return instr_size; 1344 return instr_size;
1364} 1345}
1365#endif 1346#endif
1366#ifdef VFP_DYNCOM_TRANS 1347#ifdef VFP_DYNCOM_TRANS
1367int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1348int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1368 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1349 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1369 //arch_arm_undef(cpu, bb, instr); 1350 //arch_arm_undef(cpu, bb, instr);
1370 int single = BIT(8) == 0; 1351 int single = BIT(8) == 0;
1371 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); 1352 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
1372 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); 1353 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
1373 Value* m0; 1354 Value* m0;
1374 if (single) 1355 if (single)
1375 { 1356 {
1376 m0 = FR32(m); 1357 m0 = FR32(m);
1377 m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0); 1358 m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0);
1378 LETFPS(d,m0); 1359 LETFPS(d,m0);
1379 } 1360 }
1380 else 1361 else
1381 { 1362 {
1382 /* Check endian please */ 1363 /* Check endian please */
1383 Value *lo = FR32(2 * m); 1364 Value *lo = FR32(2 * m);
1384 Value *hi = FR32(2 * m + 1); 1365 Value *hi = FR32(2 * m + 1);
1385 hi = IBITCAST32(hi); 1366 hi = IBITCAST32(hi);
1386 lo = IBITCAST32(lo); 1367 lo = IBITCAST32(lo);
1387 Value *hi64 = ZEXT64(hi); 1368 Value *hi64 = ZEXT64(hi);
1388 Value* lo64 = ZEXT64(lo); 1369 Value* lo64 = ZEXT64(lo);
1389 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 1370 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
1390 m0 = FPBITCAST64(v64); 1371 m0 = FPBITCAST64(v64);
1391 m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0); 1372 m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0);
1392 Value *val64 = IBITCAST64(m0); 1373 Value *val64 = IBITCAST64(m0);
1393 hi = LSHR(val64,CONST64(32)); 1374 hi = LSHR(val64,CONST64(32));
1394 lo = AND(val64,CONST64(0xffffffff)); 1375 lo = AND(val64,CONST64(0xffffffff));
1395 hi = TRUNC32(hi); 1376 hi = TRUNC32(hi);
1396 lo = TRUNC32(lo); 1377 lo = TRUNC32(lo);
1397 hi = FPBITCAST32(hi); 1378 hi = FPBITCAST32(hi);
1398 lo = FPBITCAST32(lo); 1379 lo = FPBITCAST32(lo);
1399 LETFPS(2*d ,lo); 1380 LETFPS(2*d ,lo);
1400 LETFPS(d*2 + 1 , hi); 1381 LETFPS(d*2 + 1 , hi);
1401 } 1382 }
1402 return No_exp; 1383 return No_exp;
1403} 1384}
1404#endif 1385#endif
1405 1386
@@ -1409,52 +1390,50 @@ int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1409 1390
1410#ifdef VFP_INTERPRETER_STRUCT 1391#ifdef VFP_INTERPRETER_STRUCT
1411typedef struct _vneg_inst { 1392typedef struct _vneg_inst {
1412 unsigned int instr; 1393 unsigned int instr;
1413 unsigned int dp_operation; 1394 unsigned int dp_operation;
1414} vneg_inst; 1395} vneg_inst;
1415#endif 1396#endif
1416#ifdef VFP_INTERPRETER_TRANS 1397#ifdef VFP_INTERPRETER_TRANS
1417ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) 1398ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
1418{ 1399{
1419 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG); 1400 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
1420 1401 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1421 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
1422 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1423 1402
1424 inst_base->cond = BITS(inst, 28, 31); 1403 inst_base->cond = BITS(inst, 28, 31);
1425 inst_base->idx = index; 1404 inst_base->idx = index;
1426 inst_base->br = NON_BRANCH; 1405 inst_base->br = NON_BRANCH;
1427 inst_base->load_r15 = 0; 1406 inst_base->load_r15 = 0;
1428 1407
1429 inst_cream->dp_operation = BIT(inst, 8); 1408 inst_cream->dp_operation = BIT(inst, 8);
1430 inst_cream->instr = inst; 1409 inst_cream->instr = inst;
1431 1410
1432 return inst_base; 1411 return inst_base;
1433} 1412}
1434#endif 1413#endif
1435#ifdef VFP_INTERPRETER_IMPL 1414#ifdef VFP_INTERPRETER_IMPL
1436VNEG_INST: 1415VNEG_INST:
1437{ 1416{
1438 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1417 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1439 CHECK_VFP_ENABLED; 1418 CHECK_VFP_ENABLED;
1419
1420 DBG("VNEG :\n");
1440 1421
1441 DBG("VNEG :\n"); 1422 vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
1442 1423
1443 vneg_inst *inst_cream = (vneg_inst *)inst_base->component; 1424 int ret;
1444 1425
1445 int ret; 1426 if (inst_cream->dp_operation)
1446 1427 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1447 if (inst_cream->dp_operation) 1428 else
1448 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 1429 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1449 else
1450 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1451 1430
1452 CHECK_VFP_CDP_RET; 1431 CHECK_VFP_CDP_RET;
1453 } 1432 }
1454 cpu->Reg[15] += GET_INST_SIZE(cpu); 1433 cpu->Reg[15] += GET_INST_SIZE(cpu);
1455 INC_PC(sizeof(vneg_inst)); 1434 INC_PC(sizeof(vneg_inst));
1456 FETCH_INST; 1435 FETCH_INST;
1457 GOTO_NEXT_INST; 1436 GOTO_NEXT_INST;
1458} 1437}
1459#endif 1438#endif
1460 1439
@@ -1464,50 +1443,50 @@ DYNCOM_FILL_ACTION(vneg),
1464#ifdef VFP_DYNCOM_TAG 1443#ifdef VFP_DYNCOM_TAG
1465int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1444int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1466{ 1445{
1467 int instr_size = INSTR_SIZE; 1446 int instr_size = INSTR_SIZE;
1468 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1447 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1469 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1448 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1470 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1449 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1471 return instr_size; 1450 return instr_size;
1472} 1451}
1473#endif 1452#endif
1474#ifdef VFP_DYNCOM_TRANS 1453#ifdef VFP_DYNCOM_TRANS
1475int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1454int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1476 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1455 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1477 //arch_arm_undef(cpu, bb, instr); 1456 //arch_arm_undef(cpu, bb, instr);
1478 int single = BIT(8) == 0; 1457 int single = BIT(8) == 0;
1479 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); 1458 int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
1480 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); 1459 int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
1481 Value* m0; 1460 Value* m0;
1482 if (single) 1461 if (single)
1483 { 1462 {
1484 m0 = FR32(m); 1463 m0 = FR32(m);
1485 m0 = FPNEG32(m0); 1464 m0 = FPNEG32(m0);
1486 LETFPS(d,m0); 1465 LETFPS(d,m0);
1487 } 1466 }
1488 else 1467 else
1489 { 1468 {
1490 /* Check endian please */ 1469 /* Check endian please */
1491 Value *lo = FR32(2 * m); 1470 Value *lo = FR32(2 * m);
1492 Value *hi = FR32(2 * m + 1); 1471 Value *hi = FR32(2 * m + 1);
1493 hi = IBITCAST32(hi); 1472 hi = IBITCAST32(hi);
1494 lo = IBITCAST32(lo); 1473 lo = IBITCAST32(lo);
1495 Value *hi64 = ZEXT64(hi); 1474 Value *hi64 = ZEXT64(hi);
1496 Value* lo64 = ZEXT64(lo); 1475 Value* lo64 = ZEXT64(lo);
1497 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); 1476 Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
1498 m0 = FPBITCAST64(v64); 1477 m0 = FPBITCAST64(v64);
1499 m0 = FPNEG64(m0); 1478 m0 = FPNEG64(m0);
1500 Value *val64 = IBITCAST64(m0); 1479 Value *val64 = IBITCAST64(m0);
1501 hi = LSHR(val64,CONST64(32)); 1480 hi = LSHR(val64,CONST64(32));
1502 lo = AND(val64,CONST64(0xffffffff)); 1481 lo = AND(val64,CONST64(0xffffffff));
1503 hi = TRUNC32(hi); 1482 hi = TRUNC32(hi);
1504 lo = TRUNC32(lo); 1483 lo = TRUNC32(lo);
1505 hi = FPBITCAST32(hi); 1484 hi = FPBITCAST32(hi);
1506 lo = FPBITCAST32(lo); 1485 lo = FPBITCAST32(lo);
1507 LETFPS(2*d ,lo); 1486 LETFPS(2*d ,lo);
1508 LETFPS(d*2 + 1 , hi); 1487 LETFPS(d*2 + 1 , hi);
1509 } 1488 }
1510 return No_exp; 1489 return No_exp;
1511} 1490}
1512#endif 1491#endif
1513 1492
@@ -1516,52 +1495,52 @@ int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1516/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ 1495/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
1517#ifdef VFP_INTERPRETER_STRUCT 1496#ifdef VFP_INTERPRETER_STRUCT
1518typedef struct _vsqrt_inst { 1497typedef struct _vsqrt_inst {
1519 unsigned int instr; 1498 unsigned int instr;
1520 unsigned int dp_operation; 1499 unsigned int dp_operation;
1521} vsqrt_inst; 1500} vsqrt_inst;
1522#endif 1501#endif
1523#ifdef VFP_INTERPRETER_TRANS 1502#ifdef VFP_INTERPRETER_TRANS
1524ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) 1503ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
1525{ 1504{
1526 VFP_DEBUG_TRANSLATE; 1505 VFP_DEBUG_TRANSLATE;
1527 1506
1528 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); 1507 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
1529 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; 1508 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1509
1510 inst_base->cond = BITS(inst, 28, 31);
1511 inst_base->idx = index;
1512 inst_base->br = NON_BRANCH;
1513 inst_base->load_r15 = 0;
1530 1514
1531 inst_base->cond = BITS(inst, 28, 31); 1515 inst_cream->dp_operation = BIT(inst, 8);
1532 inst_base->idx = index; 1516 inst_cream->instr = inst;
1533 inst_base->br = NON_BRANCH;
1534 inst_base->load_r15 = 0;
1535 1517
1536 inst_cream->dp_operation = BIT(inst, 8); 1518 return inst_base;
1537 inst_cream->instr = inst;
1538
1539 return inst_base;
1540} 1519}
1541#endif 1520#endif
1542#ifdef VFP_INTERPRETER_IMPL 1521#ifdef VFP_INTERPRETER_IMPL
1543VSQRT_INST: 1522VSQRT_INST:
1544{ 1523{
1545 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1524 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1546 CHECK_VFP_ENABLED; 1525 CHECK_VFP_ENABLED;
1547
1548 DBG("VSQRT :\n");
1549
1550 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1551 1526
1552 int ret; 1527 DBG("VSQRT :\n");
1553
1554 if (inst_cream->dp_operation)
1555 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1556 else
1557 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1558 1528
1559 CHECK_VFP_CDP_RET; 1529 vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
1560 } 1530
1561 cpu->Reg[15] += GET_INST_SIZE(cpu); 1531 int ret;
1562 INC_PC(sizeof(vsqrt_inst)); 1532
1563 FETCH_INST; 1533 if (inst_cream->dp_operation)
1564 GOTO_NEXT_INST; 1534 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1535 else
1536 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1537
1538 CHECK_VFP_CDP_RET;
1539 }
1540 cpu->Reg[15] += GET_INST_SIZE(cpu);
1541 INC_PC(sizeof(vsqrt_inst));
1542 FETCH_INST;
1543 GOTO_NEXT_INST;
1565} 1544}
1566#endif 1545#endif
1567 1546
@@ -1571,38 +1550,38 @@ DYNCOM_FILL_ACTION(vsqrt),
1571#ifdef VFP_DYNCOM_TAG 1550#ifdef VFP_DYNCOM_TAG
1572int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1551int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1573{ 1552{
1574 int instr_size = INSTR_SIZE; 1553 int instr_size = INSTR_SIZE;
1575 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1554 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1576 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1555 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1577 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1556 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1578 return instr_size; 1557 return instr_size;
1579} 1558}
1580#endif 1559#endif
1581#ifdef VFP_DYNCOM_TRANS 1560#ifdef VFP_DYNCOM_TRANS
1582int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1561int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1583 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1562 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
1584 //arch_arm_undef(cpu, bb, instr); 1563 //arch_arm_undef(cpu, bb, instr);
1585 int dp_op = (BIT(8) == 1); 1564 int dp_op = (BIT(8) == 1);
1586 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; 1565 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
1587 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; 1566 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
1588 Value* v; 1567 Value* v;
1589 Value* tmp; 1568 Value* tmp;
1590 if(dp_op){ 1569 if(dp_op){
1591 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); 1570 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
1592 tmp = ZEXT64(IBITCAST32(FR32(2 * m))); 1571 tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
1593 v = OR(v,tmp); 1572 v = OR(v,tmp);
1594 v = FPSQRT(FPBITCAST64(v)); 1573 v = FPSQRT(FPBITCAST64(v));
1595 tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32))); 1574 tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32)));
1596 v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff))); 1575 v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff)));
1597 LETFPS(2 * d , FPBITCAST32(v)); 1576 LETFPS(2 * d , FPBITCAST32(v));
1598 LETFPS(2 * d + 1, FPBITCAST32(tmp)); 1577 LETFPS(2 * d + 1, FPBITCAST32(tmp));
1599 }else { 1578 }else {
1600 v = FR32(m); 1579 v = FR32(m);
1601 v = FPSQRT(FPEXT(64,v)); 1580 v = FPSQRT(FPEXT(64,v));
1602 v = FPTRUNC(32,v); 1581 v = FPTRUNC(32,v);
1603 LETFPS(d,v); 1582 LETFPS(d,v);
1604 } 1583 }
1605 return No_exp; 1584 return No_exp;
1606} 1585}
1607#endif 1586#endif
1608 1587
@@ -1611,52 +1590,52 @@ int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1611/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */ 1590/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
1612#ifdef VFP_INTERPRETER_STRUCT 1591#ifdef VFP_INTERPRETER_STRUCT
1613typedef struct _vcmp_inst { 1592typedef struct _vcmp_inst {
1614 unsigned int instr; 1593 unsigned int instr;
1615 unsigned int dp_operation; 1594 unsigned int dp_operation;
1616} vcmp_inst; 1595} vcmp_inst;
1617#endif 1596#endif
1618#ifdef VFP_INTERPRETER_TRANS 1597#ifdef VFP_INTERPRETER_TRANS
1619ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) 1598ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
1620{ 1599{
1621 VFP_DEBUG_TRANSLATE; 1600 VFP_DEBUG_TRANSLATE;
1622 1601
1623 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); 1602 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
1624 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; 1603 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
1625 1604
1626 inst_base->cond = BITS(inst, 28, 31); 1605 inst_base->cond = BITS(inst, 28, 31);
1627 inst_base->idx = index; 1606 inst_base->idx = index;
1628 inst_base->br = NON_BRANCH; 1607 inst_base->br = NON_BRANCH;
1629 inst_base->load_r15 = 0; 1608 inst_base->load_r15 = 0;
1630 1609
1631 inst_cream->dp_operation = BIT(inst, 8); 1610 inst_cream->dp_operation = BIT(inst, 8);
1632 inst_cream->instr = inst; 1611 inst_cream->instr = inst;
1633 1612
1634 return inst_base; 1613 return inst_base;
1635} 1614}
1636#endif 1615#endif
1637#ifdef VFP_INTERPRETER_IMPL 1616#ifdef VFP_INTERPRETER_IMPL
1638VCMP_INST: 1617VCMP_INST:
1639{ 1618{
1640 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1619 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1641 CHECK_VFP_ENABLED; 1620 CHECK_VFP_ENABLED;
1621
1622 DBG("VCMP(1) :\n");
1642 1623
1643 DBG("VCMP(1) :\n"); 1624 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
1644 1625
1645 vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; 1626 int ret;
1646 1627
1647 int ret; 1628 if (inst_cream->dp_operation)
1648 1629 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1649 if (inst_cream->dp_operation) 1630 else
1650 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 1631 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1651 else
1652 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1653 1632
1654 CHECK_VFP_CDP_RET; 1633 CHECK_VFP_CDP_RET;
1655 } 1634 }
1656 cpu->Reg[15] += GET_INST_SIZE(cpu); 1635 cpu->Reg[15] += GET_INST_SIZE(cpu);
1657 INC_PC(sizeof(vcmp_inst)); 1636 INC_PC(sizeof(vcmp_inst));
1658 FETCH_INST; 1637 FETCH_INST;
1659 GOTO_NEXT_INST; 1638 GOTO_NEXT_INST;
1660} 1639}
1661#endif 1640#endif
1662 1641
@@ -1666,65 +1645,65 @@ DYNCOM_FILL_ACTION(vcmp),
1666#ifdef VFP_DYNCOM_TAG 1645#ifdef VFP_DYNCOM_TAG
1667int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1646int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1668{ 1647{
1669 int instr_size = INSTR_SIZE; 1648 int instr_size = INSTR_SIZE;
1670 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1649 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1671 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1650 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1672 return instr_size; 1651 return instr_size;
1673} 1652}
1674#endif 1653#endif
1675#ifdef VFP_DYNCOM_TRANS 1654#ifdef VFP_DYNCOM_TRANS
1676int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1655int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1677 DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); 1656 DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
1678 //arch_arm_undef(cpu, bb, instr); 1657 //arch_arm_undef(cpu, bb, instr);
1679 int dp_op = (BIT(8) == 1); 1658 int dp_op = (BIT(8) == 1);
1680 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; 1659 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
1681 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; 1660 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
1682 Value* v; 1661 Value* v;
1683 Value* tmp; 1662 Value* tmp;
1684 Value* n; 1663 Value* n;
1685 Value* z; 1664 Value* z;
1686 Value* c; 1665 Value* c;
1687 Value* vt; 1666 Value* vt;
1688 Value* v1; 1667 Value* v1;
1689 Value* nzcv; 1668 Value* nzcv;
1690 if(dp_op){ 1669 if(dp_op){
1691 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); 1670 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
1692 tmp = ZEXT64(IBITCAST32(FR32(2 * m))); 1671 tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
1693 v1 = OR(v,tmp); 1672 v1 = OR(v,tmp);
1694 v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); 1673 v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
1695 tmp = ZEXT64(IBITCAST32(FR32(2 * d))); 1674 tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
1696 v = OR(v,tmp); 1675 v = OR(v,tmp);
1697 z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); 1676 z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
1698 n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); 1677 n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
1699 c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); 1678 c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
1700 tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); 1679 tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
1701 v1 = tmp; 1680 v1 = tmp;
1702 c = OR(c,tmp); 1681 c = OR(c,tmp);
1703 n = SHL(ZEXT32(n),CONST32(31)); 1682 n = SHL(ZEXT32(n),CONST32(31));
1704 z = SHL(ZEXT32(z),CONST32(30)); 1683 z = SHL(ZEXT32(z),CONST32(30));
1705 c = SHL(ZEXT32(c),CONST32(29)); 1684 c = SHL(ZEXT32(c),CONST32(29));
1706 v1 = SHL(ZEXT32(v1),CONST(28)); 1685 v1 = SHL(ZEXT32(v1),CONST(28));
1707 nzcv = OR(OR(OR(n,z),c),v1); 1686 nzcv = OR(OR(OR(n,z),c),v1);
1708 v = R(VFP_FPSCR); 1687 v = R(VFP_FPSCR);
1709 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); 1688 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
1710 LET(VFP_FPSCR,tmp); 1689 LET(VFP_FPSCR,tmp);
1711 }else { 1690 }else {
1712 z = FPCMP_OEQ(FR32(d),FR32(m)); 1691 z = FPCMP_OEQ(FR32(d),FR32(m));
1713 n = FPCMP_OLT(FR32(d),FR32(m)); 1692 n = FPCMP_OLT(FR32(d),FR32(m));
1714 c = FPCMP_OGE(FR32(d),FR32(m)); 1693 c = FPCMP_OGE(FR32(d),FR32(m));
1715 tmp = FPCMP_UNO(FR32(d),FR32(m)); 1694 tmp = FPCMP_UNO(FR32(d),FR32(m));
1716 c = OR(c,tmp); 1695 c = OR(c,tmp);
1717 v1 = tmp; 1696 v1 = tmp;
1718 n = SHL(ZEXT32(n),CONST32(31)); 1697 n = SHL(ZEXT32(n),CONST32(31));
1719 z = SHL(ZEXT32(z),CONST32(30)); 1698 z = SHL(ZEXT32(z),CONST32(30));
1720 c = SHL(ZEXT32(c),CONST32(29)); 1699 c = SHL(ZEXT32(c),CONST32(29));
1721 v1 = SHL(ZEXT32(v1),CONST(28)); 1700 v1 = SHL(ZEXT32(v1),CONST(28));
1722 nzcv = OR(OR(OR(n,z),c),v1); 1701 nzcv = OR(OR(OR(n,z),c),v1);
1723 v = R(VFP_FPSCR); 1702 v = R(VFP_FPSCR);
1724 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); 1703 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
1725 LET(VFP_FPSCR,tmp); 1704 LET(VFP_FPSCR,tmp);
1726 } 1705 }
1727 return No_exp; 1706 return No_exp;
1728} 1707}
1729#endif 1708#endif
1730 1709
@@ -1733,52 +1712,52 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1733/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */ 1712/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
1734#ifdef VFP_INTERPRETER_STRUCT 1713#ifdef VFP_INTERPRETER_STRUCT
1735typedef struct _vcmp2_inst { 1714typedef struct _vcmp2_inst {
1736 unsigned int instr; 1715 unsigned int instr;
1737 unsigned int dp_operation; 1716 unsigned int dp_operation;
1738} vcmp2_inst; 1717} vcmp2_inst;
1739#endif 1718#endif
1740#ifdef VFP_INTERPRETER_TRANS 1719#ifdef VFP_INTERPRETER_TRANS
1741ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) 1720ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
1742{ 1721{
1743 VFP_DEBUG_TRANSLATE; 1722 VFP_DEBUG_TRANSLATE;
1744 1723
1745 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); 1724 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
1746 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; 1725 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
1747 1726
1748 inst_base->cond = BITS(inst, 28, 31); 1727 inst_base->cond = BITS(inst, 28, 31);
1749 inst_base->idx = index; 1728 inst_base->idx = index;
1750 inst_base->br = NON_BRANCH; 1729 inst_base->br = NON_BRANCH;
1751 inst_base->load_r15 = 0; 1730 inst_base->load_r15 = 0;
1752 1731
1753 inst_cream->dp_operation = BIT(inst, 8); 1732 inst_cream->dp_operation = BIT(inst, 8);
1754 inst_cream->instr = inst; 1733 inst_cream->instr = inst;
1755 1734
1756 return inst_base; 1735 return inst_base;
1757} 1736}
1758#endif 1737#endif
1759#ifdef VFP_INTERPRETER_IMPL 1738#ifdef VFP_INTERPRETER_IMPL
1760VCMP2_INST: 1739VCMP2_INST:
1761{ 1740{
1762 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1741 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1763 CHECK_VFP_ENABLED; 1742 CHECK_VFP_ENABLED;
1764 1743
1765 DBG("VCMP(2) :\n"); 1744 DBG("VCMP(2) :\n");
1766 1745
1767 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; 1746 vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
1768 1747
1769 int ret; 1748 int ret;
1770
1771 if (inst_cream->dp_operation)
1772 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1773 else
1774 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1775 1749
1776 CHECK_VFP_CDP_RET; 1750 if (inst_cream->dp_operation)
1777 } 1751 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1778 cpu->Reg[15] += GET_INST_SIZE(cpu); 1752 else
1779 INC_PC(sizeof(vcmp2_inst)); 1753 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1780 FETCH_INST; 1754
1781 GOTO_NEXT_INST; 1755 CHECK_VFP_CDP_RET;
1756 }
1757 cpu->Reg[15] += GET_INST_SIZE(cpu);
1758 INC_PC(sizeof(vcmp2_inst));
1759 FETCH_INST;
1760 GOTO_NEXT_INST;
1782} 1761}
1783#endif 1762#endif
1784 1763
@@ -1788,65 +1767,65 @@ DYNCOM_FILL_ACTION(vcmp2),
1788#ifdef VFP_DYNCOM_TAG 1767#ifdef VFP_DYNCOM_TAG
1789int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1768int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1790{ 1769{
1791 int instr_size = INSTR_SIZE; 1770 int instr_size = INSTR_SIZE;
1792 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1771 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1793 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1772 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1794 return instr_size; 1773 return instr_size;
1795} 1774}
1796#endif 1775#endif
1797#ifdef VFP_DYNCOM_TRANS 1776#ifdef VFP_DYNCOM_TRANS
1798int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1777int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1799 DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); 1778 DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
1800 //arch_arm_undef(cpu, bb, instr); 1779 //arch_arm_undef(cpu, bb, instr);
1801 int dp_op = (BIT(8) == 1); 1780 int dp_op = (BIT(8) == 1);
1802 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; 1781 int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
1803 //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; 1782 //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
1804 Value* v; 1783 Value* v;
1805 Value* tmp; 1784 Value* tmp;
1806 Value* n; 1785 Value* n;
1807 Value* z; 1786 Value* z;
1808 Value* c; 1787 Value* c;
1809 Value* vt; 1788 Value* vt;
1810 Value* v1; 1789 Value* v1;
1811 Value* nzcv; 1790 Value* nzcv;
1812 if(dp_op){ 1791 if(dp_op){
1813 v1 = CONST64(0); 1792 v1 = CONST64(0);
1814 v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); 1793 v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
1815 tmp = ZEXT64(IBITCAST32(FR32(2 * d))); 1794 tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
1816 v = OR(v,tmp); 1795 v = OR(v,tmp);
1817 z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); 1796 z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
1818 n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); 1797 n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
1819 c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); 1798 c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
1820 tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); 1799 tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
1821 v1 = tmp; 1800 v1 = tmp;
1822 c = OR(c,tmp); 1801 c = OR(c,tmp);
1823 n = SHL(ZEXT32(n),CONST32(31)); 1802 n = SHL(ZEXT32(n),CONST32(31));
1824 z = SHL(ZEXT32(z),CONST32(30)); 1803 z = SHL(ZEXT32(z),CONST32(30));
1825 c = SHL(ZEXT32(c),CONST32(29)); 1804 c = SHL(ZEXT32(c),CONST32(29));
1826 v1 = SHL(ZEXT32(v1),CONST(28)); 1805 v1 = SHL(ZEXT32(v1),CONST(28));
1827 nzcv = OR(OR(OR(n,z),c),v1); 1806 nzcv = OR(OR(OR(n,z),c),v1);
1828 v = R(VFP_FPSCR); 1807 v = R(VFP_FPSCR);
1829 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); 1808 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
1830 LET(VFP_FPSCR,tmp); 1809 LET(VFP_FPSCR,tmp);
1831 }else { 1810 }else {
1832 v1 = CONST(0); 1811 v1 = CONST(0);
1833 v1 = FPBITCAST32(v1); 1812 v1 = FPBITCAST32(v1);
1834 z = FPCMP_OEQ(FR32(d),v1); 1813 z = FPCMP_OEQ(FR32(d),v1);
1835 n = FPCMP_OLT(FR32(d),v1); 1814 n = FPCMP_OLT(FR32(d),v1);
1836 c = FPCMP_OGE(FR32(d),v1); 1815 c = FPCMP_OGE(FR32(d),v1);
1837 tmp = FPCMP_UNO(FR32(d),v1); 1816 tmp = FPCMP_UNO(FR32(d),v1);
1838 c = OR(c,tmp); 1817 c = OR(c,tmp);
1839 v1 = tmp; 1818 v1 = tmp;
1840 n = SHL(ZEXT32(n),CONST32(31)); 1819 n = SHL(ZEXT32(n),CONST32(31));
1841 z = SHL(ZEXT32(z),CONST32(30)); 1820 z = SHL(ZEXT32(z),CONST32(30));
1842 c = SHL(ZEXT32(c),CONST32(29)); 1821 c = SHL(ZEXT32(c),CONST32(29));
1843 v1 = SHL(ZEXT32(v1),CONST(28)); 1822 v1 = SHL(ZEXT32(v1),CONST(28));
1844 nzcv = OR(OR(OR(n,z),c),v1); 1823 nzcv = OR(OR(OR(n,z),c),v1);
1845 v = R(VFP_FPSCR); 1824 v = R(VFP_FPSCR);
1846 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); 1825 tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
1847 LET(VFP_FPSCR,tmp); 1826 LET(VFP_FPSCR,tmp);
1848 } 1827 }
1849 return No_exp; 1828 return No_exp;
1850} 1829}
1851#endif 1830#endif
1852 1831
@@ -1855,52 +1834,52 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1855/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */ 1834/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
1856#ifdef VFP_INTERPRETER_STRUCT 1835#ifdef VFP_INTERPRETER_STRUCT
1857typedef struct _vcvtbds_inst { 1836typedef struct _vcvtbds_inst {
1858 unsigned int instr; 1837 unsigned int instr;
1859 unsigned int dp_operation; 1838 unsigned int dp_operation;
1860} vcvtbds_inst; 1839} vcvtbds_inst;
1861#endif 1840#endif
1862#ifdef VFP_INTERPRETER_TRANS 1841#ifdef VFP_INTERPRETER_TRANS
1863ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) 1842ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
1864{ 1843{
1865 VFP_DEBUG_TRANSLATE; 1844 VFP_DEBUG_TRANSLATE;
1866 1845
1867 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); 1846 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
1868 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; 1847 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
1869 1848
1870 inst_base->cond = BITS(inst, 28, 31); 1849 inst_base->cond = BITS(inst, 28, 31);
1871 inst_base->idx = index; 1850 inst_base->idx = index;
1872 inst_base->br = NON_BRANCH; 1851 inst_base->br = NON_BRANCH;
1873 inst_base->load_r15 = 0; 1852 inst_base->load_r15 = 0;
1874 1853
1875 inst_cream->dp_operation = BIT(inst, 8); 1854 inst_cream->dp_operation = BIT(inst, 8);
1876 inst_cream->instr = inst; 1855 inst_cream->instr = inst;
1877 1856
1878 return inst_base; 1857 return inst_base;
1879} 1858}
1880#endif 1859#endif
1881#ifdef VFP_INTERPRETER_IMPL 1860#ifdef VFP_INTERPRETER_IMPL
1882VCVTBDS_INST: 1861VCVTBDS_INST:
1883{ 1862{
1884 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1863 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1885 CHECK_VFP_ENABLED; 1864 CHECK_VFP_ENABLED;
1886 1865
1887 DBG("VCVT(BDS) :\n"); 1866 DBG("VCVT(BDS) :\n");
1888 1867
1889 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; 1868 vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
1890 1869
1891 int ret; 1870 int ret;
1892
1893 if (inst_cream->dp_operation)
1894 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1895 else
1896 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1897 1871
1898 CHECK_VFP_CDP_RET; 1872 if (inst_cream->dp_operation)
1899 } 1873 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1900 cpu->Reg[15] += GET_INST_SIZE(cpu); 1874 else
1901 INC_PC(sizeof(vcvtbds_inst)); 1875 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1902 FETCH_INST; 1876
1903 GOTO_NEXT_INST; 1877 CHECK_VFP_CDP_RET;
1878 }
1879 cpu->Reg[15] += GET_INST_SIZE(cpu);
1880 INC_PC(sizeof(vcvtbds_inst));
1881 FETCH_INST;
1882 GOTO_NEXT_INST;
1904} 1883}
1905#endif 1884#endif
1906 1885
@@ -1910,39 +1889,39 @@ DYNCOM_FILL_ACTION(vcvtbds),
1910#ifdef VFP_DYNCOM_TAG 1889#ifdef VFP_DYNCOM_TAG
1911int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1890int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
1912{ 1891{
1913 int instr_size = INSTR_SIZE; 1892 int instr_size = INSTR_SIZE;
1914 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1893 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
1915 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 1894 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
1916 return instr_size; 1895 return instr_size;
1917} 1896}
1918#endif 1897#endif
1919#ifdef VFP_DYNCOM_TRANS 1898#ifdef VFP_DYNCOM_TRANS
1920int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1899int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
1921 DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__); 1900 DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
1922 //arch_arm_undef(cpu, bb, instr); 1901 //arch_arm_undef(cpu, bb, instr);
1923 int dp_op = (BIT(8) == 1); 1902 int dp_op = (BIT(8) == 1);
1924 int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15); 1903 int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15);
1925 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; 1904 int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
1926 int d2s = dp_op; 1905 int d2s = dp_op;
1927 Value* v; 1906 Value* v;
1928 Value* tmp; 1907 Value* tmp;
1929 Value* v1; 1908 Value* v1;
1930 if(d2s){ 1909 if(d2s){
1931 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); 1910 v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
1932 tmp = ZEXT64(IBITCAST32(FR32(2 * m))); 1911 tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
1933 v1 = OR(v,tmp); 1912 v1 = OR(v,tmp);
1934 tmp = FPTRUNC(32,FPBITCAST64(v1)); 1913 tmp = FPTRUNC(32,FPBITCAST64(v1));
1935 LETFPS(d,tmp); 1914 LETFPS(d,tmp);
1936 }else { 1915 }else {
1937 v = FR32(m); 1916 v = FR32(m);
1938 tmp = FPEXT(64,v); 1917 tmp = FPEXT(64,v);
1939 v = IBITCAST64(tmp); 1918 v = IBITCAST64(tmp);
1940 tmp = TRUNC32(AND(v,CONST64(0xffffffff))); 1919 tmp = TRUNC32(AND(v,CONST64(0xffffffff)));
1941 v1 = TRUNC32(LSHR(v,CONST64(32))); 1920 v1 = TRUNC32(LSHR(v,CONST64(32)));
1942 LETFPS(2 * d, FPBITCAST32(tmp) ); 1921 LETFPS(2 * d, FPBITCAST32(tmp) );
1943 LETFPS(2 * d + 1, FPBITCAST32(v1)); 1922 LETFPS(2 * d + 1, FPBITCAST32(v1));
1944 } 1923 }
1945 return No_exp; 1924 return No_exp;
1946} 1925}
1947#endif 1926#endif
1948 1927
@@ -1951,52 +1930,52 @@ int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
1951/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 1930/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
1952#ifdef VFP_INTERPRETER_STRUCT 1931#ifdef VFP_INTERPRETER_STRUCT
1953typedef struct _vcvtbff_inst { 1932typedef struct _vcvtbff_inst {
1954 unsigned int instr; 1933 unsigned int instr;
1955 unsigned int dp_operation; 1934 unsigned int dp_operation;
1956} vcvtbff_inst; 1935} vcvtbff_inst;
1957#endif 1936#endif
1958#ifdef VFP_INTERPRETER_TRANS 1937#ifdef VFP_INTERPRETER_TRANS
1959ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) 1938ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
1960{ 1939{
1961 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); 1940 VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
1962 1941
1963 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); 1942 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
1964 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; 1943 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
1965 1944
1966 inst_base->cond = BITS(inst, 28, 31); 1945 inst_base->cond = BITS(inst, 28, 31);
1967 inst_base->idx = index; 1946 inst_base->idx = index;
1968 inst_base->br = NON_BRANCH; 1947 inst_base->br = NON_BRANCH;
1969 inst_base->load_r15 = 0; 1948 inst_base->load_r15 = 0;
1970 1949
1971 inst_cream->dp_operation = BIT(inst, 8); 1950 inst_cream->dp_operation = BIT(inst, 8);
1972 inst_cream->instr = inst; 1951 inst_cream->instr = inst;
1973 1952
1974 return inst_base; 1953 return inst_base;
1975} 1954}
1976#endif 1955#endif
1977#ifdef VFP_INTERPRETER_IMPL 1956#ifdef VFP_INTERPRETER_IMPL
1978VCVTBFF_INST: 1957VCVTBFF_INST:
1979{ 1958{
1980 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1959 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1981 CHECK_VFP_ENABLED; 1960 CHECK_VFP_ENABLED;
1982 1961
1983 DBG("VCVT(BFF) :\n"); 1962 DBG("VCVT(BFF) :\n");
1984 1963
1985 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; 1964 vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
1986 1965
1987 int ret; 1966 int ret;
1988
1989 if (inst_cream->dp_operation)
1990 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1991 else
1992 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1993 1967
1994 CHECK_VFP_CDP_RET; 1968 if (inst_cream->dp_operation)
1995 } 1969 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1996 cpu->Reg[15] += GET_INST_SIZE(cpu); 1970 else
1997 INC_PC(sizeof(vcvtbff_inst)); 1971 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
1998 FETCH_INST; 1972
1999 GOTO_NEXT_INST; 1973 CHECK_VFP_CDP_RET;
1974 }
1975 cpu->Reg[15] += GET_INST_SIZE(cpu);
1976 INC_PC(sizeof(vcvtbff_inst));
1977 FETCH_INST;
1978 GOTO_NEXT_INST;
2000} 1979}
2001#endif 1980#endif
2002 1981
@@ -2006,17 +1985,17 @@ DYNCOM_FILL_ACTION(vcvtbff),
2006#ifdef VFP_DYNCOM_TAG 1985#ifdef VFP_DYNCOM_TAG
2007int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 1986int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2008{ 1987{
2009 int instr_size = INSTR_SIZE; 1988 int instr_size = INSTR_SIZE;
2010 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1989 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2011 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 1990 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2012 return instr_size; 1991 return instr_size;
2013} 1992}
2014#endif 1993#endif
2015#ifdef VFP_DYNCOM_TRANS 1994#ifdef VFP_DYNCOM_TRANS
2016int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 1995int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2017 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 1996 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2018 arch_arm_undef(cpu, bb, instr); 1997 arch_arm_undef(cpu, bb, instr);
2019 return No_exp; 1998 return No_exp;
2020} 1999}
2021#endif 2000#endif
2022 2001
@@ -2025,53 +2004,53 @@ int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2025/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ 2004/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
2026#ifdef VFP_INTERPRETER_STRUCT 2005#ifdef VFP_INTERPRETER_STRUCT
2027typedef struct _vcvtbfi_inst { 2006typedef struct _vcvtbfi_inst {
2028 unsigned int instr; 2007 unsigned int instr;
2029 unsigned int dp_operation; 2008 unsigned int dp_operation;
2030} vcvtbfi_inst; 2009} vcvtbfi_inst;
2031#endif 2010#endif
2032#ifdef VFP_INTERPRETER_TRANS 2011#ifdef VFP_INTERPRETER_TRANS
2033ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) 2012ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
2034{ 2013{
2035 VFP_DEBUG_TRANSLATE; 2014 VFP_DEBUG_TRANSLATE;
2036 2015
2037 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); 2016 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
2038 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; 2017 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2039 2018
2040 inst_base->cond = BITS(inst, 28, 31); 2019 inst_base->cond = BITS(inst, 28, 31);
2041 inst_base->idx = index; 2020 inst_base->idx = index;
2042 inst_base->br = NON_BRANCH; 2021 inst_base->br = NON_BRANCH;
2043 inst_base->load_r15 = 0; 2022 inst_base->load_r15 = 0;
2044 2023
2045 inst_cream->dp_operation = BIT(inst, 8); 2024 inst_cream->dp_operation = BIT(inst, 8);
2046 inst_cream->instr = inst; 2025 inst_cream->instr = inst;
2047 2026
2048 2027
2049 return inst_base; 2028 return inst_base;
2050} 2029}
2051#endif 2030#endif
2052#ifdef VFP_INTERPRETER_IMPL 2031#ifdef VFP_INTERPRETER_IMPL
2053VCVTBFI_INST: 2032VCVTBFI_INST:
2054{ 2033{
2055 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2034 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2056 CHECK_VFP_ENABLED; 2035 CHECK_VFP_ENABLED;
2057 2036
2058 DBG("VCVT(BFI) :\n"); 2037 DBG("VCVT(BFI) :\n");
2059 2038
2060 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; 2039 vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
2061 2040
2062 int ret; 2041 int ret;
2063
2064 if (inst_cream->dp_operation)
2065 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2066 else
2067 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2068 2042
2069 CHECK_VFP_CDP_RET; 2043 if (inst_cream->dp_operation)
2070 } 2044 ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2071 cpu->Reg[15] += GET_INST_SIZE(cpu); 2045 else
2072 INC_PC(sizeof(vcvtbfi_inst)); 2046 ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2073 FETCH_INST; 2047
2074 GOTO_NEXT_INST; 2048 CHECK_VFP_CDP_RET;
2049 }
2050 cpu->Reg[15] += GET_INST_SIZE(cpu);
2051 INC_PC(sizeof(vcvtbfi_inst));
2052 FETCH_INST;
2053 GOTO_NEXT_INST;
2075} 2054}
2076#endif 2055#endif
2077 2056
@@ -2081,87 +2060,87 @@ DYNCOM_FILL_ACTION(vcvtbfi),
2081#ifdef VFP_DYNCOM_TAG 2060#ifdef VFP_DYNCOM_TAG
2082int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2061int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2083{ 2062{
2084 int instr_size = INSTR_SIZE; 2063 int instr_size = INSTR_SIZE;
2085 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2064 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2086 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); 2065 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
2087 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 2066 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2088 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2067 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2089 return instr_size; 2068 return instr_size;
2090} 2069}
2091#endif 2070#endif
2092#ifdef VFP_DYNCOM_TRANS 2071#ifdef VFP_DYNCOM_TRANS
2093int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2072int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2094 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); 2073 DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
2095 //arch_arm_undef(cpu, bb, instr); 2074 //arch_arm_undef(cpu, bb, instr);
2096 unsigned int opc2 = BITS(16,18); 2075 unsigned int opc2 = BITS(16,18);
2097 int to_integer = ((opc2 >> 2) == 1); 2076 int to_integer = ((opc2 >> 2) == 1);
2098 int dp_op = (BIT(8) == 1); 2077 int dp_op = (BIT(8) == 1);
2099 unsigned int op = BIT(7); 2078 unsigned int op = BIT(7);
2100 int m,d; 2079 int m,d;
2101 Value* v; 2080 Value* v;
2102 Value* hi; 2081 Value* hi;
2103 Value* lo; 2082 Value* lo;
2104 Value* v64; 2083 Value* v64;
2105 if(to_integer){ 2084 if(to_integer){
2106 d = BIT(22) | (BITS(12,15) << 1); 2085 d = BIT(22) | (BITS(12,15) << 1);
2107 if(dp_op) 2086 if(dp_op)
2108 m = BITS(0,3) | BIT(5) << 4; 2087 m = BITS(0,3) | BIT(5) << 4;
2109 else 2088 else
2110 m = BIT(5) | BITS(0,3) << 1; 2089 m = BIT(5) | BITS(0,3) << 1;
2111 }else { 2090 }else {
2112 m = BIT(5) | BITS(0,3) << 1; 2091 m = BIT(5) | BITS(0,3) << 1;
2113 if(dp_op) 2092 if(dp_op)
2114 d = BITS(12,15) | BIT(22) << 4; 2093 d = BITS(12,15) | BIT(22) << 4;
2115 else 2094 else
2116 d = BIT(22) | BITS(12,15) << 1; 2095 d = BIT(22) | BITS(12,15) << 1;
2117 } 2096 }
2118 if(to_integer){ 2097 if(to_integer){
2119 if(dp_op){ 2098 if(dp_op){
2120 lo = FR32(m * 2); 2099 lo = FR32(m * 2);
2121 hi = FR32(m * 2 + 1); 2100 hi = FR32(m * 2 + 1);
2122 hi = ZEXT64(IBITCAST32(hi)); 2101 hi = ZEXT64(IBITCAST32(hi));
2123 lo = ZEXT64(IBITCAST32(lo)); 2102 lo = ZEXT64(IBITCAST32(lo));
2124 v64 = OR(SHL(hi,CONST64(32)),lo); 2103 v64 = OR(SHL(hi,CONST64(32)),lo);
2125 if(BIT(16)){ 2104 if(BIT(16)){
2126 v = FPTOSI(32,FPBITCAST64(v64)); 2105 v = FPTOSI(32,FPBITCAST64(v64));
2127 } 2106 }
2128 else 2107 else
2129 v = FPTOUI(32,FPBITCAST64(v64)); 2108 v = FPTOUI(32,FPBITCAST64(v64));
2130 2109
2131 v = FPBITCAST32(v); 2110 v = FPBITCAST32(v);
2132 LETFPS(d,v); 2111 LETFPS(d,v);
2133 }else { 2112 }else {
2134 v = FR32(m); 2113 v = FR32(m);
2135 if(BIT(16)){ 2114 if(BIT(16)){
2136 2115
2137 v = FPTOSI(32,v); 2116 v = FPTOSI(32,v);
2138 } 2117 }
2139 else 2118 else
2140 v = FPTOUI(32,v); 2119 v = FPTOUI(32,v);
2141 LETFPS(d,FPBITCAST32(v)); 2120 LETFPS(d,FPBITCAST32(v));
2142 } 2121 }
2143 }else { 2122 }else {
2144 if(dp_op){ 2123 if(dp_op){
2145 v = IBITCAST32(FR32(m)); 2124 v = IBITCAST32(FR32(m));
2146 if(BIT(7)) 2125 if(BIT(7))
2147 v64 = SITOFP(64,v); 2126 v64 = SITOFP(64,v);
2148 else 2127 else
2149 v64 = UITOFP(64,v); 2128 v64 = UITOFP(64,v);
2150 v = IBITCAST64(v64); 2129 v = IBITCAST64(v64);
2151 hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))); 2130 hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))));
2152 lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))); 2131 lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))));
2153 LETFPS(2 * d , lo); 2132 LETFPS(2 * d , lo);
2154 LETFPS(2 * d + 1, hi); 2133 LETFPS(2 * d + 1, hi);
2155 }else { 2134 }else {
2156 v = IBITCAST32(FR32(m)); 2135 v = IBITCAST32(FR32(m));
2157 if(BIT(7)) 2136 if(BIT(7))
2158 v = SITOFP(32,v); 2137 v = SITOFP(32,v);
2159 else 2138 else
2160 v = UITOFP(32,v); 2139 v = UITOFP(32,v);
2161 LETFPS(d,v); 2140 LETFPS(d,v);
2162 } 2141 }
2163 } 2142 }
2164 return No_exp; 2143 return No_exp;
2165} 2144}
2166 2145
2167/** 2146/**
@@ -2173,15 +2152,15 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2173* @return 2152* @return
2174*/ 2153*/
2175int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ 2154int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2176 int dp_operation = BIT(8); 2155 int dp_operation = BIT(8);
2177 int ret; 2156 int ret;
2178 if (dp_operation) 2157 if (dp_operation)
2179 ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 2158 ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2180 else 2159 else
2181 ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 2160 ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2182 2161
2183 vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 2162 vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2184 return 0; 2163 return 0;
2185} 2164}
2186#endif 2165#endif
2187 2166
@@ -2196,45 +2175,45 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
2196/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2175/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
2197#ifdef VFP_INTERPRETER_STRUCT 2176#ifdef VFP_INTERPRETER_STRUCT
2198typedef struct _vmovbrs_inst { 2177typedef struct _vmovbrs_inst {
2199 unsigned int to_arm; 2178 unsigned int to_arm;
2200 unsigned int t; 2179 unsigned int t;
2201 unsigned int n; 2180 unsigned int n;
2202} vmovbrs_inst; 2181} vmovbrs_inst;
2203#endif 2182#endif
2204#ifdef VFP_INTERPRETER_TRANS 2183#ifdef VFP_INTERPRETER_TRANS
2205ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) 2184ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
2206{ 2185{
2207 VFP_DEBUG_TRANSLATE; 2186 VFP_DEBUG_TRANSLATE;
2208 2187
2209 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); 2188 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
2210 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; 2189 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2211 2190
2212 inst_base->cond = BITS(inst, 28, 31); 2191 inst_base->cond = BITS(inst, 28, 31);
2213 inst_base->idx = index; 2192 inst_base->idx = index;
2214 inst_base->br = NON_BRANCH; 2193 inst_base->br = NON_BRANCH;
2215 inst_base->load_r15 = 0; 2194 inst_base->load_r15 = 0;
2216 2195
2217 inst_cream->to_arm = BIT(inst, 20) == 1; 2196 inst_cream->to_arm = BIT(inst, 20) == 1;
2218 inst_cream->t = BITS(inst, 12, 15); 2197 inst_cream->t = BITS(inst, 12, 15);
2219 inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; 2198 inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1;
2220 2199
2221 return inst_base; 2200 return inst_base;
2222} 2201}
2223#endif 2202#endif
2224#ifdef VFP_INTERPRETER_IMPL 2203#ifdef VFP_INTERPRETER_IMPL
2225VMOVBRS_INST: 2204VMOVBRS_INST:
2226{ 2205{
2227 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2206 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2228 CHECK_VFP_ENABLED; 2207 CHECK_VFP_ENABLED;
2229 2208
2230 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; 2209 vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
2231 2210
2232 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); 2211 VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
2233 } 2212 }
2234 cpu->Reg[15] += GET_INST_SIZE(cpu); 2213 cpu->Reg[15] += GET_INST_SIZE(cpu);
2235 INC_PC(sizeof(vmovbrs_inst)); 2214 INC_PC(sizeof(vmovbrs_inst));
2236 FETCH_INST; 2215 FETCH_INST;
2237 GOTO_NEXT_INST; 2216 GOTO_NEXT_INST;
2238} 2217}
2239#endif 2218#endif
2240 2219
@@ -2244,30 +2223,30 @@ DYNCOM_FILL_ACTION(vmovbrs),
2244#ifdef VFP_DYNCOM_TAG 2223#ifdef VFP_DYNCOM_TAG
2245int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2224int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2246{ 2225{
2247 int instr_size = INSTR_SIZE; 2226 int instr_size = INSTR_SIZE;
2248 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2227 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2249 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2228 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2250 return instr_size; 2229 return instr_size;
2251} 2230}
2252#endif 2231#endif
2253#ifdef VFP_DYNCOM_TRANS 2232#ifdef VFP_DYNCOM_TRANS
2254int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2233int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2255 DBG("VMOV(BRS) :\n"); 2234 DBG("VMOV(BRS) :\n");
2256 int to_arm = BIT(20) == 1; 2235 int to_arm = BIT(20) == 1;
2257 int t = BITS(12, 15); 2236 int t = BITS(12, 15);
2258 int n = BIT(7) | BITS(16, 19)<<1; 2237 int n = BIT(7) | BITS(16, 19)<<1;
2259 2238
2260 if (to_arm) 2239 if (to_arm)
2261 { 2240 {
2262 DBG("\tr%d <= s%d\n", t, n); 2241 DBG("\tr%d <= s%d\n", t, n);
2263 LET(t, IBITCAST32(FR32(n))); 2242 LET(t, IBITCAST32(FR32(n)));
2264 } 2243 }
2265 else 2244 else
2266 { 2245 {
2267 DBG("\ts%d <= r%d\n", n, t); 2246 DBG("\ts%d <= r%d\n", n, t);
2268 LETFPS(n, FPBITCAST32(R(t))); 2247 LETFPS(n, FPBITCAST32(R(t)));
2269 } 2248 }
2270 return No_exp; 2249 return No_exp;
2271} 2250}
2272#endif 2251#endif
2273 2252
@@ -2277,46 +2256,46 @@ int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2277/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2256/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
2278#ifdef VFP_INTERPRETER_STRUCT 2257#ifdef VFP_INTERPRETER_STRUCT
2279typedef struct _vmsr_inst { 2258typedef struct _vmsr_inst {
2280 unsigned int reg; 2259 unsigned int reg;
2281 unsigned int Rd; 2260 unsigned int Rd;
2282} vmsr_inst; 2261} vmsr_inst;
2283#endif 2262#endif
2284#ifdef VFP_INTERPRETER_TRANS 2263#ifdef VFP_INTERPRETER_TRANS
2285ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) 2264ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
2286{ 2265{
2287 VFP_DEBUG_TRANSLATE; 2266 VFP_DEBUG_TRANSLATE;
2288 2267
2289 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); 2268 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
2290 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; 2269 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2270
2271 inst_base->cond = BITS(inst, 28, 31);
2272 inst_base->idx = index;
2273 inst_base->br = NON_BRANCH;
2274 inst_base->load_r15 = 0;
2291 2275
2292 inst_base->cond = BITS(inst, 28, 31); 2276 inst_cream->reg = BITS(inst, 16, 19);
2293 inst_base->idx = index; 2277 inst_cream->Rd = BITS(inst, 12, 15);
2294 inst_base->br = NON_BRANCH;
2295 inst_base->load_r15 = 0;
2296 2278
2297 inst_cream->reg = BITS(inst, 16, 19); 2279 return inst_base;
2298 inst_cream->Rd = BITS(inst, 12, 15);
2299
2300 return inst_base;
2301} 2280}
2302#endif 2281#endif
2303#ifdef VFP_INTERPRETER_IMPL 2282#ifdef VFP_INTERPRETER_IMPL
2304VMSR_INST: 2283VMSR_INST:
2305{ 2284{
2306 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2285 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2307 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , 2286 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
2308 and in privilegied mode */ 2287 and in privilegied mode */
2309 /* Exceptions must be checked, according to v7 ref manual */ 2288 /* Exceptions must be checked, according to v7 ref manual */
2310 CHECK_VFP_ENABLED; 2289 CHECK_VFP_ENABLED;
2311
2312 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2313 2290
2314 VMSR(cpu, inst_cream->reg, inst_cream->Rd); 2291 vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
2315 } 2292
2316 cpu->Reg[15] += GET_INST_SIZE(cpu); 2293 VMSR(cpu, inst_cream->reg, inst_cream->Rd);
2317 INC_PC(sizeof(vmsr_inst)); 2294 }
2318 FETCH_INST; 2295 cpu->Reg[15] += GET_INST_SIZE(cpu);
2319 GOTO_NEXT_INST; 2296 INC_PC(sizeof(vmsr_inst));
2297 FETCH_INST;
2298 GOTO_NEXT_INST;
2320} 2299}
2321#endif 2300#endif
2322 2301
@@ -2326,45 +2305,45 @@ DYNCOM_FILL_ACTION(vmsr),
2326#ifdef VFP_DYNCOM_TAG 2305#ifdef VFP_DYNCOM_TAG
2327int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2306int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2328{ 2307{
2329 int instr_size = INSTR_SIZE; 2308 int instr_size = INSTR_SIZE;
2330 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2309 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2331 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 2310 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2332 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2311 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2333 return instr_size; 2312 return instr_size;
2334} 2313}
2335#endif 2314#endif
2336#ifdef VFP_DYNCOM_TRANS 2315#ifdef VFP_DYNCOM_TRANS
2337int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2316int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2338 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2317 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2339 //arch_arm_undef(cpu, bb, instr); 2318 //arch_arm_undef(cpu, bb, instr);
2340 DBG("VMSR :"); 2319 DBG("VMSR :");
2341 if(RD == 15) { 2320 if(RD == 15) {
2342 printf("in %s is not implementation.\n", __FUNCTION__); 2321 printf("in %s is not implementation.\n", __FUNCTION__);
2343 exit(-1); 2322 exit(-1);
2344 } 2323 }
2345 2324
2346 Value *data = NULL; 2325 Value *data = NULL;
2347 int reg = RN; 2326 int reg = RN;
2348 int Rt = RD; 2327 int Rt = RD;
2349 if (reg == 1) 2328 if (reg == 1)
2350 { 2329 {
2351 LET(VFP_FPSCR, R(Rt)); 2330 LET(VFP_FPSCR, R(Rt));
2352 DBG("\tflags <= fpscr\n"); 2331 DBG("\tflags <= fpscr\n");
2353 } 2332 }
2354 else 2333 else
2355 { 2334 {
2356 switch (reg) 2335 switch (reg)
2357 { 2336 {
2358 case 8: 2337 case 8:
2359 LET(VFP_FPEXC, R(Rt)); 2338 LET(VFP_FPEXC, R(Rt));
2360 DBG("\tfpexc <= r%d \n", Rt); 2339 DBG("\tfpexc <= r%d \n", Rt);
2361 break; 2340 break;
2362 default: 2341 default:
2363 DBG("\tSUBARCHITECTURE DEFINED\n"); 2342 DBG("\tSUBARCHITECTURE DEFINED\n");
2364 break; 2343 break;
2365 } 2344 }
2366 } 2345 }
2367 return No_exp; 2346 return No_exp;
2368} 2347}
2369#endif 2348#endif
2370 2349
@@ -2374,48 +2353,48 @@ int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2374/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ 2353/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
2375#ifdef VFP_INTERPRETER_STRUCT 2354#ifdef VFP_INTERPRETER_STRUCT
2376typedef struct _vmovbrc_inst { 2355typedef struct _vmovbrc_inst {
2377 unsigned int esize; 2356 unsigned int esize;
2378 unsigned int index; 2357 unsigned int index;
2379 unsigned int d; 2358 unsigned int d;
2380 unsigned int t; 2359 unsigned int t;
2381} vmovbrc_inst; 2360} vmovbrc_inst;
2382#endif 2361#endif
2383#ifdef VFP_INTERPRETER_TRANS 2362#ifdef VFP_INTERPRETER_TRANS
2384ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) 2363ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
2385{ 2364{
2386 VFP_DEBUG_TRANSLATE; 2365 VFP_DEBUG_TRANSLATE;
2387 2366
2388 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); 2367 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
2389 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; 2368 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
2390 2369
2391 inst_base->cond = BITS(inst, 28, 31); 2370 inst_base->cond = BITS(inst, 28, 31);
2392 inst_base->idx = index; 2371 inst_base->idx = index;
2393 inst_base->br = NON_BRANCH; 2372 inst_base->br = NON_BRANCH;
2394 inst_base->load_r15 = 0; 2373 inst_base->load_r15 = 0;
2395 2374
2396 inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; 2375 inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
2397 inst_cream->t = BITS(inst, 12, 15); 2376 inst_cream->t = BITS(inst, 12, 15);
2398 /* VFP variant of instruction */ 2377 /* VFP variant of instruction */
2399 inst_cream->esize = 32; 2378 inst_cream->esize = 32;
2400 inst_cream->index = BIT(inst, 21); 2379 inst_cream->index = BIT(inst, 21);
2401 2380
2402 return inst_base; 2381 return inst_base;
2403} 2382}
2404#endif 2383#endif
2405#ifdef VFP_INTERPRETER_IMPL 2384#ifdef VFP_INTERPRETER_IMPL
2406VMOVBRC_INST: 2385VMOVBRC_INST:
2407{ 2386{
2408 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2387 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2409 CHECK_VFP_ENABLED; 2388 CHECK_VFP_ENABLED;
2410 2389
2411 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; 2390 vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
2412 2391
2413 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); 2392 VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
2414 } 2393 }
2415 cpu->Reg[15] += GET_INST_SIZE(cpu); 2394 cpu->Reg[15] += GET_INST_SIZE(cpu);
2416 INC_PC(sizeof(vmovbrc_inst)); 2395 INC_PC(sizeof(vmovbrc_inst));
2417 FETCH_INST; 2396 FETCH_INST;
2418 GOTO_NEXT_INST; 2397 GOTO_NEXT_INST;
2419} 2398}
2420#endif 2399#endif
2421 2400
@@ -2425,17 +2404,17 @@ DYNCOM_FILL_ACTION(vmovbrc),
2425#ifdef VFP_DYNCOM_TAG 2404#ifdef VFP_DYNCOM_TAG
2426int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2405int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2427{ 2406{
2428 int instr_size = INSTR_SIZE; 2407 int instr_size = INSTR_SIZE;
2429 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2408 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2430 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 2409 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2431 return instr_size; 2410 return instr_size;
2432} 2411}
2433#endif 2412#endif
2434#ifdef VFP_DYNCOM_TRANS 2413#ifdef VFP_DYNCOM_TRANS
2435int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2414int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2436 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2415 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2437 arch_arm_undef(cpu, bb, instr); 2416 arch_arm_undef(cpu, bb, instr);
2438 return No_exp; 2417 return No_exp;
2439} 2418}
2440#endif 2419#endif
2441 2420
@@ -2445,88 +2424,88 @@ int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2445/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ 2424/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
2446#ifdef VFP_INTERPRETER_STRUCT 2425#ifdef VFP_INTERPRETER_STRUCT
2447typedef struct _vmrs_inst { 2426typedef struct _vmrs_inst {
2448 unsigned int reg; 2427 unsigned int reg;
2449 unsigned int Rt; 2428 unsigned int Rt;
2450} vmrs_inst; 2429} vmrs_inst;
2451#endif 2430#endif
2452#ifdef VFP_INTERPRETER_TRANS 2431#ifdef VFP_INTERPRETER_TRANS
2453ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) 2432ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
2454{ 2433{
2455 VFP_DEBUG_TRANSLATE; 2434 VFP_DEBUG_TRANSLATE;
2456 2435
2457 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); 2436 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
2458 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; 2437 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
2459 2438
2460 inst_base->cond = BITS(inst, 28, 31); 2439 inst_base->cond = BITS(inst, 28, 31);
2461 inst_base->idx = index; 2440 inst_base->idx = index;
2462 inst_base->br = NON_BRANCH; 2441 inst_base->br = NON_BRANCH;
2463 inst_base->load_r15 = 0; 2442 inst_base->load_r15 = 0;
2464 2443
2465 inst_cream->reg = BITS(inst, 16, 19); 2444 inst_cream->reg = BITS(inst, 16, 19);
2466 inst_cream->Rt = BITS(inst, 12, 15); 2445 inst_cream->Rt = BITS(inst, 12, 15);
2467 2446
2468 return inst_base; 2447 return inst_base;
2469} 2448}
2470#endif 2449#endif
2471#ifdef VFP_INTERPRETER_IMPL 2450#ifdef VFP_INTERPRETER_IMPL
2472VMRS_INST: 2451VMRS_INST:
2473{ 2452{
2474 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2453 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2475 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, 2454 /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
2476 and in privilegied mode */ 2455 and in privilegied mode */
2477 /* Exceptions must be checked, according to v7 ref manual */ 2456 /* Exceptions must be checked, according to v7 ref manual */
2478 CHECK_VFP_ENABLED; 2457 CHECK_VFP_ENABLED;
2479 2458
2480 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; 2459 vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
2481 2460
2482 DBG("VMRS :"); 2461 DBG("VMRS :");
2483 2462
2484 if (inst_cream->reg == 1) /* FPSCR */ 2463 if (inst_cream->reg == 1) /* FPSCR */
2485 { 2464 {
2486 if (inst_cream->Rt != 15) 2465 if (inst_cream->Rt != 15)
2487 { 2466 {
2488 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)]; 2467 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)];
2489 DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); 2468 DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
2490 } 2469 }
2491 else 2470 else
2492 { 2471 {
2493 cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1; 2472 cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1;
2494 cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1; 2473 cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1;
2495 cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1; 2474 cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1;
2496 cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1; 2475 cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1;
2497 DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); 2476 DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
2498 } 2477 }
2499 } 2478 }
2500 else 2479 else
2501 { 2480 {
2502 switch (inst_cream->reg) 2481 switch (inst_cream->reg)
2503 { 2482 {
2504 case 0: 2483 case 0:
2505 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)]; 2484 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)];
2506 DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]); 2485 DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]);
2507 break; 2486 break;
2508 case 6: 2487 case 6:
2509 /* MVFR1, VFPv3 only ? */ 2488 /* MVFR1, VFPv3 only ? */
2510 DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); 2489 DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt);
2511 break; 2490 break;
2512 case 7: 2491 case 7:
2513 /* MVFR0, VFPv3 only? */ 2492 /* MVFR0, VFPv3 only? */
2514 DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); 2493 DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt);
2515 break; 2494 break;
2516 case 8: 2495 case 8:
2517 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)]; 2496 cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)];
2518 DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]); 2497 DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]);
2519 break; 2498 break;
2520 default: 2499 default:
2521 DBG("\tSUBARCHITECTURE DEFINED\n"); 2500 DBG("\tSUBARCHITECTURE DEFINED\n");
2522 break; 2501 break;
2523 } 2502 }
2524 } 2503 }
2525 } 2504 }
2526 cpu->Reg[15] += GET_INST_SIZE(cpu); 2505 cpu->Reg[15] += GET_INST_SIZE(cpu);
2527 INC_PC(sizeof(vmrs_inst)); 2506 INC_PC(sizeof(vmrs_inst));
2528 FETCH_INST; 2507 FETCH_INST;
2529 GOTO_NEXT_INST; 2508 GOTO_NEXT_INST;
2530} 2509}
2531#endif 2510#endif
2532 2511
@@ -2536,64 +2515,64 @@ DYNCOM_FILL_ACTION(vmrs),
2536#ifdef VFP_DYNCOM_TAG 2515#ifdef VFP_DYNCOM_TAG
2537int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2516int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2538{ 2517{
2539 int instr_size = INSTR_SIZE; 2518 int instr_size = INSTR_SIZE;
2540 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2519 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2541 DBG("\t\tin %s .\n", __FUNCTION__); 2520 DBG("\t\tin %s .\n", __FUNCTION__);
2542 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 2521 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2543 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2522 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2544 return instr_size; 2523 return instr_size;
2545} 2524}
2546#endif 2525#endif
2547#ifdef VFP_DYNCOM_TRANS 2526#ifdef VFP_DYNCOM_TRANS
2548int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2527int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2549 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2528 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2550 //arch_arm_undef(cpu, bb, instr); 2529 //arch_arm_undef(cpu, bb, instr);
2551 2530
2552 Value *data = NULL; 2531 Value *data = NULL;
2553 int reg = BITS(16, 19);; 2532 int reg = BITS(16, 19);;
2554 int Rt = BITS(12, 15); 2533 int Rt = BITS(12, 15);
2555 DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt); 2534 DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt);
2556 if (reg == 1) 2535 if (reg == 1)
2557 { 2536 {
2558 if (Rt != 15) 2537 if (Rt != 15)
2559 { 2538 {
2560 LET(Rt, R(VFP_FPSCR)); 2539 LET(Rt, R(VFP_FPSCR));
2561 DBG("\tr%d <= fpscr\n", Rt); 2540 DBG("\tr%d <= fpscr\n", Rt);
2562 } 2541 }
2563 else 2542 else
2564 { 2543 {
2565 //LET(Rt, R(VFP_FPSCR)); 2544 //LET(Rt, R(VFP_FPSCR));
2566 update_cond_from_fpscr(cpu, instr, bb, pc); 2545 update_cond_from_fpscr(cpu, instr, bb, pc);
2567 DBG("In %s, \tflags <= fpscr\n", __FUNCTION__); 2546 DBG("In %s, \tflags <= fpscr\n", __FUNCTION__);
2568 } 2547 }
2569 } 2548 }
2570 else 2549 else
2571 { 2550 {
2572 switch (reg) 2551 switch (reg)
2573 { 2552 {
2574 case 0: 2553 case 0:
2575 LET(Rt, R(VFP_FPSID)); 2554 LET(Rt, R(VFP_FPSID));
2576 DBG("\tr%d <= fpsid\n", Rt); 2555 DBG("\tr%d <= fpsid\n", Rt);
2577 break; 2556 break;
2578 case 6: 2557 case 6:
2579 /* MVFR1, VFPv3 only ? */ 2558 /* MVFR1, VFPv3 only ? */
2580 DBG("\tr%d <= MVFR1 unimplemented\n", Rt); 2559 DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
2581 break; 2560 break;
2582 case 7: 2561 case 7:
2583 /* MVFR0, VFPv3 only? */ 2562 /* MVFR0, VFPv3 only? */
2584 DBG("\tr%d <= MVFR0 unimplemented\n", Rt); 2563 DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
2585 break; 2564 break;
2586 case 8: 2565 case 8:
2587 LET(Rt, R(VFP_FPEXC)); 2566 LET(Rt, R(VFP_FPEXC));
2588 DBG("\tr%d <= fpexc\n", Rt); 2567 DBG("\tr%d <= fpexc\n", Rt);
2589 break; 2568 break;
2590 default: 2569 default:
2591 DBG("\tSUBARCHITECTURE DEFINED\n"); 2570 DBG("\tSUBARCHITECTURE DEFINED\n");
2592 break; 2571 break;
2593 } 2572 }
2594 } 2573 }
2595 2574
2596 return No_exp; 2575 return No_exp;
2597} 2576}
2598#endif 2577#endif
2599 2578
@@ -2603,48 +2582,48 @@ int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2603/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */ 2582/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
2604#ifdef VFP_INTERPRETER_STRUCT 2583#ifdef VFP_INTERPRETER_STRUCT
2605typedef struct _vmovbcr_inst { 2584typedef struct _vmovbcr_inst {
2606 unsigned int esize; 2585 unsigned int esize;
2607 unsigned int index; 2586 unsigned int index;
2608 unsigned int d; 2587 unsigned int d;
2609 unsigned int t; 2588 unsigned int t;
2610} vmovbcr_inst; 2589} vmovbcr_inst;
2611#endif 2590#endif
2612#ifdef VFP_INTERPRETER_TRANS 2591#ifdef VFP_INTERPRETER_TRANS
2613ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) 2592ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
2614{ 2593{
2615 VFP_DEBUG_TRANSLATE; 2594 VFP_DEBUG_TRANSLATE;
2616 2595
2617 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); 2596 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
2618 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; 2597 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
2598
2599 inst_base->cond = BITS(inst, 28, 31);
2600 inst_base->idx = index;
2601 inst_base->br = NON_BRANCH;
2602 inst_base->load_r15 = 0;
2619 2603
2620 inst_base->cond = BITS(inst, 28, 31); 2604 inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
2621 inst_base->idx = index; 2605 inst_cream->t = BITS(inst, 12, 15);
2622 inst_base->br = NON_BRANCH; 2606 /* VFP variant of instruction */
2623 inst_base->load_r15 = 0; 2607 inst_cream->esize = 32;
2608 inst_cream->index = BIT(inst, 21);
2624 2609
2625 inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; 2610 return inst_base;
2626 inst_cream->t = BITS(inst, 12, 15);
2627 /* VFP variant of instruction */
2628 inst_cream->esize = 32;
2629 inst_cream->index = BIT(inst, 21);
2630
2631 return inst_base;
2632} 2611}
2633#endif 2612#endif
2634#ifdef VFP_INTERPRETER_IMPL 2613#ifdef VFP_INTERPRETER_IMPL
2635VMOVBCR_INST: 2614VMOVBCR_INST:
2636{ 2615{
2637 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2616 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2638 CHECK_VFP_ENABLED; 2617 CHECK_VFP_ENABLED;
2639 2618
2640 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; 2619 vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
2641 2620
2642 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); 2621 VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
2643 } 2622 }
2644 cpu->Reg[15] += GET_INST_SIZE(cpu); 2623 cpu->Reg[15] += GET_INST_SIZE(cpu);
2645 INC_PC(sizeof(vmovbcr_inst)); 2624 INC_PC(sizeof(vmovbcr_inst));
2646 FETCH_INST; 2625 FETCH_INST;
2647 GOTO_NEXT_INST; 2626 GOTO_NEXT_INST;
2648} 2627}
2649#endif 2628#endif
2650 2629
@@ -2654,17 +2633,17 @@ DYNCOM_FILL_ACTION(vmovbcr),
2654#ifdef VFP_DYNCOM_TAG 2633#ifdef VFP_DYNCOM_TAG
2655int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2634int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2656{ 2635{
2657 int instr_size = INSTR_SIZE; 2636 int instr_size = INSTR_SIZE;
2658 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2637 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2659 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 2638 arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
2660 return instr_size; 2639 return instr_size;
2661} 2640}
2662#endif 2641#endif
2663#ifdef VFP_DYNCOM_TRANS 2642#ifdef VFP_DYNCOM_TRANS
2664int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2643int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2665 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2644 DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2666 arch_arm_undef(cpu, bb, instr); 2645 arch_arm_undef(cpu, bb, instr);
2667 return No_exp; 2646 return No_exp;
2668} 2647}
2669#endif 2648#endif
2670 2649
@@ -2679,48 +2658,48 @@ int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2679/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2658/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
2680#ifdef VFP_INTERPRETER_STRUCT 2659#ifdef VFP_INTERPRETER_STRUCT
2681typedef struct _vmovbrrss_inst { 2660typedef struct _vmovbrrss_inst {
2682 unsigned int to_arm; 2661 unsigned int to_arm;
2683 unsigned int t; 2662 unsigned int t;
2684 unsigned int t2; 2663 unsigned int t2;
2685 unsigned int m; 2664 unsigned int m;
2686} vmovbrrss_inst; 2665} vmovbrrss_inst;
2687#endif 2666#endif
2688#ifdef VFP_INTERPRETER_TRANS 2667#ifdef VFP_INTERPRETER_TRANS
2689ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) 2668ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
2690{ 2669{
2691 VFP_DEBUG_TRANSLATE; 2670 VFP_DEBUG_TRANSLATE;
2692 2671
2693 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); 2672 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
2694 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; 2673 vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
2695 2674
2696 inst_base->cond = BITS(inst, 28, 31); 2675 inst_base->cond = BITS(inst, 28, 31);
2697 inst_base->idx = index; 2676 inst_base->idx = index;
2698 inst_base->br = NON_BRANCH; 2677 inst_base->br = NON_BRANCH;
2699 inst_base->load_r15 = 0; 2678 inst_base->load_r15 = 0;
2700 2679
2701 inst_cream->to_arm = BIT(inst, 20) == 1; 2680 inst_cream->to_arm = BIT(inst, 20) == 1;
2702 inst_cream->t = BITS(inst, 12, 15); 2681 inst_cream->t = BITS(inst, 12, 15);
2703 inst_cream->t2 = BITS(inst, 16, 19); 2682 inst_cream->t2 = BITS(inst, 16, 19);
2704 inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); 2683 inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5);
2705 2684
2706 return inst_base; 2685 return inst_base;
2707} 2686}
2708#endif 2687#endif
2709#ifdef VFP_INTERPRETER_IMPL 2688#ifdef VFP_INTERPRETER_IMPL
2710VMOVBRRSS_INST: 2689VMOVBRRSS_INST:
2711{ 2690{
2712 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2691 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2713 CHECK_VFP_ENABLED; 2692 CHECK_VFP_ENABLED;
2714 2693
2715 vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component; 2694 vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component;
2716 2695
2717 VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 2696 VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
2718 &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); 2697 &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]);
2719 } 2698 }
2720 cpu->Reg[15] += GET_INST_SIZE(cpu); 2699 cpu->Reg[15] += GET_INST_SIZE(cpu);
2721 INC_PC(sizeof(vmovbrrss_inst)); 2700 INC_PC(sizeof(vmovbrrss_inst));
2722 FETCH_INST; 2701 FETCH_INST;
2723 GOTO_NEXT_INST; 2702 GOTO_NEXT_INST;
2724} 2703}
2725#endif 2704#endif
2726#ifdef VFP_DYNCOM_TABLE 2705#ifdef VFP_DYNCOM_TABLE
@@ -2729,31 +2708,31 @@ DYNCOM_FILL_ACTION(vmovbrrss),
2729#ifdef VFP_DYNCOM_TAG 2708#ifdef VFP_DYNCOM_TAG
2730int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2709int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2731{ 2710{
2732 int instr_size = INSTR_SIZE; 2711 int instr_size = INSTR_SIZE;
2733 2712
2734 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2713 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2735 if (instr >> 28 != 0xE) 2714 if (instr >> 28 != 0xE)
2736 *tag |= TAG_CONDITIONAL; 2715 *tag |= TAG_CONDITIONAL;
2737 2716
2738 return instr_size; 2717 return instr_size;
2739} 2718}
2740#endif 2719#endif
2741#ifdef VFP_DYNCOM_TRANS 2720#ifdef VFP_DYNCOM_TRANS
2742int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) 2721int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
2743{ 2722{
2744 int to_arm = BIT(20) == 1; 2723 int to_arm = BIT(20) == 1;
2745 int t = BITS(12, 15); 2724 int t = BITS(12, 15);
2746 int t2 = BITS(16, 19); 2725 int t2 = BITS(16, 19);
2747 int n = BIT(5)<<4 | BITS(0, 3); 2726 int n = BIT(5)<<4 | BITS(0, 3);
2748 if (to_arm) { 2727 if (to_arm) {
2749 LET(t, IBITCAST32(FR32(n + 0))); 2728 LET(t, IBITCAST32(FR32(n + 0)));
2750 LET(t2, IBITCAST32(FR32(n + 1))); 2729 LET(t2, IBITCAST32(FR32(n + 1)));
2751 } 2730 }
2752 else { 2731 else {
2753 LETFPS(n + 0, FPBITCAST32(R(t))); 2732 LETFPS(n + 0, FPBITCAST32(R(t)));
2754 LETFPS(n + 1, FPBITCAST32(R(t2))); 2733 LETFPS(n + 1, FPBITCAST32(R(t2)));
2755 } 2734 }
2756 return No_exp; 2735 return No_exp;
2757} 2736}
2758#endif 2737#endif
2759 2738
@@ -2763,48 +2742,48 @@ int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t p
2763/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ 2742/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
2764#ifdef VFP_INTERPRETER_STRUCT 2743#ifdef VFP_INTERPRETER_STRUCT
2765typedef struct _vmovbrrd_inst { 2744typedef struct _vmovbrrd_inst {
2766 unsigned int to_arm; 2745 unsigned int to_arm;
2767 unsigned int t; 2746 unsigned int t;
2768 unsigned int t2; 2747 unsigned int t2;
2769 unsigned int m; 2748 unsigned int m;
2770} vmovbrrd_inst; 2749} vmovbrrd_inst;
2771#endif 2750#endif
2772#ifdef VFP_INTERPRETER_TRANS 2751#ifdef VFP_INTERPRETER_TRANS
2773ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) 2752ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
2774{ 2753{
2775 VFP_DEBUG_TRANSLATE; 2754 VFP_DEBUG_TRANSLATE;
2776
2777 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
2778 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
2779 2755
2780 inst_base->cond = BITS(inst, 28, 31); 2756 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
2781 inst_base->idx = index; 2757 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
2782 inst_base->br = NON_BRANCH;
2783 inst_base->load_r15 = 0;
2784 2758
2785 inst_cream->to_arm = BIT(inst, 20) == 1; 2759 inst_base->cond = BITS(inst, 28, 31);
2786 inst_cream->t = BITS(inst, 12, 15); 2760 inst_base->idx = index;
2787 inst_cream->t2 = BITS(inst, 16, 19); 2761 inst_base->br = NON_BRANCH;
2788 inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); 2762 inst_base->load_r15 = 0;
2789 2763
2790 return inst_base; 2764 inst_cream->to_arm = BIT(inst, 20) == 1;
2765 inst_cream->t = BITS(inst, 12, 15);
2766 inst_cream->t2 = BITS(inst, 16, 19);
2767 inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3);
2768
2769 return inst_base;
2791} 2770}
2792#endif 2771#endif
2793#ifdef VFP_INTERPRETER_IMPL 2772#ifdef VFP_INTERPRETER_IMPL
2794VMOVBRRD_INST: 2773VMOVBRRD_INST:
2795{ 2774{
2796 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2775 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2797 CHECK_VFP_ENABLED; 2776 CHECK_VFP_ENABLED;
2798 2777
2799 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; 2778 vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
2800 2779
2801 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, 2780 VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
2802 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); 2781 &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
2803 } 2782 }
2804 cpu->Reg[15] += GET_INST_SIZE(cpu); 2783 cpu->Reg[15] += GET_INST_SIZE(cpu);
2805 INC_PC(sizeof(vmovbrrd_inst)); 2784 INC_PC(sizeof(vmovbrrd_inst));
2806 FETCH_INST; 2785 FETCH_INST;
2807 GOTO_NEXT_INST; 2786 GOTO_NEXT_INST;
2808} 2787}
2809#endif 2788#endif
2810 2789
@@ -2814,31 +2793,31 @@ DYNCOM_FILL_ACTION(vmovbrrd),
2814#ifdef VFP_DYNCOM_TAG 2793#ifdef VFP_DYNCOM_TAG
2815int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2794int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2816{ 2795{
2817 int instr_size = INSTR_SIZE; 2796 int instr_size = INSTR_SIZE;
2818 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2797 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2819 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2798 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2820 if(instr >> 28 != 0xe) 2799 if(instr >> 28 != 0xe)
2821 *tag |= TAG_CONDITIONAL; 2800 *tag |= TAG_CONDITIONAL;
2822 return instr_size; 2801 return instr_size;
2823} 2802}
2824#endif 2803#endif
2825#ifdef VFP_DYNCOM_TRANS 2804#ifdef VFP_DYNCOM_TRANS
2826int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2805int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2827 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 2806 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
2828 //arch_arm_undef(cpu, bb, instr); 2807 //arch_arm_undef(cpu, bb, instr);
2829 int to_arm = BIT(20) == 1; 2808 int to_arm = BIT(20) == 1;
2830 int t = BITS(12, 15); 2809 int t = BITS(12, 15);
2831 int t2 = BITS(16, 19); 2810 int t2 = BITS(16, 19);
2832 int n = BIT(5)<<4 | BITS(0, 3); 2811 int n = BIT(5)<<4 | BITS(0, 3);
2833 if(to_arm){ 2812 if(to_arm){
2834 LET(t, IBITCAST32(FR32(n * 2))); 2813 LET(t, IBITCAST32(FR32(n * 2)));
2835 LET(t2, IBITCAST32(FR32(n * 2 + 1))); 2814 LET(t2, IBITCAST32(FR32(n * 2 + 1)));
2836 } 2815 }
2837 else{ 2816 else{
2838 LETFPS(n * 2, FPBITCAST32(R(t))); 2817 LETFPS(n * 2, FPBITCAST32(R(t)));
2839 LETFPS(n * 2 + 1, FPBITCAST32(R(t2))); 2818 LETFPS(n * 2 + 1, FPBITCAST32(R(t2)));
2840 } 2819 }
2841 return No_exp; 2820 return No_exp;
2842} 2821}
2843#endif 2822#endif
2844 2823
@@ -2852,60 +2831,60 @@ int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
2852/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */ 2831/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
2853#ifdef VFP_INTERPRETER_STRUCT 2832#ifdef VFP_INTERPRETER_STRUCT
2854typedef struct _vstr_inst { 2833typedef struct _vstr_inst {
2855 unsigned int single; 2834 unsigned int single;
2856 unsigned int n; 2835 unsigned int n;
2857 unsigned int d; 2836 unsigned int d;
2858 unsigned int imm32; 2837 unsigned int imm32;
2859 unsigned int add; 2838 unsigned int add;
2860} vstr_inst; 2839} vstr_inst;
2861#endif 2840#endif
2862#ifdef VFP_INTERPRETER_TRANS 2841#ifdef VFP_INTERPRETER_TRANS
2863ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) 2842ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
2864{ 2843{
2865 VFP_DEBUG_TRANSLATE; 2844 VFP_DEBUG_TRANSLATE;
2866 2845
2867 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); 2846 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
2868 vstr_inst *inst_cream = (vstr_inst *)inst_base->component; 2847 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
2869 2848
2870 inst_base->cond = BITS(inst, 28, 31); 2849 inst_base->cond = BITS(inst, 28, 31);
2871 inst_base->idx = index; 2850 inst_base->idx = index;
2872 inst_base->br = NON_BRANCH; 2851 inst_base->br = NON_BRANCH;
2873 inst_base->load_r15 = 0; 2852 inst_base->load_r15 = 0;
2874
2875 inst_cream->single = BIT(inst, 8) == 0;
2876 inst_cream->add = BIT(inst, 23);
2877 inst_cream->imm32 = BITS(inst, 0,7) << 2;
2878 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
2879 inst_cream->n = BITS(inst, 16, 19);
2880 2853
2881 return inst_base; 2854 inst_cream->single = BIT(inst, 8) == 0;
2855 inst_cream->add = BIT(inst, 23);
2856 inst_cream->imm32 = BITS(inst, 0,7) << 2;
2857 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
2858 inst_cream->n = BITS(inst, 16, 19);
2859
2860 return inst_base;
2882} 2861}
2883#endif 2862#endif
2884#ifdef VFP_INTERPRETER_IMPL 2863#ifdef VFP_INTERPRETER_IMPL
2885VSTR_INST: 2864VSTR_INST:
2886{ 2865{
2887 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2866 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
2888 CHECK_VFP_ENABLED; 2867 CHECK_VFP_ENABLED;
2889 2868
2890 vstr_inst *inst_cream = (vstr_inst *)inst_base->component; 2869 vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
2891 2870
2892 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 2871 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
2893 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); 2872 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
2894 2873
2895 if (inst_cream->single) 2874 if (inst_cream->single)
2896 { 2875 {
2897 Memory::Write32(addr, cpu->ExtReg[inst_cream->d]); 2876 Memory::Write32(addr, cpu->ExtReg[inst_cream->d]);
2898 } 2877 }
2899 else 2878 else
2900 { 2879 {
2901 Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]); 2880 Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]);
2902 Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]); 2881 Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]);
2903 } 2882 }
2904 } 2883 }
2905 cpu->Reg[15] += GET_INST_SIZE(cpu); 2884 cpu->Reg[15] += GET_INST_SIZE(cpu);
2906 INC_PC(sizeof(vstr_inst)); 2885 INC_PC(sizeof(vstr_inst));
2907 FETCH_INST; 2886 FETCH_INST;
2908 GOTO_NEXT_INST; 2887 GOTO_NEXT_INST;
2909} 2888}
2910#endif 2889#endif
2911 2890
@@ -2915,61 +2894,46 @@ DYNCOM_FILL_ACTION(vstr),
2915#ifdef VFP_DYNCOM_TAG 2894#ifdef VFP_DYNCOM_TAG
2916int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 2895int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
2917{ 2896{
2918 int instr_size = INSTR_SIZE; 2897 int instr_size = INSTR_SIZE;
2919 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 2898 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
2920 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 2899 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
2921 *tag |= TAG_NEW_BB; 2900 *tag |= TAG_NEW_BB;
2922 if(instr >> 28 != 0xe) 2901 if(instr >> 28 != 0xe)
2923 *tag |= TAG_CONDITIONAL; 2902 *tag |= TAG_CONDITIONAL;
2924 2903
2925 return instr_size; 2904 return instr_size;
2926} 2905}
2927#endif 2906#endif
2928#ifdef VFP_DYNCOM_TRANS 2907#ifdef VFP_DYNCOM_TRANS
2929int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 2908int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2930 int single = BIT(8) == 0; 2909 int single = BIT(8) == 0;
2931 int add = BIT(23); 2910 int add = BIT(23);
2932 int imm32 = BITS(0,7) << 2; 2911 int imm32 = BITS(0,7) << 2;
2933 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 2912 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
2934 int n = BITS(16, 19); 2913 int n = BITS(16, 19);
2935 2914
2936 Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n); 2915 Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n);
2937 Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32)); 2916 Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32));
2938 DBG("VSTR :\n"); 2917 DBG("VSTR :\n");
2939 //if(single) 2918 //if(single)
2940 // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap); 2919 // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap);
2941 //else 2920 //else
2942 // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap); 2921 // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
2943 //Value* phys_addr; 2922 //Value* phys_addr;
2944 if(single){ 2923 if(single){
2945 #if 0 2924 //memory_write(cpu, bb, Addr, RSPR(d), 32);
2946 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 2925 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
2947 bb = cpu->dyncom_engine->bb; 2926 bb = cpu->dyncom_engine->bb;
2948 arch_write_memory(cpu, bb, phys_addr, RSPR(d), 32); 2927 }
2949 #endif 2928 else{
2950 //memory_write(cpu, bb, Addr, RSPR(d), 32); 2929 //memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
2951 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32); 2930 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
2952 bb = cpu->dyncom_engine->bb; 2931 bb = cpu->dyncom_engine->bb;
2953 } 2932 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
2954 else{ 2933 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
2955 #if 0 2934 bb = cpu->dyncom_engine->bb;
2956 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 2935 }
2957 bb = cpu->dyncom_engine->bb; 2936 return No_exp;
2958 arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2), 32);
2959 #endif
2960 //memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
2961 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
2962 bb = cpu->dyncom_engine->bb;
2963 #if 0
2964 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
2965 bb = cpu->dyncom_engine->bb;
2966 arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2 + 1), 32);
2967 #endif
2968 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
2969 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
2970 bb = cpu->dyncom_engine->bb;
2971 }
2972 return No_exp;
2973} 2937}
2974#endif 2938#endif
2975 2939
@@ -2978,64 +2942,64 @@ int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
2978/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */ 2942/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
2979#ifdef VFP_INTERPRETER_STRUCT 2943#ifdef VFP_INTERPRETER_STRUCT
2980typedef struct _vpush_inst { 2944typedef struct _vpush_inst {
2981 unsigned int single; 2945 unsigned int single;
2982 unsigned int d; 2946 unsigned int d;
2983 unsigned int imm32; 2947 unsigned int imm32;
2984 unsigned int regs; 2948 unsigned int regs;
2985} vpush_inst; 2949} vpush_inst;
2986#endif 2950#endif
2987#ifdef VFP_INTERPRETER_TRANS 2951#ifdef VFP_INTERPRETER_TRANS
2988ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) 2952ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
2989{ 2953{
2990 VFP_DEBUG_TRANSLATE; 2954 VFP_DEBUG_TRANSLATE;
2991
2992 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
2993 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
2994 2955
2995 inst_base->cond = BITS(inst, 28, 31); 2956 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
2996 inst_base->idx = index; 2957 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
2997 inst_base->br = NON_BRANCH;
2998 inst_base->load_r15 = 0;
2999 2958
3000 inst_cream->single = BIT(inst, 8) == 0; 2959 inst_base->cond = BITS(inst, 28, 31);
3001 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); 2960 inst_base->idx = index;
3002 inst_cream->imm32 = BITS(inst, 0, 7)<<2; 2961 inst_base->br = NON_BRANCH;
3003 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); 2962 inst_base->load_r15 = 0;
3004 2963
3005 return inst_base; 2964 inst_cream->single = BIT(inst, 8) == 0;
2965 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
2966 inst_cream->imm32 = BITS(inst, 0, 7)<<2;
2967 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
2968
2969 return inst_base;
3006} 2970}
3007#endif 2971#endif
3008#ifdef VFP_INTERPRETER_IMPL 2972#ifdef VFP_INTERPRETER_IMPL
3009VPUSH_INST: 2973VPUSH_INST:
3010{ 2974{
3011 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 2975 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3012 CHECK_VFP_ENABLED; 2976 CHECK_VFP_ENABLED;
3013 int i; 2977 int i;
3014 2978
3015 vpush_inst *inst_cream = (vpush_inst *)inst_base->component; 2979 vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
3016 2980
3017 addr = cpu->Reg[R13] - inst_cream->imm32; 2981 addr = cpu->Reg[R13] - inst_cream->imm32;
3018 2982
3019 for (i = 0; i < inst_cream->regs; i++) 2983 for (i = 0; i < inst_cream->regs; i++)
3020 { 2984 {
3021 if (inst_cream->single) 2985 if (inst_cream->single)
3022 { 2986 {
3023 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 2987 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
3024 addr += 4; 2988 addr += 4;
3025 } 2989 }
3026 else 2990 else
3027 { 2991 {
3028 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); 2992 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
3029 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); 2993 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
3030 addr += 8; 2994 addr += 8;
3031 } 2995 }
3032 } 2996 }
3033 cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; 2997 cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32;
3034 } 2998 }
3035 cpu->Reg[15] += GET_INST_SIZE(cpu); 2999 cpu->Reg[15] += GET_INST_SIZE(cpu);
3036 INC_PC(sizeof(vpush_inst)); 3000 INC_PC(sizeof(vpush_inst));
3037 FETCH_INST; 3001 FETCH_INST;
3038 GOTO_NEXT_INST; 3002 GOTO_NEXT_INST;
3039} 3003}
3040#endif 3004#endif
3041#ifdef VFP_DYNCOM_TABLE 3005#ifdef VFP_DYNCOM_TABLE
@@ -3044,72 +3008,57 @@ DYNCOM_FILL_ACTION(vpush),
3044#ifdef VFP_DYNCOM_TAG 3008#ifdef VFP_DYNCOM_TAG
3045int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3009int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3046{ 3010{
3047 int instr_size = INSTR_SIZE; 3011 int instr_size = INSTR_SIZE;
3048 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3012 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
3049 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 3013 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
3050 *tag |= TAG_NEW_BB; 3014 *tag |= TAG_NEW_BB;
3051 if(instr >> 28 != 0xe) 3015 if(instr >> 28 != 0xe)
3052 *tag |= TAG_CONDITIONAL; 3016 *tag |= TAG_CONDITIONAL;
3053 3017
3054 return instr_size; 3018 return instr_size;
3055} 3019}
3056#endif 3020#endif
3057#ifdef VFP_DYNCOM_TRANS 3021#ifdef VFP_DYNCOM_TRANS
3058int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3022int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3059 int single = BIT(8) == 0; 3023 int single = BIT(8) == 0;
3060 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 3024 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
3061 int imm32 = BITS(0, 7)<<2; 3025 int imm32 = BITS(0, 7)<<2;
3062 int regs = (single ? BITS(0, 7) : BITS(1, 7)); 3026 int regs = (single ? BITS(0, 7) : BITS(1, 7));
3063 3027
3064 DBG("\t\tin %s \n", __FUNCTION__); 3028 DBG("\t\tin %s \n", __FUNCTION__);
3065 Value* Addr = SUB(R(13), CONST(imm32)); 3029 Value* Addr = SUB(R(13), CONST(imm32));
3066 //if(single) 3030 //if(single)
3067 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); 3031 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
3068 //else 3032 //else
3069 // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); 3033 // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
3070 //Value* phys_addr; 3034 //Value* phys_addr;
3071 int i; 3035 int i;
3072 for (i = 0; i < regs; i++) 3036 for (i = 0; i < regs; i++)
3073 { 3037 {
3074 if (single) 3038 if (single)
3075 { 3039 {
3076 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 3040 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
3077 #if 0 3041 //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
3078 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 3042 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
3079 bb = cpu->dyncom_engine->bb; 3043 bb = cpu->dyncom_engine->bb;
3080 arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32); 3044 Addr = ADD(Addr, CONST(4));
3081 #endif 3045 }
3082 //memory_write(cpu, bb, Addr, RSPR(d + i), 32); 3046 else
3083 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32); 3047 {
3084 bb = cpu->dyncom_engine->bb; 3048 /* Careful of endianness, little by default */
3085 Addr = ADD(Addr, CONST(4)); 3049 //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
3086 } 3050 memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
3087 else 3051 bb = cpu->dyncom_engine->bb;
3088 { 3052 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
3089 /* Careful of endianness, little by default */ 3053 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
3090 #if 0 3054 bb = cpu->dyncom_engine->bb;
3091 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 3055
3092 bb = cpu->dyncom_engine->bb; 3056 Addr = ADD(Addr, CONST(8));
3093 arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32); 3057 }
3094 #endif 3058 }
3095 //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); 3059 LET(13, SUB(R(13), CONST(imm32)));
3096 memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32); 3060
3097 bb = cpu->dyncom_engine->bb; 3061 return No_exp;
3098 #if 0
3099 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
3100 bb = cpu->dyncom_engine->bb;
3101 arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
3102 #endif
3103 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
3104 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
3105 bb = cpu->dyncom_engine->bb;
3106
3107 Addr = ADD(Addr, CONST(8));
3108 }
3109 }
3110 LET(13, SUB(R(13), CONST(imm32)));
3111
3112 return No_exp;
3113} 3062}
3114#endif 3063#endif
3115 3064
@@ -3118,76 +3067,76 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3118/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */ 3067/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
3119#ifdef VFP_INTERPRETER_STRUCT 3068#ifdef VFP_INTERPRETER_STRUCT
3120typedef struct _vstm_inst { 3069typedef struct _vstm_inst {
3121 unsigned int single; 3070 unsigned int single;
3122 unsigned int add; 3071 unsigned int add;
3123 unsigned int wback; 3072 unsigned int wback;
3124 unsigned int d; 3073 unsigned int d;
3125 unsigned int n; 3074 unsigned int n;
3126 unsigned int imm32; 3075 unsigned int imm32;
3127 unsigned int regs; 3076 unsigned int regs;
3128} vstm_inst; 3077} vstm_inst;
3129#endif 3078#endif
3130#ifdef VFP_INTERPRETER_TRANS 3079#ifdef VFP_INTERPRETER_TRANS
3131ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) 3080ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
3132{ 3081{
3133 VFP_DEBUG_TRANSLATE; 3082 VFP_DEBUG_TRANSLATE;
3134 3083
3135 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); 3084 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
3136 vstm_inst *inst_cream = (vstm_inst *)inst_base->component; 3085 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
3137 3086
3138 inst_base->cond = BITS(inst, 28, 31); 3087 inst_base->cond = BITS(inst, 28, 31);
3139 inst_base->idx = index; 3088 inst_base->idx = index;
3140 inst_base->br = NON_BRANCH; 3089 inst_base->br = NON_BRANCH;
3141 inst_base->load_r15 = 0; 3090 inst_base->load_r15 = 0;
3142 3091
3143 inst_cream->single = BIT(inst, 8) == 0; 3092 inst_cream->single = BIT(inst, 8) == 0;
3144 inst_cream->add = BIT(inst, 23); 3093 inst_cream->add = BIT(inst, 23);
3145 inst_cream->wback = BIT(inst, 21); 3094 inst_cream->wback = BIT(inst, 21);
3146 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); 3095 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
3147 inst_cream->n = BITS(inst, 16, 19); 3096 inst_cream->n = BITS(inst, 16, 19);
3148 inst_cream->imm32 = BITS(inst, 0, 7)<<2; 3097 inst_cream->imm32 = BITS(inst, 0, 7)<<2;
3149 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); 3098 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
3150 3099
3151 return inst_base; 3100 return inst_base;
3152} 3101}
3153#endif 3102#endif
3154#ifdef VFP_INTERPRETER_IMPL 3103#ifdef VFP_INTERPRETER_IMPL
3155VSTM_INST: /* encoding 1 */ 3104VSTM_INST: /* encoding 1 */
3156{ 3105{
3157 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3106 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3158 CHECK_VFP_ENABLED; 3107 CHECK_VFP_ENABLED;
3159 3108
3160 int i; 3109 int i;
3161 3110
3162 vstm_inst *inst_cream = (vstm_inst *)inst_base->component; 3111 vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
3163 3112
3164 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3113 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
3165 3114
3166 for (i = 0; i < inst_cream->regs; i++) 3115 for (i = 0; i < inst_cream->regs; i++)
3167 { 3116 {
3168 if (inst_cream->single) 3117 if (inst_cream->single)
3169 { 3118 {
3170 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 3119 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
3171 addr += 4; 3120 addr += 4;
3172 } 3121 }
3173 else 3122 else
3174 { 3123 {
3175 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); 3124 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
3176 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); 3125 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
3177 addr += 8; 3126 addr += 8;
3178 } 3127 }
3179 } 3128 }
3180 if (inst_cream->wback){ 3129 if (inst_cream->wback){
3181 cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : 3130 cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
3182 cpu->Reg[inst_cream->n] - inst_cream->imm32); 3131 cpu->Reg[inst_cream->n] - inst_cream->imm32);
3183 } 3132 }
3184 3133
3185 } 3134 }
3186 cpu->Reg[15] += 4; 3135 cpu->Reg[15] += 4;
3187 INC_PC(sizeof(vstm_inst)); 3136 INC_PC(sizeof(vstm_inst));
3188 3137
3189 FETCH_INST; 3138 FETCH_INST;
3190 GOTO_NEXT_INST; 3139 GOTO_NEXT_INST;
3191} 3140}
3192#endif 3141#endif
3193 3142
@@ -3197,90 +3146,75 @@ DYNCOM_FILL_ACTION(vstm),
3197#ifdef VFP_DYNCOM_TAG 3146#ifdef VFP_DYNCOM_TAG
3198int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3147int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3199{ 3148{
3200 int instr_size = INSTR_SIZE; 3149 int instr_size = INSTR_SIZE;
3201 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3150 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3202 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 3151 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
3203 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3152 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
3204 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 3153 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
3205 *tag |= TAG_NEW_BB; 3154 *tag |= TAG_NEW_BB;
3206 if(instr >> 28 != 0xe) 3155 if(instr >> 28 != 0xe)
3207 *tag |= TAG_CONDITIONAL; 3156 *tag |= TAG_CONDITIONAL;
3208 3157
3209 return instr_size; 3158 return instr_size;
3210} 3159}
3211#endif 3160#endif
3212#ifdef VFP_DYNCOM_TRANS 3161#ifdef VFP_DYNCOM_TRANS
3213int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3162int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3214 //arch_arm_undef(cpu, bb, instr); 3163 //arch_arm_undef(cpu, bb, instr);
3215 int single = BIT(8) == 0; 3164 int single = BIT(8) == 0;
3216 int add = BIT(23); 3165 int add = BIT(23);
3217 int wback = BIT(21); 3166 int wback = BIT(21);
3218 int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4); 3167 int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4);
3219 int n = BITS(16, 19); 3168 int n = BITS(16, 19);
3220 int imm32 = BITS(0, 7)<<2; 3169 int imm32 = BITS(0, 7)<<2;
3221 int regs = single ? BITS(0, 7) : BITS(1, 7); 3170 int regs = single ? BITS(0, 7) : BITS(1, 7);
3222 3171
3223 Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); 3172 Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
3224 DBG("VSTM \n"); 3173 DBG("VSTM \n");
3225 //if(single) 3174 //if(single)
3226 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); 3175 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
3227 //else 3176 //else
3228 // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); 3177 // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
3229 3178
3230 int i; 3179 int i;
3231 Value* phys_addr; 3180 Value* phys_addr;
3232 for (i = 0; i < regs; i++) 3181 for (i = 0; i < regs; i++)
3233 { 3182 {
3234 if (single) 3183 if (single)
3235 { 3184 {
3236 3185
3237 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 3186 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
3238 /* if R(i) is R15? */ 3187 /* if R(i) is R15? */
3239 #if 0 3188 //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
3240 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 3189 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
3241 bb = cpu->dyncom_engine->bb; 3190 bb = cpu->dyncom_engine->bb;
3242 arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32); 3191 //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
3243 #endif 3192 Addr = ADD(Addr, CONST(4));
3244 //memory_write(cpu, bb, Addr, RSPR(d + i), 32); 3193 }
3245 memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); 3194 else
3246 bb = cpu->dyncom_engine->bb; 3195 {
3247 //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 3196
3248 Addr = ADD(Addr, CONST(4)); 3197 //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
3249 } 3198 //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
3250 else 3199 memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
3251 { 3200 bb = cpu->dyncom_engine->bb;
3252 3201
3253 //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); 3202 //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
3254 #if 0 3203 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
3255 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 3204 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
3256 bb = cpu->dyncom_engine->bb; 3205 bb = cpu->dyncom_engine->bb;
3257 arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32); 3206 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3258 #endif 3207 //addr += 8;
3259 //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); 3208 Addr = ADD(Addr, CONST(8));
3260 memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); 3209 }
3261 bb = cpu->dyncom_engine->bb; 3210 }
3262 3211 if (wback){
3263 //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); 3212 //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
3264 #if 0 3213 // cpu->Reg[n] - imm32);
3265 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); 3214 LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
3266 bb = cpu->dyncom_engine->bb; 3215 DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
3267 arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32); 3216 }
3268 #endif 3217 return No_exp;
3269 //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
3270 memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
3271 bb = cpu->dyncom_engine->bb;
3272 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3273 //addr += 8;
3274 Addr = ADD(Addr, CONST(8));
3275 }
3276 }
3277 if (wback){
3278 //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
3279 // cpu->Reg[n] - imm32);
3280 LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
3281 DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
3282 }
3283 return No_exp;
3284} 3218}
3285#endif 3219#endif
3286 3220
@@ -3289,69 +3223,69 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3289/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */ 3223/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
3290#ifdef VFP_INTERPRETER_STRUCT 3224#ifdef VFP_INTERPRETER_STRUCT
3291typedef struct _vpop_inst { 3225typedef struct _vpop_inst {
3292 unsigned int single; 3226 unsigned int single;
3293 unsigned int d; 3227 unsigned int d;
3294 unsigned int imm32; 3228 unsigned int imm32;
3295 unsigned int regs; 3229 unsigned int regs;
3296} vpop_inst; 3230} vpop_inst;
3297#endif 3231#endif
3298#ifdef VFP_INTERPRETER_TRANS 3232#ifdef VFP_INTERPRETER_TRANS
3299ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) 3233ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
3300{ 3234{
3301 VFP_DEBUG_TRANSLATE; 3235 VFP_DEBUG_TRANSLATE;
3302 3236
3303 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); 3237 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
3304 vpop_inst *inst_cream = (vpop_inst *)inst_base->component; 3238 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
3305 3239
3306 inst_base->cond = BITS(inst, 28, 31); 3240 inst_base->cond = BITS(inst, 28, 31);
3307 inst_base->idx = index; 3241 inst_base->idx = index;
3308 inst_base->br = NON_BRANCH; 3242 inst_base->br = NON_BRANCH;
3309 inst_base->load_r15 = 0; 3243 inst_base->load_r15 = 0;
3310 3244
3311 inst_cream->single = BIT(inst, 8) == 0; 3245 inst_cream->single = BIT(inst, 8) == 0;
3312 inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4)); 3246 inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
3313 inst_cream->imm32 = BITS(inst, 0, 7)<<2; 3247 inst_cream->imm32 = BITS(inst, 0, 7)<<2;
3314 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); 3248 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
3315 3249
3316 return inst_base; 3250 return inst_base;
3317} 3251}
3318#endif 3252#endif
3319#ifdef VFP_INTERPRETER_IMPL 3253#ifdef VFP_INTERPRETER_IMPL
3320VPOP_INST: 3254VPOP_INST:
3321{ 3255{
3322 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3256 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3323 CHECK_VFP_ENABLED; 3257 CHECK_VFP_ENABLED;
3324 3258
3325 int i; 3259 int i;
3326 unsigned int value1, value2; 3260 unsigned int value1, value2;
3327 3261
3328 vpop_inst *inst_cream = (vpop_inst *)inst_base->component; 3262 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
3329 3263
3330 addr = cpu->Reg[R13]; 3264 addr = cpu->Reg[R13];
3331 3265
3332 for (i = 0; i < inst_cream->regs; i++) 3266 for (i = 0; i < inst_cream->regs; i++)
3333 { 3267 {
3334 if (inst_cream->single) 3268 if (inst_cream->single)
3335 { 3269 {
3336 value1 = Memory::Read32(addr); 3270 value1 = Memory::Read32(addr);
3337 cpu->ExtReg[inst_cream->d+i] = value1; 3271 cpu->ExtReg[inst_cream->d+i] = value1;
3338 addr += 4; 3272 addr += 4;
3339 } 3273 }
3340 else 3274 else
3341 { 3275 {
3342 value1 = Memory::Read32(addr); 3276 value1 = Memory::Read32(addr);
3343 value2 = Memory::Read32(addr + 4); 3277 value2 = Memory::Read32(addr + 4);
3344 cpu->ExtReg[(inst_cream->d+i)*2] = value1; 3278 cpu->ExtReg[(inst_cream->d+i)*2] = value1;
3345 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; 3279 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2;
3346 addr += 8; 3280 addr += 8;
3347 } 3281 }
3348 } 3282 }
3349 cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; 3283 cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32;
3350 } 3284 }
3351 cpu->Reg[15] += GET_INST_SIZE(cpu); 3285 cpu->Reg[15] += GET_INST_SIZE(cpu);
3352 INC_PC(sizeof(vpop_inst)); 3286 INC_PC(sizeof(vpop_inst));
3353 FETCH_INST; 3287 FETCH_INST;
3354 GOTO_NEXT_INST; 3288 GOTO_NEXT_INST;
3355} 3289}
3356#endif 3290#endif
3357 3291
@@ -3361,82 +3295,67 @@ DYNCOM_FILL_ACTION(vpop),
3361#ifdef VFP_DYNCOM_TAG 3295#ifdef VFP_DYNCOM_TAG
3362int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3296int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3363{ 3297{
3364 int instr_size = INSTR_SIZE; 3298 int instr_size = INSTR_SIZE;
3365 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3299 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3366 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 3300 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
3367 /* Should check if PC is destination register */ 3301 /* Should check if PC is destination register */
3368 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3302 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
3369 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 3303 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
3370 *tag |= TAG_NEW_BB; 3304 *tag |= TAG_NEW_BB;
3371 if(instr >> 28 != 0xe) 3305 if(instr >> 28 != 0xe)
3372 *tag |= TAG_CONDITIONAL; 3306 *tag |= TAG_CONDITIONAL;
3373 3307
3374 return instr_size; 3308 return instr_size;
3375} 3309}
3376#endif 3310#endif
3377#ifdef VFP_DYNCOM_TRANS 3311#ifdef VFP_DYNCOM_TRANS
3378int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3312int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3379 DBG("\t\tin %s instruction .\n", __FUNCTION__); 3313 DBG("\t\tin %s instruction .\n", __FUNCTION__);
3380 //arch_arm_undef(cpu, bb, instr); 3314 //arch_arm_undef(cpu, bb, instr);
3381 int single = BIT(8) == 0; 3315 int single = BIT(8) == 0;
3382 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 3316 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
3383 int imm32 = BITS(0, 7)<<2; 3317 int imm32 = BITS(0, 7)<<2;
3384 int regs = (single ? BITS(0, 7) : BITS(1, 7)); 3318 int regs = (single ? BITS(0, 7) : BITS(1, 7));
3385 3319
3386 int i; 3320 int i;
3387 unsigned int value1, value2; 3321 unsigned int value1, value2;
3388 3322
3389 DBG("VPOP :\n"); 3323 DBG("VPOP :\n");
3390 3324
3391 Value* Addr = R(13); 3325 Value* Addr = R(13);
3392 Value* val; 3326 Value* val;
3393 //if(single) 3327 //if(single)
3394 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); 3328 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
3395 //else 3329 //else
3396 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); 3330 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
3397 //Value* phys_addr; 3331 //Value* phys_addr;
3398 for (i = 0; i < regs; i++) 3332 for (i = 0; i < regs; i++)
3399 { 3333 {
3400 if (single) 3334 if (single)
3401 { 3335 {
3402 #if 0 3336 memory_read(cpu, bb, Addr, 0, 32);
3403 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3337 bb = cpu->dyncom_engine->bb;
3404 bb = cpu->dyncom_engine->bb; 3338 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3405 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3339 LETFPS(d + i, FPBITCAST32(val));
3406 #endif 3340 Addr = ADD(Addr, CONST(4));
3407 memory_read(cpu, bb, Addr, 0, 32); 3341 }
3408 bb = cpu->dyncom_engine->bb; 3342 else
3409 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3343 {
3410 LETFPS(d + i, FPBITCAST32(val)); 3344 /* Careful of endianness, little by default */
3411 Addr = ADD(Addr, CONST(4)); 3345 memory_read(cpu, bb, Addr, 0, 32);
3412 } 3346 bb = cpu->dyncom_engine->bb;
3413 else 3347 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3414 { 3348 LETFPS((d + i) * 2, FPBITCAST32(val));
3415 /* Careful of endianness, little by default */ 3349 memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
3416 #if 0 3350 bb = cpu->dyncom_engine->bb;
3417 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3351 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3418 bb = cpu->dyncom_engine->bb; 3352 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
3419 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3353
3420 #endif 3354 Addr = ADD(Addr, CONST(8));
3421 memory_read(cpu, bb, Addr, 0, 32); 3355 }
3422 bb = cpu->dyncom_engine->bb; 3356 }
3423 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3357 LET(13, ADD(R(13), CONST(imm32)));
3424 LETFPS((d + i) * 2, FPBITCAST32(val)); 3358 return No_exp;
3425 #if 0
3426 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
3427 bb = cpu->dyncom_engine->bb;
3428 val = arch_read_memory(cpu,bb,phys_addr,0,32);
3429 #endif
3430 memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
3431 bb = cpu->dyncom_engine->bb;
3432 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3433 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
3434
3435 Addr = ADD(Addr, CONST(8));
3436 }
3437 }
3438 LET(13, ADD(R(13), CONST(imm32)));
3439 return No_exp;
3440} 3359}
3441#endif 3360#endif
3442 3361
@@ -3445,64 +3364,64 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3445/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ 3364/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
3446#ifdef VFP_INTERPRETER_STRUCT 3365#ifdef VFP_INTERPRETER_STRUCT
3447typedef struct _vldr_inst { 3366typedef struct _vldr_inst {
3448 unsigned int single; 3367 unsigned int single;
3449 unsigned int n; 3368 unsigned int n;
3450 unsigned int d; 3369 unsigned int d;
3451 unsigned int imm32; 3370 unsigned int imm32;
3452 unsigned int add; 3371 unsigned int add;
3453} vldr_inst; 3372} vldr_inst;
3454#endif 3373#endif
3455#ifdef VFP_INTERPRETER_TRANS 3374#ifdef VFP_INTERPRETER_TRANS
3456ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) 3375ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
3457{ 3376{
3458 VFP_DEBUG_TRANSLATE; 3377 VFP_DEBUG_TRANSLATE;
3459 3378
3460 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); 3379 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
3461 vldr_inst *inst_cream = (vldr_inst *)inst_base->component; 3380 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
3462 3381
3463 inst_base->cond = BITS(inst, 28, 31); 3382 inst_base->cond = BITS(inst, 28, 31);
3464 inst_base->idx = index; 3383 inst_base->idx = index;
3465 inst_base->br = NON_BRANCH; 3384 inst_base->br = NON_BRANCH;
3466 inst_base->load_r15 = 0; 3385 inst_base->load_r15 = 0;
3467
3468 inst_cream->single = BIT(inst, 8) == 0;
3469 inst_cream->add = BIT(inst, 23);
3470 inst_cream->imm32 = BITS(inst, 0,7) << 2;
3471 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
3472 inst_cream->n = BITS(inst, 16, 19);
3473 3386
3474 return inst_base; 3387 inst_cream->single = BIT(inst, 8) == 0;
3388 inst_cream->add = BIT(inst, 23);
3389 inst_cream->imm32 = BITS(inst, 0,7) << 2;
3390 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
3391 inst_cream->n = BITS(inst, 16, 19);
3392
3393 return inst_base;
3475} 3394}
3476#endif 3395#endif
3477#ifdef VFP_INTERPRETER_IMPL 3396#ifdef VFP_INTERPRETER_IMPL
3478VLDR_INST: 3397VLDR_INST:
3479{ 3398{
3480 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3399 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3481 CHECK_VFP_ENABLED; 3400 CHECK_VFP_ENABLED;
3482 3401
3483 vldr_inst *inst_cream = (vldr_inst *)inst_base->component; 3402 vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
3484 3403
3485 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); 3404 unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
3486 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); 3405 addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
3487 3406
3488 if (inst_cream->single) 3407 if (inst_cream->single)
3489 { 3408 {
3490 cpu->ExtReg[inst_cream->d] = Memory::Read32(addr); 3409 cpu->ExtReg[inst_cream->d] = Memory::Read32(addr);
3491 } 3410 }
3492 else 3411 else
3493 { 3412 {
3494 unsigned int word1, word2; 3413 unsigned int word1, word2;
3495 word1 = Memory::Read32(addr); 3414 word1 = Memory::Read32(addr);
3496 word2 = Memory::Read32(addr + 4); 3415 word2 = Memory::Read32(addr + 4);
3497 3416
3498 cpu->ExtReg[inst_cream->d*2] = word1; 3417 cpu->ExtReg[inst_cream->d*2] = word1;
3499 cpu->ExtReg[inst_cream->d*2+1] = word2; 3418 cpu->ExtReg[inst_cream->d*2+1] = word2;
3500 } 3419 }
3501 } 3420 }
3502 cpu->Reg[15] += GET_INST_SIZE(cpu); 3421 cpu->Reg[15] += GET_INST_SIZE(cpu);
3503 INC_PC(sizeof(vldr_inst)); 3422 INC_PC(sizeof(vldr_inst));
3504 FETCH_INST; 3423 FETCH_INST;
3505 GOTO_NEXT_INST; 3424 GOTO_NEXT_INST;
3506} 3425}
3507#endif 3426#endif
3508 3427
@@ -3512,76 +3431,61 @@ DYNCOM_FILL_ACTION(vldr),
3512#ifdef VFP_DYNCOM_TAG 3431#ifdef VFP_DYNCOM_TAG
3513int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3432int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3514{ 3433{
3515 int instr_size = INSTR_SIZE; 3434 int instr_size = INSTR_SIZE;
3516 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3435 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3517 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 3436 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
3518 /* Should check if PC is destination register */ 3437 /* Should check if PC is destination register */
3519 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3438 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
3520 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 3439 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
3521 *tag |= TAG_NEW_BB; 3440 *tag |= TAG_NEW_BB;
3522 if(instr >> 28 != 0xe) 3441 if(instr >> 28 != 0xe)
3523 *tag |= TAG_CONDITIONAL; 3442 *tag |= TAG_CONDITIONAL;
3524 3443
3525 return instr_size; 3444 return instr_size;
3526} 3445}
3527#endif 3446#endif
3528#ifdef VFP_DYNCOM_TRANS 3447#ifdef VFP_DYNCOM_TRANS
3529int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3448int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3530 int single = BIT(8) == 0; 3449 int single = BIT(8) == 0;
3531 int add = BIT(23); 3450 int add = BIT(23);
3532 int wback = BIT(21); 3451 int wback = BIT(21);
3533 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); 3452 int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
3534 int n = BITS(16, 19); 3453 int n = BITS(16, 19);
3535 int imm32 = BITS(0, 7)<<2; 3454 int imm32 = BITS(0, 7)<<2;
3536 int regs = (single ? BITS(0, 7) : BITS(1, 7)); 3455 int regs = (single ? BITS(0, 7) : BITS(1, 7));
3537 Value* base = R(n); 3456 Value* base = R(n);
3538 DBG("\t\tin %s .\n", __FUNCTION__); 3457 DBG("\t\tin %s .\n", __FUNCTION__);
3539 if(n == 15){ 3458 if(n == 15){
3540 base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8)); 3459 base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8));
3541 } 3460 }
3542 Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32))); 3461 Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32)));
3543 //if(single) 3462 //if(single)
3544 // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap); 3463 // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap);
3545 //else 3464 //else
3546 // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap); 3465 // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap);
3547 //Value* phys_addr; 3466 //Value* phys_addr;
3548 Value* val; 3467 Value* val;
3549 if(single){ 3468 if(single){
3550 #if 0 3469 memory_read(cpu, bb, Addr, 0, 32);
3551 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3470 bb = cpu->dyncom_engine->bb;
3552 bb = cpu->dyncom_engine->bb; 3471 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3553 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3472 //LETS(d, val);
3554 #endif 3473 LETFPS(d,FPBITCAST32(val));
3555 memory_read(cpu, bb, Addr, 0, 32); 3474 }
3556 bb = cpu->dyncom_engine->bb; 3475 else{
3557 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3476 memory_read(cpu, bb, Addr, 0, 32);
3558 //LETS(d, val); 3477 bb = cpu->dyncom_engine->bb;
3559 LETFPS(d,FPBITCAST32(val)); 3478 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3560 } 3479 //LETS(d * 2, val);
3561 else{ 3480 LETFPS(d * 2,FPBITCAST32(val));
3562 #if 0 3481 memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
3563 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3482 bb = cpu->dyncom_engine->bb;
3564 bb = cpu->dyncom_engine->bb; 3483 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3565 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3484 //LETS(d * 2 + 1, val);
3566 #endif 3485 LETFPS( d * 2 + 1,FPBITCAST32(val));
3567 memory_read(cpu, bb, Addr, 0, 32); 3486 }
3568 bb = cpu->dyncom_engine->bb; 3487
3569 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3488 return No_exp;
3570 //LETS(d * 2, val);
3571 LETFPS(d * 2,FPBITCAST32(val));
3572 #if 0
3573 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
3574 bb = cpu->dyncom_engine->bb;
3575 val = arch_read_memory(cpu,bb,phys_addr,0,32);
3576 #endif
3577 memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
3578 bb = cpu->dyncom_engine->bb;
3579 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3580 //LETS(d * 2 + 1, val);
3581 LETFPS( d * 2 + 1,FPBITCAST32(val));
3582 }
3583
3584 return No_exp;
3585} 3489}
3586#endif 3490#endif
3587 3491
@@ -3590,76 +3494,76 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3590/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */ 3494/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
3591#ifdef VFP_INTERPRETER_STRUCT 3495#ifdef VFP_INTERPRETER_STRUCT
3592typedef struct _vldm_inst { 3496typedef struct _vldm_inst {
3593 unsigned int single; 3497 unsigned int single;
3594 unsigned int add; 3498 unsigned int add;
3595 unsigned int wback; 3499 unsigned int wback;
3596 unsigned int d; 3500 unsigned int d;
3597 unsigned int n; 3501 unsigned int n;
3598 unsigned int imm32; 3502 unsigned int imm32;
3599 unsigned int regs; 3503 unsigned int regs;
3600} vldm_inst; 3504} vldm_inst;
3601#endif 3505#endif
3602#ifdef VFP_INTERPRETER_TRANS 3506#ifdef VFP_INTERPRETER_TRANS
3603ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) 3507ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
3604{ 3508{
3605 VFP_DEBUG_TRANSLATE; 3509 VFP_DEBUG_TRANSLATE;
3606 3510
3607 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); 3511 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
3608 vldm_inst *inst_cream = (vldm_inst *)inst_base->component; 3512 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
3609 3513
3610 inst_base->cond = BITS(inst, 28, 31); 3514 inst_base->cond = BITS(inst, 28, 31);
3611 inst_base->idx = index; 3515 inst_base->idx = index;
3612 inst_base->br = NON_BRANCH; 3516 inst_base->br = NON_BRANCH;
3613 inst_base->load_r15 = 0; 3517 inst_base->load_r15 = 0;
3614 3518
3615 inst_cream->single = BIT(inst, 8) == 0; 3519 inst_cream->single = BIT(inst, 8) == 0;
3616 inst_cream->add = BIT(inst, 23); 3520 inst_cream->add = BIT(inst, 23);
3617 inst_cream->wback = BIT(inst, 21); 3521 inst_cream->wback = BIT(inst, 21);
3618 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); 3522 inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
3619 inst_cream->n = BITS(inst, 16, 19); 3523 inst_cream->n = BITS(inst, 16, 19);
3620 inst_cream->imm32 = BITS(inst, 0, 7)<<2; 3524 inst_cream->imm32 = BITS(inst, 0, 7)<<2;
3621 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); 3525 inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
3622 3526
3623 return inst_base; 3527 return inst_base;
3624} 3528}
3625#endif 3529#endif
3626#ifdef VFP_INTERPRETER_IMPL 3530#ifdef VFP_INTERPRETER_IMPL
3627VLDM_INST: 3531VLDM_INST:
3628{ 3532{
3629 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3533 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
3630 CHECK_VFP_ENABLED; 3534 CHECK_VFP_ENABLED;
3631 3535
3632 int i; 3536 int i;
3633 3537
3634 vldm_inst *inst_cream = (vldm_inst *)inst_base->component; 3538 vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
3635 3539
3636 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); 3540 addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
3637 3541
3638 for (i = 0; i < inst_cream->regs; i++) 3542 for (i = 0; i < inst_cream->regs; i++)
3639 { 3543 {
3640 if (inst_cream->single) 3544 if (inst_cream->single)
3641 { 3545 {
3642 cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr); 3546 cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr);
3643 addr += 4; 3547 addr += 4;
3644 } 3548 }
3645 else 3549 else
3646 { 3550 {
3647 cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr); 3551 cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr);
3648 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4); 3552 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4);
3649 addr += 8; 3553 addr += 8;
3650 } 3554 }
3651 } 3555 }
3652 if (inst_cream->wback){ 3556 if (inst_cream->wback){
3653 cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : 3557 cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
3654 cpu->Reg[inst_cream->n] - inst_cream->imm32); 3558 cpu->Reg[inst_cream->n] - inst_cream->imm32);
3655 DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]); 3559 DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]);
3656 } 3560 }
3657 3561
3658 } 3562 }
3659 cpu->Reg[15] += GET_INST_SIZE(cpu); 3563 cpu->Reg[15] += GET_INST_SIZE(cpu);
3660 INC_PC(sizeof(vldm_inst)); 3564 INC_PC(sizeof(vldm_inst));
3661 FETCH_INST; 3565 FETCH_INST;
3662 GOTO_NEXT_INST; 3566 GOTO_NEXT_INST;
3663} 3567}
3664#endif 3568#endif
3665 3569
@@ -3669,91 +3573,76 @@ DYNCOM_FILL_ACTION(vldm),
3669#ifdef VFP_DYNCOM_TAG 3573#ifdef VFP_DYNCOM_TAG
3670int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) 3574int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
3671{ 3575{
3672 int instr_size = INSTR_SIZE; 3576 int instr_size = INSTR_SIZE;
3673 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); 3577 //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
3674 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); 3578 //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
3675 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); 3579 arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
3676 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); 3580 DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
3677 *tag |= TAG_NEW_BB; 3581 *tag |= TAG_NEW_BB;
3678 if(instr >> 28 != 0xe) 3582 if(instr >> 28 != 0xe)
3679 *tag |= TAG_CONDITIONAL; 3583 *tag |= TAG_CONDITIONAL;
3680 3584
3681 return instr_size; 3585 return instr_size;
3682} 3586}
3683#endif 3587#endif
3684#ifdef VFP_DYNCOM_TRANS 3588#ifdef VFP_DYNCOM_TRANS
3685int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ 3589int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
3686 int single = BIT(8) == 0; 3590 int single = BIT(8) == 0;
3687 int add = BIT(23); 3591 int add = BIT(23);
3688 int wback = BIT(21); 3592 int wback = BIT(21);
3689 int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4; 3593 int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4;
3690 int n = BITS(16, 19); 3594 int n = BITS(16, 19);
3691 int imm32 = BITS(0, 7)<<2; 3595 int imm32 = BITS(0, 7)<<2;
3692 int regs = single ? BITS(0, 7) : BITS(1, 7); 3596 int regs = single ? BITS(0, 7) : BITS(1, 7);
3693 3597
3694 Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); 3598 Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
3695 //if(single) 3599 //if(single)
3696 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); 3600 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
3697 //else 3601 //else
3698 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); 3602 // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
3699 3603
3700 DBG("VLDM \n"); 3604 DBG("VLDM \n");
3701 int i; 3605 int i;
3702 //Value* phys_addr; 3606 //Value* phys_addr;
3703 Value* val; 3607 Value* val;
3704 for (i = 0; i < regs; i++) 3608 for (i = 0; i < regs; i++)
3705 { 3609 {
3706 if (single) 3610 if (single)
3707 { 3611 {
3708 3612
3709 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 3613 //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
3710 /* if R(i) is R15? */ 3614 /* if R(i) is R15? */
3711 #if 0 3615 memory_read(cpu, bb, Addr, 0, 32);
3712 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3616 bb = cpu->dyncom_engine->bb;
3713 bb = cpu->dyncom_engine->bb; 3617 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3714 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3618 //LETS(d + i, val);
3715 #endif 3619 LETFPS(d + i, FPBITCAST32(val));
3716 memory_read(cpu, bb, Addr, 0, 32); 3620 //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
3717 bb = cpu->dyncom_engine->bb; 3621 Addr = ADD(Addr, CONST(4));
3718 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3622 }
3719 //LETS(d + i, val); 3623 else
3720 LETFPS(d + i, FPBITCAST32(val)); 3624 {
3721 //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 3625 memory_read(cpu, bb, Addr, 0, 32);
3722 Addr = ADD(Addr, CONST(4)); 3626 bb = cpu->dyncom_engine->bb;
3723 } 3627 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3724 else 3628 LETFPS((d + i) * 2, FPBITCAST32(val));
3725 { 3629 memory_read(cpu, bb, Addr, 0, 32);
3726 #if 0 3630 bb = cpu->dyncom_engine->bb;
3727 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 3631 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
3728 bb = cpu->dyncom_engine->bb; 3632 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
3729 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3633
3730 #endif 3634 //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
3731 memory_read(cpu, bb, Addr, 0, 32); 3635 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3732 bb = cpu->dyncom_engine->bb; 3636 //addr += 8;
3733 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3637 Addr = ADD(Addr, CONST(8));
3734 LETFPS((d + i) * 2, FPBITCAST32(val)); 3638 }
3735 #if 0 3639 }
3736 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1); 3640 if (wback){
3737 bb = cpu->dyncom_engine->bb; 3641 //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
3738 val = arch_read_memory(cpu,bb,phys_addr,0,32); 3642 // cpu->Reg[n] - imm32);
3739 #endif 3643 LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
3740 memory_read(cpu, bb, Addr, 0, 32); 3644 DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
3741 bb = cpu->dyncom_engine->bb; 3645 }
3742 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 3646 return No_exp;
3743 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
3744
3745 //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
3746 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3747 //addr += 8;
3748 Addr = ADD(Addr, CONST(8));
3749 }
3750 }
3751 if (wback){
3752 //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
3753 // cpu->Reg[n] - imm32);
3754 LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
3755 DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
3756 }
3757 return No_exp;
3758} 3647}
3759#endif 3648#endif
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 22213d647..8ac4481cc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -53,10 +53,10 @@ int Init() {
53 g_sys_core = new ARM_Interpreter(); 53 g_sys_core = new ARM_Interpreter();
54 54
55 switch (Settings::values.cpu_core) { 55 switch (Settings::values.cpu_core) {
56 case CPU_FastInterpreter: 56 case CPU_Interpreter:
57 g_app_core = new ARM_DynCom(); 57 g_app_core = new ARM_DynCom();
58 break; 58 break;
59 case CPU_Interpreter: 59 case CPU_OldInterpreter:
60 default: 60 default:
61 g_app_core = new ARM_Interpreter(); 61 g_app_core = new ARM_Interpreter();
62 break; 62 break;
diff --git a/src/core/core.h b/src/core/core.h
index 05dbe0ae5..ecd58a73a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -13,7 +13,7 @@ namespace Core {
13 13
14enum CPUCore { 14enum CPUCore {
15 CPU_Interpreter, 15 CPU_Interpreter,
16 CPU_FastInterpreter 16 CPU_OldInterpreter,
17}; 17};
18 18
19extern ARM_Interface* g_app_core; ///< ARM11 application core 19extern ARM_Interface* g_app_core; ///< ARM11 application core
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
index 1612c35c2..390178f67 100644
--- a/src/core/file_sys/archive_backend.h
+++ b/src/core/file_sys/archive_backend.h
@@ -88,6 +88,7 @@ public:
88 const std::string DebugStr() const { 88 const std::string DebugStr() const {
89 switch (GetType()) { 89 switch (GetType()) {
90 case Invalid: 90 case Invalid:
91 default:
91 return "[Invalid]"; 92 return "[Invalid]";
92 case Empty: 93 case Empty:
93 return "[Empty]"; 94 return "[Empty]";
@@ -117,6 +118,7 @@ public:
117 return {}; 118 return {};
118 case Invalid: 119 case Invalid:
119 case Binary: 120 case Binary:
121 default:
120 // TODO(yuriks): Add assert 122 // TODO(yuriks): Add assert
121 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); 123 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
122 return {}; 124 return {};
@@ -159,6 +161,7 @@ public:
159 case Empty: 161 case Empty:
160 return {}; 162 return {};
161 case Invalid: 163 case Invalid:
164 default:
162 // TODO(yuriks): Add assert 165 // TODO(yuriks): Add assert
163 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); 166 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
164 return {}; 167 return {};
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 2fc3831b7..a30f73d0e 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -5,11 +5,10 @@
5#include <memory> 5#include <memory>
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/file_util.h"
8#include "common/make_unique.h" 9#include "common/make_unique.h"
9 10
10#include "core/file_sys/archive_romfs.h" 11#include "core/file_sys/archive_romfs.h"
11#include "core/file_sys/directory_romfs.h"
12#include "core/file_sys/file_romfs.h"
13 12
14//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace 14// FileSys namespace
@@ -23,48 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
23 } 22 }
24} 23}
25 24
26std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
27 return Common::make_unique<File_RomFS>(this);
28}
29
30bool Archive_RomFS::DeleteFile(const Path& path) const {
31 LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS.");
32 return false;
33}
34
35bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const {
36 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
37 return false;
38}
39
40bool Archive_RomFS::DeleteDirectory(const Path& path) const {
41 LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS.");
42 return false;
43}
44
45ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const {
46 LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS.");
47 // TODO: Verify error code
48 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
49}
50
51bool Archive_RomFS::CreateDirectory(const Path& path) const {
52 LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS.");
53 return false;
54}
55
56bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const {
57 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
58 return false;
59}
60
61std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const {
62 return Common::make_unique<Directory_RomFS>();
63}
64
65ResultCode Archive_RomFS::Format(const Path& path) const {
66 LOG_WARNING(Service_FS, "Attempted to format ROMFS.");
67 return UnimplementedFunction(ErrorModule::FS);
68}
69
70} // namespace FileSys 25} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index d4b1eb7f2..5cb75e04d 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -8,7 +8,7 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11#include "core/file_sys/archive_backend.h" 11#include "core/file_sys/ivfc_archive.h"
12#include "core/loader/loader.h" 12#include "core/loader/loader.h"
13 13
14//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,82 +17,12 @@
17namespace FileSys { 17namespace FileSys {
18 18
19/// File system interface to the RomFS archive 19/// File system interface to the RomFS archive
20class Archive_RomFS final : public ArchiveBackend { 20class Archive_RomFS final : public IVFCArchive {
21public: 21public:
22 Archive_RomFS(const Loader::AppLoader& app_loader); 22 Archive_RomFS(const Loader::AppLoader& app_loader);
23 23
24 std::string GetName() const override { return "RomFS"; } 24 std::string GetName() const override { return "RomFS"; }
25 25 ResultCode Open(const Path& path) override { return RESULT_SUCCESS; }
26 /**
27 * Open a file specified by its path, using the specified mode
28 * @param path Path relative to the archive
29 * @param mode Mode to open the file with
30 * @return Opened file, or nullptr
31 */
32 std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
33
34 /**
35 * Delete a file specified by its path
36 * @param path Path relative to the archive
37 * @return Whether the file could be deleted
38 */
39 bool DeleteFile(const Path& path) const override;
40
41 /**
42 * Rename a File specified by its path
43 * @param src_path Source path relative to the archive
44 * @param dest_path Destination path relative to the archive
45 * @return Whether rename succeeded
46 */
47 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
48
49 /**
50 * Delete a directory specified by its path
51 * @param path Path relative to the archive
52 * @return Whether the directory could be deleted
53 */
54 bool DeleteDirectory(const Path& path) const override;
55
56 /**
57 * Create a file specified by its path
58 * @param path Path relative to the Archive
59 * @param size The size of the new file, filled with zeroes
60 * @return File creation result code
61 */
62 ResultCode CreateFile(const Path& path, u32 size) const override;
63
64 /**
65 * Create a directory specified by its path
66 * @param path Path relative to the archive
67 * @return Whether the directory could be created
68 */
69 bool CreateDirectory(const Path& path) const override;
70
71 /**
72 * Rename a Directory specified by its path
73 * @param src_path Source path relative to the archive
74 * @param dest_path Destination path relative to the archive
75 * @return Whether rename succeeded
76 */
77 bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
78
79 /**
80 * Open a directory specified by its path
81 * @param path Path relative to the archive
82 * @return Opened directory, or nullptr
83 */
84 std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
85
86 ResultCode Open(const Path& path) override {
87 return RESULT_SUCCESS;
88 }
89
90 ResultCode Format(const Path& path) const override;
91
92private:
93 friend class File_RomFS;
94
95 std::vector<u8> raw_data;
96}; 26};
97 27
98} // namespace FileSys 28} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp
new file mode 100644
index 000000000..233158a0c
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.cpp
@@ -0,0 +1,41 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/file_util.h"
6
7#include "core/file_sys/archive_savedatacheck.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace
11
12namespace FileSys {
13
14Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) {
15}
16
17ResultCode Archive_SaveDataCheck::Open(const Path& path) {
18 // TODO(Subv): We should not be overwriting raw_data everytime this function is called,
19 // but until we use factory classes to create the archives at runtime instead of creating them beforehand
20 // and allow multiple archives of the same type to be open at the same time without clobbering each other,
21 // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed.
22 // There are a number of problems with this, for example opening a file in this archive, then opening
23 // this archive again with a different path, will corrupt the previously open file.
24 auto vec = path.AsBinary();
25 const u32* data = reinterpret_cast<u32*>(vec.data());
26 std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]);
27 FileUtil::IOFile file(file_path, "rb");
28
29 std::fill(raw_data.begin(), raw_data.end(), 0);
30
31 if (!file.IsOpen()) {
32 return ResultCode(-1); // TODO(Subv): Find the right error code
33 }
34 auto size = file.GetSize();
35 raw_data.resize(size);
36 file.ReadBytes(raw_data.data(), size);
37 file.Close();
38 return RESULT_SUCCESS;
39}
40
41} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h
new file mode 100644
index 000000000..f6e73e803
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.h
@@ -0,0 +1,31 @@
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 <vector>
8
9#include "common/common_types.h"
10
11#include "core/file_sys/ivfc_archive.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19/// File system interface to the SaveDataCheck archive
20class Archive_SaveDataCheck final : public IVFCArchive {
21public:
22 Archive_SaveDataCheck(const std::string& mount_point);
23
24 std::string GetName() const override { return "SaveDataCheck"; }
25 ResultCode Open(const Path& path) override;
26
27private:
28 std::string mount_point;
29};
30
31} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp
deleted file mode 100644
index e130aca17..000000000
--- a/src/core/file_sys/directory_romfs.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6
7#include "core/file_sys/directory_romfs.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace
11
12namespace FileSys {
13
14Directory_RomFS::Directory_RomFS() {
15}
16
17Directory_RomFS::~Directory_RomFS() {
18}
19
20bool Directory_RomFS::Open() {
21 return false;
22}
23
24u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
25 return 0;
26}
27
28bool Directory_RomFS::Close() const {
29 return false;
30}
31
32} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h
deleted file mode 100644
index 2297f1645..000000000
--- a/src/core/file_sys/directory_romfs.h
+++ /dev/null
@@ -1,43 +0,0 @@
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#include "core/file_sys/directory_backend.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17class Directory_RomFS final : public DirectoryBackend {
18public:
19 Directory_RomFS();
20 ~Directory_RomFS() override;
21
22 /**
23 * Open the directory
24 * @return true if the directory opened correctly
25 */
26 bool Open() override;
27
28 /**
29 * List files contained in the directory
30 * @param count Number of entries to return at once in entries
31 * @param entries Buffer to read data into
32 * @return Number of entries listed
33 */
34 u32 Read(const u32 count, Entry* entries) override;
35
36 /**
37 * Close the directory
38 * @return true if the directory closed correctly
39 */
40 bool Close() const override;
41};
42
43} // namespace FileSys
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 0197f727d..c6e033fcd 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -6,6 +6,7 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/file_util.h" 8#include "common/file_util.h"
9#include "common/make_unique.h"
9 10
10#include "core/file_sys/disk_archive.h" 11#include "core/file_sys/disk_archive.h"
11#include "core/settings.h" 12#include "core/settings.h"
@@ -17,10 +18,10 @@ namespace FileSys {
17 18
18std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const { 19std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
19 LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); 20 LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
20 DiskFile* file = new DiskFile(this, path, mode); 21 auto file = Common::make_unique<DiskFile>(this, path, mode);
21 if (!file->Open()) 22 if (!file->Open())
22 return nullptr; 23 return nullptr;
23 return std::unique_ptr<FileBackend>(file); 24 return std::move(file);
24} 25}
25 26
26bool DiskArchive::DeleteFile(const Path& path) const { 27bool DiskArchive::DeleteFile(const Path& path) const {
@@ -66,10 +67,10 @@ bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) c
66 67
67std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const { 68std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const {
68 LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); 69 LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str());
69 DiskDirectory* directory = new DiskDirectory(this, path); 70 auto directory = Common::make_unique<DiskDirectory>(this, path);
70 if (!directory->Open()) 71 if (!directory->Open())
71 return nullptr; 72 return nullptr;
72 return std::unique_ptr<DirectoryBackend>(directory); 73 return std::move(directory);
73} 74}
74 75
75//////////////////////////////////////////////////////////////////////////////////////////////////// 76////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -100,7 +101,7 @@ bool DiskFile::Open() {
100 // Open the file in binary mode, to avoid problems with CR/LF on Windows systems 101 // Open the file in binary mode, to avoid problems with CR/LF on Windows systems
101 mode_string += "b"; 102 mode_string += "b";
102 103
103 file = new FileUtil::IOFile(path, mode_string.c_str()); 104 file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
104 return true; 105 return true;
105} 106}
106 107
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h
index f18d96f5a..3472f6874 100644
--- a/src/core/file_sys/disk_archive.h
+++ b/src/core/file_sys/disk_archive.h
@@ -56,10 +56,6 @@ public:
56 DiskFile(); 56 DiskFile();
57 DiskFile(const DiskArchive* archive, const Path& path, const Mode mode); 57 DiskFile(const DiskArchive* archive, const Path& path, const Mode mode);
58 58
59 ~DiskFile() override {
60 Close();
61 }
62
63 bool Open() override; 59 bool Open() override;
64 size_t Read(const u64 offset, const u32 length, u8* buffer) const override; 60 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
65 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; 61 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
@@ -75,7 +71,7 @@ protected:
75 const DiskArchive* archive; 71 const DiskArchive* archive;
76 std::string path; 72 std::string path;
77 Mode mode; 73 Mode mode;
78 FileUtil::IOFile* file; 74 std::unique_ptr<FileUtil::IOFile> file;
79}; 75};
80 76
81class DiskDirectory : public DirectoryBackend { 77class DiskDirectory : public DirectoryBackend {
diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp
deleted file mode 100644
index 7467d6d31..000000000
--- a/src/core/file_sys/file_romfs.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6
7#include "core/file_sys/file_romfs.h"
8#include "core/file_sys/archive_romfs.h"
9
10////////////////////////////////////////////////////////////////////////////////////////////////////
11// FileSys namespace
12
13namespace FileSys {
14
15bool File_RomFS::Open() {
16 return true;
17}
18
19size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
20 LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
21 memcpy(buffer, &archive->raw_data[(u32)offset], length);
22 return length;
23}
24
25size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
26 LOG_WARNING(Service_FS, "Attempted to write to ROMFS.");
27 return 0;
28}
29
30size_t File_RomFS::GetSize() const {
31 return sizeof(u8) * archive->raw_data.size();
32}
33
34bool File_RomFS::SetSize(const u64 size) const {
35 LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS");
36 return false;
37}
38
39bool File_RomFS::Close() const {
40 return false;
41}
42
43} // namespace FileSys
diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h
deleted file mode 100644
index 04d8a16a2..000000000
--- a/src/core/file_sys/file_romfs.h
+++ /dev/null
@@ -1,73 +0,0 @@
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#include "core/file_sys/file_backend.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17class Archive_RomFS;
18
19class File_RomFS final : public FileBackend {
20public:
21 File_RomFS(const Archive_RomFS* archive) : archive(archive) {}
22
23 /**
24 * Open the file
25 * @return true if the file opened correctly
26 */
27 bool Open() override;
28
29 /**
30 * Read data from the file
31 * @param offset Offset in bytes to start reading data from
32 * @param length Length in bytes of data to read from file
33 * @param buffer Buffer to read data into
34 * @return Number of bytes read
35 */
36 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
37
38 /**
39 * Write data to the file
40 * @param offset Offset in bytes to start writing data to
41 * @param length Length in bytes of data to write to file
42 * @param flush The flush parameters (0 == do not flush)
43 * @param buffer Buffer to read data from
44 * @return Number of bytes written
45 */
46 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
47
48 /**
49 * Get the size of the file in bytes
50 * @return Size of the file in bytes
51 */
52 size_t GetSize() const override;
53
54 /**
55 * Set the size of the file in bytes
56 * @param size New size of the file
57 * @return true if successful
58 */
59 bool SetSize(const u64 size) const override;
60
61 /**
62 * Close the file
63 * @return true if the file closed correctly
64 */
65 bool Close() const override;
66
67 void Flush() const override { }
68
69private:
70 const Archive_RomFS* archive;
71};
72
73} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp
new file mode 100644
index 000000000..68c3c8b81
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.cpp
@@ -0,0 +1,88 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9#include "common/make_unique.h"
10
11#include "core/file_sys/ivfc_archive.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18IVFCArchive::IVFCArchive() {
19}
20
21std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
22 return Common::make_unique<IVFCFile>(this);
23}
24
25bool IVFCArchive::DeleteFile(const Path& path) const {
26 LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str());
27 return false;
28}
29
30bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
31 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
32 return false;
33}
34
35bool IVFCArchive::DeleteDirectory(const Path& path) const {
36 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str());
37 return false;
38}
39
40ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const {
41 LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str());
42 // TODO: Verify error code
43 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
44}
45
46bool IVFCArchive::CreateDirectory(const Path& path) const {
47 LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str());
48 return false;
49}
50
51bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
52 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
53 return false;
54}
55
56std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) const {
57 return Common::make_unique<IVFCDirectory>();
58}
59
60ResultCode IVFCArchive::Format(const Path& path) const {
61 LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str());
62 // TODO: Verify error code
63 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
64}
65
66////////////////////////////////////////////////////////////////////////////////////////////////////
67
68size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const {
69 LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
70 memcpy(buffer, &archive->raw_data[(u32)offset], length);
71 return length;
72}
73
74size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
75 LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str());
76 return 0;
77}
78
79size_t IVFCFile::GetSize() const {
80 return sizeof(u8) * archive->raw_data.size();
81}
82
83bool IVFCFile::SetSize(const u64 size) const {
84 LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str());
85 return false;
86}
87
88} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h
new file mode 100644
index 000000000..6f4cc86df
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.h
@@ -0,0 +1,66 @@
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 <vector>
8
9#include "common/common_types.h"
10
11#include "core/file_sys/archive_backend.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19/**
20 * Helper which implements an interface to deal with IVFC images used in some archives
21 * This should be subclassed by concrete archive types, which will provide the
22 * input data (load the raw IVFC archive) and override any required methods
23 */
24class IVFCArchive : public ArchiveBackend {
25public:
26 IVFCArchive();
27
28 std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
29 bool DeleteFile(const Path& path) const override;
30 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
31 bool DeleteDirectory(const Path& path) const override;
32 ResultCode CreateFile(const Path& path, u32 size) const override;
33 bool CreateDirectory(const Path& path) const override;
34 bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
35 std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
36 ResultCode Format(const Path& path) const override;
37
38protected:
39 friend class IVFCFile;
40 std::vector<u8> raw_data;
41};
42
43class IVFCFile : public FileBackend {
44public:
45 IVFCFile(const IVFCArchive* archive) : archive(archive) {}
46
47 bool Open() override { return true; }
48 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
49 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
50 size_t GetSize() const override;
51 bool SetSize(const u64 size) const override;
52 bool Close() const override { return false; }
53 void Flush() const override { }
54
55private:
56 const IVFCArchive* archive;
57};
58
59class IVFCDirectory : public DirectoryBackend {
60public:
61 bool Open() override { return false; }
62 u32 Read(const u32 count, Entry* entries) override { return 0; }
63 bool Close() const override { return false; }
64};
65
66} // namespace FileSys
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 38705e3cd..736bbc36a 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -51,6 +51,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
51 HLE::Reschedule(__func__); 51 HLE::Reschedule(__func__);
52 } 52 }
53 break; 53 break;
54
55 case ArbitrationType::DecrementAndWaitIfLessThan:
56 {
57 s32 memory_value = Memory::Read32(address) - 1;
58 Memory::Write32(address, memory_value);
59 if (memory_value <= value) {
60 Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address);
61 HLE::Reschedule(__func__);
62 }
63 break;
64 }
54 65
55 default: 66 default:
56 LOG_ERROR(Kernel, "unknown type=%d", type); 67 LOG_ERROR(Kernel, "unknown type=%d", type);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 558068c79..3dfeffc9b 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -168,9 +168,9 @@ Handle CreateMutex(bool initial_locked, const std::string& name) {
168ResultVal<bool> Mutex::WaitSynchronization() { 168ResultVal<bool> Mutex::WaitSynchronization() {
169 bool wait = locked; 169 bool wait = locked;
170 if (locked) { 170 if (locked) {
171 waiting_threads.push_back(GetCurrentThreadHandle());
171 Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); 172 Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle());
172 } 173 } else {
173 else {
174 // Lock the mutex when the first thread accesses it 174 // Lock the mutex when the first thread accesses it
175 locked = true; 175 locked = true;
176 MutexAcquireLock(this); 176 MutexAcquireLock(this);
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 2cf4d118f..d4affdfbf 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -12,9 +12,23 @@
12 12
13namespace DSP_DSP { 13namespace DSP_DSP {
14 14
15static u32 read_pipe_count; 15static u32 read_pipe_count = 0;
16static Handle semaphore_event; 16static Handle semaphore_event = 0;
17static Handle interrupt_event; 17static Handle interrupt_event = 0;
18
19void SignalInterrupt() {
20 // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
21 // application that a DSP interrupt occurred, without specifying which one. Since we do not
22 // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
23 // that check the DSP interrupt signal event to run. We should figure out the different types of
24 // DSP interrupts, and trigger them at the appropriate times.
25
26 if (interrupt_event == 0) {
27 LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!");
28 return;
29 }
30 Kernel::SignalEvent(interrupt_event);
31}
18 32
19/** 33/**
20 * DSP_DSP::ConvertProcessAddressFromDspDram service function 34 * DSP_DSP::ConvertProcessAddressFromDspDram service function
@@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
102void WriteReg0x10(Service::Interface* self) { 116void WriteReg0x10(Service::Interface* self) {
103 u32* cmd_buff = Kernel::GetCommandBuffer(); 117 u32* cmd_buff = Kernel::GetCommandBuffer();
104 118
105 Kernel::SignalEvent(interrupt_event); 119 SignalInterrupt();
106 120
107 cmd_buff[1] = 0; // No error 121 cmd_buff[1] = 0; // No error
108 122
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 0b8b64600..fa13bfb7c 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -20,4 +20,7 @@ public:
20 } 20 }
21}; 21};
22 22
23/// Signals that a DSP interrupt has occurred to userland code
24void SignalInterrupt();
25
23} // namespace 26} // namespace
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index f19ca3a9f..f761c6ab9 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -10,9 +10,11 @@
10#include "common/make_unique.h" 10#include "common/make_unique.h"
11#include "common/math_util.h" 11#include "common/math_util.h"
12 12
13#include "core/file_sys/archive_savedata.h"
14#include "core/file_sys/archive_extsavedata.h"
15#include "core/file_sys/archive_backend.h" 13#include "core/file_sys/archive_backend.h"
14#include "core/file_sys/archive_extsavedata.h"
15#include "core/file_sys/archive_romfs.h"
16#include "core/file_sys/archive_savedata.h"
17#include "core/file_sys/archive_savedatacheck.h"
16#include "core/file_sys/archive_sdmc.h" 18#include "core/file_sys/archive_sdmc.h"
17#include "core/file_sys/directory_backend.h" 19#include "core/file_sys/directory_backend.h"
18#include "core/hle/service/fs/archive.h" 20#include "core/hle/service/fs/archive.h"
@@ -50,6 +52,9 @@ enum class FileCommand : u32 {
50 SetAttributes = 0x08070040, 52 SetAttributes = 0x08070040,
51 Close = 0x08080000, 53 Close = 0x08080000,
52 Flush = 0x08090000, 54 Flush = 0x08090000,
55 SetPriority = 0x080A0040,
56 GetPriority = 0x080B0000,
57 OpenLinkFile = 0x080C0000,
53}; 58};
54 59
55// Command to access directory 60// Command to access directory
@@ -63,7 +68,7 @@ enum class DirectoryCommand : u32 {
63class Archive { 68class Archive {
64public: 69public:
65 Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) 70 Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code)
66 : backend(std::move(backend)), id_code(id_code) { 71 : id_code(id_code), backend(std::move(backend)) {
67 } 72 }
68 73
69 std::string GetName() const { return "Archive: " + backend->GetName(); } 74 std::string GetName() const { return "Archive: " + backend->GetName(); }
@@ -75,12 +80,13 @@ public:
75class File : public Kernel::Session { 80class File : public Kernel::Session {
76public: 81public:
77 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) 82 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
78 : backend(std::move(backend)), path(path) { 83 : path(path), backend(std::move(backend)), priority(0) {
79 } 84 }
80 85
81 std::string GetName() const override { return "Path: " + path.DebugStr(); } 86 std::string GetName() const override { return "Path: " + path.DebugStr(); }
82 87
83 FileSys::Path path; ///< Path of the file 88 FileSys::Path path; ///< Path of the file
89 u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
84 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface 90 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
85 91
86 ResultVal<bool> SyncRequest() override { 92 ResultVal<bool> SyncRequest() override {
@@ -145,6 +151,27 @@ public:
145 break; 151 break;
146 } 152 }
147 153
154 case FileCommand::OpenLinkFile:
155 {
156 LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
157 cmd_buff[3] = GetHandle();
158 break;
159 }
160
161 case FileCommand::SetPriority:
162 {
163 priority = cmd_buff[1];
164 LOG_TRACE(Service_FS, "SetPriority %u", priority);
165 break;
166 }
167
168 case FileCommand::GetPriority:
169 {
170 cmd_buff[2] = priority;
171 LOG_TRACE(Service_FS, "GetPriority");
172 break;
173 }
174
148 // Unknown command... 175 // Unknown command...
149 default: 176 default:
150 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 177 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -160,7 +187,7 @@ public:
160class Directory : public Kernel::Session { 187class Directory : public Kernel::Session {
161public: 188public:
162 Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) 189 Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path)
163 : backend(std::move(backend)), path(path) { 190 : path(path), backend(std::move(backend)) {
164 } 191 }
165 192
166 std::string GetName() const override { return "Directory: " + path.DebugStr(); } 193 std::string GetName() const override { return "Directory: " + path.DebugStr(); }
@@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
327 ErrorSummary::Canceled, ErrorLevel::Status); 354 ErrorSummary::Canceled, ErrorLevel::Status);
328} 355}
329 356
330ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) { 357ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
331 Archive* archive = GetArchive(archive_handle); 358 Archive* archive = GetArchive(archive_handle);
332 if (archive == nullptr) 359 if (archive == nullptr)
333 return InvalidHandle(ErrorModule::FS); 360 return InvalidHandle(ErrorModule::FS);
@@ -435,6 +462,11 @@ void ArchiveInit() {
435 else 462 else
436 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 463 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
437 sharedextsavedata_directory.c_str()); 464 sharedextsavedata_directory.c_str());
465
466 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
467 std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX);
468 auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory);
469 CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
438} 470}
439 471
440/// Shutdown archives 472/// Shutdown archives
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index c23b8cc46..9e9efa019 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
22 SystemSaveData = 0x00000008, 22 SystemSaveData = 0x00000008,
23 SDMC = 0x00000009, 23 SDMC = 0x00000009,
24 SDMCWriteOnly = 0x0000000A, 24 SDMCWriteOnly = 0x0000000A,
25 SaveDataCheck = 0x2345678A,
25}; 26};
26 27
27typedef u64 ArchiveHandle; 28typedef u64 ArchiveHandle;
@@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
90 * @param file_size The size of the new file, filled with zeroes 91 * @param file_size The size of the new file, filled with zeroes
91 * @return File creation result code 92 * @return File creation result code
92 */ 93 */
93ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size); 94ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size);
94 95
95/** 96/**
96 * Create a Directory from an Archive 97 * Create a Directory from an Archive
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0f3cc2aa8..c5233e687 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -37,6 +37,7 @@
37#include "core/hle/service/soc_u.h" 37#include "core/hle/service/soc_u.h"
38#include "core/hle/service/srv.h" 38#include "core/hle/service/srv.h"
39#include "core/hle/service/ssl_c.h" 39#include "core/hle/service/ssl_c.h"
40#include "core/hle/service/y2r_u.h"
40 41
41namespace Service { 42namespace Service {
42 43
@@ -122,6 +123,7 @@ void Init() {
122 g_manager->AddService(new PTM_U::Interface); 123 g_manager->AddService(new PTM_U::Interface);
123 g_manager->AddService(new SOC_U::Interface); 124 g_manager->AddService(new SOC_U::Interface);
124 g_manager->AddService(new SSL_C::Interface); 125 g_manager->AddService(new SSL_C::Interface);
126 g_manager->AddService(new Y2R_U::Interface);
125 127
126 LOG_DEBUG(Service, "initialized OK"); 128 LOG_DEBUG(Service, "initialized OK");
127} 129}
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 9fbf18b26..f502c6afe 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -308,11 +308,11 @@ static void Socket(Service::Interface* self) {
308 308
309 u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol)); 309 u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));
310 310
311 if (socket_handle != SOCKET_ERROR_VALUE) 311 if ((s32)socket_handle != SOCKET_ERROR_VALUE)
312 open_sockets[socket_handle] = { socket_handle, true }; 312 open_sockets[socket_handle] = { socket_handle, true };
313 313
314 int result = 0; 314 int result = 0;
315 if (socket_handle == SOCKET_ERROR_VALUE) 315 if ((s32)socket_handle == SOCKET_ERROR_VALUE)
316 result = TranslateError(GET_ERRNO); 316 result = TranslateError(GET_ERRNO);
317 317
318 cmd_buffer[1] = result; 318 cmd_buffer[1] = result;
@@ -404,7 +404,7 @@ static void Fcntl(Service::Interface* self) {
404 } 404 }
405#endif 405#endif
406 } else { 406 } else {
407 LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call"); 407 LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call", ctr_cmd);
408 result = TranslateError(EINVAL); // TODO: Find the correct error 408 result = TranslateError(EINVAL); // TODO: Find the correct error
409 posix_ret = -1; 409 posix_ret = -1;
410 return; 410 return;
@@ -436,11 +436,11 @@ static void Accept(Service::Interface* self) {
436 socklen_t addr_len = sizeof(addr); 436 socklen_t addr_len = sizeof(addr);
437 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); 437 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
438 438
439 if (ret != SOCKET_ERROR_VALUE) 439 if ((s32)ret != SOCKET_ERROR_VALUE)
440 open_sockets[ret] = { ret, true }; 440 open_sockets[ret] = { ret, true };
441 441
442 int result = 0; 442 int result = 0;
443 if (ret == SOCKET_ERROR_VALUE) { 443 if ((s32)ret == SOCKET_ERROR_VALUE) {
444 result = TranslateError(GET_ERRNO); 444 result = TranslateError(GET_ERRNO);
445 } else { 445 } else {
446 CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr); 446 CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr);
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
new file mode 100644
index 000000000..f9e3619dd
--- /dev/null
+++ b/src/core/hle/service/y2r_u.cpp
@@ -0,0 +1,45 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/log.h"
6#include "core/hle/hle.h"
7#include "core/hle/kernel/event.h"
8#include "core/hle/service/y2r_u.h"
9
10////////////////////////////////////////////////////////////////////////////////////////////////////
11// Namespace Y2R_U
12
13namespace Y2R_U {
14
15const Interface::FunctionInfo FunctionTable[] = {
16 {0x00010040, nullptr, "SetInputFormat"},
17 {0x00030040, nullptr, "SetOutputFormat"},
18 {0x00050040, nullptr, "SetRotation"},
19 {0x00070040, nullptr, "SetBlockAlignment"},
20 {0x000D0040, nullptr, "SetTransferEndInterrupt"},
21 {0x000F0000, nullptr, "GetTransferEndEvent"},
22 {0x00100102, nullptr, "SetSendingY"},
23 {0x00110102, nullptr, "SetSendingU"},
24 {0x00120102, nullptr, "SetSendingV"},
25 {0x00180102, nullptr, "SetReceiving"},
26 {0x001A0040, nullptr, "SetInputLineWidth"},
27 {0x001C0040, nullptr, "SetInputLines"},
28 {0x00200040, nullptr, "SetStandardCoefficient"},
29 {0x00220040, nullptr, "SetAlpha"},
30 {0x00260000, nullptr, "StartConversion"},
31 {0x00270000, nullptr, "StopConversion"},
32 {0x00280000, nullptr, "IsBusyConversion"},
33 {0x002A0000, nullptr, "PingProcess"},
34 {0x002B0000, nullptr, "DriverInitialize"},
35 {0x002C0000, nullptr, "DriverFinalize"}
36};
37
38////////////////////////////////////////////////////////////////////////////////////////////////////
39// Interface class
40
41Interface::Interface() {
42 Register(FunctionTable, ARRAY_SIZE(FunctionTable));
43}
44
45} // namespace
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
new file mode 100644
index 000000000..171aecfd1
--- /dev/null
+++ b/src/core/hle/service/y2r_u.h
@@ -0,0 +1,23 @@
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 "core/hle/service/service.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace Y2R_U
11
12namespace Y2R_U {
13
14class Interface : public Service::Interface {
15public:
16 Interface();
17
18 std::string GetPortName() const override {
19 return "y2r:u";
20 }
21};
22
23} // namespace
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index dd619cb16..e346e0ad6 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -10,6 +10,7 @@
10 10
11#include "core/hle/hle.h" 11#include "core/hle/hle.h"
12#include "core/hle/service/gsp_gpu.h" 12#include "core/hle/service/gsp_gpu.h"
13#include "core/hle/service/dsp_dsp.h"
13 14
14#include "core/hw/gpu.h" 15#include "core/hw/gpu.h"
15 16
@@ -94,11 +95,15 @@ inline void Write(u32 addr, const T data) {
94 int r, g, b, a; 95 int r, g, b, a;
95 } source_color = { 0, 0, 0, 0 }; 96 } source_color = { 0, 0, 0, 0 };
96 97
98 // Cheap emulation of horizontal scaling: Just skip each second pixel of the
99 // input framebuffer. We keep track of this in the pixel_skip variable.
100 unsigned pixel_skip = (config.scale_horizontally != 0) ? 2 : 1;
101
97 switch (config.input_format) { 102 switch (config.input_format) {
98 case Regs::PixelFormat::RGBA8: 103 case Regs::PixelFormat::RGBA8:
99 { 104 {
100 // TODO: Most likely got the component order messed up. 105 // TODO: Most likely got the component order messed up.
101 u8* srcptr = source_pointer + x * 4 + y * config.input_width * 4; 106 u8* srcptr = source_pointer + x * 4 * pixel_skip + y * config.input_width * 4 * pixel_skip;
102 source_color.r = srcptr[0]; // blue 107 source_color.r = srcptr[0]; // blue
103 source_color.g = srcptr[1]; // green 108 source_color.g = srcptr[1]; // green
104 source_color.b = srcptr[2]; // red 109 source_color.b = srcptr[2]; // red
@@ -210,13 +215,18 @@ void Update() {
210 // - If frameskip == 0 (disabled), always swap buffers 215 // - If frameskip == 0 (disabled), always swap buffers
211 // - If frameskip == 1, swap buffers every other frame (starting from the first frame) 216 // - If frameskip == 1, swap buffers every other frame (starting from the first frame)
212 // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame) 217 // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
213
214 if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) || 218 if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
215 Settings::values.frame_skip == 0) { 219 Settings::values.frame_skip == 0) {
216 VideoCore::g_renderer->SwapBuffers(); 220 VideoCore::g_renderer->SwapBuffers();
217 } 221 }
218 222
223 // Signal to GSP that GPU interrupt has occurred
219 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); 224 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
225
226 // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but
227 // until we can emulate DSP interrupts, this is probably the only reasonable place to do
228 // this. Certain games expect this to be periodically signaled.
229 DSP_DSP::SignalInterrupt();
220 } 230 }
221 } 231 }
222} 232}
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 292f496c1..7de055232 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -157,6 +157,9 @@ struct Regs {
157 BitField< 8, 3, PixelFormat> input_format; 157 BitField< 8, 3, PixelFormat> input_format;
158 BitField<12, 3, PixelFormat> output_format; 158 BitField<12, 3, PixelFormat> output_format;
159 BitField<16, 1, u32> output_tiled; // stores output in a tiled format 159 BitField<16, 1, u32> output_tiled; // stores output in a tiled format
160
161 // TODO: Not really sure if this actually scales, or even resizes at all.
162 BitField<24, 1, u32> scale_horizontally;
160 }; 163 };
161 164
162 INSERT_PADDING_WORDS(0x1); 165 INSERT_PADDING_WORDS(0x1);
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 354335014..3ca60c072 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -222,7 +222,7 @@ public:
222 int GetSectionSize(SectionID section) const { return sections[section].sh_size; } 222 int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
223 SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found 223 SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
224 224
225 bool DidRelocate() { 225 bool DidRelocate() const {
226 return relocate; 226 return relocate;
227 } 227 }
228}; 228};
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 87580cb2a..45cf425df 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -45,6 +45,8 @@ FileType IdentifyFile(const std::string &filename) {
45 return FileType::CCI; 45 return FileType::CCI;
46 } else if (extension == ".bin") { 46 } else if (extension == ".bin") {
47 return FileType::BIN; 47 return FileType::BIN;
48 } else if (extension == ".3ds") {
49 return FileType::CCI;
48 } else if (extension == ".3dsx") { 50 } else if (extension == ".3dsx") {
49 return FileType::THREEDSX; 51 return FileType::THREEDSX;
50 } 52 }
diff --git a/src/video_core/color.h b/src/video_core/color.h
new file mode 100644
index 000000000..e86ac1265
--- /dev/null
+++ b/src/video_core/color.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
9namespace Color {
10
11/// Convert a 1-bit color component to 8 bit
12static inline u8 Convert1To8(u8 value) {
13 return value * 255;
14}
15
16/// Convert a 4-bit color component to 8 bit
17static inline u8 Convert4To8(u8 value) {
18 return (value << 4) | value;
19}
20
21/// Convert a 5-bit color component to 8 bit
22static inline u8 Convert5To8(u8 value) {
23 return (value << 3) | (value >> 2);
24}
25
26/// Convert a 6-bit color component to 8 bit
27static inline u8 Convert6To8(u8 value) {
28 return (value << 2) | (value >> 4);
29}
30
31
32} // namespace
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 9602779f4..0d9f4ba66 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -112,6 +112,11 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
112 // Initialize data for the current vertex 112 // Initialize data for the current vertex
113 VertexShader::InputVertex input; 113 VertexShader::InputVertex input;
114 114
115 // Load a debugging token to check whether this gets loaded by the running
116 // application or not.
117 static const float24 debug_token = float24::FromRawFloat24(0x00abcdef);
118 input.attr[0].w = debug_token;
119
115 for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { 120 for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) {
116 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { 121 for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) {
117 const u8* srcdata = Memory::GetPointer(PAddrToVAddr(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i])); 122 const u8* srcdata = Memory::GetPointer(PAddrToVAddr(vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]));
@@ -136,6 +141,16 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
136 } 141 }
137 } 142 }
138 143
144 // HACK: Some games do not initialize the vertex position's w component. This leads
145 // to critical issues since it messes up perspective division. As a
146 // workaround, we force the fourth component to 1.0 if we find this to be the
147 // case.
148 // To do this, we additionally have to assume that the first input attribute
149 // is the vertex position, since there's no information about this other than
150 // the empiric observation that this is usually the case.
151 if (input.attr[0].w == debug_token)
152 input.attr[0].w = float24::FromFloat32(1.0);
153
139 if (g_debug_context) 154 if (g_debug_context)
140 g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); 155 g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input);
141 156
@@ -173,6 +188,19 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) {
173 188
174 break; 189 break;
175 190
191 case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[0], 0x2b1):
192 case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[1], 0x2b2):
193 case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[2], 0x2b3):
194 case PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[3], 0x2b4):
195 {
196 int index = (id - PICA_REG_INDEX_WORKAROUND(vs_int_uniforms[0], 0x2b1));
197 auto values = registers.vs_int_uniforms[index];
198 VertexShader::GetIntUniform(index) = Math::Vec4<u8>(values.x, values.y, values.z, values.w);
199 LOG_TRACE(HW_GPU, "Set integer uniform %d to %02x %02x %02x %02x",
200 index, values.x.Value(), values.y.Value(), values.z.Value(), values.w.Value());
201 break;
202 }
203
176 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[0], 0x2c1): 204 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[0], 0x2c1):
177 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[1], 0x2c2): 205 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[1], 0x2c2):
178 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[2], 0x2c3): 206 case PICA_REG_INDEX_WORKAROUND(vs_uniform_setup.set_value[2], 0x2c3):
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 5921185a6..a494465b9 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -19,6 +19,7 @@
19#include "common/log.h" 19#include "common/log.h"
20#include "common/file_util.h" 20#include "common/file_util.h"
21 21
22#include "video_core/color.h"
22#include "video_core/math.h" 23#include "video_core/math.h"
23#include "video_core/pica.h" 24#include "video_core/pica.h"
24 25
@@ -359,29 +360,26 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
359 u8 g = ((source_ptr) >> 6) & 0x1F; 360 u8 g = ((source_ptr) >> 6) & 0x1F;
360 u8 b = (source_ptr >> 1) & 0x1F; 361 u8 b = (source_ptr >> 1) & 0x1F;
361 u8 a = source_ptr & 1; 362 u8 a = source_ptr & 1;
362 return Math::MakeVec<u8>((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), disable_alpha ? 255 : (a * 255)); 363 return Math::MakeVec<u8>(Color::Convert5To8(r), Color::Convert5To8(g),
364 Color::Convert5To8(b), disable_alpha ? 255 : Color::Convert1To8(a));
363 } 365 }
364 366
365 case Regs::TextureFormat::RGB565: 367 case Regs::TextureFormat::RGB565:
366 { 368 {
367 const u16 source_ptr = *(const u16*)(source + offset * 2); 369 const u16 source_ptr = *(const u16*)(source + offset * 2);
368 u8 r = (source_ptr >> 11) & 0x1F; 370 u8 r = Color::Convert5To8((source_ptr >> 11) & 0x1F);
369 u8 g = ((source_ptr) >> 5) & 0x3F; 371 u8 g = Color::Convert6To8(((source_ptr) >> 5) & 0x3F);
370 u8 b = (source_ptr) & 0x1F; 372 u8 b = Color::Convert5To8((source_ptr) & 0x1F);
371 return Math::MakeVec<u8>((r << 3) | (r >> 2), (g << 2) | (g >> 4), (b << 3) | (b >> 2), 255); 373 return Math::MakeVec<u8>(r, g, b, 255);
372 } 374 }
373 375
374 case Regs::TextureFormat::RGBA4: 376 case Regs::TextureFormat::RGBA4:
375 { 377 {
376 const u8* source_ptr = source + offset * 2; 378 const u8* source_ptr = source + offset * 2;
377 u8 r = source_ptr[1] >> 4; 379 u8 r = Color::Convert4To8(source_ptr[1] >> 4);
378 u8 g = source_ptr[1] & 0xFF; 380 u8 g = Color::Convert4To8(source_ptr[1] & 0xF);
379 u8 b = source_ptr[0] >> 4; 381 u8 b = Color::Convert4To8(source_ptr[0] >> 4);
380 u8 a = source_ptr[0] & 0xFF; 382 u8 a = Color::Convert4To8(source_ptr[0] & 0xF);
381 r = (r << 4) | r;
382 g = (g << 4) | g;
383 b = (b << 4) | b;
384 a = (a << 4) | a;
385 return { r, g, b, disable_alpha ? (u8)255 : a }; 383 return { r, g, b, disable_alpha ? (u8)255 : a };
386 } 384 }
387 385
@@ -389,13 +387,11 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
389 { 387 {
390 const u8* source_ptr = source + offset * 2; 388 const u8* source_ptr = source + offset * 2;
391 389
392 // TODO: component order not verified
393
394 if (disable_alpha) { 390 if (disable_alpha) {
395 // Show intensity as red, alpha as green 391 // Show intensity as red, alpha as green
396 return { source_ptr[0], source_ptr[1], 0, 255 }; 392 return { source_ptr[1], source_ptr[0], 0, 255 };
397 } else { 393 } else {
398 return { source_ptr[0], source_ptr[0], source_ptr[0], source_ptr[1]}; 394 return { source_ptr[1], source_ptr[1], source_ptr[1], source_ptr[0]};
399 } 395 }
400 } 396 }
401 397
@@ -418,14 +414,10 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
418 414
419 case Regs::TextureFormat::IA4: 415 case Regs::TextureFormat::IA4:
420 { 416 {
421 const u8* source_ptr = source + offset / 2; 417 const u8* source_ptr = source + offset;
422
423 // TODO: component order not verified
424 418
425 u8 i = (*source_ptr) & 0xF; 419 u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4);
426 u8 a = ((*source_ptr) & 0xF0) >> 4; 420 u8 a = Color::Convert4To8((*source_ptr) & 0xF);
427 a |= a << 4;
428 i |= i << 4;
429 421
430 if (disable_alpha) { 422 if (disable_alpha) {
431 // Show intensity as red, alpha as green 423 // Show intensity as red, alpha as green
@@ -439,15 +431,13 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
439 { 431 {
440 const u8* source_ptr = source + offset / 2; 432 const u8* source_ptr = source + offset / 2;
441 433
442 // TODO: component order not verified
443
444 u8 a = (coarse_x % 2) ? ((*source_ptr)&0xF) : (((*source_ptr) & 0xF0) >> 4); 434 u8 a = (coarse_x % 2) ? ((*source_ptr)&0xF) : (((*source_ptr) & 0xF0) >> 4);
445 a |= a << 4; 435 a = Color::Convert4To8(a);
446 436
447 if (disable_alpha) { 437 if (disable_alpha) {
448 return { *source_ptr, *source_ptr, *source_ptr, 255 }; 438 return { a, a, a, 255 };
449 } else { 439 } else {
450 return { 0, 0, 0, *source_ptr }; 440 return { 0, 0, 0, a };
451 } 441 }
452 } 442 }
453 443
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 38bac748c..f5771ed84 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -50,7 +50,19 @@ struct Regs {
50 50
51 u32 trigger_irq; 51 u32 trigger_irq;
52 52
53 INSERT_PADDING_WORDS(0x30); 53 INSERT_PADDING_WORDS(0x2f);
54
55 enum class CullMode : u32 {
56 // Select which polygons are considered to be "frontfacing".
57 KeepAll = 0,
58 KeepClockWise = 1,
59 KeepCounterClockWise = 2,
60 // TODO: What does the third value imply?
61 };
62
63 union {
64 BitField<0, 2, CullMode> cull_mode;
65 };
54 66
55 BitField<0, 24, u32> viewport_size_x; 67 BitField<0, 24, u32> viewport_size_x;
56 68
@@ -289,7 +301,7 @@ struct Regs {
289 TevStageConfig tev_stage4; 301 TevStageConfig tev_stage4;
290 INSERT_PADDING_WORDS(0x3); 302 INSERT_PADDING_WORDS(0x3);
291 TevStageConfig tev_stage5; 303 TevStageConfig tev_stage5;
292 INSERT_PADDING_WORDS(0x13); 304 INSERT_PADDING_WORDS(0x3);
293 305
294 const std::array<Regs::TevStageConfig,6> GetTevStages() const { 306 const std::array<Regs::TevStageConfig,6> GetTevStages() const {
295 return { tev_stage0, tev_stage1, 307 return { tev_stage0, tev_stage1,
@@ -298,6 +310,60 @@ struct Regs {
298 }; 310 };
299 311
300 struct { 312 struct {
313 enum DepthFunc : u32 {
314 Always = 1,
315 LessThan = 4,
316 GreaterThan = 6,
317 };
318
319 union {
320 // If false, logic blending is used
321 BitField<8, 1, u32> alphablend_enable;
322 };
323
324 union {
325 enum BlendEquation : u32 {
326 Add = 0,
327 };
328
329 enum BlendFactor : u32 {
330 Zero = 0,
331 One = 1,
332
333 SourceAlpha = 6,
334 OneMinusSourceAlpha = 7,
335 };
336
337 BitField< 0, 8, BlendEquation> blend_equation_rgb;
338 BitField< 8, 8, BlendEquation> blend_equation_a;
339
340 BitField<16, 4, BlendFactor> factor_source_rgb;
341 BitField<20, 4, BlendFactor> factor_dest_rgb;
342
343 BitField<24, 4, BlendFactor> factor_source_a;
344 BitField<28, 4, BlendFactor> factor_dest_a;
345 } alpha_blending;
346
347 union {
348 enum Op {
349 Set = 4,
350 };
351
352 BitField<0, 4, Op> op;
353 } logic_op;
354
355 INSERT_PADDING_WORDS(0x4);
356
357 union {
358 BitField< 0, 1, u32> depth_test_enable;
359 BitField< 4, 3, DepthFunc> depth_test_func;
360 BitField<12, 1, u32> depth_write_enable;
361 };
362
363 INSERT_PADDING_WORDS(0x8);
364 } output_merger;
365
366 struct {
301 enum ColorFormat : u32 { 367 enum ColorFormat : u32 {
302 RGBA8 = 0, 368 RGBA8 = 0,
303 RGB8 = 1, 369 RGB8 = 1,
@@ -495,8 +561,14 @@ struct Regs {
495 INSERT_PADDING_WORDS(0x51); 561 INSERT_PADDING_WORDS(0x51);
496 562
497 BitField<0, 16, u32> vs_bool_uniforms; 563 BitField<0, 16, u32> vs_bool_uniforms;
564 union {
565 BitField< 0, 8, u32> x;
566 BitField< 8, 8, u32> y;
567 BitField<16, 8, u32> z;
568 BitField<24, 8, u32> w;
569 } vs_int_uniforms[4];
498 570
499 INSERT_PADDING_WORDS(0x9); 571 INSERT_PADDING_WORDS(0x5);
500 572
501 // Offset to shader program entry point (in words) 573 // Offset to shader program entry point (in words)
502 BitField<0, 16, u32> vs_main_offset; 574 BitField<0, 16, u32> vs_main_offset;
@@ -599,6 +671,7 @@ struct Regs {
599 } while(false) 671 } while(false)
600 672
601 ADD_FIELD(trigger_irq); 673 ADD_FIELD(trigger_irq);
674 ADD_FIELD(cull_mode);
602 ADD_FIELD(viewport_size_x); 675 ADD_FIELD(viewport_size_x);
603 ADD_FIELD(viewport_size_y); 676 ADD_FIELD(viewport_size_y);
604 ADD_FIELD(viewport_depth_range); 677 ADD_FIELD(viewport_depth_range);
@@ -617,6 +690,7 @@ struct Regs {
617 ADD_FIELD(tev_stage3); 690 ADD_FIELD(tev_stage3);
618 ADD_FIELD(tev_stage4); 691 ADD_FIELD(tev_stage4);
619 ADD_FIELD(tev_stage5); 692 ADD_FIELD(tev_stage5);
693 ADD_FIELD(output_merger);
620 ADD_FIELD(framebuffer); 694 ADD_FIELD(framebuffer);
621 ADD_FIELD(vertex_attributes); 695 ADD_FIELD(vertex_attributes);
622 ADD_FIELD(index_array); 696 ADD_FIELD(index_array);
@@ -625,6 +699,7 @@ struct Regs {
625 ADD_FIELD(trigger_draw_indexed); 699 ADD_FIELD(trigger_draw_indexed);
626 ADD_FIELD(triangle_topology); 700 ADD_FIELD(triangle_topology);
627 ADD_FIELD(vs_bool_uniforms); 701 ADD_FIELD(vs_bool_uniforms);
702 ADD_FIELD(vs_int_uniforms);
628 ADD_FIELD(vs_main_offset); 703 ADD_FIELD(vs_main_offset);
629 ADD_FIELD(vs_input_register_map); 704 ADD_FIELD(vs_input_register_map);
630 ADD_FIELD(vs_uniform_setup); 705 ADD_FIELD(vs_uniform_setup);
@@ -668,6 +743,7 @@ private:
668#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(Regs, field_name) == position * 4, "Field "#field_name" has invalid position") 743#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(Regs, field_name) == position * 4, "Field "#field_name" has invalid position")
669 744
670ASSERT_REG_POSITION(trigger_irq, 0x10); 745ASSERT_REG_POSITION(trigger_irq, 0x10);
746ASSERT_REG_POSITION(cull_mode, 0x40);
671ASSERT_REG_POSITION(viewport_size_x, 0x41); 747ASSERT_REG_POSITION(viewport_size_x, 0x41);
672ASSERT_REG_POSITION(viewport_size_y, 0x43); 748ASSERT_REG_POSITION(viewport_size_y, 0x43);
673ASSERT_REG_POSITION(viewport_depth_range, 0x4d); 749ASSERT_REG_POSITION(viewport_depth_range, 0x4d);
@@ -688,6 +764,7 @@ ASSERT_REG_POSITION(tev_stage2, 0xd0);
688ASSERT_REG_POSITION(tev_stage3, 0xd8); 764ASSERT_REG_POSITION(tev_stage3, 0xd8);
689ASSERT_REG_POSITION(tev_stage4, 0xf0); 765ASSERT_REG_POSITION(tev_stage4, 0xf0);
690ASSERT_REG_POSITION(tev_stage5, 0xf8); 766ASSERT_REG_POSITION(tev_stage5, 0xf8);
767ASSERT_REG_POSITION(output_merger, 0x100);
691ASSERT_REG_POSITION(framebuffer, 0x110); 768ASSERT_REG_POSITION(framebuffer, 0x110);
692ASSERT_REG_POSITION(vertex_attributes, 0x200); 769ASSERT_REG_POSITION(vertex_attributes, 0x200);
693ASSERT_REG_POSITION(index_array, 0x227); 770ASSERT_REG_POSITION(index_array, 0x227);
@@ -696,6 +773,7 @@ ASSERT_REG_POSITION(trigger_draw, 0x22e);
696ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); 773ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f);
697ASSERT_REG_POSITION(triangle_topology, 0x25e); 774ASSERT_REG_POSITION(triangle_topology, 0x25e);
698ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0); 775ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0);
776ASSERT_REG_POSITION(vs_int_uniforms, 0x2b1);
699ASSERT_REG_POSITION(vs_main_offset, 0x2ba); 777ASSERT_REG_POSITION(vs_main_offset, 0x2ba);
700ASSERT_REG_POSITION(vs_input_register_map, 0x2bb); 778ASSERT_REG_POSITION(vs_input_register_map, 0x2bb);
701ASSERT_REG_POSITION(vs_uniform_setup, 0x2c0); 779ASSERT_REG_POSITION(vs_uniform_setup, 0x2c0);
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index a80148872..025d4e484 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -18,51 +18,82 @@ namespace Pica {
18namespace Rasterizer { 18namespace Rasterizer {
19 19
20static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { 20static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
21 u32* color_buffer = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetColorBufferPhysicalAddress()))); 21 const PAddr addr = registers.framebuffer.GetColorBufferPhysicalAddress();
22 u32* color_buffer = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(addr)));
22 u32 value = (color.a() << 24) | (color.r() << 16) | (color.g() << 8) | color.b(); 23 u32 value = (color.a() << 24) | (color.r() << 16) | (color.g() << 8) | color.b();
23 24
24 // Assuming RGBA8 format until actual framebuffer format handling is implemented 25 // Assuming RGBA8 format until actual framebuffer format handling is implemented
25 *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value; 26 *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value;
26} 27}
27 28
29static const Math::Vec4<u8> GetPixel(int x, int y) {
30 const PAddr addr = registers.framebuffer.GetColorBufferPhysicalAddress();
31 u32* color_buffer_u32 = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(addr)));
32
33 u32 value = *(color_buffer_u32 + x + y * registers.framebuffer.GetWidth());
34 Math::Vec4<u8> ret;
35 ret.a() = value >> 24;
36 ret.r() = (value >> 16) & 0xFF;
37 ret.g() = (value >> 8) & 0xFF;
38 ret.b() = value & 0xFF;
39 return ret;
40 }
41
28static u32 GetDepth(int x, int y) { 42static u32 GetDepth(int x, int y) {
29 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress()))); 43 const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress();
44 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(addr)));
30 45
31 // Assuming 16-bit depth buffer format until actual format handling is implemented 46 // Assuming 16-bit depth buffer format until actual format handling is implemented
32 return *(depth_buffer + x + y * registers.framebuffer.GetWidth()); 47 return *(depth_buffer + x + y * registers.framebuffer.GetWidth());
33} 48}
34 49
35static void SetDepth(int x, int y, u16 value) { 50static void SetDepth(int x, int y, u16 value) {
36 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress()))); 51 const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress();
52 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(addr)));
37 53
38 // Assuming 16-bit depth buffer format until actual format handling is implemented 54 // Assuming 16-bit depth buffer format until actual format handling is implemented
39 *(depth_buffer + x + y * registers.framebuffer.GetWidth()) = value; 55 *(depth_buffer + x + y * registers.framebuffer.GetWidth()) = value;
40} 56}
41 57
42void ProcessTriangle(const VertexShader::OutputVertex& v0, 58// NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values
43 const VertexShader::OutputVertex& v1, 59struct Fix12P4 {
44 const VertexShader::OutputVertex& v2) 60 Fix12P4() {}
45{ 61 Fix12P4(u16 val) : val(val) {}
46 // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values
47 struct Fix12P4 {
48 Fix12P4() {}
49 Fix12P4(u16 val) : val(val) {}
50 62
51 static u16 FracMask() { return 0xF; } 63 static u16 FracMask() { return 0xF; }
52 static u16 IntMask() { return (u16)~0xF; } 64 static u16 IntMask() { return (u16)~0xF; }
53 65
54 operator u16() const { 66 operator u16() const {
55 return val; 67 return val;
56 } 68 }
57 69
58 bool operator < (const Fix12P4& oth) const { 70 bool operator < (const Fix12P4& oth) const {
59 return (u16)*this < (u16)oth; 71 return (u16)*this < (u16)oth;
60 } 72 }
61 73
62 private: 74private:
63 u16 val; 75 u16 val;
64 }; 76};
77
78/**
79 * Calculate signed area of the triangle spanned by the three argument vertices.
80 * The sign denotes an orientation.
81 *
82 * @todo define orientation concretely.
83 */
84static int SignedArea (const Math::Vec2<Fix12P4>& vtx1,
85 const Math::Vec2<Fix12P4>& vtx2,
86 const Math::Vec2<Fix12P4>& vtx3) {
87 const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0);
88 const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0);
89 // TODO: There is a very small chance this will overflow for sizeof(int) == 4
90 return Math::Cross(vec1, vec2).z;
91};
65 92
93void ProcessTriangle(const VertexShader::OutputVertex& v0,
94 const VertexShader::OutputVertex& v1,
95 const VertexShader::OutputVertex& v2)
96{
66 // vertex positions in rasterizer coordinates 97 // vertex positions in rasterizer coordinates
67 auto FloatToFix = [](float24 flt) { 98 auto FloatToFix = [](float24 flt) {
68 return Fix12P4(static_cast<unsigned short>(flt.ToFloat32() * 16.0f)); 99 return Fix12P4(static_cast<unsigned short>(flt.ToFloat32() * 16.0f));
@@ -70,10 +101,23 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
70 auto ScreenToRasterizerCoordinates = [FloatToFix](const Math::Vec3<float24> vec) { 101 auto ScreenToRasterizerCoordinates = [FloatToFix](const Math::Vec3<float24> vec) {
71 return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)}; 102 return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
72 }; 103 };
104
73 Math::Vec3<Fix12P4> vtxpos[3]{ ScreenToRasterizerCoordinates(v0.screenpos), 105 Math::Vec3<Fix12P4> vtxpos[3]{ ScreenToRasterizerCoordinates(v0.screenpos),
74 ScreenToRasterizerCoordinates(v1.screenpos), 106 ScreenToRasterizerCoordinates(v1.screenpos),
75 ScreenToRasterizerCoordinates(v2.screenpos) }; 107 ScreenToRasterizerCoordinates(v2.screenpos) };
76 108
109 if (registers.cull_mode == Regs::CullMode::KeepClockWise) {
110 // Reverse vertex order and use the CCW code path.
111 std::swap(vtxpos[1], vtxpos[2]);
112 }
113
114 if (registers.cull_mode != Regs::CullMode::KeepAll) {
115 // Cull away triangles which are wound clockwise.
116 // TODO: A check for degenerate triangles ("== 0") should be considered for CullMode::KeepAll
117 if (SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0)
118 return;
119 }
120
77 // TODO: Proper scissor rect test! 121 // TODO: Proper scissor rect test!
78 u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); 122 u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x});
79 u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); 123 u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y});
@@ -116,18 +160,9 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
116 for (u16 x = min_x; x < max_x; x += 0x10) { 160 for (u16 x = min_x; x < max_x; x += 0x10) {
117 161
118 // Calculate the barycentric coordinates w0, w1 and w2 162 // Calculate the barycentric coordinates w0, w1 and w2
119 auto orient2d = [](const Math::Vec2<Fix12P4>& vtx1, 163 int w0 = bias0 + SignedArea(vtxpos[1].xy(), vtxpos[2].xy(), {x, y});
120 const Math::Vec2<Fix12P4>& vtx2, 164 int w1 = bias1 + SignedArea(vtxpos[2].xy(), vtxpos[0].xy(), {x, y});
121 const Math::Vec2<Fix12P4>& vtx3) { 165 int w2 = bias2 + SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), {x, y});
122 const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0);
123 const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0);
124 // TODO: There is a very small chance this will overflow for sizeof(int) == 4
125 return Math::Cross(vec1, vec2).z;
126 };
127
128 int w0 = bias0 + orient2d(vtxpos[1].xy(), vtxpos[2].xy(), {x, y});
129 int w1 = bias1 + orient2d(vtxpos[2].xy(), vtxpos[0].xy(), {x, y});
130 int w2 = bias2 + orient2d(vtxpos[0].xy(), vtxpos[1].xy(), {x, y});
131 int wsum = w0 + w1 + w2; 166 int wsum = w0 + w1 + w2;
132 167
133 // If current pixel is not covered by the current primitive 168 // If current pixel is not covered by the current primitive
@@ -201,8 +236,8 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
201 return 0; 236 return 0;
202 } 237 }
203 }; 238 };
204 s = GetWrappedTexCoord(registers.texture0.wrap_s, s, registers.texture0.width); 239 s = GetWrappedTexCoord(texture.config.wrap_s, s, texture.config.width);
205 t = GetWrappedTexCoord(registers.texture0.wrap_t, t, registers.texture0.height); 240 t = texture.config.height - 1 - GetWrappedTexCoord(texture.config.wrap_t, t, texture.config.height);
206 241
207 u8* texture_data = Memory::GetPointer(PAddrToVAddr(texture.config.GetPhysicalAddress())); 242 u8* texture_data = Memory::GetPointer(PAddrToVAddr(texture.config.GetPhysicalAddress()));
208 auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); 243 auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format);
@@ -279,12 +314,15 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
279 } 314 }
280 }; 315 };
281 316
282 auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> { 317 static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> {
283 switch (factor) 318 switch (factor)
284 { 319 {
285 case ColorModifier::SourceColor: 320 case ColorModifier::SourceColor:
286 return values.rgb(); 321 return values.rgb();
287 322
323 case ColorModifier::OneMinusSourceColor:
324 return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
325
288 case ColorModifier::SourceAlpha: 326 case ColorModifier::SourceAlpha:
289 return { values.a(), values.a(), values.a() }; 327 return { values.a(), values.a(), values.a() };
290 328
@@ -295,7 +333,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
295 } 333 }
296 }; 334 };
297 335
298 auto GetAlphaModifier = [](AlphaModifier factor, u8 value) -> u8 { 336 static auto GetAlphaModifier = [](AlphaModifier factor, u8 value) -> u8 {
299 switch (factor) { 337 switch (factor) {
300 case AlphaModifier::SourceAlpha: 338 case AlphaModifier::SourceAlpha:
301 return value; 339 return value;
@@ -310,7 +348,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
310 } 348 }
311 }; 349 };
312 350
313 auto ColorCombine = [](Operation op, const Math::Vec3<u8> input[3]) -> Math::Vec3<u8> { 351 static auto ColorCombine = [](Operation op, const Math::Vec3<u8> input[3]) -> Math::Vec3<u8> {
314 switch (op) { 352 switch (op) {
315 case Operation::Replace: 353 case Operation::Replace:
316 return input[0]; 354 return input[0];
@@ -330,6 +368,15 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
330 case Operation::Lerp: 368 case Operation::Lerp:
331 return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>(); 369 return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>();
332 370
371 case Operation::Subtract:
372 {
373 auto result = input[0].Cast<int>() - input[1].Cast<int>();
374 result.r() = std::max(0, result.r());
375 result.g() = std::max(0, result.g());
376 result.b() = std::max(0, result.b());
377 return result.Cast<u8>();
378 }
379
333 default: 380 default:
334 LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op); 381 LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op);
335 _dbg_assert_(HW_GPU, 0); 382 _dbg_assert_(HW_GPU, 0);
@@ -337,7 +384,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
337 } 384 }
338 }; 385 };
339 386
340 auto AlphaCombine = [](Operation op, const std::array<u8,3>& input) -> u8 { 387 static auto AlphaCombine = [](Operation op, const std::array<u8,3>& input) -> u8 {
341 switch (op) { 388 switch (op) {
342 case Operation::Replace: 389 case Operation::Replace:
343 return input[0]; 390 return input[0];
@@ -351,6 +398,9 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
351 case Operation::Lerp: 398 case Operation::Lerp:
352 return (input[0] * input[2] + input[1] * (255 - input[2])) / 255; 399 return (input[0] * input[2] + input[1] * (255 - input[2])) / 255;
353 400
401 case Operation::Subtract:
402 return std::max(0, (int)input[0] - (int)input[1]);
403
354 default: 404 default:
355 LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op); 405 LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op);
356 _dbg_assert_(HW_GPU, 0); 406 _dbg_assert_(HW_GPU, 0);
@@ -381,12 +431,111 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
381 combiner_output = Math::MakeVec(color_output, alpha_output); 431 combiner_output = Math::MakeVec(color_output, alpha_output);
382 } 432 }
383 433
384 // TODO: Not sure if the multiplication by 65535 has already been taken care 434 // TODO: Does depth indeed only get written even if depth testing is enabled?
385 // of when transforming to screen coordinates or not. 435 if (registers.output_merger.depth_test_enable) {
386 u16 z = (u16)(((float)v0.screenpos[2].ToFloat32() * w0 + 436 u16 z = (u16)(-(v0.screenpos[2].ToFloat32() * w0 +
387 (float)v1.screenpos[2].ToFloat32() * w1 + 437 v1.screenpos[2].ToFloat32() * w1 +
388 (float)v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); 438 v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum);
389 SetDepth(x >> 4, y >> 4, z); 439 u16 ref_z = GetDepth(x >> 4, y >> 4);
440
441 bool pass = false;
442
443 switch (registers.output_merger.depth_test_func) {
444 case registers.output_merger.Always:
445 pass = true;
446 break;
447
448 case registers.output_merger.LessThan:
449 pass = z < ref_z;
450 break;
451
452 case registers.output_merger.GreaterThan:
453 pass = z > ref_z;
454 break;
455
456 default:
457 LOG_ERROR(HW_GPU, "Unknown depth test function %x", registers.output_merger.depth_test_func.Value());
458 break;
459 }
460
461 if (!pass)
462 continue;
463
464 if (registers.output_merger.depth_write_enable)
465 SetDepth(x >> 4, y >> 4, z);
466 }
467
468 auto dest = GetPixel(x >> 4, y >> 4);
469
470 if (registers.output_merger.alphablend_enable) {
471 auto params = registers.output_merger.alpha_blending;
472
473 auto LookupFactorRGB = [&](decltype(params)::BlendFactor factor) -> Math::Vec3<u8> {
474 switch(factor) {
475 case params.Zero:
476 return Math::Vec3<u8>(0, 0, 0);
477
478 case params.One:
479 return Math::Vec3<u8>(255, 255, 255);
480
481 case params.SourceAlpha:
482 return Math::MakeVec(combiner_output.a(), combiner_output.a(), combiner_output.a());
483
484 case params.OneMinusSourceAlpha:
485 return Math::Vec3<u8>(255-combiner_output.a(), 255-combiner_output.a(), 255-combiner_output.a());
486
487 default:
488 LOG_CRITICAL(HW_GPU, "Unknown color blend factor %x", factor);
489 exit(0);
490 break;
491 }
492 };
493
494 auto LookupFactorA = [&](decltype(params)::BlendFactor factor) -> u8 {
495 switch(factor) {
496 case params.Zero:
497 return 0;
498
499 case params.One:
500 return 255;
501
502 case params.SourceAlpha:
503 return combiner_output.a();
504
505 case params.OneMinusSourceAlpha:
506 return 255 - combiner_output.a();
507
508 default:
509 LOG_CRITICAL(HW_GPU, "Unknown alpha blend factor %x", factor);
510 exit(0);
511 break;
512 }
513 };
514
515 auto srcfactor = Math::MakeVec(LookupFactorRGB(params.factor_source_rgb),
516 LookupFactorA(params.factor_source_a));
517 auto dstfactor = Math::MakeVec(LookupFactorRGB(params.factor_dest_rgb),
518 LookupFactorA(params.factor_dest_a));
519
520 switch (params.blend_equation_rgb) {
521 case params.Add:
522 {
523 auto result = (combiner_output * srcfactor + dest * dstfactor) / 255;
524 result.r() = std::min(255, result.r());
525 result.g() = std::min(255, result.g());
526 result.b() = std::min(255, result.b());
527 combiner_output = result.Cast<u8>();
528 break;
529 }
530
531 default:
532 LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", params.blend_equation_rgb.Value());
533 exit(0);
534 }
535 } else {
536 LOG_CRITICAL(HW_GPU, "logic op: %x", registers.output_merger.logic_op);
537 exit(0);
538 }
390 539
391 DrawPixel(x >> 4, y >> 4, combiner_output); 540 DrawPixel(x >> 4, y >> 4, combiner_output);
392 } 541 }
diff --git a/src/video_core/utils.h b/src/video_core/utils.h
index 63ebccbde..6fd640425 100644
--- a/src/video_core/utils.h
+++ b/src/video_core/utils.h
@@ -8,32 +8,6 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace FormatPrecision {
12
13/// Adjust RGBA8 color with RGBA6 precision
14static inline u32 rgba8_with_rgba6(u32 src) {
15 u32 color = src;
16 color &= 0xFCFCFCFC;
17 color |= (color >> 6) & 0x03030303;
18 return color;
19}
20
21/// Adjust RGBA8 color with RGB565 precision
22static inline u32 rgba8_with_rgb565(u32 src) {
23 u32 color = (src & 0xF8FCF8);
24 color |= (color >> 5) & 0x070007;
25 color |= (color >> 6) & 0x000300;
26 color |= 0xFF000000;
27 return color;
28}
29
30/// Adjust Z24 depth value with Z16 precision
31static inline u32 z24_with_z16(u32 src) {
32 return (src & 0xFFFF00) | (src >> 16);
33}
34
35} // namespace
36
37namespace VideoCore { 11namespace VideoCore {
38 12
39/// Structure for the TGA texture format (for dumping) 13/// Structure for the TGA texture format (for dumping)
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp
index bed5081a0..ff825e2e1 100644
--- a/src/video_core/vertex_shader.cpp
+++ b/src/video_core/vertex_shader.cpp
@@ -30,6 +30,8 @@ static struct {
30 Math::Vec4<float24> f[96]; 30 Math::Vec4<float24> f[96];
31 31
32 std::array<bool,16> b; 32 std::array<bool,16> b;
33
34 std::array<Math::Vec4<u8>,4> i;
33} shader_uniforms; 35} shader_uniforms;
34 36
35// TODO: Not sure where the shader binary and swizzle patterns are supposed to be loaded to! 37// TODO: Not sure where the shader binary and swizzle patterns are supposed to be loaded to!
@@ -37,33 +39,31 @@ static struct {
37static std::array<u32, 1024> shader_memory; 39static std::array<u32, 1024> shader_memory;
38static std::array<u32, 1024> swizzle_data; 40static std::array<u32, 1024> swizzle_data;
39 41
40void SubmitShaderMemoryChange(u32 addr, u32 value) 42void SubmitShaderMemoryChange(u32 addr, u32 value) {
41{
42 shader_memory[addr] = value; 43 shader_memory[addr] = value;
43} 44}
44 45
45void SubmitSwizzleDataChange(u32 addr, u32 value) 46void SubmitSwizzleDataChange(u32 addr, u32 value) {
46{
47 swizzle_data[addr] = value; 47 swizzle_data[addr] = value;
48} 48}
49 49
50Math::Vec4<float24>& GetFloatUniform(u32 index) 50Math::Vec4<float24>& GetFloatUniform(u32 index) {
51{
52 return shader_uniforms.f[index]; 51 return shader_uniforms.f[index];
53} 52}
54 53
55bool& GetBoolUniform(u32 index) 54bool& GetBoolUniform(u32 index) {
56{
57 return shader_uniforms.b[index]; 55 return shader_uniforms.b[index];
58} 56}
59 57
60const std::array<u32, 1024>& GetShaderBinary() 58Math::Vec4<u8>& GetIntUniform(u32 index) {
61{ 59 return shader_uniforms.i[index];
60}
61
62const std::array<u32, 1024>& GetShaderBinary() {
62 return shader_memory; 63 return shader_memory;
63} 64}
64 65
65const std::array<u32, 1024>& GetSwizzlePatterns() 66const std::array<u32, 1024>& GetSwizzlePatterns() {
66{
67 return swizzle_data; 67 return swizzle_data;
68} 68}
69 69
@@ -437,8 +437,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
437 } 437 }
438} 438}
439 439
440OutputVertex RunShader(const InputVertex& input, int num_attributes) 440OutputVertex RunShader(const InputVertex& input, int num_attributes) {
441{
442 VertexShaderState state; 441 VertexShaderState state;
443 442
444 const u32* main = &shader_memory[registers.vs_main_offset]; 443 const u32* main = &shader_memory[registers.vs_main_offset];
diff --git a/src/video_core/vertex_shader.h b/src/video_core/vertex_shader.h
index af3fb2a2f..3a68a3409 100644
--- a/src/video_core/vertex_shader.h
+++ b/src/video_core/vertex_shader.h
@@ -73,6 +73,7 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes);
73 73
74Math::Vec4<float24>& GetFloatUniform(u32 index); 74Math::Vec4<float24>& GetFloatUniform(u32 index);
75bool& GetBoolUniform(u32 index); 75bool& GetBoolUniform(u32 index);
76Math::Vec4<u8>& GetIntUniform(u32 index);
76 77
77const std::array<u32, 1024>& GetShaderBinary(); 78const std::array<u32, 1024>& GetShaderBinary();
78const std::array<u32, 1024>& GetSwizzlePatterns(); 79const std::array<u32, 1024>& GetSwizzlePatterns();