diff options
55 files changed, 3460 insertions, 3323 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) { Core::RunLoop(); } + System::Shutdown(); + delete emu_window; 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 = pad_sright = [Core] -cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) +cpu_core = ## 0: Interpreter (default), 1: OldInterpreter (may work better, soon to be deprecated) gpu_refresh_rate = ## 30 (default) frame_skip = ## 0: No frameskip (default), 1 : 2x frameskip, 2 : 4x frameskip, etc. 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 @@ #include "core/core.h" #include "core/settings.h" +#include "core/system.h" #include "video_core/debug_utils/debug_utils.h" @@ -89,6 +90,8 @@ void EmuThread::Stop() } } LOG_INFO(Frontend, "EmuThread stopped"); + + System::Shutdown(); } 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <atomic> #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QDialogButtonBox> #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #ifndef _CONTROLLER_CONFIG_HXX_ #define _CONTROLLER_CONFIG_HXX_ 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QPushButton> #include <QStyle> #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #ifndef _CONTROLLER_CONFIG_UTIL_HXX_ #define _CONTROLLER_CONFIG_UTIL_HXX_ diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp index 16c6113be..4a47ad468 100644 --- a/src/citra_qt/debugger/callstack.cpp +++ b/src/citra_qt/debugger/callstack.cpp @@ -1,3 +1,7 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QStandardItemModel> #include "callstack.hxx" 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QDockWidget> #include "ui_callstack.h" 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "disassembler.hxx" #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QAbstractItemModel> #include <QDockWidget> #include "ui_disassembler.h" 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "ramview.hxx" #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "qhexedit.h" class 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "registers.hxx" #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "ui_registers.h" #include <QDockWidget> 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QKeySequence> #include <QSettings> #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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <QShortcut> #include <QDialog> #include "ui_hotkeys.h" diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 5864f1f9d..88f959d9a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1,3 +1,7 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include <thread> #include <QtGui> 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #ifndef _CITRA_QT_MAIN_HXX_ #define _CITRA_QT_MAIN_HXX_ 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + // TODO: Supposed to be generated... // GENERATED - Do not edit! #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 @@ #define SDMC_DIR "sdmc" #define EXTSAVEDATA_DIR "extsavedata" #define SAVEDATA_DIR "savedata" +#define SAVEDATACHECK_DIR "savedatacheck" #define SYSDATA_DIR "sysdata" #define SYSSAVEDATA_DIR "syssavedata" #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 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; + paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; 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 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; + paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP; paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 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 { D_SDMC_IDX, D_EXTSAVEDATA, D_SAVEDATA_IDX, + D_SAVEDATACHECK_IDX, D_SYSDATA_IDX, D_SYSSAVEDATA_IDX, D_HIRESTEXTURES_IDX, diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a08447ca2..b67226d8d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -20,11 +20,11 @@ set(SRCS file_sys/archive_extsavedata.cpp file_sys/archive_romfs.cpp file_sys/archive_savedata.cpp + file_sys/archive_savedatacheck.cpp file_sys/archive_sdmc.cpp file_sys/archive_systemsavedata.cpp file_sys/disk_archive.cpp - file_sys/file_romfs.cpp - file_sys/directory_romfs.cpp + file_sys/ivfc_archive.cpp hle/kernel/address_arbiter.cpp hle/kernel/event.cpp hle/kernel/kernel.cpp @@ -109,13 +109,13 @@ set(HEADERS file_sys/archive_extsavedata.h file_sys/archive_romfs.h file_sys/archive_savedata.h + file_sys/archive_savedatacheck.h file_sys/archive_sdmc.h file_sys/archive_systemsavedata.h file_sys/disk_archive.h file_sys/file_backend.h - file_sys/file_romfs.h + file_sys/ivfc_archive.h file_sys/directory_backend.h - file_sys/directory_romfs.h hle/kernel/address_arbiter.h hle/kernel/event.h hle/kernel/kernel.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[] = { { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, - // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, { "mcrr", 1, 6, 20, 27, 0x000000c4 }, { "mrrc", 1, 6, 20, 27, 0x000000c5 }, @@ -194,6 +193,10 @@ const ISEITEM arm_instruction[] = { { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, { "swi", 1, 0, 24, 27, 0x0000000f }, { "bbl", 1, 0, 25, 27, 0x00000005 }, + { "ldrexd", 2, ARMV6K, 20, 27, 0x0000001B, 4, 7, 0x00000009 }, + { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 }, + { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 }, + { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 }, }; const ISEITEM arm_exclusion_code[] = { @@ -383,6 +386,11 @@ const ISEITEM arm_exclusion_code[] = { { "ldc", 0, 0, 0 }, { "swi", 0, 0, 0 }, { "bbl", 0, 0, 0 }, + { "ldrexd", 0, ARMV6K, 0 }, + { "strexd", 0, ARMV6K, 0 }, + { "ldrexh", 0, ARMV6K, 0 }, + { "strexh", 0, ARMV6K, 0 }, + { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] { "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) { int ret = DECODE_FAILURE; int i = 0; int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); + for (i = 0; i < instr_slots; i++) { n = arm_instruction[i].attribute_value; 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 @@ -/* Copyright (C) -* 2012 - Michael.Kang blackfin.kang@gmail.com -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -*/ - -/** -* @file arm_dyncom_dec.h -* @brief Some common utility for arm instruction decoder -* @author Michael.Kang blackfin.kang@gmail.com -* @version 7849 -* @date 2012-03-15 -*/ - -#ifndef __ARM_DYNCOM_DEC__ -#define __ARM_DYNCOM_DEC__ - -#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) -#define BIT(n) ((instr >> (n)) & 1) -#define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0); -#define ptr_N cpu->ptr_N -#define ptr_Z cpu->ptr_Z -#define ptr_C cpu->ptr_C -#define ptr_V cpu->ptr_V -#define ptr_I cpu->ptr_I -#define ptr_T cpu->ptr_T -#define ptr_CPSR cpu->ptr_gpr[16] - -/* for MUL instructions */ -/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ -#define RDHi ((instr >> 16) & 0xF) -/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ -#define RDLo ((instr >> 12) & 0xF) -/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ -#define MUL_RD ((instr >> 16) & 0xF) -/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ -#define MUL_RN ((instr >> 12) & 0xF) -/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */ -#define RS ((instr >> 8) & 0xF) - -/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ -#define RD ((instr >> 12) & 0xF) -/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ -#define RN ((instr >> 16) & 0xF) -/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ -#define RM (instr & 0xF) - -/* CP15 registers */ -#define OPCODE_1 BITS(21, 23) -#define CRn BITS(16, 19) -#define CRm BITS(0, 3) -#define OPCODE_2 BITS(5, 7) - -/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */ -#define I BIT(25) -/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */ -#define S BIT(20) - -#define SHIFT BITS(5,6) -#define SHIFT_IMM BITS(7,11) -#define IMMH BITS(8,11) -#define IMML BITS(0,3) - -#define LSPBIT BIT(24) -#define LSUBIT BIT(23) -#define LSBBIT BIT(22) -#define LSWBIT BIT(21) -#define LSLBIT BIT(20) -#define LSSHBITS BITS(5,6) -#define OFFSET12 BITS(0,11) -#define SBIT BIT(20) -#define DESTReg (BITS (12, 15)) - -/* they are in unused state, give a corrent value when using */ +// Copyright 2012 Michael Kang, 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) +#define BIT(n) ((instr >> (n)) & 1) +#define BAD do { printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); } while(0); +#define ptr_N cpu->ptr_N +#define ptr_Z cpu->ptr_Z +#define ptr_C cpu->ptr_C +#define ptr_V cpu->ptr_V +#define ptr_I cpu->ptr_I +#define ptr_T cpu->ptr_T +#define ptr_CPSR cpu->ptr_gpr[16] + +// For MUL instructions +#define RDHi ((instr >> 16) & 0xF) +#define RDLo ((instr >> 12) & 0xF) +#define MUL_RD ((instr >> 16) & 0xF) +#define MUL_RN ((instr >> 12) & 0xF) +#define RS ((instr >> 8) & 0xF) +#define RD ((instr >> 12) & 0xF) +#define RN ((instr >> 16) & 0xF) +#define RM (instr & 0xF) + +// CP15 registers +#define OPCODE_1 BITS(21, 23) +#define CRn BITS(16, 19) +#define CRm BITS(0, 3) +#define OPCODE_2 BITS(5, 7) + +#define I BIT(25) +#define S BIT(20) + +#define SHIFT BITS(5,6) +#define SHIFT_IMM BITS(7,11) +#define IMMH BITS(8,11) +#define IMML BITS(0,3) + +#define LSPBIT BIT(24) +#define LSUBIT BIT(23) +#define LSBBIT BIT(22) +#define LSWBIT BIT(21) +#define LSLBIT BIT(20) +#define LSSHBITS BITS(5,6) +#define OFFSET12 BITS(0,11) +#define SBIT BIT(20) +#define DESTReg (BITS (12, 15)) + +// They are in unused state, give a corrent value when using #define IS_V5E 0 #define IS_V5 0 #define IS_V6 0 #define LHSReg 0 -/* temp define the using the pc reg need implement a flow */ -#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) +// Temp define the using the pc reg need implement a flow +#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) -#define OPERAND operand(cpu,instr,bb,NULL) -#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) -#define BOPERAND boperand(instr) +#define OPERAND operand(cpu,instr,bb,NULL) +#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) +#define BOPERAND boperand(instr) -#define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN)) -#define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN)) +#define CHECK_RN_PC (RN == 15 ? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)) : R(RN)) +#define CHECK_RN_PC_WA (RN == 15 ? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)) : R(RN)) -#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) +#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) int decode_arm_instr(uint32_t instr, int32_t *idx); enum DECODE_STATUS { - DECODE_SUCCESS, - DECODE_FAILURE + DECODE_SUCCESS, + DECODE_FAILURE }; struct instruction_set_encoding_item { - const char *name; - int attribute_value; - int version; - u32 content[21]; + const char *name; + int attribute_value; + int version; + u32 content[21]; }; typedef struct instruction_set_encoding_item ISEITEM; -#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;} +#define RECORD_WB(value, flag) { cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag; } #define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag) -#define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \ - LET(base_reg, cpu->dyncom_engine->wb_value);} -inline int get_reg_count(uint32_t instr){ - int i = BITS(0,15); - int count = 0; - while(i){ - if(i & 1) - count ++; - i = i >> 1; - } - return count; +#define EXECUTE_WB(base_reg) { if(cpu->dyncom_engine->wb_flag) LET(base_reg, cpu->dyncom_engine->wb_value); } + +inline int get_reg_count(uint32_t instr) { + int i = BITS(0, 15); + int count = 0; + while (i) { + if (i & 1) + count++; + i = i >> 1; + } + return count; } enum ARMVER { - INVALID = 0, - ARMALL, - ARMV4, - ARMV4T, - ARMV5T, - ARMV5TE, - ARMV5TEJ, - ARMV6, - ARM1176JZF_S, - ARMVFP2, - ARMVFP3 + INVALID = 0, + ARMALL, + ARMV4, + ARMV4T, + ARMV5T, + ARMV5TE, + ARMV5TEJ, + ARMV6, + ARM1176JZF_S, + ARMVFP2, + ARMVFP3, + ARMV6K, }; -//extern const INSTRACT arm_instruction_action[]; extern const ISEITEM arm_instruction[]; - -#endif diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 7ba82503d..5e89c724e 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 } unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); unsigned int start_addr = rn - count * 4 + 4; - unsigned int end_addr = rn; - virt_addr = end_addr; virt_addr = start_addr; if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { @@ -873,6 +871,8 @@ typedef struct _mvn_inst { typedef struct _rev_inst { unsigned int Rd; unsigned int Rm; + unsigned int op1; + unsigned int op2; } rev_inst; typedef struct _rsb_inst { @@ -930,6 +930,8 @@ typedef struct _smlad_inst { unsigned int Rd; unsigned int Ra; unsigned int Rn; + unsigned int op1; + unsigned int op2; } smlad_inst; typedef struct _smla_inst { @@ -972,6 +974,16 @@ typedef struct _smlal_inst { unsigned int RdLo; } smlal_inst; +typedef struct smlald_inst { + unsigned int RdLo; + unsigned int RdHi; + unsigned int Rm; + unsigned int Rn; + unsigned int swap; + unsigned int op1; + unsigned int op2; +} smlald_inst; + typedef struct _mla_inst { unsigned int S; unsigned int Rn; @@ -1067,7 +1079,7 @@ typedef struct _cdp_inst { unsigned int cp_num; unsigned int opcode_2; unsigned int CRm; - uint32 inst; + unsigned int inst; }cdp_inst; typedef struct _uxtb_inst { @@ -1102,10 +1114,10 @@ typedef struct _blx_1_thumb { }blx_1_thumb; typedef struct _pkh_inst { - u32 Rm; - u32 Rn; - u32 Rd; - u8 imm; + unsigned int Rm; + unsigned int Rn; + unsigned int Rd; + unsigned char imm; } pkh_inst; typedef arm_inst * ARM_INST_PTR; @@ -1738,40 +1750,31 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) return inst_base; } - ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15 - inst_cream->inst = inst; - //inst_cream->get_addr = get_calc_addr_op(inst); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - - inst_cream->inst = inst; - inst_cream->get_addr = get_calc_addr_op(inst); - - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + return INTERPRETER_TRANSLATE(ldrex)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(ldrex)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(ldrex)(inst, index); } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) { @@ -2092,36 +2095,33 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } + ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); - rev_inst *inst_cream = (rev_inst *)inst_base->component; + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); + rev_inst* const inst_cream = (rev_inst*)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->op1 = BITS(inst, 20, 22); + inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); - rev_inst *inst_cream = (rev_inst *)inst_base->component; - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); - - return inst_base; +ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(rev)(inst, index); } -ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(rev)(inst, index); +} + ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) { @@ -2313,25 +2313,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); - smlad_inst *inst_cream = (smlad_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; +ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->m = BIT(inst, 4); - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->m = BIT(inst, 5); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->op1 = BITS(inst, 20, 22); + inst_cream->op2 = BITS(inst, 5, 7); - if (CHECK_RM ) - inst_base->load_r15 = 1; return inst_base; } +ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smlad)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smlad)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smlad)(inst, index); +} + ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); @@ -2352,15 +2367,82 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) inst_base->load_r15 = 1; return inst_base; } + ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSD"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSLD"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLA"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLS"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMUL"); } -ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); } + +ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->m = BIT(inst, 6); + + return inst_base; +} + +ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst)); + smlald_inst* const inst_cream = (smlald_inst*)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->RdLo = BITS(inst, 12, 15); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->swap = BIT(inst, 5); + inst_cream->op1 = BITS(inst, 20, 22); + inst_cream->op2 = BITS(inst, 5, 7); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smlald)(inst, index); +} + +ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->m = BIT(inst, 5); + inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->op1 = BITS(inst, 20, 22); + inst_cream->op2 = BITS(inst, 5, 7); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smmla)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(smmla)(inst, index); +} + ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); @@ -2423,7 +2505,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) inst_base->load_r15 = 1; return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); } ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); } ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) { @@ -2609,37 +2690,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ } ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; - inst_cream->inst = inst; - inst_cream->get_addr = get_calc_addr_op(inst); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - - inst_cream->inst = inst; - inst_cream->get_addr = get_calc_addr_op(inst); - - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + return INTERPRETER_TRANSLATE(strex)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(strex)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(strex)(inst, index); } ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) { @@ -3341,6 +3415,11 @@ const transop_fp_t arm_instruction_trans[] = { INTERPRETER_TRANSLATE(ldc), INTERPRETER_TRANSLATE(swi), INTERPRETER_TRANSLATE(bbl), + INTERPRETER_TRANSLATE(ldrexd), + INTERPRETER_TRANSLATE(strexd), + INTERPRETER_TRANSLATE(ldrexh), + INTERPRETER_TRANSLATE(strexh), + // All the thumb instructions should be placed the end of table INTERPRETER_TRANSLATE(b_2_thumb), INTERPRETER_TRANSLATE(b_cond_thumb), @@ -3379,7 +3458,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); if(ret == t_branch){ // TODO: FIXME, endian should be judged - uint32 tinstr; + u32 tinstr; if((addr & 0x3) != 0) tinstr = inst >> 16; else @@ -3392,7 +3471,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr case 26: case 27: if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ - uint32 cond = (tinstr & 0x0F00) >> 8; + u32 cond = (tinstr & 0x0F00) >> 8; inst_index = table_length - 4; *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); } else { @@ -3429,8 +3508,6 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr return ret; } -unsigned int *InstLength; - enum { KEEP_GOING, FETCH_EXCEPTION @@ -3515,28 +3592,6 @@ translated: #define LOG_IN_CLR skyeye_printf_in_color -int cmp(const void *x, const void *y) { - return *(unsigned long long int*)x - *(unsigned long long int *)y; -} - -void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) { - int array_size = size / sizeof(void *); - unsigned long long int *InstLabel = new unsigned long long int[array_size]; - memcpy(InstLabel, ptr, size); - qsort(InstLabel, array_size, sizeof(void *), cmp); - InstLength = new unsigned int[array_size - 4]; - for (int i = 0; i < array_size - 4; i++) { - for (int j = 0; j < array_size; j++) { - if (ptr[i] == InstLabel[j]) { - InstLength[i] = InstLabel[j + 1] - InstLabel[j]; - break; - } - } - } - for (int i = 0; i < array_size - 4; i++) - LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); -} - int clz(unsigned int x) { int n; if (x == 0) return (32); @@ -3561,6 +3616,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { #define CRm inst_cream->crm #define CP15_REG(n) cpu->CP15[CP15(n)] #define RD cpu->Reg[inst_cream->Rd] + #define RD2 cpu->Reg[inst_cream->Rd + 1] #define RN cpu->Reg[inst_cream->Rn] #define RM cpu->Reg[inst_cream->Rm] #define RS cpu->Reg[inst_cream->Rs] @@ -3772,14 +3828,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) { case 182: goto LDC_INST; \ case 183: goto SWI_INST; \ case 184: goto BBL_INST; \ - case 185: goto B_2_THUMB ; \ - case 186: goto B_COND_THUMB ; \ - case 187: goto BL_1_THUMB ; \ - case 188: goto BL_2_THUMB ; \ - case 189: goto BLX_1_THUMB ; \ - case 190: goto DISPATCH; \ - case 191: goto INIT_INST_LENGTH; \ - case 192: goto END; \ + case 185: goto LDREXD_INST; \ + case 186: goto STREXD_INST; \ + case 187: goto LDREXH_INST; \ + case 188: goto STREXH_INST; \ + case 189: goto B_2_THUMB ; \ + case 190: goto B_COND_THUMB ; \ + case 191: goto BL_1_THUMB ; \ + case 192: goto BL_2_THUMB ; \ + case 193: goto BLX_1_THUMB ; \ + case 194: goto DISPATCH; \ + case 195: goto INIT_INST_LENGTH; \ + case 196: goto END; \ } #endif @@ -3840,8 +3900,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, - &&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, - &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END + &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&LDREXD_INST, + &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST,&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH, + &&INIT_INST_LENGTH,&&END }; #endif arm_inst * inst_base; @@ -4442,45 +4503,84 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LDREX_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; - - unsigned int value = Memory::Read32(addr); + unsigned int read_addr = RN; - add_exclusive_addr(cpu, addr); + add_exclusive_addr(cpu, read_addr); cpu->exclusive_state = 1; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); + RD = Memory::Read32(read_addr); + if (inst_cream->Rd == 15) { + INC_PC(sizeof(generic_arm_inst)); goto DISPATCH; } } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); + INC_PC(sizeof(generic_arm_inst)); FETCH_INST; GOTO_NEXT_INST; } LDREXB_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; + unsigned int read_addr = RN; - unsigned int value = Memory::Read8(addr); + add_exclusive_addr(cpu, read_addr); + cpu->exclusive_state = 1; + + RD = Memory::Read8(read_addr); + if (inst_cream->Rd == 15) { + INC_PC(sizeof(generic_arm_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDREXH_INST: + { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int read_addr = RN; - add_exclusive_addr(cpu, addr); + add_exclusive_addr(cpu, read_addr); cpu->exclusive_state = 1; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); + RD = Memory::Read16(read_addr); + if (inst_cream->Rd == 15) { + INC_PC(sizeof(generic_arm_inst)); goto DISPATCH; } } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDREXD_INST: + { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int read_addr = RN; + + add_exclusive_addr(cpu, read_addr); + cpu->exclusive_state = 1; + // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive? + + RD = Memory::Read32(read_addr); + RD2 = Memory::Read32(read_addr + 4); + + if (inst_cream->Rd == 15) { + INC_PC(sizeof(generic_arm_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); FETCH_INST; GOTO_NEXT_INST; } @@ -5007,39 +5107,40 @@ unsigned InterpreterMainLoop(ARMul_State* state) { QDADD_INST: QDSUB_INST: QSUB_INST: + REV_INST: - { - rev_inst *inst_cream = (rev_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = ((RM & 0xff) << 24) | - (((RM >> 8) & 0xff) << 16) | - (((RM >> 16) & 0xff) << 8) | - ((RM >> 24) & 0xff); - if (inst_cream->Rm == 15) { - LOG_ERROR(Core_ARM11, "invalid operand for REV"); - CITRA_IGNORE_EXIT(-1); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(rev_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } REV16_INST: + REVSH_INST: { - rev_inst *inst_cream = (rev_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = (BITS(RM, 0, 7) << 8) | - BITS(RM, 8, 15) | - (BITS(RM, 16, 23) << 24) | - (BITS(RM, 24, 31) << 16); + + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + rev_inst* const inst_cream = (rev_inst*)inst_base->component; + + const u8 op1 = inst_cream->op1; + const u8 op2 = inst_cream->op2; + + // REV + if (op1 == 0x03 && op2 == 0x01) { + RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF); + } + // REV16 + else if (op1 == 0x03 && op2 == 0x05) { + RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8); + } + // REVSH + else if (op1 == 0x07 && op2 == 0x05) { + RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8); + if (RD & 0x8000) + RD |= 0xffff0000; + } } + cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(rev_inst)); FETCH_INST; GOTO_NEXT_INST; } - REVSH_INST: + RFE_INST: RSB_INST: { @@ -5382,44 +5483,59 @@ unsigned InterpreterMainLoop(ARMul_State* state) { FETCH_INST; GOTO_NEXT_INST; } + SMLAD_INST: + SMLSD_INST: + SMUAD_INST: + SMUSD_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smlad_inst *inst_cream = (smlad_inst *)inst_base->component; - long long int rm = cpu->Reg[inst_cream->Rm]; - long long int rn = cpu->Reg[inst_cream->Rn]; - long long int ra = cpu->Reg[inst_cream->Ra]; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + const u8 op2 = inst_cream->op2; - // See SMUAD - if(inst_cream->Ra == 15) - CITRA_IGNORE_EXIT(-1); - int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; - int half_rn, half_operand2; + u32 rm_val = cpu->Reg[inst_cream->Rm]; + const u32 rn_val = cpu->Reg[inst_cream->Rn]; + + if (inst_cream->m) + rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - half_rn = rn & 0xFFFF; - half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; + const s16 rm_lo = (rm_val & 0xFFFF); + const s16 rm_hi = ((rm_val >> 16) & 0xFFFF); + const s16 rn_lo = (rn_val & 0xFFFF); + const s16 rn_hi = ((rn_val >> 16) & 0xFFFF); - half_operand2 = operand2 & 0xFFFF; - half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; + const u32 product1 = (rn_lo * rm_lo); + const u32 product2 = (rn_hi * rm_hi); - long long int product1 = half_rn * half_operand2; + // SMUAD and SMLAD + if (BIT(op2, 1) == 0) { + RD = (product1 + product2); - half_rn = (rn & 0xFFFF0000) >> 16; - half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; + if (inst_cream->Ra != 15) { + RD += cpu->Reg[inst_cream->Ra]; - half_operand2 = (operand2 & 0xFFFF0000) >> 16; - half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; + if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra])) + cpu->Cpsr |= (1 << 27); + } - long long int product2 = half_rn * half_operand2; + if (ARMul_AddOverflowQ(product1, product2)) + cpu->Cpsr |= (1 << 27); + } + // SMUSD and SMLSD + else { + RD = (product1 - product2); - long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; - long long int result = product1 + product2 + signed_ra; - cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; + if (inst_cream->Ra != 15) { + RD += cpu->Reg[inst_cream->Ra]; - // TODO: FIXME should check Signed overflow + if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra])) + cpu->Cpsr |= (1 << 27); + } + } } + cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umlal_inst)); + INC_PC(sizeof(smlad_inst)); FETCH_INST; GOTO_NEXT_INST; } @@ -5452,15 +5568,108 @@ unsigned InterpreterMainLoop(ARMul_State* state) { FETCH_INST; GOTO_NEXT_INST; } + SMLALXY_INST: - SMLALD_INST: + SMLAW_INST: - SMLSD_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + + const u32 rm_val = RM; + const u32 rn_val = RN; + const u32 ra_val = cpu->Reg[inst_cream->Ra]; + const bool high = (inst_cream->m == 1); + + const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF); + const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16); + + RD = (result & (0xFFFFFFFFFFFFFFFFLL >> 15)) >> 16; + + if ((result >> 16) != (s32)RD) + cpu->Cpsr |= (1 << 27); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SMLALD_INST: SMLSLD_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smlald_inst* const inst_cream = (smlald_inst*)inst_base->component; + + const bool do_swap = (inst_cream->swap == 1); + const u32 rdlo_val = RDLO; + const u32 rdhi_val = RDHI; + const u32 rn_val = RN; + u32 rm_val = RM; + + if (do_swap) + rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); + + const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); + const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); + s64 result; + + // SMLALD + if (BIT(inst_cream->op2, 1) == 0) { + result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); + } + // SMLSLD + else { + result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); + } + + RDLO = (result & 0xFFFFFFFF); + RDHI = ((result >> 32) & 0xFFFFFFFF); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smlald_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SMMLA_INST: SMMLS_INST: SMMUL_INST: - SMUAD_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + + const u32 rm_val = RM; + const u32 rn_val = RN; + const bool do_round = (inst_cream->m == 1); + + // Assume SMMUL by default. + s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val; + + if (inst_cream->Ra != 15) { + const u32 ra_val = cpu->Reg[inst_cream->Ra]; + + // SMMLA, otherwise SMMLS + if (BIT(inst_cream->op2, 1) == 0) + result += ((s64)ra_val << 32); + else + result = ((s64)ra_val << 32) - result; + } + + if (do_round) + result += 0x80000000; + + RD = ((result >> 32) & 0xFFFFFFFF); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SMUL_INST: { if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { @@ -5528,8 +5737,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { GOTO_NEXT_INST; } - SMUSD_INST: SRS_INST: + SSAT_INST: { if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { @@ -5757,46 +5966,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STREX_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - int dest_reg = BITS(inst_cream->inst, 12, 15); - if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ - remove_exclusive(cpu, addr); - cpu->Reg[dest_reg] = 0; + if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { + remove_exclusive(cpu, write_addr); cpu->exclusive_state = 0; - Memory::Write32(addr, value); + Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); + RD = 0; } else { // Failed to write due to mutex access - cpu->Reg[dest_reg] = 1; + RD = 1; } } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); + INC_PC(sizeof(generic_arm_inst)); FETCH_INST; GOTO_NEXT_INST; } STREXB_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; - int dest_reg = BITS(inst_cream->inst, 12, 15); - if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ - remove_exclusive(cpu, addr); - cpu->Reg[dest_reg] = 0; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { + remove_exclusive(cpu, write_addr); cpu->exclusive_state = 0; - Memory::Write8(addr, value); + + Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); + RD = 0; } else { - cpu->Reg[dest_reg] = 1; + // Failed to write due to mutex access + RD = 1; } } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STREXD_INST: + { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { + remove_exclusive(cpu, write_addr); + cpu->exclusive_state = 0; + // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD + + Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); + Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); + RD = 0; + } + else { + // Failed to write due to mutex access + RD = 1; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STREXH_INST: + { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { + remove_exclusive(cpu, write_addr); + cpu->exclusive_state = 0; + + Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]); + RD = 0; + } else { + // Failed to write due to mutex access + RD = 1; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); FETCH_INST; GOTO_NEXT_INST; } @@ -6366,7 +6625,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { BLX_1_THUMB: { // BLX 1 for armv5t and above - uint32 tmp = cpu->Reg[15]; + u32 tmp = cpu->Reg[15]; blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; cpu->Reg[14] = ((tmp + 2) | 1); @@ -6564,9 +6823,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } INIT_INST_LENGTH: { -#if defined __GNUC__ || defined __clang__ - InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); -#endif cpu->NumInstrsToExecute = 0; return num_instrs; } 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 @@ void switch_mode(arm_core_t *core, uint32_t mode); /* FIXME, we temporarily think thumb instruction is always 16 bit */ -static inline uint32 GET_INST_SIZE(arm_core_t* core){ - return core->TFlag? 2 : 4; +static inline u32 GET_INST_SIZE(arm_core_t* core) { + return core->TFlag? 2 : 4; } /** @@ -36,8 +36,8 @@ static inline uint32 GET_INST_SIZE(arm_core_t* core){ * * @return */ -static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){ - return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; +static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn) { + return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; } /** @@ -48,8 +48,8 @@ static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){ * * @return */ -static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){ - return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; +static inline u32 CHECK_READ_REG15(arm_core_t* core, int Rn) { + return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; } #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 { t_uninitialized, }; -tdstate -thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size); -static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){ - uint32 tinstr; +tdstate thumb_translate(addr_t addr, u32 instr, u32* ainstr, u32* inst_size); + +static inline u32 get_thumb_instr(u32 instr, addr_t pc) { + u32 tinstr; if ((pc & 0x3) != 0) tinstr = instr >> 16; else diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 43b1ba40e..12166bf79 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp @@ -6470,17 +6470,23 @@ L_stm_s_takeabort: if (BITS(12, 15) != 15) { state->Reg[rd_idx] += state->Reg[ra_idx]; - ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]); + if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx])) + SETQ; } - ARMul_AddOverflowQ(state, product1, product2); + if (ARMul_AddOverflowQ(product1, product2)) + SETQ; } // SMUSD and SMLSD else { state->Reg[rd_idx] = product1 - product2; - - if (BITS(12, 15) != 15) + + if (BITS(12, 15) != 15) { state->Reg[rd_idx] += state->Reg[ra_idx]; + + if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx])) + SETQ; + } } return 1; diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 426b67831..eec34143e 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -453,12 +453,14 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) ASSIGNV (AddOverflow (a, b, result)); } -/* Assigns the Q flag if the given result is considered an overflow from the addition of a and b */ -void ARMul_AddOverflowQ(ARMul_State* state, ARMword a, ARMword b) +// Returns true if the Q flag should be set as a result of overflow. +bool ARMul_AddOverflowQ(ARMword a, ARMword b) { u32 result = a + b; if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) - SETQ; + return true; + + return false; } /* 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..c2c78cd5a 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -790,6 +790,8 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword); extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); extern void ARMul_SelectProcessor(ARMul_State*, unsigned); +extern bool ARMul_AddOverflowQ(ARMword, ARMword); + extern u8 ARMul_SignedSaturatedAdd8(u8, u8); extern u8 ARMul_SignedSaturatedSub8(u8, u8); extern 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..e1b286f0f 100644 --- a/src/core/arm/skyeye_common/armemu.h +++ b/src/core/arm/skyeye_common/armemu.h @@ -602,7 +602,6 @@ extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); -extern void ARMul_AddOverflowQ(ARMul_State*, ARMword, ARMword); extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); extern 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 @@ * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com> */ -#ifndef __SKYEYE_TYPES_H -#define __SKYEYE_TYPES_H +#pragma once -#include <stdint.h> - -/*default machine word length */ - -#ifndef __BEOS__ -/* To avoid the type conflict with the qemu */ -#ifndef QEMU -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -typedef int8_t sint8; -typedef int16_t sint16; -typedef int32_t sint32; -typedef int64_t sint64; -#endif +#include <cstdint> typedef uint32_t address_t; -typedef uint32_t uinteger_t; -typedef int32_t integer_t; - typedef uint32_t physical_address_t; -typedef uint32_t generic_address_t; - -#endif - -#endif +typedef uint32_t generic_address_t; 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 @@ -/* - vfp/vfpinstr.c - ARM VFPv3 emulation unit - Individual instructions data - Copyright (C) 2003 Skyeye Develop Group - for help please send mail to <skyeye-developer@lists.gro.clinux.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ +// Copyright 2012 Michael Kang, 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. /* Notice: this file should not be compiled as is, and is meant to be included in other files only. */ @@ -30,52 +14,52 @@ /* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmla_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vmla_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); - vmla_inst *inst_cream = (vmla_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); + vmla_inst *inst_cream = (vmla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMLA_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VMLA :\n"); - - vmla_inst *inst_cream = (vmla_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VMLA :\n"); - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + vmla_inst *inst_cream = (vmla_inst *)inst_base->component; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmla_inst)); - FETCH_INST; - GOTO_NEXT_INST; + int ret; + + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmla_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -85,66 +69,66 @@ DYNCOM_FILL_ACTION(vmla), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int add = (BIT(6) == 0); - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG32(tmp); - mm = FR32(d); - tmp = FPADD(mm,tmp); - //LETS(d,tmp); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * m))); - nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); - tmp = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(tmp); - tmp = ZEXT64(IBITCAST32(FR32(2 * n))); - nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); - nn = OR(SHL(nn,CONST64(32)),tmp); - nn = FPBITCAST64(nn); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG64(tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * d))); - nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); - mm = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(mm); - tmp = FPADD(mm,tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); - LETFPS(2*d ,FPBITCAST32(nn)); - LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } - return No_exp; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int add = (BIT(6) == 0); + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG32(tmp); + mm = FR32(d); + tmp = FPADD(mm,tmp); + //LETS(d,tmp); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * m))); + nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); + tmp = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(tmp); + tmp = ZEXT64(IBITCAST32(FR32(2 * n))); + nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); + nn = OR(SHL(nn,CONST64(32)),tmp); + nn = FPBITCAST64(nn); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG64(tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * d))); + nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); + mm = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(mm); + tmp = FPADD(mm,tmp); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + LETFPS(2*d ,FPBITCAST32(nn)); + LETFPS(d*2 + 1 , FPBITCAST32(mm)); + } + return No_exp; } #endif @@ -153,52 +137,52 @@ int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmls_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vmls_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); - vmls_inst *inst_cream = (vmls_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); + vmls_inst *inst_cream = (vmls_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMLS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VMLS :\n"); - - vmls_inst *inst_cream = (vmls_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + DBG("VMLS :\n"); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmls_inst)); - FETCH_INST; - GOTO_NEXT_INST; + vmls_inst *inst_cream = (vmls_inst *)inst_base->component; + + int ret; + + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmls_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -208,66 +192,66 @@ DYNCOM_FILL_ACTION(vmls), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int add = (BIT(6) == 0); - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG32(tmp); - mm = FR32(d); - tmp = FPADD(mm,tmp); - //LETS(d,tmp); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * m))); - nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); - tmp = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(tmp); - tmp = ZEXT64(IBITCAST32(FR32(2 * n))); - nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); - nn = OR(SHL(nn,CONST64(32)),tmp); - nn = FPBITCAST64(nn); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG64(tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * d))); - nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); - mm = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(mm); - tmp = FPADD(mm,tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); - LETFPS(2*d ,FPBITCAST32(nn)); - LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } - return No_exp; + DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int add = (BIT(6) == 0); + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG32(tmp); + mm = FR32(d); + tmp = FPADD(mm,tmp); + //LETS(d,tmp); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * m))); + nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); + tmp = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(tmp); + tmp = ZEXT64(IBITCAST32(FR32(2 * n))); + nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); + nn = OR(SHL(nn,CONST64(32)),tmp); + nn = FPBITCAST64(nn); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG64(tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * d))); + nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); + mm = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(mm); + tmp = FPADD(mm,tmp); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + LETFPS(2*d ,FPBITCAST32(nn)); + LETFPS(d*2 + 1 , FPBITCAST32(mm)); + } + return No_exp; } #endif @@ -276,52 +260,52 @@ int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmla_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vnmla_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); - vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); + vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VNMLA_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VNMLA :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VNMLA :\n"); + + vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; - vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vnmla_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vnmla_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -332,66 +316,66 @@ DYNCOM_FILL_ACTION(vnmla), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int add = (BIT(6) == 0); - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG32(tmp); - mm = FR32(d); - tmp = FPADD(FPNEG32(mm),tmp); - //LETS(d,tmp); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * m))); - nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); - tmp = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(tmp); - tmp = ZEXT64(IBITCAST32(FR32(2 * n))); - nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); - nn = OR(SHL(nn,CONST64(32)),tmp); - nn = FPBITCAST64(nn); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG64(tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * d))); - nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); - mm = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(mm); - tmp = FPADD(FPNEG64(mm),tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); - LETFPS(2*d ,FPBITCAST32(nn)); - LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } - return No_exp; + DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int add = (BIT(6) == 0); + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG32(tmp); + mm = FR32(d); + tmp = FPADD(FPNEG32(mm),tmp); + //LETS(d,tmp); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * m))); + nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); + tmp = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(tmp); + tmp = ZEXT64(IBITCAST32(FR32(2 * n))); + nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); + nn = OR(SHL(nn,CONST64(32)),tmp); + nn = FPBITCAST64(nn); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG64(tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * d))); + nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); + mm = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(mm); + tmp = FPADD(FPNEG64(mm),tmp); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + LETFPS(2*d ,FPBITCAST32(nn)); + LETFPS(d*2 + 1 , FPBITCAST32(mm)); + } + return No_exp; } #endif @@ -401,52 +385,52 @@ int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmls_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vnmls_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); - vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); + vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VNMLS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VNMLS :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VNMLS :\n"); + + vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; - vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vnmls_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vnmls_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -456,66 +440,66 @@ DYNCOM_FILL_ACTION(vnmls), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int add = (BIT(6) == 0); - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG32(tmp); - mm = FR32(d); - tmp = FPADD(FPNEG32(mm),tmp); - //LETS(d,tmp); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * m))); - nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); - tmp = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(tmp); - tmp = ZEXT64(IBITCAST32(FR32(2 * n))); - nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); - nn = OR(SHL(nn,CONST64(32)),tmp); - nn = FPBITCAST64(nn); - tmp = FPMUL(nn,mm); - if(!add) - tmp = FPNEG64(tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * d))); - nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); - mm = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(mm); - tmp = FPADD(FPNEG64(mm),tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); - LETFPS(2*d ,FPBITCAST32(nn)); - LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int add = (BIT(6) == 0); + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG32(tmp); + mm = FR32(d); + tmp = FPADD(FPNEG32(mm),tmp); + //LETS(d,tmp); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * m))); + nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); + tmp = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(tmp); + tmp = ZEXT64(IBITCAST32(FR32(2 * n))); + nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); + nn = OR(SHL(nn,CONST64(32)),tmp); + nn = FPBITCAST64(nn); + tmp = FPMUL(nn,mm); + if(!add) + tmp = FPNEG64(tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * d))); + nn = ZEXT64(IBITCAST32(FR32(2 * d + 1))); + mm = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(mm); + tmp = FPADD(FPNEG64(mm),tmp); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + LETFPS(2*d ,FPBITCAST32(nn)); + LETFPS(d*2 + 1 , FPBITCAST32(mm)); + } + return No_exp; } #endif @@ -524,52 +508,52 @@ int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmul_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vnmul_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); - vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); + vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VNMUL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VNMUL :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VNMUL :\n"); + + vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; - vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vnmul_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vnmul_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -579,56 +563,56 @@ DYNCOM_FILL_ACTION(vnmul), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; -} + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; +} #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int add = (BIT(6) == 0); - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - //LETS(d,tmp); - LETFPS(d,FPNEG32(tmp)); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - mm = ZEXT64(IBITCAST32(FR32(2 * m))); - nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); - tmp = OR(SHL(nn,CONST64(32)),mm); - mm = FPBITCAST64(tmp); - tmp = ZEXT64(IBITCAST32(FR32(2 * n))); - nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); - nn = OR(SHL(nn,CONST64(32)),tmp); - nn = FPBITCAST64(nn); - tmp = FPMUL(nn,mm); - tmp = FPNEG64(tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); - LETFPS(2*d ,FPBITCAST32(nn)); - LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int add = (BIT(6) == 0); + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + //LETS(d,tmp); + LETFPS(d,FPNEG32(tmp)); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + mm = ZEXT64(IBITCAST32(FR32(2 * m))); + nn = ZEXT64(IBITCAST32(FR32(2 * m + 1))); + tmp = OR(SHL(nn,CONST64(32)),mm); + mm = FPBITCAST64(tmp); + tmp = ZEXT64(IBITCAST32(FR32(2 * n))); + nn = ZEXT64(IBITCAST32(FR32(2 * n + 1))); + nn = OR(SHL(nn,CONST64(32)),tmp); + nn = FPBITCAST64(nn); + tmp = FPMUL(nn,mm); + tmp = FPNEG64(tmp); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + LETFPS(2*d ,FPBITCAST32(nn)); + LETFPS(d*2 + 1 , FPBITCAST32(mm)); + } + return No_exp; } #endif @@ -638,52 +622,52 @@ int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmul_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vmul_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); - vmul_inst *inst_cream = (vmul_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); + vmul_inst *inst_cream = (vmul_inst *)inst_base->component; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMUL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VMUL :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VMUL :\n"); + + vmul_inst *inst_cream = (vmul_inst *)inst_base->component; - vmul_inst *inst_cream = (vmul_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmul_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmul_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -693,70 +677,70 @@ DYNCOM_FILL_ACTION(vmul), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - //mm = SITOFP(32,FR(m)); - //nn = SITOFP(32,FRn)); - mm = FR32(m); - nn = FR32(n); - tmp = FPMUL(nn,mm); - //LETS(d,tmp); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - //mm = SITOFP(32,RSPR(m)); - //LETS(d,tmp); - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value* m0 = FPBITCAST64(v64); - lo = FR32(2 * n); - hi = FR32(2 * n + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - hi64 = ZEXT64(hi); - lo64 = ZEXT64(lo); - v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); - tmp = FPMUL(n0,m0); - Value *val64 = IBITCAST64(tmp); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + //mm = SITOFP(32,FR(m)); + //nn = SITOFP(32,FRn)); + mm = FR32(m); + nn = FR32(n); + tmp = FPMUL(nn,mm); + //LETS(d,tmp); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + //mm = SITOFP(32,RSPR(m)); + //LETS(d,tmp); + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value* m0 = FPBITCAST64(v64); + lo = FR32(2 * n); + hi = FR32(2 * n + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + hi64 = ZEXT64(hi); + lo64 = ZEXT64(lo); + v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value *n0 = FPBITCAST64(v64); + tmp = FPMUL(n0,m0); + Value *val64 = IBITCAST64(tmp); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -765,52 +749,52 @@ int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vadd_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vadd_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); - vadd_inst *inst_cream = (vadd_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); + vadd_inst *inst_cream = (vadd_inst *)inst_base->component; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VADD_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VADD :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VADD :\n"); - vadd_inst *inst_cream = (vadd_inst *)inst_base->component; + vadd_inst *inst_cream = (vadd_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vadd_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vadd_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -820,64 +804,64 @@ DYNCOM_FILL_ACTION(vadd), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPADD(nn,mm); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value* m0 = FPBITCAST64(v64); - lo = FR32(2 * n); - hi = FR32(2 * n + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - hi64 = ZEXT64(hi); - lo64 = ZEXT64(lo); - v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); - tmp = FPADD(n0,m0); - Value *val64 = IBITCAST64(tmp); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPADD(nn,mm); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value* m0 = FPBITCAST64(v64); + lo = FR32(2 * n); + hi = FR32(2 * n + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + hi64 = ZEXT64(hi); + lo64 = ZEXT64(lo); + v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value *n0 = FPBITCAST64(v64); + tmp = FPADD(n0,m0); + Value *val64 = IBITCAST64(tmp); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -886,52 +870,52 @@ int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vsub_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vsub_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); - vsub_inst *inst_cream = (vsub_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); + vsub_inst *inst_cream = (vsub_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VSUB_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VSUB :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VSUB :\n"); - vsub_inst *inst_cream = (vsub_inst *)inst_base->component; + vsub_inst *inst_cream = (vsub_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vsub_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vsub_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif #ifdef VFP_DYNCOM_TABLE @@ -940,63 +924,63 @@ DYNCOM_FILL_ACTION(vsub), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPSUB(nn,mm); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value* m0 = FPBITCAST64(v64); - lo = FR32(2 * n); - hi = FR32(2 * n + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - hi64 = ZEXT64(hi); - lo64 = ZEXT64(lo); - v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); - tmp = FPSUB(n0,m0); - Value *val64 = IBITCAST64(tmp); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPSUB(nn,mm); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value* m0 = FPBITCAST64(v64); + lo = FR32(2 * n); + hi = FR32(2 * n + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + hi64 = ZEXT64(hi); + lo64 = ZEXT64(lo); + v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value *n0 = FPBITCAST64(v64); + tmp = FPSUB(n0,m0); + Value *val64 = IBITCAST64(tmp); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -1005,52 +989,52 @@ int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vdiv_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vdiv_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); - vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); + vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VDIV_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VDIV :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VDIV :\n"); - vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; + vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vdiv_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vdiv_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1060,64 +1044,64 @@ DYNCOM_FILL_ACTION(vdiv), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int m; - int n; - int d ; - int s = BIT(8) == 0; - Value *mm; - Value *nn; - Value *tmp; - if(s){ - m = BIT(5) | BITS(0,3) << 1; - n = BIT(7) | BITS(16,19) << 1; - d = BIT(22) | BITS(12,15) << 1; - mm = FR32(m); - nn = FR32(n); - tmp = FPDIV(nn,mm); - LETFPS(d,tmp); - }else { - m = BITS(0,3) | BIT(5) << 4; - n = BITS(16,19) | BIT(7) << 4; - d = BIT(22) << 4 | BITS(12,15); - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value* m0 = FPBITCAST64(v64); - lo = FR32(2 * n); - hi = FR32(2 * n + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - hi64 = ZEXT64(hi); - lo64 = ZEXT64(lo); - v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); - tmp = FPDIV(n0,m0); - Value *val64 = IBITCAST64(tmp); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int m; + int n; + int d ; + int s = BIT(8) == 0; + Value *mm; + Value *nn; + Value *tmp; + if(s){ + m = BIT(5) | BITS(0,3) << 1; + n = BIT(7) | BITS(16,19) << 1; + d = BIT(22) | BITS(12,15) << 1; + mm = FR32(m); + nn = FR32(n); + tmp = FPDIV(nn,mm); + LETFPS(d,tmp); + }else { + m = BITS(0,3) | BIT(5) << 4; + n = BITS(16,19) | BIT(7) << 4; + d = BIT(22) << 4 | BITS(12,15); + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value* m0 = FPBITCAST64(v64); + lo = FR32(2 * n); + hi = FR32(2 * n + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + hi64 = ZEXT64(hi); + lo64 = ZEXT64(lo); + v64 = OR(SHL(hi64,CONST64(32)),lo64); + Value *n0 = FPBITCAST64(v64); + tmp = FPDIV(n0,m0); + Value *val64 = IBITCAST64(tmp); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -1127,48 +1111,48 @@ int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovi_inst { - unsigned int single; - unsigned int d; - unsigned int imm; + unsigned int single; + unsigned int d; + unsigned int imm; } vmovi_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); - vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); - unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3); - if (inst_cream->single) - inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19; - else - inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16; - return inst_base; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); + vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); + unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3); + if (inst_cream->single) + inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19; + else + inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVI_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovi_inst)); - FETCH_INST; - GOTO_NEXT_INST; + vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; + + VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovi_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1178,37 +1162,37 @@ DYNCOM_FILL_ACTION(vmovi), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int single = (BIT(8) == 0); - int d; - int imm32; - Value *v; - Value *tmp; - v = CONST32(BITS(0,3) | BITS(16,19) << 4); - //v = CONST64(0x3ff0000000000000); - if(single){ - d = BIT(22) | BITS(12,15) << 1; - }else { - d = BITS(12,15) | BIT(22) << 4; - } - if(single){ - LETFPS(d,FPBITCAST32(v)); - }else { - //v = UITOFP(64,v); - //tmp = IBITCAST64(v); - LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))))); - LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))))); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int single = (BIT(8) == 0); + int d; + int imm32; + Value *v; + Value *tmp; + v = CONST32(BITS(0,3) | BITS(16,19) << 4); + //v = CONST64(0x3ff0000000000000); + if(single){ + d = BIT(22) | BITS(12,15) << 1; + }else { + d = BITS(12,15) | BIT(22) << 4; + } + if(single){ + LETFPS(d,FPBITCAST32(v)); + }else { + //v = UITOFP(64,v); + //tmp = IBITCAST64(v); + LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))))); + LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))))); + } + return No_exp; } #endif @@ -1218,45 +1202,44 @@ int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovr_inst { - unsigned int single; - unsigned int d; - unsigned int m; + unsigned int single; + unsigned int d; + unsigned int m; } vmovr_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - VFP_DEBUG_UNTESTED(VMOVR); - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); - vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); + vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); - inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4); - return inst_base; + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); + inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4); + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; + + VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovr_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1266,33 +1249,33 @@ DYNCOM_FILL_ACTION(vmovr), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VMOV \n", __FUNCTION__); - int single = BIT(8) == 0; - int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); - int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); + DBG("\t\tin %s VMOV \n", __FUNCTION__); + int single = BIT(8) == 0; + int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); + int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); - if (single) - { - LETFPS(d, FR32(m)); - } - else - { - /* Check endian please */ - LETFPS((d*2 + 1), FR32(m*2 + 1)); - LETFPS((d * 2), FR32(m * 2)); - } - return No_exp; + if (single) + { + LETFPS(d, FR32(m)); + } + else + { + /* Check endian please */ + LETFPS((d*2 + 1), FR32(m*2 + 1)); + LETFPS((d * 2), FR32(m * 2)); + } + return No_exp; } #endif @@ -1301,52 +1284,50 @@ int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vabs_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vabs_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS); - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); - vabs_inst *inst_cream = (vabs_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); + vabs_inst *inst_cream = (vabs_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VABS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VABS :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VABS :\n"); + + vabs_inst *inst_cream = (vabs_inst *)inst_base->component; - vabs_inst *inst_cream = (vabs_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vabs_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vabs_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1356,50 +1337,50 @@ DYNCOM_FILL_ACTION(vabs), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int single = BIT(8) == 0; - int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); - int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); - Value* m0; - if (single) - { - m0 = FR32(m); - m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0); - LETFPS(d,m0); - } - else - { - /* Check endian please */ - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - m0 = FPBITCAST64(v64); - m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0); - Value *val64 = IBITCAST64(m0); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int single = BIT(8) == 0; + int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); + int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); + Value* m0; + if (single) + { + m0 = FR32(m); + m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0); + LETFPS(d,m0); + } + else + { + /* Check endian please */ + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + m0 = FPBITCAST64(v64); + m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0); + Value *val64 = IBITCAST64(m0); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -1409,52 +1390,50 @@ int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vneg_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vneg_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG); - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst)); - vneg_inst *inst_cream = (vneg_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst)); + vneg_inst *inst_cream = (vneg_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VNEG_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VNEG :\n"); - DBG("VNEG :\n"); + vneg_inst *inst_cream = (vneg_inst *)inst_base->component; - vneg_inst *inst_cream = (vneg_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vneg_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vneg_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1464,50 +1443,50 @@ DYNCOM_FILL_ACTION(vneg), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int single = BIT(8) == 0; - int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); - int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); - Value* m0; - if (single) - { - m0 = FR32(m); - m0 = FPNEG32(m0); - LETFPS(d,m0); - } - else - { - /* Check endian please */ - Value *lo = FR32(2 * m); - Value *hi = FR32(2 * m + 1); - hi = IBITCAST32(hi); - lo = IBITCAST32(lo); - Value *hi64 = ZEXT64(hi); - Value* lo64 = ZEXT64(lo); - Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); - m0 = FPBITCAST64(v64); - m0 = FPNEG64(m0); - Value *val64 = IBITCAST64(m0); - hi = LSHR(val64,CONST64(32)); - lo = AND(val64,CONST64(0xffffffff)); - hi = TRUNC32(hi); - lo = TRUNC32(lo); - hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); - LETFPS(2*d ,lo); - LETFPS(d*2 + 1 , hi); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int single = BIT(8) == 0; + int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); + int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); + Value* m0; + if (single) + { + m0 = FR32(m); + m0 = FPNEG32(m0); + LETFPS(d,m0); + } + else + { + /* Check endian please */ + Value *lo = FR32(2 * m); + Value *hi = FR32(2 * m + 1); + hi = IBITCAST32(hi); + lo = IBITCAST32(lo); + Value *hi64 = ZEXT64(hi); + Value* lo64 = ZEXT64(lo); + Value* v64 = OR(SHL(hi64,CONST64(32)),lo64); + m0 = FPBITCAST64(v64); + m0 = FPNEG64(m0); + Value *val64 = IBITCAST64(m0); + hi = LSHR(val64,CONST64(32)); + lo = AND(val64,CONST64(0xffffffff)); + hi = TRUNC32(hi); + lo = TRUNC32(lo); + hi = FPBITCAST32(hi); + lo = FPBITCAST32(lo); + LETFPS(2*d ,lo); + LETFPS(d*2 + 1 , hi); + } + return No_exp; } #endif @@ -1516,52 +1495,52 @@ int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vsqrt_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vsqrt_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); - vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); + vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VSQRT_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VSQRT :\n"); - - vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + DBG("VSQRT :\n"); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vsqrt_inst)); - FETCH_INST; - GOTO_NEXT_INST; + vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; + + int ret; + + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vsqrt_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1571,38 +1550,38 @@ DYNCOM_FILL_ACTION(vsqrt), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int dp_op = (BIT(8) == 1); - int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; - int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; - Value* v; - Value* tmp; - if(dp_op){ - v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); - tmp = ZEXT64(IBITCAST32(FR32(2 * m))); - v = OR(v,tmp); - v = FPSQRT(FPBITCAST64(v)); - tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32))); - v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff))); - LETFPS(2 * d , FPBITCAST32(v)); - LETFPS(2 * d + 1, FPBITCAST32(tmp)); - }else { - v = FR32(m); - v = FPSQRT(FPEXT(64,v)); - v = FPTRUNC(32,v); - LETFPS(d,v); - } - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int dp_op = (BIT(8) == 1); + int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; + int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; + Value* v; + Value* tmp; + if(dp_op){ + v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); + tmp = ZEXT64(IBITCAST32(FR32(2 * m))); + v = OR(v,tmp); + v = FPSQRT(FPBITCAST64(v)); + tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32))); + v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff))); + LETFPS(2 * d , FPBITCAST32(v)); + LETFPS(2 * d + 1, FPBITCAST32(tmp)); + }else { + v = FR32(m); + v = FPSQRT(FPEXT(64,v)); + v = FPTRUNC(32,v); + LETFPS(d,v); + } + return No_exp; } #endif @@ -1611,52 +1590,52 @@ int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcmp_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vcmp_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); - vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); + vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VCMP_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VCMP(1) :\n"); - DBG("VCMP(1) :\n"); + vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; - vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; + int ret; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vcmp_inst)); - FETCH_INST; - GOTO_NEXT_INST; + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vcmp_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1666,65 +1645,65 @@ DYNCOM_FILL_ACTION(vcmp), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int dp_op = (BIT(8) == 1); - int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; - int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; - Value* v; - Value* tmp; - Value* n; - Value* z; - Value* c; - Value* vt; - Value* v1; - Value* nzcv; - if(dp_op){ - v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); - tmp = ZEXT64(IBITCAST32(FR32(2 * m))); - v1 = OR(v,tmp); - v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); - tmp = ZEXT64(IBITCAST32(FR32(2 * d))); - v = OR(v,tmp); - z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); - n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); - c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); - tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); - v1 = tmp; - c = OR(c,tmp); - n = SHL(ZEXT32(n),CONST32(31)); - z = SHL(ZEXT32(z),CONST32(30)); - c = SHL(ZEXT32(c),CONST32(29)); - v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); - v = R(VFP_FPSCR); - tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); - LET(VFP_FPSCR,tmp); - }else { - z = FPCMP_OEQ(FR32(d),FR32(m)); - n = FPCMP_OLT(FR32(d),FR32(m)); - c = FPCMP_OGE(FR32(d),FR32(m)); - tmp = FPCMP_UNO(FR32(d),FR32(m)); - c = OR(c,tmp); - v1 = tmp; - n = SHL(ZEXT32(n),CONST32(31)); - z = SHL(ZEXT32(z),CONST32(30)); - c = SHL(ZEXT32(c),CONST32(29)); - v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); - v = R(VFP_FPSCR); - tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); - LET(VFP_FPSCR,tmp); - } - return No_exp; + DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int dp_op = (BIT(8) == 1); + int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; + int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; + Value* v; + Value* tmp; + Value* n; + Value* z; + Value* c; + Value* vt; + Value* v1; + Value* nzcv; + if(dp_op){ + v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); + tmp = ZEXT64(IBITCAST32(FR32(2 * m))); + v1 = OR(v,tmp); + v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); + tmp = ZEXT64(IBITCAST32(FR32(2 * d))); + v = OR(v,tmp); + z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); + n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); + c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); + tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); + v1 = tmp; + c = OR(c,tmp); + n = SHL(ZEXT32(n),CONST32(31)); + z = SHL(ZEXT32(z),CONST32(30)); + c = SHL(ZEXT32(c),CONST32(29)); + v1 = SHL(ZEXT32(v1),CONST(28)); + nzcv = OR(OR(OR(n,z),c),v1); + v = R(VFP_FPSCR); + tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); + LET(VFP_FPSCR,tmp); + }else { + z = FPCMP_OEQ(FR32(d),FR32(m)); + n = FPCMP_OLT(FR32(d),FR32(m)); + c = FPCMP_OGE(FR32(d),FR32(m)); + tmp = FPCMP_UNO(FR32(d),FR32(m)); + c = OR(c,tmp); + v1 = tmp; + n = SHL(ZEXT32(n),CONST32(31)); + z = SHL(ZEXT32(z),CONST32(30)); + c = SHL(ZEXT32(c),CONST32(29)); + v1 = SHL(ZEXT32(v1),CONST(28)); + nzcv = OR(OR(OR(n,z),c),v1); + v = R(VFP_FPSCR); + tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); + LET(VFP_FPSCR,tmp); + } + return No_exp; } #endif @@ -1733,52 +1712,52 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcmp2_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vcmp2_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); - vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); + vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VCMP2_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VCMP(2) :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VCMP(2) :\n"); - vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; + vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vcmp2_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vcmp2_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1788,65 +1767,65 @@ DYNCOM_FILL_ACTION(vcmp2), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int dp_op = (BIT(8) == 1); - int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; - //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; - Value* v; - Value* tmp; - Value* n; - Value* z; - Value* c; - Value* vt; - Value* v1; - Value* nzcv; - if(dp_op){ - v1 = CONST64(0); - v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); - tmp = ZEXT64(IBITCAST32(FR32(2 * d))); - v = OR(v,tmp); - z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); - n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); - c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); - tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); - v1 = tmp; - c = OR(c,tmp); - n = SHL(ZEXT32(n),CONST32(31)); - z = SHL(ZEXT32(z),CONST32(30)); - c = SHL(ZEXT32(c),CONST32(29)); - v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); - v = R(VFP_FPSCR); - tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); - LET(VFP_FPSCR,tmp); - }else { - v1 = CONST(0); - v1 = FPBITCAST32(v1); - z = FPCMP_OEQ(FR32(d),v1); - n = FPCMP_OLT(FR32(d),v1); - c = FPCMP_OGE(FR32(d),v1); - tmp = FPCMP_UNO(FR32(d),v1); - c = OR(c,tmp); - v1 = tmp; - n = SHL(ZEXT32(n),CONST32(31)); - z = SHL(ZEXT32(z),CONST32(30)); - c = SHL(ZEXT32(c),CONST32(29)); - v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); - v = R(VFP_FPSCR); - tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); - LET(VFP_FPSCR,tmp); - } - return No_exp; + DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int dp_op = (BIT(8) == 1); + int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; + //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; + Value* v; + Value* tmp; + Value* n; + Value* z; + Value* c; + Value* vt; + Value* v1; + Value* nzcv; + if(dp_op){ + v1 = CONST64(0); + v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32)); + tmp = ZEXT64(IBITCAST32(FR32(2 * d))); + v = OR(v,tmp); + z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); + n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); + c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); + tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); + v1 = tmp; + c = OR(c,tmp); + n = SHL(ZEXT32(n),CONST32(31)); + z = SHL(ZEXT32(z),CONST32(30)); + c = SHL(ZEXT32(c),CONST32(29)); + v1 = SHL(ZEXT32(v1),CONST(28)); + nzcv = OR(OR(OR(n,z),c),v1); + v = R(VFP_FPSCR); + tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); + LET(VFP_FPSCR,tmp); + }else { + v1 = CONST(0); + v1 = FPBITCAST32(v1); + z = FPCMP_OEQ(FR32(d),v1); + n = FPCMP_OLT(FR32(d),v1); + c = FPCMP_OGE(FR32(d),v1); + tmp = FPCMP_UNO(FR32(d),v1); + c = OR(c,tmp); + v1 = tmp; + n = SHL(ZEXT32(n),CONST32(31)); + z = SHL(ZEXT32(z),CONST32(30)); + c = SHL(ZEXT32(c),CONST32(29)); + v1 = SHL(ZEXT32(v1),CONST(28)); + nzcv = OR(OR(OR(n,z),c),v1); + v = R(VFP_FPSCR); + tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); + LET(VFP_FPSCR,tmp); + } + return No_exp; } #endif @@ -1855,52 +1834,52 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbds_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vcvtbds_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); - vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); + vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VCVTBDS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VCVT(BDS) :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VCVT(BDS) :\n"); - vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; + vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vcvtbds_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vcvtbds_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -1910,39 +1889,39 @@ DYNCOM_FILL_ACTION(vcvtbds), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int dp_op = (BIT(8) == 1); - int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15); - int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; - int d2s = dp_op; - Value* v; - Value* tmp; - Value* v1; - if(d2s){ - v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); - tmp = ZEXT64(IBITCAST32(FR32(2 * m))); - v1 = OR(v,tmp); - tmp = FPTRUNC(32,FPBITCAST64(v1)); - LETFPS(d,tmp); - }else { - v = FR32(m); - tmp = FPEXT(64,v); - v = IBITCAST64(tmp); - tmp = TRUNC32(AND(v,CONST64(0xffffffff))); - v1 = TRUNC32(LSHR(v,CONST64(32))); - LETFPS(2 * d, FPBITCAST32(tmp) ); - LETFPS(2 * d + 1, FPBITCAST32(v1)); - } - return No_exp; + DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int dp_op = (BIT(8) == 1); + int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15); + int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1; + int d2s = dp_op; + Value* v; + Value* tmp; + Value* v1; + if(d2s){ + v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32)); + tmp = ZEXT64(IBITCAST32(FR32(2 * m))); + v1 = OR(v,tmp); + tmp = FPTRUNC(32,FPBITCAST64(v1)); + LETFPS(d,tmp); + }else { + v = FR32(m); + tmp = FPEXT(64,v); + v = IBITCAST64(tmp); + tmp = TRUNC32(AND(v,CONST64(0xffffffff))); + v1 = TRUNC32(LSHR(v,CONST64(32))); + LETFPS(2 * d, FPBITCAST32(tmp) ); + LETFPS(2 * d + 1, FPBITCAST32(v1)); + } + return No_exp; } #endif @@ -1951,52 +1930,52 @@ int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbff_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vcvtbff_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); - vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); + vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; - - return inst_base; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VCVTBFF_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VCVT(BFF) :\n"); + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VCVT(BFF) :\n"); - vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; + vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vcvtbff_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vcvtbff_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2006,17 +1985,17 @@ DYNCOM_FILL_ACTION(vcvtbff), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arch_arm_undef(cpu, bb, instr); - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arch_arm_undef(cpu, bb, instr); + return No_exp; } #endif @@ -2025,53 +2004,53 @@ int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbfi_inst { - unsigned int instr; - unsigned int dp_operation; + unsigned int instr; + unsigned int dp_operation; } vcvtbfi_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); - vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); + vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->dp_operation = BIT(inst, 8); - inst_cream->instr = inst; + inst_cream->dp_operation = BIT(inst, 8); + inst_cream->instr = inst; - - return inst_base; + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VCVTBFI_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - DBG("VCVT(BFI) :\n"); - - vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + DBG("VCVT(BFI) :\n"); + + vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; - int ret; - - if (inst_cream->dp_operation) - ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int ret; - CHECK_VFP_CDP_RET; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vcvtbfi_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (inst_cream->dp_operation) + ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + + CHECK_VFP_CDP_RET; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vcvtbfi_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2081,87 +2060,87 @@ DYNCOM_FILL_ACTION(vcvtbfi), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - unsigned int opc2 = BITS(16,18); - int to_integer = ((opc2 >> 2) == 1); - int dp_op = (BIT(8) == 1); - unsigned int op = BIT(7); - int m,d; - Value* v; - Value* hi; - Value* lo; - Value* v64; - if(to_integer){ - d = BIT(22) | (BITS(12,15) << 1); - if(dp_op) - m = BITS(0,3) | BIT(5) << 4; - else - m = BIT(5) | BITS(0,3) << 1; - }else { - m = BIT(5) | BITS(0,3) << 1; - if(dp_op) - d = BITS(12,15) | BIT(22) << 4; - else - d = BIT(22) | BITS(12,15) << 1; - } - if(to_integer){ - if(dp_op){ - lo = FR32(m * 2); - hi = FR32(m * 2 + 1); - hi = ZEXT64(IBITCAST32(hi)); - lo = ZEXT64(IBITCAST32(lo)); - v64 = OR(SHL(hi,CONST64(32)),lo); - if(BIT(16)){ - v = FPTOSI(32,FPBITCAST64(v64)); - } - else - v = FPTOUI(32,FPBITCAST64(v64)); - - v = FPBITCAST32(v); - LETFPS(d,v); - }else { - v = FR32(m); - if(BIT(16)){ - - v = FPTOSI(32,v); - } - else - v = FPTOUI(32,v); - LETFPS(d,FPBITCAST32(v)); - } - }else { - if(dp_op){ - v = IBITCAST32(FR32(m)); - if(BIT(7)) - v64 = SITOFP(64,v); - else - v64 = UITOFP(64,v); - v = IBITCAST64(v64); - hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))); - lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))); - LETFPS(2 * d , lo); - LETFPS(2 * d + 1, hi); - }else { - v = IBITCAST32(FR32(m)); - if(BIT(7)) - v = SITOFP(32,v); - else - v = UITOFP(32,v); - LETFPS(d,v); - } - } - return No_exp; + DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + unsigned int opc2 = BITS(16,18); + int to_integer = ((opc2 >> 2) == 1); + int dp_op = (BIT(8) == 1); + unsigned int op = BIT(7); + int m,d; + Value* v; + Value* hi; + Value* lo; + Value* v64; + if(to_integer){ + d = BIT(22) | (BITS(12,15) << 1); + if(dp_op) + m = BITS(0,3) | BIT(5) << 4; + else + m = BIT(5) | BITS(0,3) << 1; + }else { + m = BIT(5) | BITS(0,3) << 1; + if(dp_op) + d = BITS(12,15) | BIT(22) << 4; + else + d = BIT(22) | BITS(12,15) << 1; + } + if(to_integer){ + if(dp_op){ + lo = FR32(m * 2); + hi = FR32(m * 2 + 1); + hi = ZEXT64(IBITCAST32(hi)); + lo = ZEXT64(IBITCAST32(lo)); + v64 = OR(SHL(hi,CONST64(32)),lo); + if(BIT(16)){ + v = FPTOSI(32,FPBITCAST64(v64)); + } + else + v = FPTOUI(32,FPBITCAST64(v64)); + + v = FPBITCAST32(v); + LETFPS(d,v); + }else { + v = FR32(m); + if(BIT(16)){ + + v = FPTOSI(32,v); + } + else + v = FPTOUI(32,v); + LETFPS(d,FPBITCAST32(v)); + } + }else { + if(dp_op){ + v = IBITCAST32(FR32(m)); + if(BIT(7)) + v64 = SITOFP(64,v); + else + v64 = UITOFP(64,v); + v = IBITCAST64(v64); + hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))); + lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))); + LETFPS(2 * d , lo); + LETFPS(2 * d + 1, hi); + }else { + v = IBITCAST32(FR32(m)); + if(BIT(7)) + v = SITOFP(32,v); + else + v = UITOFP(32,v); + LETFPS(d,v); + } + } + return No_exp; } /** @@ -2173,15 +2152,15 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) * @return */ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ - int dp_operation = BIT(8); - int ret; - if (dp_operation) - ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - else - ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + int dp_operation = BIT(8); + int ret; + if (dp_operation) + ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + else + ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - return 0; + vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + return 0; } #endif @@ -2196,45 +2175,45 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrs_inst { - unsigned int to_arm; - unsigned int t; - unsigned int n; + unsigned int to_arm; + unsigned int t; + unsigned int n; } vmovbrs_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); - vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); + vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVBRS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; + vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; - VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovbrs_inst)); - FETCH_INST; - GOTO_NEXT_INST; + VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovbrs_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2244,30 +2223,30 @@ DYNCOM_FILL_ACTION(vmovbrs), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("VMOV(BRS) :\n"); - int to_arm = BIT(20) == 1; - int t = BITS(12, 15); - int n = BIT(7) | BITS(16, 19)<<1; + DBG("VMOV(BRS) :\n"); + int to_arm = BIT(20) == 1; + int t = BITS(12, 15); + int n = BIT(7) | BITS(16, 19)<<1; - if (to_arm) - { - DBG("\tr%d <= s%d\n", t, n); - LET(t, IBITCAST32(FR32(n))); - } - else - { - DBG("\ts%d <= r%d\n", n, t); - LETFPS(n, FPBITCAST32(R(t))); - } - return No_exp; + if (to_arm) + { + DBG("\tr%d <= s%d\n", t, n); + LET(t, IBITCAST32(FR32(n))); + } + else + { + DBG("\ts%d <= r%d\n", n, t); + LETFPS(n, FPBITCAST32(R(t))); + } + return No_exp; } #endif @@ -2277,46 +2256,46 @@ int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmsr_inst { - unsigned int reg; - unsigned int Rd; + unsigned int reg; + unsigned int Rd; } vmsr_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); - vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); + vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_cream->reg = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMSR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , - and in privilegied mode */ - /* Exceptions must be checked, according to v7 ref manual */ - CHECK_VFP_ENABLED; - - vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , + and in privilegied mode */ + /* Exceptions must be checked, according to v7 ref manual */ + CHECK_VFP_ENABLED; - VMSR(cpu, inst_cream->reg, inst_cream->Rd); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmsr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; + + VMSR(cpu, inst_cream->reg, inst_cream->Rd); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmsr_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2326,45 +2305,45 @@ DYNCOM_FILL_ACTION(vmsr), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - DBG("VMSR :"); - if(RD == 15) { - printf("in %s is not implementation.\n", __FUNCTION__); - exit(-1); - } - - Value *data = NULL; - int reg = RN; - int Rt = RD; - if (reg == 1) - { - LET(VFP_FPSCR, R(Rt)); - DBG("\tflags <= fpscr\n"); - } - else - { - switch (reg) - { - case 8: - LET(VFP_FPEXC, R(Rt)); - DBG("\tfpexc <= r%d \n", Rt); - break; - default: - DBG("\tSUBARCHITECTURE DEFINED\n"); - break; - } - } - return No_exp; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + DBG("VMSR :"); + if(RD == 15) { + printf("in %s is not implementation.\n", __FUNCTION__); + exit(-1); + } + + Value *data = NULL; + int reg = RN; + int Rt = RD; + if (reg == 1) + { + LET(VFP_FPSCR, R(Rt)); + DBG("\tflags <= fpscr\n"); + } + else + { + switch (reg) + { + case 8: + LET(VFP_FPEXC, R(Rt)); + DBG("\tfpexc <= r%d \n", Rt); + break; + default: + DBG("\tSUBARCHITECTURE DEFINED\n"); + break; + } + } + return No_exp; } #endif @@ -2374,48 +2353,48 @@ int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrc_inst { - unsigned int esize; - unsigned int index; - unsigned int d; - unsigned int t; + unsigned int esize; + unsigned int index; + unsigned int d; + unsigned int t; } vmovbrc_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); - vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); + vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; - inst_cream->t = BITS(inst, 12, 15); - /* VFP variant of instruction */ - inst_cream->esize = 32; - inst_cream->index = BIT(inst, 21); - - return inst_base; + inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; + inst_cream->t = BITS(inst, 12, 15); + /* VFP variant of instruction */ + inst_cream->esize = 32; + inst_cream->index = BIT(inst, 21); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVBRC_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; - - VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovbrc_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; + + VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovbrc_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2425,17 +2404,17 @@ DYNCOM_FILL_ACTION(vmovbrc), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arch_arm_undef(cpu, bb, instr); - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arch_arm_undef(cpu, bb, instr); + return No_exp; } #endif @@ -2445,88 +2424,88 @@ int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmrs_inst { - unsigned int reg; - unsigned int Rt; + unsigned int reg; + unsigned int Rt; } vmrs_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); - vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); + vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rt = BITS(inst, 12, 15); + inst_cream->reg = BITS(inst, 16, 19); + inst_cream->Rt = BITS(inst, 12, 15); - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMRS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, - and in privilegied mode */ - /* Exceptions must be checked, according to v7 ref manual */ - CHECK_VFP_ENABLED; - - vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; - - DBG("VMRS :"); - - if (inst_cream->reg == 1) /* FPSCR */ - { - if (inst_cream->Rt != 15) - { - cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)]; - DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); - } - else - { - cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1; - cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1; - cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1; - cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1; - DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); - } - } - else - { - switch (inst_cream->reg) - { - case 0: - cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)]; - DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]); - break; - case 6: - /* MVFR1, VFPv3 only ? */ - DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); - break; - case 7: - /* MVFR0, VFPv3 only? */ - DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); - break; - case 8: - cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)]; - DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]); - break; - default: - DBG("\tSUBARCHITECTURE DEFINED\n"); - break; - } - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmrs_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, + and in privilegied mode */ + /* Exceptions must be checked, according to v7 ref manual */ + CHECK_VFP_ENABLED; + + vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; + + DBG("VMRS :"); + + if (inst_cream->reg == 1) /* FPSCR */ + { + if (inst_cream->Rt != 15) + { + cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)]; + DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); + } + else + { + cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1; + cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1; + cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1; + cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1; + DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); + } + } + else + { + switch (inst_cream->reg) + { + case 0: + cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)]; + DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]); + break; + case 6: + /* MVFR1, VFPv3 only ? */ + DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); + break; + case 7: + /* MVFR0, VFPv3 only? */ + DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); + break; + case 8: + cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)]; + DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]); + break; + default: + DBG("\tSUBARCHITECTURE DEFINED\n"); + break; + } + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmrs_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2536,64 +2515,64 @@ DYNCOM_FILL_ACTION(vmrs), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - DBG("\t\tin %s .\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + DBG("\t\tin %s .\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - - Value *data = NULL; - int reg = BITS(16, 19);; - int Rt = BITS(12, 15); - DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt); - if (reg == 1) - { - if (Rt != 15) - { - LET(Rt, R(VFP_FPSCR)); - DBG("\tr%d <= fpscr\n", Rt); - } - else - { - //LET(Rt, R(VFP_FPSCR)); - update_cond_from_fpscr(cpu, instr, bb, pc); - DBG("In %s, \tflags <= fpscr\n", __FUNCTION__); - } - } - else - { - switch (reg) - { - case 0: - LET(Rt, R(VFP_FPSID)); - DBG("\tr%d <= fpsid\n", Rt); - break; - case 6: - /* MVFR1, VFPv3 only ? */ - DBG("\tr%d <= MVFR1 unimplemented\n", Rt); - break; - case 7: - /* MVFR0, VFPv3 only? */ - DBG("\tr%d <= MVFR0 unimplemented\n", Rt); - break; - case 8: - LET(Rt, R(VFP_FPEXC)); - DBG("\tr%d <= fpexc\n", Rt); - break; - default: - DBG("\tSUBARCHITECTURE DEFINED\n"); - break; - } - } - - return No_exp; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + + Value *data = NULL; + int reg = BITS(16, 19);; + int Rt = BITS(12, 15); + DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt); + if (reg == 1) + { + if (Rt != 15) + { + LET(Rt, R(VFP_FPSCR)); + DBG("\tr%d <= fpscr\n", Rt); + } + else + { + //LET(Rt, R(VFP_FPSCR)); + update_cond_from_fpscr(cpu, instr, bb, pc); + DBG("In %s, \tflags <= fpscr\n", __FUNCTION__); + } + } + else + { + switch (reg) + { + case 0: + LET(Rt, R(VFP_FPSID)); + DBG("\tr%d <= fpsid\n", Rt); + break; + case 6: + /* MVFR1, VFPv3 only ? */ + DBG("\tr%d <= MVFR1 unimplemented\n", Rt); + break; + case 7: + /* MVFR0, VFPv3 only? */ + DBG("\tr%d <= MVFR0 unimplemented\n", Rt); + break; + case 8: + LET(Rt, R(VFP_FPEXC)); + DBG("\tr%d <= fpexc\n", Rt); + break; + default: + DBG("\tSUBARCHITECTURE DEFINED\n"); + break; + } + } + + return No_exp; } #endif @@ -2603,48 +2582,48 @@ int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbcr_inst { - unsigned int esize; - unsigned int index; - unsigned int d; - unsigned int t; + unsigned int esize; + unsigned int index; + unsigned int d; + unsigned int t; } vmovbcr_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); - vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); + vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; + inst_cream->t = BITS(inst, 12, 15); + /* VFP variant of instruction */ + inst_cream->esize = 32; + inst_cream->index = BIT(inst, 21); - inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; - inst_cream->t = BITS(inst, 12, 15); - /* VFP variant of instruction */ - inst_cream->esize = 32; - inst_cream->index = BIT(inst, 21); - - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVBCR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; - - VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovbcr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; + + VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovbcr_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2654,17 +2633,17 @@ DYNCOM_FILL_ACTION(vmovbcr), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - return instr_size; + int instr_size = INSTR_SIZE; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arch_arm_undef(cpu, bb, instr); - return No_exp; + DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arch_arm_undef(cpu, bb, instr); + return No_exp; } #endif @@ -2679,48 +2658,48 @@ int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrrss_inst { - unsigned int to_arm; - unsigned int t; - unsigned int t2; - unsigned int m; + unsigned int to_arm; + unsigned int t; + unsigned int t2; + unsigned int m; } vmovbrrss_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); - vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); + vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVBRRSS_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; - vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component; + vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component; - VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, - &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovbrrss_inst)); - FETCH_INST; - GOTO_NEXT_INST; + VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, + &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovbrrss_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif #ifdef VFP_DYNCOM_TABLE @@ -2729,31 +2708,31 @@ DYNCOM_FILL_ACTION(vmovbrrss), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; + int instr_size = INSTR_SIZE; - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - if (instr >> 28 != 0xE) - *tag |= TAG_CONDITIONAL; + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + if (instr >> 28 != 0xE) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) { - int to_arm = BIT(20) == 1; - int t = BITS(12, 15); - int t2 = BITS(16, 19); - int n = BIT(5)<<4 | BITS(0, 3); - if (to_arm) { - LET(t, IBITCAST32(FR32(n + 0))); - LET(t2, IBITCAST32(FR32(n + 1))); - } - else { - LETFPS(n + 0, FPBITCAST32(R(t))); - LETFPS(n + 1, FPBITCAST32(R(t2))); - } - return No_exp; + int to_arm = BIT(20) == 1; + int t = BITS(12, 15); + int t2 = BITS(16, 19); + int n = BIT(5)<<4 | BITS(0, 3); + if (to_arm) { + LET(t, IBITCAST32(FR32(n + 0))); + LET(t2, IBITCAST32(FR32(n + 1))); + } + else { + LETFPS(n + 0, FPBITCAST32(R(t))); + LETFPS(n + 1, FPBITCAST32(R(t2))); + } + return No_exp; } #endif @@ -2763,48 +2742,48 @@ int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t p /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrrd_inst { - unsigned int to_arm; - unsigned int t; - unsigned int t2; - unsigned int m; + unsigned int to_arm; + unsigned int t; + unsigned int t2; + unsigned int m; } vmovbrrd_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); - vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); + vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - return inst_base; + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VMOVBRRD_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; - - VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, - &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vmovbrrd_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; + + VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, + &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vmovbrrd_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2814,31 +2793,31 @@ DYNCOM_FILL_ACTION(vmovbrrd), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; - return instr_size; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int to_arm = BIT(20) == 1; - int t = BITS(12, 15); - int t2 = BITS(16, 19); - int n = BIT(5)<<4 | BITS(0, 3); - if(to_arm){ - LET(t, IBITCAST32(FR32(n * 2))); - LET(t2, IBITCAST32(FR32(n * 2 + 1))); - } - else{ - LETFPS(n * 2, FPBITCAST32(R(t))); - LETFPS(n * 2 + 1, FPBITCAST32(R(t2))); - } - return No_exp; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int to_arm = BIT(20) == 1; + int t = BITS(12, 15); + int t2 = BITS(16, 19); + int n = BIT(5)<<4 | BITS(0, 3); + if(to_arm){ + LET(t, IBITCAST32(FR32(n * 2))); + LET(t2, IBITCAST32(FR32(n * 2 + 1))); + } + else{ + LETFPS(n * 2, FPBITCAST32(R(t))); + LETFPS(n * 2 + 1, FPBITCAST32(R(t2))); + } + return No_exp; } #endif @@ -2852,60 +2831,60 @@ int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc /* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vstr_inst { - unsigned int single; - unsigned int n; - unsigned int d; - unsigned int imm32; - unsigned int add; + unsigned int single; + unsigned int n; + unsigned int d; + unsigned int imm32; + unsigned int add; } vstr_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); - vstr_inst *inst_cream = (vstr_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); + vstr_inst *inst_cream = (vstr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->imm32 = BITS(inst, 0,7) << 2; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - return inst_base; + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->add = BIT(inst, 23); + inst_cream->imm32 = BITS(inst, 0,7) << 2; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); + inst_cream->n = BITS(inst, 16, 19); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VSTR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vstr_inst *inst_cream = (vstr_inst *)inst_base->component; - - unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); - addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); - - if (inst_cream->single) - { - Memory::Write32(addr, cpu->ExtReg[inst_cream->d]); - } - else - { - Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]); - Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vstr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + vstr_inst *inst_cream = (vstr_inst *)inst_base->component; + + unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); + addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); + + if (inst_cream->single) + { + Memory::Write32(addr, cpu->ExtReg[inst_cream->d]); + } + else + { + Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]); + Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vstr_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -2915,61 +2894,46 @@ DYNCOM_FILL_ACTION(vstr), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - int single = BIT(8) == 0; - int add = BIT(23); - int imm32 = BITS(0,7) << 2; - int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); - int n = BITS(16, 19); - - Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n); - Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32)); - DBG("VSTR :\n"); - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap); - //Value* phys_addr; - if(single){ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR(d), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR(d), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32); - bb = cpu->dyncom_engine->bb; - } - else{ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR(d * 2), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32); - bb = cpu->dyncom_engine->bb; - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2 + 1), 32); - #endif - //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32); - memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32); - bb = cpu->dyncom_engine->bb; - } - return No_exp; + int single = BIT(8) == 0; + int add = BIT(23); + int imm32 = BITS(0,7) << 2; + int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); + int n = BITS(16, 19); + + Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n); + Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32)); + DBG("VSTR :\n"); + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap); + //Value* phys_addr; + if(single){ + //memory_write(cpu, bb, Addr, RSPR(d), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32); + bb = cpu->dyncom_engine->bb; + } + else{ + //memory_write(cpu, bb, Addr, RSPR(d * 2), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32); + bb = cpu->dyncom_engine->bb; + //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32); + memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32); + bb = cpu->dyncom_engine->bb; + } + return No_exp; } #endif @@ -2978,64 +2942,64 @@ int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vpush_inst { - unsigned int single; - unsigned int d; - unsigned int imm32; - unsigned int regs; + unsigned int single; + unsigned int d; + unsigned int imm32; + unsigned int regs; } vpush_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); - vpush_inst *inst_cream = (vpush_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); + vpush_inst *inst_cream = (vpush_inst *)inst_base->component; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - return inst_base; + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); + inst_cream->imm32 = BITS(inst, 0, 7)<<2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VPUSH_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - int i; - - vpush_inst *inst_cream = (vpush_inst *)inst_base->component; - - addr = cpu->Reg[R13] - inst_cream->imm32; - - for (i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); - addr += 4; - } - else - { - Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); - Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); - addr += 8; - } - } - cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vpush_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + int i; + + vpush_inst *inst_cream = (vpush_inst *)inst_base->component; + + addr = cpu->Reg[R13] - inst_cream->imm32; + + for (i = 0; i < inst_cream->regs; i++) + { + if (inst_cream->single) + { + Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); + addr += 4; + } + else + { + Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); + Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); + addr += 8; + } + } + cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vpush_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif #ifdef VFP_DYNCOM_TABLE @@ -3044,72 +3008,57 @@ DYNCOM_FILL_ACTION(vpush), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - int single = BIT(8) == 0; - int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); - int imm32 = BITS(0, 7)<<2; - int regs = (single ? BITS(0, 7) : BITS(1, 7)); - - DBG("\t\tin %s \n", __FUNCTION__); - Value* Addr = SUB(R(13), CONST(imm32)); - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); - //Value* phys_addr; - int i; - for (i = 0; i < regs; i++) - { - if (single) - { - //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR(d + i), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32); - bb = cpu->dyncom_engine->bb; - Addr = ADD(Addr, CONST(4)); - } - else - { - /* Careful of endianness, little by default */ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32); - bb = cpu->dyncom_engine->bb; - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32); - #endif - //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); - memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); - bb = cpu->dyncom_engine->bb; - - Addr = ADD(Addr, CONST(8)); - } - } - LET(13, SUB(R(13), CONST(imm32))); - - return No_exp; + int single = BIT(8) == 0; + int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); + int imm32 = BITS(0, 7)<<2; + int regs = (single ? BITS(0, 7) : BITS(1, 7)); + + DBG("\t\tin %s \n", __FUNCTION__); + Value* Addr = SUB(R(13), CONST(imm32)); + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); + //Value* phys_addr; + int i; + for (i = 0; i < regs; i++) + { + if (single) + { + //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); + //memory_write(cpu, bb, Addr, RSPR(d + i), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32); + bb = cpu->dyncom_engine->bb; + Addr = ADD(Addr, CONST(4)); + } + else + { + /* Careful of endianness, little by default */ + //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32); + bb = cpu->dyncom_engine->bb; + //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); + memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); + bb = cpu->dyncom_engine->bb; + + Addr = ADD(Addr, CONST(8)); + } + } + LET(13, SUB(R(13), CONST(imm32))); + + return No_exp; } #endif @@ -3118,76 +3067,76 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vstm_inst { - unsigned int single; - unsigned int add; - unsigned int wback; - unsigned int d; - unsigned int n; - unsigned int imm32; - unsigned int regs; + unsigned int single; + unsigned int add; + unsigned int wback; + unsigned int d; + unsigned int n; + unsigned int imm32; + unsigned int regs; } vstm_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); - vstm_inst *inst_cream = (vstm_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); + vstm_inst *inst_cream = (vstm_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->wback = BIT(inst, 21); - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->add = BIT(inst, 23); + inst_cream->wback = BIT(inst, 21); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); + inst_cream->n = BITS(inst, 16, 19); + inst_cream->imm32 = BITS(inst, 0, 7)<<2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VSTM_INST: /* encoding 1 */ { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - int i; - - vstm_inst *inst_cream = (vstm_inst *)inst_base->component; - - addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); - - for (i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); - addr += 4; - } - else - { - Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); - Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); - addr += 8; - } - } - if (inst_cream->wback){ - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : - cpu->Reg[inst_cream->n] - inst_cream->imm32); - } - - } - cpu->Reg[15] += 4; - INC_PC(sizeof(vstm_inst)); - - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + int i; + + vstm_inst *inst_cream = (vstm_inst *)inst_base->component; + + addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); + + for (i = 0; i < inst_cream->regs; i++) + { + if (inst_cream->single) + { + Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); + addr += 4; + } + else + { + Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); + Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); + addr += 8; + } + } + if (inst_cream->wback){ + cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : + cpu->Reg[inst_cream->n] - inst_cream->imm32); + } + + } + cpu->Reg[15] += 4; + INC_PC(sizeof(vstm_inst)); + + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -3197,90 +3146,75 @@ DYNCOM_FILL_ACTION(vstm), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //arch_arm_undef(cpu, bb, instr); - int single = BIT(8) == 0; - int add = BIT(23); - int wback = BIT(21); - int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4); - int n = BITS(16, 19); - int imm32 = BITS(0, 7)<<2; - int regs = single ? BITS(0, 7) : BITS(1, 7); - - Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); - DBG("VSTM \n"); - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); - - int i; - Value* phys_addr; - for (i = 0; i < regs; i++) - { - if (single) - { - - //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); - /* if R(i) is R15? */ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR(d + i), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); - bb = cpu->dyncom_engine->bb; - //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); - Addr = ADD(Addr, CONST(4)); - } - else - { - - //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32); - #endif - //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); - memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); - bb = cpu->dyncom_engine->bb; - - //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); - bb = cpu->dyncom_engine->bb; - arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32); - #endif - //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); - memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); - bb = cpu->dyncom_engine->bb; - //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]); - //addr += 8; - Addr = ADD(Addr, CONST(8)); - } - } - if (wback){ - //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : - // cpu->Reg[n] - imm32); - LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); - DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); - } - return No_exp; + //arch_arm_undef(cpu, bb, instr); + int single = BIT(8) == 0; + int add = BIT(23); + int wback = BIT(21); + int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4); + int n = BITS(16, 19); + int imm32 = BITS(0, 7)<<2; + int regs = single ? BITS(0, 7) : BITS(1, 7); + + Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); + DBG("VSTM \n"); + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); + + int i; + Value* phys_addr; + for (i = 0; i < regs; i++) + { + if (single) + { + + //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); + /* if R(i) is R15? */ + //memory_write(cpu, bb, Addr, RSPR(d + i), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); + bb = cpu->dyncom_engine->bb; + //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); + Addr = ADD(Addr, CONST(4)); + } + else + { + + //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); + //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); + memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); + bb = cpu->dyncom_engine->bb; + + //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); + //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); + memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); + bb = cpu->dyncom_engine->bb; + //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]); + //addr += 8; + Addr = ADD(Addr, CONST(8)); + } + } + if (wback){ + //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : + // cpu->Reg[n] - imm32); + LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); + DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); + } + return No_exp; } #endif @@ -3289,69 +3223,69 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vpop_inst { - unsigned int single; - unsigned int d; - unsigned int imm32; - unsigned int regs; + unsigned int single; + unsigned int d; + unsigned int imm32; + unsigned int regs; } vpop_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); - vpop_inst *inst_cream = (vpop_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); + vpop_inst *inst_cream = (vpop_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4)); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); - - return inst_base; + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4)); + inst_cream->imm32 = BITS(inst, 0, 7)<<2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VPOP_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - int i; - unsigned int value1, value2; - - vpop_inst *inst_cream = (vpop_inst *)inst_base->component; - - addr = cpu->Reg[R13]; - - for (i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - value1 = Memory::Read32(addr); - cpu->ExtReg[inst_cream->d+i] = value1; - addr += 4; - } - else - { - value1 = Memory::Read32(addr); - value2 = Memory::Read32(addr + 4); - cpu->ExtReg[(inst_cream->d+i)*2] = value1; - cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; - addr += 8; - } - } - cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vpop_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + int i; + unsigned int value1, value2; + + vpop_inst *inst_cream = (vpop_inst *)inst_base->component; + + addr = cpu->Reg[R13]; + + for (i = 0; i < inst_cream->regs; i++) + { + if (inst_cream->single) + { + value1 = Memory::Read32(addr); + cpu->ExtReg[inst_cream->d+i] = value1; + addr += 4; + } + else + { + value1 = Memory::Read32(addr); + value2 = Memory::Read32(addr + 4); + cpu->ExtReg[(inst_cream->d+i)*2] = value1; + cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; + addr += 8; + } + } + cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vpop_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -3361,82 +3295,67 @@ DYNCOM_FILL_ACTION(vpop), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - /* Should check if PC is destination register */ - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + /* Should check if PC is destination register */ + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction .\n", __FUNCTION__); - //arch_arm_undef(cpu, bb, instr); - int single = BIT(8) == 0; - int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); - int imm32 = BITS(0, 7)<<2; - int regs = (single ? BITS(0, 7) : BITS(1, 7)); - - int i; - unsigned int value1, value2; - - DBG("VPOP :\n"); - - Value* Addr = R(13); - Value* val; - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - //Value* phys_addr; - for (i = 0; i < regs; i++) - { - if (single) - { - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - LETFPS(d + i, FPBITCAST32(val)); - Addr = ADD(Addr, CONST(4)); - } - else - { - /* Careful of endianness, little by default */ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - LETFPS((d + i) * 2, FPBITCAST32(val)); - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); - - Addr = ADD(Addr, CONST(8)); - } - } - LET(13, ADD(R(13), CONST(imm32))); - return No_exp; + DBG("\t\tin %s instruction .\n", __FUNCTION__); + //arch_arm_undef(cpu, bb, instr); + int single = BIT(8) == 0; + int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); + int imm32 = BITS(0, 7)<<2; + int regs = (single ? BITS(0, 7) : BITS(1, 7)); + + int i; + unsigned int value1, value2; + + DBG("VPOP :\n"); + + Value* Addr = R(13); + Value* val; + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); + //Value* phys_addr; + for (i = 0; i < regs; i++) + { + if (single) + { + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + LETFPS(d + i, FPBITCAST32(val)); + Addr = ADD(Addr, CONST(4)); + } + else + { + /* Careful of endianness, little by default */ + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + LETFPS((d + i) * 2, FPBITCAST32(val)); + memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); + + Addr = ADD(Addr, CONST(8)); + } + } + LET(13, ADD(R(13), CONST(imm32))); + return No_exp; } #endif @@ -3445,64 +3364,64 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vldr_inst { - unsigned int single; - unsigned int n; - unsigned int d; - unsigned int imm32; - unsigned int add; + unsigned int single; + unsigned int n; + unsigned int d; + unsigned int imm32; + unsigned int add; } vldr_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); - vldr_inst *inst_cream = (vldr_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); + vldr_inst *inst_cream = (vldr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->imm32 = BITS(inst, 0,7) << 2; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - return inst_base; + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->add = BIT(inst, 23); + inst_cream->imm32 = BITS(inst, 0,7) << 2; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); + inst_cream->n = BITS(inst, 16, 19); + + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VLDR_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - vldr_inst *inst_cream = (vldr_inst *)inst_base->component; - - unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); - addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); - - if (inst_cream->single) - { - cpu->ExtReg[inst_cream->d] = Memory::Read32(addr); - } - else - { - unsigned int word1, word2; - word1 = Memory::Read32(addr); - word2 = Memory::Read32(addr + 4); - - cpu->ExtReg[inst_cream->d*2] = word1; - cpu->ExtReg[inst_cream->d*2+1] = word2; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vldr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + vldr_inst *inst_cream = (vldr_inst *)inst_base->component; + + unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); + addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); + + if (inst_cream->single) + { + cpu->ExtReg[inst_cream->d] = Memory::Read32(addr); + } + else + { + unsigned int word1, word2; + word1 = Memory::Read32(addr); + word2 = Memory::Read32(addr + 4); + + cpu->ExtReg[inst_cream->d*2] = word1; + cpu->ExtReg[inst_cream->d*2+1] = word2; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vldr_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -3512,76 +3431,61 @@ DYNCOM_FILL_ACTION(vldr), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - /* Should check if PC is destination register */ - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + /* Should check if PC is destination register */ + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - int single = BIT(8) == 0; - int add = BIT(23); - int wback = BIT(21); - int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); - int n = BITS(16, 19); - int imm32 = BITS(0, 7)<<2; - int regs = (single ? BITS(0, 7) : BITS(1, 7)); - Value* base = R(n); - DBG("\t\tin %s .\n", __FUNCTION__); - if(n == 15){ - base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8)); - } - Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32))); - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap); - //Value* phys_addr; - Value* val; - if(single){ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - //LETS(d, val); - LETFPS(d,FPBITCAST32(val)); - } - else{ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - //LETS(d * 2, val); - LETFPS(d * 2,FPBITCAST32(val)); - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - //LETS(d * 2 + 1, val); - LETFPS( d * 2 + 1,FPBITCAST32(val)); - } - - return No_exp; + int single = BIT(8) == 0; + int add = BIT(23); + int wback = BIT(21); + int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); + int n = BITS(16, 19); + int imm32 = BITS(0, 7)<<2; + int regs = (single ? BITS(0, 7) : BITS(1, 7)); + Value* base = R(n); + DBG("\t\tin %s .\n", __FUNCTION__); + if(n == 15){ + base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8)); + } + Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32))); + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap); + //Value* phys_addr; + Value* val; + if(single){ + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + //LETS(d, val); + LETFPS(d,FPBITCAST32(val)); + } + else{ + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + //LETS(d * 2, val); + LETFPS(d * 2,FPBITCAST32(val)); + memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + //LETS(d * 2 + 1, val); + LETFPS( d * 2 + 1,FPBITCAST32(val)); + } + + return No_exp; } #endif @@ -3590,76 +3494,76 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ /* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */ #ifdef VFP_INTERPRETER_STRUCT typedef struct _vldm_inst { - unsigned int single; - unsigned int add; - unsigned int wback; - unsigned int d; - unsigned int n; - unsigned int imm32; - unsigned int regs; + unsigned int single; + unsigned int add; + unsigned int wback; + unsigned int d; + unsigned int n; + unsigned int imm32; + unsigned int regs; } vldm_inst; #endif #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); - vldm_inst *inst_cream = (vldm_inst *)inst_base->component; + VFP_DEBUG_TRANSLATE; + + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); + vldm_inst *inst_cream = (vldm_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->wback = BIT(inst, 21); - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->add = BIT(inst, 23); + inst_cream->wback = BIT(inst, 21); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); + inst_cream->n = BITS(inst, 16, 19); + inst_cream->imm32 = BITS(inst, 0, 7)<<2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); - return inst_base; + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL VLDM_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - CHECK_VFP_ENABLED; - - int i; - - vldm_inst *inst_cream = (vldm_inst *)inst_base->component; - - addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); - - for (i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr); - addr += 4; - } - else - { - cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr); - cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4); - addr += 8; - } - } - if (inst_cream->wback){ - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : - cpu->Reg[inst_cream->n] - inst_cream->imm32); - DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]); - } - - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vldm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + CHECK_VFP_ENABLED; + + int i; + + vldm_inst *inst_cream = (vldm_inst *)inst_base->component; + + addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); + + for (i = 0; i < inst_cream->regs; i++) + { + if (inst_cream->single) + { + cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr); + addr += 4; + } + else + { + cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr); + cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4); + addr += 8; + } + } + if (inst_cream->wback){ + cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : + cpu->Reg[inst_cream->n] - inst_cream->imm32); + DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]); + } + + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(vldm_inst)); + FETCH_INST; + GOTO_NEXT_INST; } #endif @@ -3669,91 +3573,76 @@ DYNCOM_FILL_ACTION(vldm), #ifdef VFP_DYNCOM_TAG int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { - int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); - arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); - *tag |= TAG_NEW_BB; - if(instr >> 28 != 0xe) - *tag |= TAG_CONDITIONAL; + int instr_size = INSTR_SIZE; + //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); + arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); + DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); + *tag |= TAG_NEW_BB; + if(instr >> 28 != 0xe) + *tag |= TAG_CONDITIONAL; - return instr_size; + return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - int single = BIT(8) == 0; - int add = BIT(23); - int wback = BIT(21); - int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4; - int n = BITS(16, 19); - int imm32 = BITS(0, 7)<<2; - int regs = single ? BITS(0, 7) : BITS(1, 7); - - Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); - //if(single) - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - //else - // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - - DBG("VLDM \n"); - int i; - //Value* phys_addr; - Value* val; - for (i = 0; i < regs; i++) - { - if (single) - { - - //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); - /* if R(i) is R15? */ - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - //LETS(d + i, val); - LETFPS(d + i, FPBITCAST32(val)); - //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); - Addr = ADD(Addr, CONST(4)); - } - else - { - #if 0 - phys_addr = get_phys_addr(cpu, bb, Addr, 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - LETFPS((d + i) * 2, FPBITCAST32(val)); - #if 0 - phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1); - bb = cpu->dyncom_engine->bb; - val = arch_read_memory(cpu,bb,phys_addr,0,32); - #endif - memory_read(cpu, bb, Addr, 0, 32); - bb = cpu->dyncom_engine->bb; - val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); - LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); - - //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); - //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]); - //addr += 8; - Addr = ADD(Addr, CONST(8)); - } - } - if (wback){ - //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : - // cpu->Reg[n] - imm32); - LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); - DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); - } - return No_exp; + int single = BIT(8) == 0; + int add = BIT(23); + int wback = BIT(21); + int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4; + int n = BITS(16, 19); + int imm32 = BITS(0, 7)<<2; + int regs = single ? BITS(0, 7) : BITS(1, 7); + + Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); + //if(single) + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); + //else + // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); + + DBG("VLDM \n"); + int i; + //Value* phys_addr; + Value* val; + for (i = 0; i < regs; i++) + { + if (single) + { + + //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); + /* if R(i) is R15? */ + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + //LETS(d + i, val); + LETFPS(d + i, FPBITCAST32(val)); + //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); + Addr = ADD(Addr, CONST(4)); + } + else + { + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + LETFPS((d + i) * 2, FPBITCAST32(val)); + memory_read(cpu, bb, Addr, 0, 32); + bb = cpu->dyncom_engine->bb; + val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); + LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); + + //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); + //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]); + //addr += 8; + Addr = ADD(Addr, CONST(8)); + } + } + if (wback){ + //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : + // cpu->Reg[n] - imm32); + LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); + DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); + } + return No_exp; } #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() { g_sys_core = new ARM_Interpreter(); switch (Settings::values.cpu_core) { - case CPU_FastInterpreter: + case CPU_Interpreter: g_app_core = new ARM_DynCom(); break; - case CPU_Interpreter: + case CPU_OldInterpreter: default: g_app_core = new ARM_Interpreter(); 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 { enum CPUCore { CPU_Interpreter, - CPU_FastInterpreter + CPU_OldInterpreter, }; extern 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: const std::string DebugStr() const { switch (GetType()) { case Invalid: + default: return "[Invalid]"; case Empty: return "[Empty]"; @@ -117,6 +118,7 @@ public: return {}; case Invalid: case Binary: + default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); return {}; @@ -159,6 +161,7 @@ public: case Empty: return {}; case Invalid: + default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); 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 @@ #include <memory> #include "common/common_types.h" +#include "common/file_util.h" #include "common/make_unique.h" #include "core/file_sys/archive_romfs.h" -#include "core/file_sys/directory_romfs.h" -#include "core/file_sys/file_romfs.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace @@ -23,48 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { } } -std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique<File_RomFS>(this); -} - -bool Archive_RomFS::DeleteFile(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS."); - return false; -} - -bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); - return false; -} - -bool Archive_RomFS::DeleteDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS."); - return false; -} - -ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const { - LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS."); - // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); -} - -bool Archive_RomFS::CreateDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS."); - return false; -} - -bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); - return false; -} - -std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const { - return Common::make_unique<Directory_RomFS>(); -} - -ResultCode Archive_RomFS::Format(const Path& path) const { - LOG_WARNING(Service_FS, "Attempted to format ROMFS."); - return UnimplementedFunction(ErrorModule::FS); -} - } // 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 @@ #include "common/common_types.h" -#include "core/file_sys/archive_backend.h" +#include "core/file_sys/ivfc_archive.h" #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -17,82 +17,12 @@ namespace FileSys { /// File system interface to the RomFS archive -class Archive_RomFS final : public ArchiveBackend { +class Archive_RomFS final : public IVFCArchive { public: Archive_RomFS(const Loader::AppLoader& app_loader); std::string GetName() const override { return "RomFS"; } - - /** - * Open a file specified by its path, using the specified mode - * @param path Path relative to the archive - * @param mode Mode to open the file with - * @return Opened file, or nullptr - */ - std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; - - /** - * Delete a file specified by its path - * @param path Path relative to the archive - * @return Whether the file could be deleted - */ - bool DeleteFile(const Path& path) const override; - - /** - * Rename a File specified by its path - * @param src_path Source path relative to the archive - * @param dest_path Destination path relative to the archive - * @return Whether rename succeeded - */ - bool RenameFile(const Path& src_path, const Path& dest_path) const override; - - /** - * Delete a directory specified by its path - * @param path Path relative to the archive - * @return Whether the directory could be deleted - */ - bool DeleteDirectory(const Path& path) const override; - - /** - * Create a file specified by its path - * @param path Path relative to the Archive - * @param size The size of the new file, filled with zeroes - * @return File creation result code - */ - ResultCode CreateFile(const Path& path, u32 size) const override; - - /** - * Create a directory specified by its path - * @param path Path relative to the archive - * @return Whether the directory could be created - */ - bool CreateDirectory(const Path& path) const override; - - /** - * Rename a Directory specified by its path - * @param src_path Source path relative to the archive - * @param dest_path Destination path relative to the archive - * @return Whether rename succeeded - */ - bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; - - /** - * Open a directory specified by its path - * @param path Path relative to the archive - * @return Opened directory, or nullptr - */ - std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; - - ResultCode Open(const Path& path) override { - return RESULT_SUCCESS; - } - - ResultCode Format(const Path& path) const override; - -private: - friend class File_RomFS; - - std::vector<u8> raw_data; + ResultCode Open(const Path& path) override { return RESULT_SUCCESS; } }; } // 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/file_util.h" + +#include "core/file_sys/archive_savedatacheck.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) { +} + +ResultCode Archive_SaveDataCheck::Open(const Path& path) { + // TODO(Subv): We should not be overwriting raw_data everytime this function is called, + // but until we use factory classes to create the archives at runtime instead of creating them beforehand + // and allow multiple archives of the same type to be open at the same time without clobbering each other, + // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed. + // There are a number of problems with this, for example opening a file in this archive, then opening + // this archive again with a different path, will corrupt the previously open file. + auto vec = path.AsBinary(); + const u32* data = reinterpret_cast<u32*>(vec.data()); + std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]); + FileUtil::IOFile file(file_path, "rb"); + + std::fill(raw_data.begin(), raw_data.end(), 0); + + if (!file.IsOpen()) { + return ResultCode(-1); // TODO(Subv): Find the right error code + } + auto size = file.GetSize(); + raw_data.resize(size); + file.ReadBytes(raw_data.data(), size); + file.Close(); + return RESULT_SUCCESS; +} + +} // 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> + +#include "common/common_types.h" + +#include "core/file_sys/ivfc_archive.h" +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +/// File system interface to the SaveDataCheck archive +class Archive_SaveDataCheck final : public IVFCArchive { +public: + Archive_SaveDataCheck(const std::string& mount_point); + + std::string GetName() const override { return "SaveDataCheck"; } + ResultCode Open(const Path& path) override; + +private: + std::string mount_point; +}; + +} // 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 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/common_types.h" - -#include "core/file_sys/directory_romfs.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -Directory_RomFS::Directory_RomFS() { -} - -Directory_RomFS::~Directory_RomFS() { -} - -bool Directory_RomFS::Open() { - return false; -} - -u32 Directory_RomFS::Read(const u32 count, Entry* entries) { - return 0; -} - -bool Directory_RomFS::Close() const { - return false; -} - -} // 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 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -#include "core/file_sys/directory_backend.h" -#include "core/loader/loader.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -class Directory_RomFS final : public DirectoryBackend { -public: - Directory_RomFS(); - ~Directory_RomFS() override; - - /** - * Open the directory - * @return true if the directory opened correctly - */ - bool Open() override; - - /** - * List files contained in the directory - * @param count Number of entries to return at once in entries - * @param entries Buffer to read data into - * @return Number of entries listed - */ - u32 Read(const u32 count, Entry* entries) override; - - /** - * Close the directory - * @return true if the directory closed correctly - */ - bool Close() const override; -}; - -} // 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 @@ #include "common/common_types.h" #include "common/file_util.h" +#include "common/make_unique.h" #include "core/file_sys/disk_archive.h" #include "core/settings.h" @@ -17,10 +18,10 @@ namespace FileSys { std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); - DiskFile* file = new DiskFile(this, path, mode); + auto file = Common::make_unique<DiskFile>(this, path, mode); if (!file->Open()) return nullptr; - return std::unique_ptr<FileBackend>(file); + return std::move(file); } bool DiskArchive::DeleteFile(const Path& path) const { @@ -66,10 +67,10 @@ bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) c std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const { LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); - DiskDirectory* directory = new DiskDirectory(this, path); + auto directory = Common::make_unique<DiskDirectory>(this, path); if (!directory->Open()) return nullptr; - return std::unique_ptr<DirectoryBackend>(directory); + return std::move(directory); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -100,7 +101,7 @@ bool DiskFile::Open() { // Open the file in binary mode, to avoid problems with CR/LF on Windows systems mode_string += "b"; - file = new FileUtil::IOFile(path, mode_string.c_str()); + file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str()); return true; } 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: DiskFile(); DiskFile(const DiskArchive* archive, const Path& path, const Mode mode); - ~DiskFile() override { - Close(); - } - bool Open() override; size_t Read(const u64 offset, const u32 length, u8* buffer) const override; size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; @@ -75,7 +71,7 @@ protected: const DiskArchive* archive; std::string path; Mode mode; - FileUtil::IOFile* file; + std::unique_ptr<FileUtil::IOFile> file; }; class 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 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/common_types.h" - -#include "core/file_sys/file_romfs.h" -#include "core/file_sys/archive_romfs.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -bool File_RomFS::Open() { - return true; -} - -size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { - LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - memcpy(buffer, &archive->raw_data[(u32)offset], length); - return length; -} - -size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { - LOG_WARNING(Service_FS, "Attempted to write to ROMFS."); - return 0; -} - -size_t File_RomFS::GetSize() const { - return sizeof(u8) * archive->raw_data.size(); -} - -bool File_RomFS::SetSize(const u64 size) const { - LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS"); - return false; -} - -bool File_RomFS::Close() const { - return false; -} - -} // 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 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -#include "core/file_sys/file_backend.h" -#include "core/loader/loader.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// FileSys namespace - -namespace FileSys { - -class Archive_RomFS; - -class File_RomFS final : public FileBackend { -public: - File_RomFS(const Archive_RomFS* archive) : archive(archive) {} - - /** - * Open the file - * @return true if the file opened correctly - */ - bool Open() override; - - /** - * Read data from the file - * @param offset Offset in bytes to start reading data from - * @param length Length in bytes of data to read from file - * @param buffer Buffer to read data into - * @return Number of bytes read - */ - size_t Read(const u64 offset, const u32 length, u8* buffer) const override; - - /** - * Write data to the file - * @param offset Offset in bytes to start writing data to - * @param length Length in bytes of data to write to file - * @param flush The flush parameters (0 == do not flush) - * @param buffer Buffer to read data from - * @return Number of bytes written - */ - size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; - - /** - * Get the size of the file in bytes - * @return Size of the file in bytes - */ - size_t GetSize() const override; - - /** - * Set the size of the file in bytes - * @param size New size of the file - * @return true if successful - */ - bool SetSize(const u64 size) const override; - - /** - * Close the file - * @return true if the file closed correctly - */ - bool Close() const override; - - void Flush() const override { } - -private: - const Archive_RomFS* archive; -}; - -} // 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/common_types.h" +#include "common/file_util.h" +#include "common/make_unique.h" + +#include "core/file_sys/ivfc_archive.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +IVFCArchive::IVFCArchive() { +} + +std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { + return Common::make_unique<IVFCFile>(this); +} + +bool IVFCArchive::DeleteFile(const Path& path) const { + LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::DeleteDirectory(const Path& path) const { + LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); + return false; +} + +ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const { + LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); +} + +bool IVFCArchive::CreateDirectory(const Path& path) const { + LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); + return false; +} + +bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + return false; +} + +std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) const { + return Common::make_unique<IVFCDirectory>(); +} + +ResultCode IVFCArchive::Format(const Path& path) const { + LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { + LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); + memcpy(buffer, &archive->raw_data[(u32)offset], length); + return length; +} + +size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { + LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); + return 0; +} + +size_t IVFCFile::GetSize() const { + return sizeof(u8) * archive->raw_data.size(); +} + +bool IVFCFile::SetSize(const u64 size) const { + LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); + return false; +} + +} // 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 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> + +#include "common/common_types.h" + +#include "core/file_sys/archive_backend.h" +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +/** + * Helper which implements an interface to deal with IVFC images used in some archives + * This should be subclassed by concrete archive types, which will provide the + * input data (load the raw IVFC archive) and override any required methods + */ +class IVFCArchive : public ArchiveBackend { +public: + IVFCArchive(); + + std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; + bool DeleteFile(const Path& path) const override; + bool RenameFile(const Path& src_path, const Path& dest_path) const override; + bool DeleteDirectory(const Path& path) const override; + ResultCode CreateFile(const Path& path, u32 size) const override; + bool CreateDirectory(const Path& path) const override; + bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; + std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; + ResultCode Format(const Path& path) const override; + +protected: + friend class IVFCFile; + std::vector<u8> raw_data; +}; + +class IVFCFile : public FileBackend { +public: + IVFCFile(const IVFCArchive* archive) : archive(archive) {} + + bool Open() override { return true; } + size_t Read(const u64 offset, const u32 length, u8* buffer) const override; + size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override; + size_t GetSize() const override; + bool SetSize(const u64 size) const override; + bool Close() const override { return false; } + void Flush() const override { } + +private: + const IVFCArchive* archive; +}; + +class IVFCDirectory : public DirectoryBackend { +public: + bool Open() override { return false; } + u32 Read(const u32 count, Entry* entries) override { return 0; } + bool Close() const override { return false; } +}; + +} // namespace FileSys 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 @@ #include "common/make_unique.h" #include "common/math_util.h" -#include "core/file_sys/archive_savedata.h" -#include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_backend.h" +#include "core/file_sys/archive_extsavedata.h" +#include "core/file_sys/archive_romfs.h" +#include "core/file_sys/archive_savedata.h" +#include "core/file_sys/archive_savedatacheck.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" @@ -50,6 +52,9 @@ enum class FileCommand : u32 { SetAttributes = 0x08070040, Close = 0x08080000, Flush = 0x08090000, + SetPriority = 0x080A0040, + GetPriority = 0x080B0000, + OpenLinkFile = 0x080C0000, }; // Command to access directory @@ -63,7 +68,7 @@ enum class DirectoryCommand : u32 { class Archive { public: Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) - : backend(std::move(backend)), id_code(id_code) { + : id_code(id_code), backend(std::move(backend)) { } std::string GetName() const { return "Archive: " + backend->GetName(); } @@ -75,12 +80,13 @@ public: class File : public Kernel::Session { public: File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) - : backend(std::move(backend)), path(path) { + : path(path), backend(std::move(backend)), priority(0) { } std::string GetName() const override { return "Path: " + path.DebugStr(); } FileSys::Path path; ///< Path of the file + u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface ResultVal<bool> SyncRequest() override { @@ -145,6 +151,27 @@ public: break; } + case FileCommand::OpenLinkFile: + { + LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); + cmd_buff[3] = GetHandle(); + break; + } + + case FileCommand::SetPriority: + { + priority = cmd_buff[1]; + LOG_TRACE(Service_FS, "SetPriority %u", priority); + break; + } + + case FileCommand::GetPriority: + { + cmd_buff[2] = priority; + LOG_TRACE(Service_FS, "GetPriority"); + break; + } + // Unknown command... default: LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); @@ -160,7 +187,7 @@ public: class Directory : public Kernel::Session { public: Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) - : backend(std::move(backend)), path(path) { + : path(path), backend(std::move(backend)) { } std::string GetName() const override { return "Directory: " + path.DebugStr(); } @@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) { +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) { Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return InvalidHandle(ErrorModule::FS); @@ -435,6 +462,11 @@ void ArchiveInit() { else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", sharedextsavedata_directory.c_str()); + + // Create the SaveDataCheck archive, basically a small variation of the RomFS archive + std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX); + auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory); + CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); } /// 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 { SystemSaveData = 0x00000008, SDMC = 0x00000009, SDMCWriteOnly = 0x0000000A, + SaveDataCheck = 0x2345678A, }; typedef u64 ArchiveHandle; @@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy * @param file_size The size of the new file, filled with zeroes * @return File creation result code */ -ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size); +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size); /** * Create a Directory from an Archive diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 9fbf18b26..8e7abcf9c 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -404,7 +404,7 @@ static void Fcntl(Service::Interface* self) { } #endif } else { - LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call"); + LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call", ctr_cmd); result = TranslateError(EINVAL); // TODO: Find the correct error posix_ret = -1; return; 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: int GetSectionSize(SectionID section) const { return sections[section].sh_size; } SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found - bool DidRelocate() { + bool DidRelocate() const { return relocate; } }; |